From 18978d87ca93e0d2673497ec478171eaf68c4dc7 Mon Sep 17 00:00:00 2001 From: Andrea Mazzotti Date: Wed, 21 Aug 2024 16:32:31 +0200 Subject: [PATCH] Add SeedImage.status.checksumURL Signed-off-by: Andrea Mazzotti --- .obs/chartfile/crds/templates/crds.yaml | 4 +++ api/v1beta1/seedimage_type.go | 3 ++ .../bases/elemental.cattle.io_seedimages.yaml | 4 +++ controllers/seedimage_controller.go | 29 ++++++++++++++----- pkg/server/api_seedimage.go | 5 ++-- pkg/server/api_seedimage_test.go | 4 +-- 6 files changed, 37 insertions(+), 12 deletions(-) diff --git a/.obs/chartfile/crds/templates/crds.yaml b/.obs/chartfile/crds/templates/crds.yaml index bc8358ff3..dae1cb588 100644 --- a/.obs/chartfile/crds/templates/crds.yaml +++ b/.obs/chartfile/crds/templates/crds.yaml @@ -3815,6 +3815,10 @@ spec: type: object status: properties: + checksumURL: + description: ChecksumURL the URL from which the SeedImage checksum + can be downloaded once the image is built. + type: string conditions: description: Conditions describe the state of the machine registration object. diff --git a/api/v1beta1/seedimage_type.go b/api/v1beta1/seedimage_type.go index 9bd2e653a..b28473440 100644 --- a/api/v1beta1/seedimage_type.go +++ b/api/v1beta1/seedimage_type.go @@ -114,6 +114,9 @@ type SeedImageStatus struct { // DownloadURL the URL from which the SeedImage can be downloaded once built. // +optional DownloadURL string `json:"downloadURL,omitempty"` + // ChecksumURL the URL from which the SeedImage checksum can be downloaded once the image is built. + // +optional + ChecksumURL string `json:"checksumURL,omitempty"` // State reflect the state of the seed image build process. // +kubebuilder:validation:Enum=Initialized;Started;Completed;Failed;NotStarted // +optional diff --git a/config/crd/bases/elemental.cattle.io_seedimages.yaml b/config/crd/bases/elemental.cattle.io_seedimages.yaml index feb31f163..07dbbcbb7 100644 --- a/config/crd/bases/elemental.cattle.io_seedimages.yaml +++ b/config/crd/bases/elemental.cattle.io_seedimages.yaml @@ -159,6 +159,10 @@ spec: type: object status: properties: + checksumURL: + description: ChecksumURL the URL from which the SeedImage checksum + can be downloaded once the image is built. + type: string conditions: description: Conditions describe the state of the machine registration object. diff --git a/controllers/seedimage_controller.go b/controllers/seedimage_controller.go index ea03149bb..ac864077f 100644 --- a/controllers/seedimage_controller.go +++ b/controllers/seedimage_controller.go @@ -317,7 +317,7 @@ func (r *SeedImageReconciler) reconcileConfigMapObject(ctx context.Context, seed return fmt.Errorf("failed marshalling cloud-config: %w", err) } - outputName := fmt.Sprintf("elemental-%s-%s.%s", seedImg.Spec.MachineRegistrationRef.Name, time.Now().Format(time.RFC3339), seedImg.Spec.Type) + outputName := fmt.Sprintf("%s-%s.%s", mRegistration.Name, time.Now().Format(time.RFC3339), seedImg.Spec.Type) if err := r.Get(ctx, types.NamespacedName{ Name: seedImg.Name, @@ -448,13 +448,21 @@ func (r *SeedImageReconciler) updateStatusFromPod(ctx context.Context, seedImg * return errMsg } - // Use the registration name or else default to "elemental" for the image file name - imageName := "elemental" - if seedImg.Spec.MachineRegistrationRef != nil && len(seedImg.Spec.MachineRegistrationRef.Name) > 0 { - imageName = seedImg.Spec.MachineRegistrationRef.Name + podConfigMap := &corev1.ConfigMap{} + if err := r.Get(ctx, types.NamespacedName{ + Name: seedImg.Name, + Namespace: seedImg.Namespace, + }, podConfigMap); err != nil { + return fmt.Errorf("getting ConfigMap '%s': %w", seedImg.Name, err) + } + outputName, found := podConfigMap.Data[configMapKeyOutputName] + if !found { + return fmt.Errorf("Could not find '%s' value in ConfigMap '%s'", configMapKeyOutputName, seedImg.Name) } + seedImg.Status.DownloadToken = token - seedImg.Status.DownloadURL = fmt.Sprintf("https://%s/elemental/seedimage/%s/%s.%s", rancherURL, token, imageName, seedImg.Spec.Type) + seedImg.Status.DownloadURL = fmt.Sprintf("https://%s/elemental/seedimage/%s/%s", rancherURL, token, outputName) + seedImg.Status.ChecksumURL = fmt.Sprintf("%s.sha256", seedImg.Status.DownloadURL) meta.SetStatusCondition(&seedImg.Status.Conditions, metav1.Condition{ Type: elementalv1.SeedImageConditionReady, Status: metav1.ConditionTrue, @@ -482,6 +490,7 @@ func (r *SeedImageReconciler) updateStatusFromPod(ctx context.Context, seedImg * return errMsg } seedImg.Status.DownloadURL = "" + seedImg.Status.ChecksumURL = "" meta.SetStatusCondition(&seedImg.Status.Conditions, metav1.Condition{ Type: elementalv1.SeedImageConditionReady, Status: metav1.ConditionTrue, @@ -519,6 +528,7 @@ func (r *SeedImageReconciler) deleteChildResources(ctx context.Context, seedImg } } seedImg.Status.DownloadURL = "" + seedImg.Status.ChecksumURL = "" foundSvc := &corev1.Service{} svcName := seedImg.Name @@ -593,14 +603,13 @@ func fillBuildImagePod(seedImg *elementalv1.SeedImage, buildImg string, pullPoli ContainerPort: 80, }, }, - Args: []string{"-d", "$(ELEMENTAL_OUTPUT_NAME)", "-t", fmt.Sprintf("%d", deadline*60)}, + Args: []string{"-d", "/srv", "-t", fmt.Sprintf("%d", deadline*60)}, VolumeMounts: []corev1.VolumeMount{ { Name: "iso-storage", MountPath: "/srv", }, }, - WorkingDir: "/srv", Env: []corev1.EnvVar{ { Name: "ELEMENTAL_OUTPUT_NAME", @@ -672,6 +681,8 @@ func defaultRawInitContainers(seedImg *elementalv1.SeedImage, buildImg string, p --system $(ELEMENTAL_BASE_IMAGE)`, platformArg), "mv /iso/elemental.raw /iso/$(ELEMENTAL_OUTPUT_NAME)", + + "cd /iso && sha256sum $(ELEMENTAL_OUTPUT_NAME) > $(ELEMENTAL_OUTPUT_NAME).sha256 && cd ../", } return []corev1.Container{ @@ -735,6 +746,8 @@ func defaultIsoInitContainers(seedImg *elementalv1.SeedImage, buildImg string, p ) } + buildCommands = append(buildCommands, "cd /iso && sha256sum $(ELEMENTAL_OUTPUT_NAME) > $(ELEMENTAL_OUTPUT_NAME).sha256 && cd ../") + containers = append( containers, corev1.Container{ Name: "build", diff --git a/pkg/server/api_seedimage.go b/pkg/server/api_seedimage.go index 772c977b9..3d63052ef 100644 --- a/pkg/server/api_seedimage.go +++ b/pkg/server/api_seedimage.go @@ -35,12 +35,13 @@ func (i *InventoryServer) apiSeedImage(resp http.ResponseWriter, req *http.Reque var seedImg *elementalv1.SeedImage // expected splittedPath = {"seedimage", {token}, {imgName.imgType}} - if len(splittedPath) < 2 { + if len(splittedPath) < 3 { err = fmt.Errorf("unexpected path: %v", splittedPath) http.Error(resp, err.Error(), http.StatusNotFound) return err } token := splittedPath[1] + fileName := splittedPath[2] if seedImg, err = i.getSeedImage(token); err != nil { http.Error(resp, err.Error(), http.StatusNotFound) @@ -54,7 +55,7 @@ func (i *InventoryServer) apiSeedImage(resp http.ResponseWriter, req *http.Reque return errMsg } - rawURL := fmt.Sprintf("http://%s", svc.Spec.ClusterIP) + rawURL := fmt.Sprintf("http://%s/%s", svc.Spec.ClusterIP, fileName) seedImgURL, err := url.Parse(rawURL) if err != nil { errMsg := fmt.Errorf("failed to parse url '%s'", rawURL) diff --git a/pkg/server/api_seedimage_test.go b/pkg/server/api_seedimage_test.go index 835b59c29..48a82ed8b 100644 --- a/pkg/server/api_seedimage_test.go +++ b/pkg/server/api_seedimage_test.go @@ -52,12 +52,12 @@ func TestApiSeedImage(t *testing.T) { t.Logf("Testing token %s\n", test.token) req := httptest.NewRequest( "GET", - fmt.Sprintf("%s/%s", "http://localhost/elemental/seedimage/", test.token), + fmt.Sprintf("%s/%s/foo.bar", "http://localhost/elemental/seedimage/", test.token), nil) resp := httptest.NewRecorder() splittedPath := test.splittedPath if splittedPath == nil { - splittedPath = []string{"seedimage", test.token} + splittedPath = []string{"seedimage", test.token, "foo.bar"} } err := server.apiSeedImage(resp, req, splittedPath)