Skip to content

Instantly share code, notes, and snippets.

@alaypatel07
Last active July 19, 2024 19:24
Show Gist options
  • Save alaypatel07/94a0766dc90262e3263b680082f62798 to your computer and use it in GitHub Desktop.
Save alaypatel07/94a0766dc90262e3263b680082f62798 to your computer and use it in GitHub Desktop.
avoiding 409 conflict errors with strategic merge patch
package main
import (
"context"
"encoding/json"
"fmt"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
// Load kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile)
if err != nil {
panic(err.Error())
}
// Create a clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
// Define a BusyBox pod
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "busybox-pod",
Namespace: "default",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "busybox",
Image: "busybox",
Command: []string{"sh", "-c", "sleep 3600"},
},
},
},
}
// Create the pod
createdPod, err := clientset.CoreV1().Pods("default").Create(context.TODO(), pod, metav1.CreateOptions{})
if err != nil {
panic(err.Error())
}
// Create a new pod object with the updated owner reference
updatedPod := createdPod.DeepCopy()
updatedPod.OwnerReferences = []metav1.OwnerReference{
{
APIVersion: "v1",
Kind: "Pod",
Name: createdPod.Name,
UID: createdPod.UID,
},
}
// Marshal the original and updated pod to JSON
originalJSON, err := json.Marshal(createdPod)
if err != nil {
panic(err.Error())
}
updatedJSON, err := json.Marshal(updatedPod)
if err != nil {
panic(err.Error())
}
// Create the strategic merge patch
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(originalJSON, updatedJSON, corev1.Pod{})
if err != nil {
panic(err.Error())
}
fmt.Println("created pod version: ", createdPod.ResourceVersion)
getPod, err := clientset.CoreV1().Pods("default").Get(context.TODO(), pod.Name, metav1.GetOptions{})
if err != nil {
panic(err.Error())
}
fmt.Println("pod version now: ", getPod.ResourceVersion)
// Update the pod with a strategic merge patch
_, err = clientset.CoreV1().Pods("default").Patch(context.TODO(), createdPod.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{})
if err != nil {
panic(fmt.Errorf("update failed: %v", err))
}
fmt.Printf("Updated pod %s with owner reference\n", createdPod.Name)
createdPod.Annotations = map[string]string{
"apiVersion": "v1",
"kind": "Pod",
"name": createdPod.Name,
"uid": string(createdPod.UID),
}
fmt.Println("created pod version: ", createdPod.ResourceVersion)
getPod, err = clientset.CoreV1().Pods("default").Get(context.TODO(), pod.Name, metav1.GetOptions{})
if err != nil {
panic(err.Error())
}
fmt.Println("pod version now: ", getPod.ResourceVersion)
_, err = clientset.CoreV1().Pods("default").Update(context.TODO(), createdPod, metav1.UpdateOptions{})
if err != nil {
if errors.IsConflict(err) {
fmt.Println("conflict error found")
}
panic(fmt.Errorf("update failed: %v", err))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment