Skip to content

Commit 6c5c4d0

Browse files
committed
Add Pods to recognized objects in sync package
Add functions for comparing Pods to sync package to allow pods to be handled with updates/syncing. This is necessary to allow using pods in workspace kubernetes-type components without having a warning condition set on the DevWorkspace Signed-off-by: Angel Misevski <[email protected]>
1 parent c106b4d commit 6c5c4d0

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

pkg/provision/sync/diff.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ var diffFuncs = map[reflect.Type]diffFunc{
4141
reflect.TypeOf(rbacv1.RoleBinding{}): allDiffFuncs(metadataDiffFunc, basicDiffFunc(rolebindingDiffOpts)),
4242
reflect.TypeOf(corev1.ServiceAccount{}): metadataDiffFunc,
4343
reflect.TypeOf(appsv1.Deployment{}): allDiffFuncs(deploymentDiffFunc, metadataDiffFunc, basicDiffFunc(deploymentDiffOpts)),
44+
reflect.TypeOf(corev1.Pod{}): allDiffFuncs(podDiffFunc, metadataDiffFunc),
4445
reflect.TypeOf(corev1.ConfigMap{}): allDiffFuncs(metadataDiffFunc, basicDiffFunc(configmapDiffOpts)),
4546
reflect.TypeOf(corev1.Secret{}): allDiffFuncs(metadataDiffFunc, basicDiffFunc(secretDiffOpts)),
4647
reflect.TypeOf(v1alpha1.DevWorkspaceRouting{}): allDiffFuncs(routingDiffFunc, metadataDiffFunc, basicDiffFunc(routingDiffOpts)),
@@ -105,6 +106,107 @@ func deploymentDiffFunc(spec, cluster crclient.Object) (delete, update bool) {
105106
return false, false
106107
}
107108

109+
func podDiffFunc(spec, cluster crclient.Object) (delete, update bool) {
110+
specPod := spec.(*corev1.Pod)
111+
clusterPod := cluster.(*corev1.Pod)
112+
// Check immutable podSpecFields -- unset fields we don't want to check
113+
specCopy := specPod.DeepCopy()
114+
clusterCopy := clusterPod.DeepCopy()
115+
for _, specVolume := range specCopy.Spec.Volumes {
116+
found := false
117+
for _, clusterVolume := range clusterCopy.Spec.Volumes {
118+
if equality.Semantic.DeepDerivative(specVolume, clusterVolume) {
119+
found = true
120+
break
121+
}
122+
}
123+
if !found {
124+
return true, false
125+
}
126+
}
127+
specCopy.Spec.ActiveDeadlineSeconds = clusterCopy.Spec.ActiveDeadlineSeconds
128+
specCopy.Spec.TerminationGracePeriodSeconds = clusterCopy.Spec.TerminationGracePeriodSeconds
129+
specCopy.Spec.Tolerations = clusterCopy.Spec.Tolerations
130+
specCopy.Spec.Containers = nil
131+
specCopy.Spec.InitContainers = nil
132+
specCopy.Spec.Volumes = nil
133+
if !equality.Semantic.DeepDerivative(specCopy.Spec, clusterCopy.Spec) {
134+
return true, false
135+
}
136+
137+
// Check mutable pod fields
138+
if specPod.Spec.ActiveDeadlineSeconds != nil &&
139+
specPod.Spec.ActiveDeadlineSeconds != clusterPod.Spec.ActiveDeadlineSeconds {
140+
return false, true
141+
}
142+
if specPod.Spec.TerminationGracePeriodSeconds != nil &&
143+
specPod.Spec.TerminationGracePeriodSeconds != clusterPod.Spec.TerminationGracePeriodSeconds {
144+
negOne := int64(-1)
145+
if clusterPod.Spec.TerminationGracePeriodSeconds == &negOne {
146+
return false, true
147+
} else {
148+
return true, false
149+
}
150+
}
151+
if len(specPod.Spec.Tolerations) > 0 {
152+
// Technically, it's safe to add tolerations. However, this would require including any default tolerations
153+
// in the object we're applying, so instead we delete the pod and re-create it if tolerations are changed.
154+
for _, specToleration := range clusterPod.Spec.Tolerations {
155+
found := false
156+
for _, clusterToleration := range clusterPod.Spec.Tolerations {
157+
if cmp.Equal(specToleration, clusterToleration) {
158+
found = true
159+
}
160+
}
161+
if !found {
162+
return true, false
163+
}
164+
}
165+
}
166+
167+
shouldDelete, shouldUpdate := containersDiffFunc(specPod.Spec.Containers, clusterPod.Spec.Containers)
168+
if shouldDelete || shouldUpdate {
169+
return shouldDelete, shouldUpdate
170+
}
171+
shouldDelete, shouldUpdate = containersDiffFunc(specPod.Spec.InitContainers, clusterPod.Spec.InitContainers)
172+
if shouldDelete || shouldUpdate {
173+
return shouldDelete, shouldUpdate
174+
}
175+
176+
return false, false
177+
}
178+
179+
// containersDiffFunc compares a pods containers/initContainers and returns whether
180+
// the pod should be re-created or updated. Only the image field in containers is
181+
// updatable.
182+
func containersDiffFunc(spec, cluster []corev1.Container) (delete, update bool) {
183+
findContainer := func(name string, containers []corev1.Container) (corev1.Container, bool) {
184+
for _, container := range containers {
185+
if container.Name == name {
186+
return container, true
187+
}
188+
}
189+
return corev1.Container{}, false
190+
}
191+
for _, clusterContainer := range cluster {
192+
specContainer, ok := findContainer(clusterContainer.Name, spec)
193+
if !ok {
194+
return true, false
195+
}
196+
specImage := specContainer.Image
197+
clusterImage := clusterContainer.Image
198+
// Images can be updated, so we want to ignore changes when checking for immutable fields
199+
specContainer.Image = clusterImage
200+
if !equality.Semantic.DeepDerivative(specContainer, clusterContainer) {
201+
return true, false
202+
}
203+
if specImage != clusterImage {
204+
return false, true
205+
}
206+
}
207+
return false, false
208+
}
209+
108210
func routingDiffFunc(spec, cluster crclient.Object) (delete, update bool) {
109211
specRouting := spec.(*v1alpha1.DevWorkspaceRouting)
110212
clusterRouting := cluster.(*v1alpha1.DevWorkspaceRouting)

pkg/provision/sync/diffopts.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ var deploymentDiffOpts = cmp.Options{
6565
}),
6666
}
6767

68+
var podDiffOpts = cmp.Options{
69+
cmpopts.IgnoreFields(corev1.Pod{}, "TypeMeta", "ObjectMeta", "Status"),
70+
}
71+
6872
var configmapDiffOpts = cmp.Options{
6973
cmpopts.IgnoreFields(corev1.ConfigMap{}, "TypeMeta", "ObjectMeta"),
7074
}

pkg/provision/sync/sync.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ func printDiff(specObj, clusterObj crclient.Object, log logr.Logger) {
196196
diffOpts = rolebindingDiffOpts
197197
case *appsv1.Deployment:
198198
diffOpts = deploymentDiffOpts
199+
case *corev1.Pod:
200+
diffOpts = podDiffOpts
199201
case *corev1.ConfigMap:
200202
diffOpts = configmapDiffOpts
201203
case *corev1.Secret:

0 commit comments

Comments
 (0)