Skip to content

Commit

Permalink
fix: avoid injector pod name collisions
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas Rodriguez committed Jun 13, 2024
1 parent 5c25319 commit 748fce5
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 16 deletions.
52 changes: 42 additions & 10 deletions src/pkg/cluster/injector.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package cluster

import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"net/http"
"os"
Expand Down Expand Up @@ -43,7 +45,7 @@ var (
type imageNodeMap map[string][]string

// StartInjectionMadness initializes a Zarf injection into the cluster.
func (c *Cluster) StartInjectionMadness(ctx context.Context, tmpDir string, imagesDir string, injectorSeedSrcs []string) {
func (c *Cluster) StartInjectionMadness(ctx context.Context, tmpDir string, imagesDir string, injectorSeedSrcs []string) error {
spinner := message.NewProgressSpinner("Attempting to bootstrap the seed image into the cluster")
defer spinner.Stop()

Expand Down Expand Up @@ -115,12 +117,21 @@ func (c *Cluster) StartInjectionMadness(ctx context.Context, tmpDir string, imag
GracePeriodSeconds: &deleteGracePeriod,
PropagationPolicy: &deletePolicy,
}
err := c.Clientset.CoreV1().Pods(ZarfNamespaceName).Delete(ctx, "injector", deleteOpts)
selector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "zarf-injector",
},
})
if err != nil {
message.Debug("could not delete pod injector:", err)
return err
}
listOpts := metav1.ListOptions{
LabelSelector: selector.String(),
}
err = c.Clientset.CoreV1().Pods(ZarfNamespaceName).DeleteCollection(ctx, deleteOpts, listOpts)
if err != nil {
return err
}

// Update the podspec image path and use the first node found

pod, err := c.buildInjectionPod(node[0], image, payloadConfigmaps, sha256sum)
if err != nil {
Expand All @@ -140,34 +151,46 @@ func (c *Cluster) StartInjectionMadness(ctx context.Context, tmpDir string, imag
// if no error, try and wait for a seed image to be present, return if successful
if c.injectorIsReady(ctx, seedImages, spinner) {
spinner.Success()
return
return nil
}

// Otherwise just continue to try next image
}

// All images were exhausted and still no happiness
spinner.Fatalf(nil, "Unable to perform the injection")
return nil
}

// StopInjectionMadness handles cleanup once the seed registry is up.
func (c *Cluster) StopInjectionMadness(ctx context.Context) error {
// Try to kill the injector pod now
err := c.Clientset.CoreV1().Pods(ZarfNamespaceName).Delete(ctx, "injector", metav1.DeleteOptions{})
selector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "zarf-injector",
},
})
if err != nil {
return err
}
listOpts := metav1.ListOptions{
LabelSelector: selector.String(),
}
err = c.Clientset.CoreV1().Pods(ZarfNamespaceName).DeleteCollection(ctx, metav1.DeleteOptions{}, listOpts)
if err != nil {
return err
}

