Jananath Banuka
Jananath Banuka

Reputation: 3943

GoLang - How to get the Kubernetes modifications

I am new to golang and I have the following requirement:

  1. I have a deployment running with the image nginx:latest
  2. Then manually someone update this image to something else (eg: nginx:1.22)
  3. I need to get the old image version and the new image version

So, I researched on the "Shared Informers" in Go Lang. And I wrote this:


func main() {

. . . 

    // create shared informers for resources in all known API group versions with a reSync period and namespace
    factory := informers.NewSharedInformerFactoryWithOptions(clientSet, 1*time.Hour, informers.WithNamespace(namespace_to_watch))
    podInformer := factory.Core().V1().Pods().Informer()

    defer runtime.HandleCrash()

    // start informer ->
    go factory.Start(stopper)

    // start to sync and call list
    if !cache.WaitForCacheSync(stopper, podInformer.HasSynced) {
        runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))
        return
    }

    podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
        AddFunc:    onAdd, // register add eventhandler
        UpdateFunc: onUpdate,
        DeleteFunc: onDelete,
    })
}

func onUpdate(oldObj interface{}, newObj interface{}) {
    oldPod := oldObj.(*corev1.Pod)
    newPod := newObj.(*corev1.Pod)

    for container_old := range oldPod.Spec.Containers {
       fmt.Printf("Container Old :%s", container_old.Image )
    }

    for container_new := range newPod.Spec.Containers {
       fmt.Printf("Container New :%s", container_new.Image )
    }
  
}

As above, according to the onUpdate function, I should be getting the two values, instead, I am getting the same value on each update as below:

Container Old : nginx:latest

Container New : nginx:latest

Container Old : nginx:1.22

Container New : nginx:1.22

Container Old : nginx:1.22

Container New : nginx:1.22

Above output is because somehow, the onUpdate function is triggered thrice, but as you can see in all the times, the values are the same (for each output). But I was expecting something like below:

Container Old : nginx:latest

Container New : nginx:1.22

Can someone help me with this?

Upvotes: 1

Views: 443

Answers (1)

Raihan Khan
Raihan Khan

Reputation: 456

When an image is updated in the deployments, the pods restart with new image containers and there's no trace of the old pod spec remains. You should watch the deployments instead of the pods and check the image between old deployment and new deployment object. Here's a sample of how you can modify your onUpdate method.

func onUpdate(oldObj interface{}, newObj interface{}) {
    oldDepl := oldObj.(*v1.Deployment)
    newDepl := newObj.(*v1.Deployment)

    for oldContainerID := range oldDepl.Spec.Template.Spec.Containers {
        for newContainerID := range newDepl.Spec.Template.Spec.Containers {
            if oldDepl.Spec.Template.Spec.Containers[oldContainerID].Name == newDepl.Spec.Template.Spec.Containers[newContainerID].Name {
                if oldDepl.Spec.Template.Spec.Containers[oldContainerID].Image != newDepl.Spec.Template.Spec.Containers[newContainerID].Image {
                    fmt.Printf("CONTAINER IMAGE UPDATED FROM %s to %s",
                        oldDepl.Spec.Template.Spec.Containers[oldContainerID].Image, newDepl.Spec.Template.Spec.Containers[newContainerID].Image)
                }
            }
        }
    }
}

Upvotes: 1

Related Questions