From 2260deb2da2c8e5695ecd40bca39d2dc86e3cac7 Mon Sep 17 00:00:00 2001 From: Andrew Block Date: Sun, 19 Aug 2018 12:20:06 -0500 Subject: [PATCH] Various enhancements (#14) --- cmd/istio-pod-network-controller/init/init.go | 9 +++- cmd/istio-pod-network-controller/run/run.go | 8 +--- pkg/handler/handler.go | 11 +++-- pkg/init/init.go | 48 ++++++++++++------- 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/cmd/istio-pod-network-controller/init/init.go b/cmd/istio-pod-network-controller/init/init.go index bac1a49..a63103a 100644 --- a/cmd/istio-pod-network-controller/init/init.go +++ b/cmd/istio-pod-network-controller/init/init.go @@ -17,6 +17,7 @@ package init import ( "os" "runtime" + "time" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -48,10 +49,14 @@ func NewInitCmd() *cobra.Command { initCmd.Flags().String("file", initial.PodAnnotationsFileName, "Location of the file containing Pod Annotations") initCmd.Flags().String("annotation-key", initial.PodAnnotationsKeyName, "Name of the Annotation Key to Wait For") initCmd.Flags().String("annotation-value", initial.PodAnnotationsValueName, "Name of the Annotation Value to Wait For") + initCmd.Flags().Int("timeout", initial.InitTimeout, "Timeout value waiting for pod annotation") + initCmd.Flags().Int("delay", initial.InitDelay, "Amount of time between checking whether pod has been annotated") viper.BindPFlag("file", initCmd.Flags().Lookup("file")) viper.BindPFlag("annotation-key", initCmd.Flags().Lookup("annotation-key")) viper.BindPFlag("annotation-value", initCmd.Flags().Lookup("annotation-value")) + viper.BindPFlag("timeout", initCmd.Flags().Lookup("timeout")) + viper.BindPFlag("delay", initCmd.Flags().Lookup("delay")) return initCmd @@ -69,10 +74,12 @@ func initFunc(cmd *cobra.Command, args []string) { file := viper.GetString("file") annotationKey := viper.GetString("annotation-key") annotationValue := viper.GetString("annotation-value") + delay := viper.GetInt("delay") + timeout := viper.GetInt("timeout") log.Printf("Waiting for Initialized Pod Annotation (%s=%s)", annotationKey, annotationValue) - err := initial.WaitForAnnotationInFile(file, annotationKey, annotationValue) + err := initial.WaitForAnnotationInFile(file, annotationKey, annotationValue, time.Duration(timeout)*time.Second, delay) if err != nil { log.Errorf("Error occurred waiting for pod annotation in file: %v", err) diff --git a/cmd/istio-pod-network-controller/run/run.go b/cmd/istio-pod-network-controller/run/run.go index 4e25369..5512cf0 100644 --- a/cmd/istio-pod-network-controller/run/run.go +++ b/cmd/istio-pod-network-controller/run/run.go @@ -17,20 +17,16 @@ package run import ( "context" + "runtime" + "github.com/spf13/cobra" "github.com/spf13/viper" - "context" - - "runtime" - "github.com/docker/docker/client" sdk "github.com/operator-framework/operator-sdk/pkg/sdk" sdkVersion "github.com/operator-framework/operator-sdk/version" handler "github.com/sabre1041/istio-pod-network-controller/pkg/handler" "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - "github.com/spf13/viper" ) var log = logrus.New() diff --git a/pkg/handler/handler.go b/pkg/handler/handler.go index dfb3900..0948c02 100644 --- a/pkg/handler/handler.go +++ b/pkg/handler/handler.go @@ -13,6 +13,7 @@ import ( "github.com/docker/docker/client" "github.com/operator-framework/operator-sdk/pkg/sdk" "github.com/sirupsen/logrus" + "k8s.io/client-go/tools/cache" "github.com/spf13/viper" corev1 "k8s.io/api/core/v1" @@ -159,27 +160,29 @@ func (h *Handler) getPidDocker(ctx context.Context, pod *corev1.Pod) (string, er func filterPod(pod *corev1.Pod) bool { + podNamespaceName, _ := cache.MetaNamespaceKeyFunc(pod) + // filter by state if pod.Status.Phase != "Running" && pod.Status.Phase != "Pending" { - log.Debugf("Pod %s terminated, ignoring", pod.ObjectMeta.Name) + log.Debugf("Pod %s terminated, ignoring", podNamespaceName) return false } // make sure the pod if not a deployer pod if _, ok := pod.ObjectMeta.Labels[DeployerPodAnnotation]; ok { - log.Debugf("Pod %s is a deployer, ignoring", pod.ObjectMeta.Name) + log.Debugf("Pod %s is a deployer, ignoring", podNamespaceName) return false } // make sure the pod if not a build pod if _, ok := pod.ObjectMeta.Labels[BuildPodAnnotation]; ok { - log.Debugf("Pod %s is a builder, ignoring", pod.ObjectMeta.Name) + log.Debugf("Pod %s is a builder, ignoring", podNamespaceName) return false } // filter by being already initialized if PodNetworkControllerAnnotationInitialized == pod.ObjectMeta.Annotations[PodNetworkControllerAnnotation] { - log.Infof("Pod %s previously initialized, ignoring", pod.ObjectMeta.Name) + log.Infof("Pod %s previously initialized, ignoring", podNamespaceName) return false } diff --git a/pkg/init/init.go b/pkg/init/init.go index 16e463f..1d2e49b 100644 --- a/pkg/init/init.go +++ b/pkg/init/init.go @@ -2,7 +2,9 @@ package init import ( "bufio" + "errors" "fmt" + "io/ioutil" "os" "strings" "time" @@ -11,41 +13,55 @@ import ( const PodAnnotationsFileName = "/etc/podinfo/pod_annotations" const PodAnnotationsKeyName = "pod-network-controller.istio.io/status" const PodAnnotationsValueName = "initialized" +const InitTimeout = 300 +const InitDelay = 10 -func WaitForAnnotationInFile(filePath string, annotationKey string, annotationValue string) error { +func WaitForAnnotationInFile(filePath string, annotationKey string, annotationValue string, timeout time.Duration, delay int) error { if _, err := os.Stat(filePath); os.IsNotExist(err) { return fmt.Errorf("File '%s' Does Not Exist", filePath) } - for { - result, err := checkForAnnotation(filePath, annotationKey, annotationValue) + done := make(chan interface{}, 1) + var resultError error - if result { - break - } else if err != nil { - return err - } + deadline := time.Now().Add(timeout) - // Delay for 5 seconds - time.Sleep(time.Second * 5) + go func() { + defer close(done) - } + for time.Now().Before(deadline) { + result, err := checkForAnnotation(filePath, annotationKey, annotationValue) + + if result { + return + } else if err != nil { + resultError = err + return + } + + time.Sleep(time.Duration(delay) * time.Second) - return nil + } + }() + + select { + case <-time.After(timeout): + return errors.New("Timed out waiting for pod annotation") + case <-done: + return resultError + } } func checkForAnnotation(filePath string, annotationKey string, annotationValue string) (bool, error) { - file, err := os.Open(filePath) + fileContents, err := ioutil.ReadFile(filePath) if err != nil { return false, fmt.Errorf("Error accessing file: %v", err) } - defer file.Close() - - scanner := bufio.NewScanner(file) + scanner := bufio.NewScanner(strings.NewReader(string(fileContents))) for scanner.Scan() { line := scanner.Text()