// Remove the configmaps
selector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
selector, err = metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
MatchLabels: map[string]string{
"zarf-injector": "payload",
},
})
if err != nil {
return err
}
listOpts := metav1.ListOptions{
listOpts = metav1.ListOptions{
LabelSelector: selector.String(),
}
err = c.Clientset.CoreV1().ConfigMaps(ZarfNamespaceName).DeleteCollection(ctx, metav1.DeleteOptions{}, listOpts)
Expand Down Expand Up @@ -384,13 +407,22 @@ func (c *Cluster) createService(ctx context.Context) (*corev1.Service, error) {
// buildInjectionPod return a pod for injection with the appropriate containers to perform the injection.
func (c *Cluster) buildInjectionPod(node, image string, payloadConfigmaps []string, payloadShasum string) (*corev1.Pod, error) {
executeMode := int32(0777)

// Create a SHA-256 hash of the image name to allow unique injector pod names.
// This prevents collisions where `zarf init` is ran back to back and a previous injector pod still exists.
hasher := sha256.New()
if _, err := hasher.Write([]byte(image)); err != nil {
return nil, err
}
hash := hex.EncodeToString(hasher.Sum(nil))[:8]

pod := &corev1.Pod{
TypeMeta: metav1.TypeMeta{
APIVersion: corev1.SchemeGroupVersion.String(),
Kind: "Pod",
},
ObjectMeta: metav1.ObjectMeta{
Name: "injector",
Name: fmt.Sprintf("injector-%s", hash),
Namespace: ZarfNamespaceName,
Labels: map[string]string{
"app": "zarf-injector",
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/cluster/testdata/expected-injection-pod.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"kind":"Pod","apiVersion":"v1","metadata":{"name":"injector","namespace":"zarf","creationTimestamp":null,"labels":{"app":"zarf-injector","zarf.dev/agent":"ignore"}},"spec":{"volumes":[{"name":"init","configMap":{"name":"rust-binary","defaultMode":511}},{"name":"seed","emptyDir":{}},{"name":"foo","configMap":{"name":"foo"}},{"name":"bar","configMap":{"name":"bar"}}],"containers":[{"name":"injector","image":"docker.io/library/ubuntu:latest","command":["/zarf-init/zarf-injector","shasum"],"workingDir":"/zarf-init","resources":{"limits":{"cpu":"1","memory":"256Mi"},"requests":{"cpu":"500m","memory":"64Mi"}},"volumeMounts":[{"name":"init","mountPath":"/zarf-init/zarf-injector","subPath":"zarf-injector"},{"name":"seed","mountPath":"/zarf-seed"},{"name":"foo","mountPath":"/zarf-init/foo","subPath":"foo"},{"name":"bar","mountPath":"/zarf-init/bar","subPath":"bar"}],"readinessProbe":{"httpGet":{"path":"/v2/","port":5000},"periodSeconds":2,"successThreshold":1,"failureThreshold":10},"imagePullPolicy":"IfNotPresent"}],"restartPolicy":"Never","nodeName":"injection-node"},"status":{}}
{"kind":"Pod","apiVersion":"v1","metadata":{"name":"injector-b68304d6","namespace":"zarf","creationTimestamp":null,"labels":{"app":"zarf-injector","zarf.dev/agent":"ignore"}},"spec":{"volumes":[{"name":"init","configMap":{"name":"rust-binary","defaultMode":511}},{"name":"seed","emptyDir":{}},{"name":"foo","configMap":{"name":"foo"}},{"name":"bar","configMap":{"name":"bar"}}],"containers":[{"name":"injector","image":"docker.io/library/ubuntu:latest","command":["/zarf-init/zarf-injector","shasum"],"workingDir":"/zarf-init","resources":{"limits":{"cpu":"1","memory":"256Mi"},"requests":{"cpu":"500m","memory":"64Mi"}},"volumeMounts":[{"name":"init","mountPath":"/zarf-init/zarf-injector","subPath":"zarf-injector"},{"name":"seed","mountPath":"/zarf-seed"},{"name":"foo","mountPath":"/zarf-init/foo","subPath":"foo"},{"name":"bar","mountPath":"/zarf-init/bar","subPath":"bar"}],"readinessProbe":{"httpGet":{"path":"/v2/","port":5000},"periodSeconds":2,"successThreshold":1,"failureThreshold":10},"imagePullPolicy":"IfNotPresent"}],"restartPolicy":"Never","nodeName":"injection-node"},"status":{}}
13 changes: 8 additions & 5 deletions src/pkg/packager/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,13 @@ func (p *Packager) deployInitComponent(ctx context.Context, component types.Zarf
if component.RequiresCluster() && p.state == nil {
err = p.cluster.InitZarfState(ctx, p.cfg.InitOpts)
if err != nil {
return charts, fmt.Errorf("unable to initialize Zarf state: %w", err)
return nil, fmt.Errorf("unable to initialize Zarf state: %w", err)
}
}

if hasExternalRegistry && (isSeedRegistry || isInjector || isRegistry) {
message.Notef("Not deploying the component (%s) since external registry information was provided during `zarf init`", component.Name)
return charts, nil
return nil, nil
}

if isRegistry {
Expand All @@ -253,18 +253,21 @@ func (p *Packager) deployInitComponent(ctx context.Context, component types.Zarf

// Before deploying the seed registry, start the injector
if isSeedRegistry {
p.cluster.StartInjectionMadness(ctx, p.layout.Base, p.layout.Images.Base, component.Images)
err := p.cluster.StartInjectionMadness(ctx, p.layout.Base, p.layout.Images.Base, component.Images)
if err != nil {
return nil, err
}
}

charts, err = p.deployComponent(ctx, component, isAgent /* skip img checksum if isAgent */, isSeedRegistry /* skip image push if isSeedRegistry */)
if err != nil {
return charts, err
return nil, err
}

// Do cleanup for when we inject the seed registry during initialization
if isSeedRegistry {
if err := p.cluster.StopInjectionMadness(ctx); err != nil {
return charts, fmt.Errorf("unable to seed the Zarf Registry: %w", err)
return nil, fmt.Errorf("unable to seed the Zarf Registry: %w", err)
}
}

Expand Down

0 comments on commit 748fce5

Please sign in to comment.