From 1688aa6dea8ac0d3c19dd55de4228c582fab5fb4 Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Sun, 2 Mar 2025 17:03:03 +0100 Subject: [PATCH] moved configuration to fetcher object. --- cmd/fetcher/{sync.go => fetcher.go} | 42 ++++++++++++++++------------- cmd/fetcher/main.go | 19 +++++-------- 2 files changed, 31 insertions(+), 30 deletions(-) rename cmd/fetcher/{sync.go => fetcher.go} (76%) diff --git a/cmd/fetcher/sync.go b/cmd/fetcher/fetcher.go similarity index 76% rename from cmd/fetcher/sync.go rename to cmd/fetcher/fetcher.go index c791a83..e97e347 100644 --- a/cmd/fetcher/sync.go +++ b/cmd/fetcher/fetcher.go @@ -13,7 +13,15 @@ import ( "time" ) -func canonicalizeImageName(image string) string { +type Fetcher struct { + KubernetesNamespace string + SocketPath string + ContainerdNamespace string + Nodename string + ReadyDuration time.Duration +} + +func (fetcher *Fetcher) canonicalizeImageName(image string) string { pattern := `^(?:(?P[a-zA-Z0-9][-a-zA-Z0-9.]*[a-zA-Z0-9](?::[0-9]+)?)/)?(?P(?:[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*)*)?)?(?::(?P[\w][\w.-]{0,127}))?(?:@(?P[a-z][a-z0-9]*(?:[+.-][a-z][a-z0-9]*)*:[a-zA-Z0-9*+,-./:;=@_]{32,}))?$` re := regexp.MustCompile(pattern) matches := re.FindStringSubmatch(image) @@ -64,11 +72,11 @@ func canonicalizeImageName(image string) string { return fullimage } -func isReadyForSomeTime(pod *v1.Pod, duration time.Duration) bool { +func (fetcher *Fetcher) isReadyForSomeTime(pod *v1.Pod) bool { ready := false for _, condition := range pod.Status.Conditions { if condition.Type == corev1.PodReady && condition.Status == corev1.ConditionTrue { - if time.Now().Sub(condition.LastTransitionTime.Time) > duration { + if time.Now().Sub(condition.LastTransitionTime.Time) > fetcher.ReadyDuration { ready = true } } @@ -79,9 +87,8 @@ func isReadyForSomeTime(pod *v1.Pod, duration time.Duration) bool { return ready } -func getContainers(clientset *kubernetes.Clientset, kubernetesNamespace, nodename string, - readyDuration time.Duration) map[string]bool { - pods, err := clientset.CoreV1().Pods(kubernetesNamespace).List(context.Background(), +func (fetcher *Fetcher) getContainers(clientset *kubernetes.Clientset) map[string]bool { + pods, err := clientset.CoreV1().Pods(fetcher.KubernetesNamespace).List(context.Background(), metav1.ListOptions{}) if err != nil { panic(err) @@ -94,21 +101,21 @@ func getContainers(clientset *kubernetes.Clientset, kubernetesNamespace, nodenam klog.V(3).Infof("%s/%s\n", pod.Namespace, pod.Name) for _, container := range pod.Spec.InitContainers { klog.V(3).Infof(" %s\n", container.Image) - if pod.Spec.NodeName == nodename { - containersOnCurrentNode[canonicalizeImageName(container.Image)] = true + if pod.Spec.NodeName == fetcher.Nodename { + containersOnCurrentNode[fetcher.canonicalizeImageName(container.Image)] = true } else { - if isReadyForSomeTime(&pod, readyDuration) { - containers[canonicalizeImageName(container.Image)] = true + if fetcher.isReadyForSomeTime(&pod) { + containers[fetcher.canonicalizeImageName(container.Image)] = true } } } for _, container := range pod.Spec.Containers { klog.V(3).Infof(" %s\n", container.Image) - if pod.Spec.NodeName == nodename { - containersOnCurrentNode[canonicalizeImageName(container.Image)] = true + if pod.Spec.NodeName == fetcher.Nodename { + containersOnCurrentNode[fetcher.canonicalizeImageName(container.Image)] = true } else { - if isReadyForSomeTime(&pod, readyDuration) { - containers[canonicalizeImageName(container.Image)] = true + if fetcher.isReadyForSomeTime(&pod) { + containers[fetcher.canonicalizeImageName(container.Image)] = true } } } @@ -120,11 +127,10 @@ func getContainers(clientset *kubernetes.Clientset, kubernetesNamespace, nodenam return containers } -func pullAndPin(kubernetesNamespace, socketPath, containerdNamespace, nodename string, - readyDuration time.Duration) error { +func (fetcher *Fetcher) pullAndPin() error { // Create the image manager - containerd, err := NewContainerd(socketPath, containerdNamespace) + containerd, err := NewContainerd(fetcher.SocketPath, fetcher.ContainerdNamespace) if err != nil { klog.Fatalf("Failed to create image manager: %v", err) } @@ -136,7 +142,7 @@ func pullAndPin(kubernetesNamespace, socketPath, containerdNamespace, nodename s clientset, _ := GetKubernetesConnection() - containers := getContainers(clientset, kubernetesNamespace, nodename, readyDuration) + containers := fetcher.getContainers(clientset) for container, _ := range containers { klog.V(3).Infof("Found container %s\n", container) } diff --git a/cmd/fetcher/main.go b/cmd/fetcher/main.go index 8d36287..dfdeaf2 100644 --- a/cmd/fetcher/main.go +++ b/cmd/fetcher/main.go @@ -12,11 +12,7 @@ func main() { klogFlags := goflags.NewFlagSet("", goflags.PanicOnError) klog.InitFlags(klogFlags) - var kubernetesNamespace string - var socketPath string - var containerdNamespace string - var nodename string - var readyDuration time.Duration + fetcher := Fetcher{} cmd := &cobra.Command{ Use: "kube-fetcher", @@ -26,21 +22,20 @@ Queries k8s for all running pods and makes sure that all images referenced in pods are made available on the local k8s node and pinned so they don't get garbage collected'`, RunE: func(cmd *cobra.Command, args []string) error { - err := pullAndPin(kubernetesNamespace, socketPath, containerdNamespace, nodename, - readyDuration) + err := fetcher.pullAndPin() return err }, } - cmd.PersistentFlags().StringVar(&kubernetesNamespace, "kubernetes-namespace", + cmd.PersistentFlags().StringVar(&fetcher.KubernetesNamespace, "kubernetes-namespace", "", "Kubernetes containerdNamespace to inspect (default is all namespaces)") - cmd.PersistentFlags().StringVar(&socketPath, "socket", + cmd.PersistentFlags().StringVar(&fetcher.SocketPath, "socket", "/run/containerd/containerd.sock", "Containerd socket") - cmd.PersistentFlags().StringVar(&containerdNamespace, "containerd-namespace", + cmd.PersistentFlags().StringVar(&fetcher.ContainerdNamespace, "containerd-namespace", "k8s.io", "Containerd namespace to use") - cmd.PersistentFlags().StringVar(&nodename, "nodename", "", + cmd.PersistentFlags().StringVar(&fetcher.Nodename, "nodename", "", "Kubernetes node name the fetcher is running on, it will only fetch images running on other nodes") - cmd.PersistentFlags().DurationVar(&readyDuration, "ready-duration", + cmd.PersistentFlags().DurationVar(&fetcher.ReadyDuration, "ready-duration", 1*time.Hour, "Time a pod must be ready before its image will be fetched") cmd.Flags().AddGoFlagSet(klogFlags)