diff --git a/api/v1/artifact_types.go b/api/v1/artifact_types.go index 97edfc43..21e44bfa 100644 --- a/api/v1/artifact_types.go +++ b/api/v1/artifact_types.go @@ -43,11 +43,6 @@ type Artifact struct { // +optional Revision string `json:"revision"` - // Checksum is the SHA256 checksum of the Artifact file. - // Deprecated: use Artifact.Digest instead. - // +optional - Checksum string `json:"checksum,omitempty"` - // Digest is the digest of the file in the form of ':'. // +optional // +kubebuilder:validation:Pattern="^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$" @@ -76,13 +71,13 @@ func (in *Artifact) HasRevision(revision string) bool { return TransformLegacyRevision(in.Revision) == TransformLegacyRevision(revision) } -// HasChecksum returns if the given checksum matches the current Checksum of -// the Artifact. -func (in *Artifact) HasChecksum(checksum string) bool { +// HasDigest returns if the given digest matches the current Digest of the +// Artifact. +func (in *Artifact) HasDigest(digest string) bool { if in == nil { return false } - return in.Checksum == checksum + return in.Digest == digest } // ArtifactDir returns the artifact dir path in the form of diff --git a/config/crd/bases/source.toolkit.fluxcd.io_buckets.yaml b/config/crd/bases/source.toolkit.fluxcd.io_buckets.yaml index f7c01722..73f21a1b 100644 --- a/config/crd/bases/source.toolkit.fluxcd.io_buckets.yaml +++ b/config/crd/bases/source.toolkit.fluxcd.io_buckets.yaml @@ -376,10 +376,6 @@ spec: artifact: description: Artifact represents the last successful Bucket reconciliation. properties: - checksum: - description: 'Checksum is the SHA256 checksum of the Artifact - file. Deprecated: use Artifact.Digest instead.' - type: string digest: description: Digest is the digest of the file in the form of ':'. pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ diff --git a/config/crd/bases/source.toolkit.fluxcd.io_gitrepositories.yaml b/config/crd/bases/source.toolkit.fluxcd.io_gitrepositories.yaml index 0588e905..de2477a0 100644 --- a/config/crd/bases/source.toolkit.fluxcd.io_gitrepositories.yaml +++ b/config/crd/bases/source.toolkit.fluxcd.io_gitrepositories.yaml @@ -198,10 +198,6 @@ spec: description: Artifact represents the last successful GitRepository reconciliation. properties: - checksum: - description: 'Checksum is the SHA256 checksum of the Artifact - file. Deprecated: use Artifact.Digest instead.' - type: string digest: description: Digest is the digest of the file in the form of ':'. pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ @@ -325,10 +321,6 @@ spec: items: description: Artifact represents the output of a Source reconciliation. properties: - checksum: - description: 'Checksum is the SHA256 checksum of the Artifact - file. Deprecated: use Artifact.Digest instead.' - type: string digest: description: Digest is the digest of the file in the form of ':'. @@ -973,10 +965,6 @@ spec: description: Artifact represents the last successful GitRepository reconciliation. properties: - checksum: - description: 'Checksum is the SHA256 checksum of the Artifact - file. Deprecated: use Artifact.Digest instead.' - type: string digest: description: Digest is the digest of the file in the form of ':'. pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ @@ -1100,10 +1088,6 @@ spec: items: description: Artifact represents the output of a Source reconciliation. properties: - checksum: - description: 'Checksum is the SHA256 checksum of the Artifact - file. Deprecated: use Artifact.Digest instead.' - type: string digest: description: Digest is the digest of the file in the form of ':'. diff --git a/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml b/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml index 28ec52c4..6c7b468d 100644 --- a/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml +++ b/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml @@ -451,10 +451,6 @@ spec: description: Artifact represents the output of the last successful reconciliation. properties: - checksum: - description: 'Checksum is the SHA256 checksum of the Artifact - file. Deprecated: use Artifact.Digest instead.' - type: string digest: description: Digest is the digest of the file in the form of ':'. pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ diff --git a/config/crd/bases/source.toolkit.fluxcd.io_helmrepositories.yaml b/config/crd/bases/source.toolkit.fluxcd.io_helmrepositories.yaml index 8be7d8d2..cd8d5098 100644 --- a/config/crd/bases/source.toolkit.fluxcd.io_helmrepositories.yaml +++ b/config/crd/bases/source.toolkit.fluxcd.io_helmrepositories.yaml @@ -368,10 +368,6 @@ spec: description: Artifact represents the last successful HelmRepository reconciliation. properties: - checksum: - description: 'Checksum is the SHA256 checksum of the Artifact - file. Deprecated: use Artifact.Digest instead.' - type: string digest: description: Digest is the digest of the file in the form of ':'. pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ diff --git a/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml b/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml index d610216c..1cd95d67 100644 --- a/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml +++ b/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml @@ -194,10 +194,6 @@ spec: description: Artifact represents the output of the last successful OCI Repository sync. properties: - checksum: - description: 'Checksum is the SHA256 checksum of the Artifact - file. Deprecated: use Artifact.Digest instead.' - type: string digest: description: Digest is the digest of the file in the form of ':'. pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ diff --git a/controllers/artifact_matchers_test.go b/controllers/artifact_matchers_test.go index 9ee26114..11b12a89 100644 --- a/controllers/artifact_matchers_test.go +++ b/controllers/artifact_matchers_test.go @@ -51,9 +51,6 @@ func (m matchArtifact) Match(actual interface{}) (success bool, err error) { if ok, err = Equal(m.expected.Revision).Match(actualArtifact.Revision); !ok { return ok, err } - if ok, err = Equal(m.expected.Checksum).Match(actualArtifact.Checksum); !ok { - return ok, err - } if ok, err = Equal(m.expected.Size).Match(actualArtifact.Size); !ok { return ok, err } diff --git a/controllers/bucket_controller.go b/controllers/bucket_controller.go index ccabfdf1..ad54781d 100644 --- a/controllers/bucket_controller.go +++ b/controllers/bucket_controller.go @@ -329,21 +329,13 @@ func (r *BucketReconciler) notify(ctx context.Context, oldObj, newObj *bucketv1. if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil { annotations := map[string]string{ fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaRevisionKey): newObj.Status.Artifact.Revision, - fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, - } - if newObj.Status.Artifact.Digest != "" { - annotations[sourcev1.GroupVersion.Group+"/"+eventv1.MetaDigestKey] = newObj.Status.Artifact.Digest - } - - var oldChecksum string - if oldObj.GetArtifact() != nil { - oldChecksum = oldObj.GetArtifact().Checksum + fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest, } message := fmt.Sprintf("stored artifact with %d fetched files from '%s' bucket", index.Len(), newObj.Spec.BucketName) // Notify on new artifact and failure recovery. - if oldChecksum != newObj.GetArtifact().Checksum { + if !oldObj.GetArtifact().HasDigest(newObj.GetArtifact().Digest) { r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal, "NewArtifact", message) ctrl.LoggerFrom(ctx).Info(message) diff --git a/controllers/bucket_controller_test.go b/controllers/bucket_controller_test.go index 409ca6f2..80b7967d 100644 --- a/controllers/bucket_controller_test.go +++ b/controllers/bucket_controller_test.go @@ -194,7 +194,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/reconcile-storage/d.txt", Revision: "d", - Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", + Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", URL: testStorage.Hostname + "/reconcile-storage/d.txt", Size: int64p(int64(len("d"))), }, @@ -242,7 +242,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) { obj.Status.Artifact = &sourcev1.Artifact{ Path: fmt.Sprintf("/reconcile-storage/hostname.txt"), Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: "http://outdated.com/reconcile-storage/hostname.txt", } if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { @@ -261,7 +261,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/reconcile-storage/hostname.txt", Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: testStorage.Hostname + "/reconcile-storage/hostname.txt", Size: int64p(int64(len("file"))), }, @@ -1293,7 +1293,7 @@ func TestBucketReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, newObjBeforeFunc: func(obj *bucketv1.Bucket) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} }, wantEvent: "Normal NewArtifact stored artifact with 2 fetched files from", }, @@ -1302,12 +1302,12 @@ func TestBucketReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *bucketv1.Bucket) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *bucketv1.Bucket) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, wantEvent: "Normal Succeeded stored artifact with 2 fetched files from", @@ -1317,12 +1317,12 @@ func TestBucketReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *bucketv1.Bucket) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *bucketv1.Bucket) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Checksum: "bbb"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, wantEvent: "Normal NewArtifact stored artifact with 2 fetched files from", @@ -1332,11 +1332,11 @@ func TestBucketReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *bucketv1.Bucket) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, newObjBeforeFunc: func(obj *bucketv1.Bucket) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, }, diff --git a/controllers/gitrepository_controller.go b/controllers/gitrepository_controller.go index eb7b15bb..aafd51b7 100644 --- a/controllers/gitrepository_controller.go +++ b/controllers/gitrepository_controller.go @@ -325,15 +325,7 @@ func (r *GitRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *so if r.shouldNotify(oldObj, newObj, res, resErr) { annotations := map[string]string{ fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaRevisionKey): newObj.Status.Artifact.Revision, - fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, - } - if newObj.Status.Artifact.Digest != "" { - annotations[sourcev1.GroupVersion.Group+"/"+eventv1.MetaDigestKey] = newObj.Status.Artifact.Digest - } - - var oldChecksum string - if oldObj.GetArtifact() != nil { - oldChecksum = oldObj.GetArtifact().Checksum + fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest, } // A partial commit due to no-op clone doesn't contain the commit @@ -346,7 +338,7 @@ func (r *GitRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *so } // Notify on new artifact and failure recovery. - if oldChecksum != newObj.GetArtifact().Checksum { + if !oldObj.GetArtifact().HasDigest(newObj.GetArtifact().Digest) { r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal, "NewArtifact", message) ctrl.LoggerFrom(ctx).Info(message) @@ -1019,7 +1011,7 @@ func gitContentConfigChanged(obj *sourcev1.GitRepository, includes *artifactSet) observedInclArtifact := obj.Status.IncludedArtifacts[index] currentIncl := artifacts[index] - // Check if the include are the same in spec and status. + // Check if include is the same in spec and status. if !gitRepositoryIncludeEqual(incl, observedIncl) { return true } @@ -1028,7 +1020,7 @@ func gitContentConfigChanged(obj *sourcev1.GitRepository, includes *artifactSet) if !observedInclArtifact.HasRevision(currentIncl.Revision) { return true } - if observedInclArtifact.Checksum != currentIncl.Checksum { + if !observedInclArtifact.HasDigest(currentIncl.Digest) { return true } } diff --git a/controllers/gitrepository_controller_test.go b/controllers/gitrepository_controller_test.go index 068d87be..688db75d 100644 --- a/controllers/gitrepository_controller_test.go +++ b/controllers/gitrepository_controller_test.go @@ -926,7 +926,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) { }, afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { t.Expect(obj.GetArtifact()).ToNot(BeNil()) - t.Expect(obj.GetArtifact().Checksum).To(Equal("60a3bf69f337cb5ec9ebd00abefbb6e7f2a2cf27158ecf438d52b2035b184172")) + t.Expect(obj.GetArtifact().Digest).To(Equal("sha256:60a3bf69f337cb5ec9ebd00abefbb6e7f2a2cf27158ecf438d52b2035b184172")) t.Expect(obj.Status.IncludedArtifacts).ToNot(BeEmpty()) t.Expect(obj.Status.URL).ToNot(BeEmpty()) }, @@ -938,14 +938,14 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) { { name: "Up-to-date artifact should not update status", dir: "testdata/git/repository", - includes: artifactSet{&sourcev1.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Checksum: "some-checksum"}}, + includes: artifactSet{&sourcev1.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Digest: "some-checksum"}}, beforeFunc: func(obj *sourcev1.GitRepository) { obj.Spec.Interval = metav1.Duration{Duration: interval} obj.Spec.Include = []sourcev1.GitRepositoryInclude{ {GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}}, } obj.Status.Artifact = &sourcev1.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91"} - obj.Status.IncludedArtifacts = []*sourcev1.Artifact{{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Checksum: "some-checksum"}} + obj.Status.IncludedArtifacts = []*sourcev1.Artifact{{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Digest: "some-checksum"}} obj.Status.ObservedInclude = obj.Spec.Include }, afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { @@ -959,14 +959,14 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) { { name: "Up-to-date artifact with legacy revision format should not update status", dir: "testdata/git/repository", - includes: artifactSet{&sourcev1.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Checksum: "some-checksum"}}, + includes: artifactSet{&sourcev1.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Digest: "some-checksum"}}, beforeFunc: func(obj *sourcev1.GitRepository) { obj.Spec.Interval = metav1.Duration{Duration: interval} obj.Spec.Include = []sourcev1.GitRepositoryInclude{ {GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}}, } obj.Status.Artifact = &sourcev1.Artifact{Revision: "main/b9b3feadba509cb9b22e968a5d27e96c2bc2ff91"} - obj.Status.IncludedArtifacts = []*sourcev1.Artifact{{Revision: "main/b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Checksum: "some-checksum"}} + obj.Status.IncludedArtifacts = []*sourcev1.Artifact{{Revision: "main/b9b3feadba509cb9b22e968a5d27e96c2bc2ff91", Digest: "some-checksum"}} obj.Status.ObservedInclude = obj.Spec.Include }, afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { @@ -987,7 +987,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) { }, afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { t.Expect(obj.GetArtifact()).ToNot(BeNil()) - t.Expect(obj.GetArtifact().Checksum).To(Equal("11f7f007dce5619bd79e6c57688261058d09f5271e802463ac39f2b9ead7cabd")) + t.Expect(obj.GetArtifact().Digest).To(Equal("sha256:11f7f007dce5619bd79e6c57688261058d09f5271e802463ac39f2b9ead7cabd")) }, want: sreconcile.ResultSuccess, assertConditions: []metav1.Condition{ @@ -1002,7 +1002,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) { }, afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { t.Expect(obj.GetArtifact()).ToNot(BeNil()) - t.Expect(obj.GetArtifact().Checksum).To(Equal("29186e024dde5a414cfc990829c6b2e85f6b3bd2d950f50ca9f418f5d2261d79")) + t.Expect(obj.GetArtifact().Digest).To(Equal("sha256:29186e024dde5a414cfc990829c6b2e85f6b3bd2d950f50ca9f418f5d2261d79")) }, want: sreconcile.ResultSuccess, assertConditions: []metav1.Condition{ @@ -1018,7 +1018,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) { }, afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { t.Expect(obj.GetArtifact()).ToNot(BeNil()) - t.Expect(obj.GetArtifact().Checksum).To(Equal("60a3bf69f337cb5ec9ebd00abefbb6e7f2a2cf27158ecf438d52b2035b184172")) + t.Expect(obj.GetArtifact().Digest).To(Equal("sha256:60a3bf69f337cb5ec9ebd00abefbb6e7f2a2cf27158ecf438d52b2035b184172")) t.Expect(obj.Status.URL).ToNot(BeEmpty()) }, want: sreconcile.ResultSuccess, @@ -1333,7 +1333,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/reconcile-storage/d.txt", Revision: "d", - Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", + Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", URL: testStorage.Hostname + "/reconcile-storage/d.txt", Size: int64p(int64(len("d"))), }, @@ -1381,7 +1381,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) { obj.Status.Artifact = &sourcev1.Artifact{ Path: "/reconcile-storage/hostname.txt", Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: "http://outdated.com/reconcile-storage/hostname.txt", } if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { @@ -1400,7 +1400,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/reconcile-storage/hostname.txt", Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: testStorage.Hostname + "/reconcile-storage/hostname.txt", Size: int64p(int64(len("file"))), }, @@ -2052,7 +2052,7 @@ func TestGitRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, newObjBeforeFunc: func(obj *sourcev1.GitRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} }, commit: concreteCommit, wantEvent: "Normal NewArtifact stored artifact for commit 'test commit'", @@ -2062,12 +2062,12 @@ func TestGitRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *sourcev1.GitRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *sourcev1.GitRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, commit: concreteCommit, @@ -2078,12 +2078,12 @@ func TestGitRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *sourcev1.GitRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *sourcev1.GitRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Checksum: "bbb"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, commit: concreteCommit, @@ -2094,11 +2094,11 @@ func TestGitRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *sourcev1.GitRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, newObjBeforeFunc: func(obj *sourcev1.GitRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, }, @@ -2107,12 +2107,12 @@ func TestGitRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultEmpty, resErr: noopErr, oldObjBeforeFunc: func(obj *sourcev1.GitRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *sourcev1.GitRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, commit: partialCommit, // no-op will always result in partial commit. @@ -2484,11 +2484,11 @@ func TestGitContentConfigChanged(t *testing.T) { ToPath: "baz", }, }, - IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}}, + IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}}, }, }, artifacts: []*sourcev1.Artifact{ - {Revision: "aaa", Checksum: "bbb"}, + {Revision: "aaa", Digest: "bbb"}, }, want: false, }, @@ -2512,16 +2512,16 @@ func TestGitContentConfigChanged(t *testing.T) { ToPath: "baz", }, }, - IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}}, + IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}}, }, }, artifacts: []*sourcev1.Artifact{ - {Revision: "ccc", Checksum: "bbb"}, + {Revision: "ccc", Digest: "bbb"}, }, want: true, }, { - name: "observed include but different artifact checksum", + name: "observed include but different artifact digest", obj: sourcev1.GitRepository{ Spec: sourcev1.GitRepositorySpec{ Include: []sourcev1.GitRepositoryInclude{ @@ -2540,11 +2540,11 @@ func TestGitContentConfigChanged(t *testing.T) { ToPath: "baz", }, }, - IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}}, + IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}}, }, }, artifacts: []*sourcev1.Artifact{ - {Revision: "aaa", Checksum: "ddd"}, + {Revision: "aaa", Digest: "ddd"}, }, want: true, }, @@ -2568,11 +2568,11 @@ func TestGitContentConfigChanged(t *testing.T) { ToPath: "baz", }, }, - IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}}, + IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}}, }, }, artifacts: []*sourcev1.Artifact{ - {Revision: "aaa", Checksum: "bbb"}, + {Revision: "aaa", Digest: "bbb"}, }, want: true, }, @@ -2595,14 +2595,14 @@ func TestGitContentConfigChanged(t *testing.T) { }, Status: sourcev1.GitRepositoryStatus{ IncludedArtifacts: []*sourcev1.Artifact{ - {Revision: "aaa", Checksum: "bbb"}, - {Revision: "ccc", Checksum: "ccc"}, + {Revision: "aaa", Digest: "bbb"}, + {Revision: "ccc", Digest: "ccc"}, }, }, }, artifacts: []*sourcev1.Artifact{ - {Revision: "aaa", Checksum: "bbb"}, - {Revision: "ccc", Checksum: "ddd"}, + {Revision: "aaa", Digest: "bbb"}, + {Revision: "ccc", Digest: "ddd"}, }, want: true, }, @@ -2637,13 +2637,13 @@ func TestGitContentConfigChanged(t *testing.T) { }, }, IncludedArtifacts: []*sourcev1.Artifact{ - {Revision: "aaa", Checksum: "bbb"}, - {Revision: "ccc", Checksum: "ccc"}, + {Revision: "aaa", Digest: "bbb"}, + {Revision: "ccc", Digest: "ccc"}, }, }, }, artifacts: []*sourcev1.Artifact{ - {Revision: "aaa", Checksum: "bbb"}, + {Revision: "aaa", Digest: "bbb"}, }, want: true, }, @@ -2678,13 +2678,13 @@ func TestGitContentConfigChanged(t *testing.T) { }, }, IncludedArtifacts: []*sourcev1.Artifact{ - {Revision: "aaa", Checksum: "bbb"}, + {Revision: "aaa", Digest: "bbb"}, }, }, }, artifacts: []*sourcev1.Artifact{ - {Revision: "aaa", Checksum: "bbb"}, - {Revision: "ccc", Checksum: "ccc"}, + {Revision: "aaa", Digest: "bbb"}, + {Revision: "ccc", Digest: "ccc"}, }, want: true, }, diff --git a/controllers/helmchart_controller.go b/controllers/helmchart_controller.go index 192cffce..5826313d 100644 --- a/controllers/helmchart_controller.go +++ b/controllers/helmchart_controller.go @@ -332,19 +332,11 @@ func (r *HelmChartReconciler) notify(ctx context.Context, oldObj, newObj *helmv1 if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil { annotations := map[string]string{ fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaRevisionKey): newObj.Status.Artifact.Revision, - fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, - } - if newObj.Status.Artifact.Digest != "" { - annotations[sourcev1.GroupVersion.Group+"/"+eventv1.MetaDigestKey] = newObj.Status.Artifact.Digest - } - - var oldChecksum string - if oldObj.GetArtifact() != nil { - oldChecksum = oldObj.GetArtifact().Checksum + fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest, } // Notify on new artifact and failure recovery. - if oldChecksum != newObj.GetArtifact().Checksum { + if !oldObj.GetArtifact().HasDigest(newObj.GetArtifact().Digest) { r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal, reasonForBuild(build), build.Summary()) ctrl.LoggerFrom(ctx).Info(build.Summary()) @@ -803,7 +795,7 @@ func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj } if obj.Spec.SourceRef.Kind == helmv1.BucketKind { if dig := digest.Digest(sourcev1.TransformLegacyRevision(rev)); dig.Validate() == nil { - rev = dig.Hex() + rev = dig.Encoded() } } if kind := obj.Spec.SourceRef.Kind; kind == sourcev1.GitRepositoryKind || kind == helmv1.BucketKind { diff --git a/controllers/helmchart_controller_test.go b/controllers/helmchart_controller_test.go index 900d3b4e..00924d29 100644 --- a/controllers/helmchart_controller_test.go +++ b/controllers/helmchart_controller_test.go @@ -315,7 +315,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/reconcile-storage/d.txt", Revision: "d", - Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", + Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", URL: testStorage.Hostname + "/reconcile-storage/d.txt", Size: int64p(int64(len("d"))), }, @@ -363,7 +363,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) { obj.Status.Artifact = &sourcev1.Artifact{ Path: "/reconcile-storage/hostname.txt", Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: "http://outdated.com/reconcile-storage/hostname.txt", } if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { @@ -382,7 +382,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/reconcile-storage/hostname.txt", Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: testStorage.Hostname + "/reconcile-storage/hostname.txt", Size: int64p(int64(len("file"))), }, @@ -1440,7 +1440,7 @@ func TestHelmChartReconciler_reconcileArtifact(t *testing.T) { }, afterFunc: func(t *WithT, obj *helmv1.HelmChart) { t.Expect(obj.GetArtifact()).ToNot(BeNil()) - t.Expect(obj.GetArtifact().Checksum).To(Equal("bbdf96023c912c393b49d5238e227576ed0d20d1bb145d7476d817b80e20c11a")) + t.Expect(obj.GetArtifact().Digest).To(Equal("sha256:bbdf96023c912c393b49d5238e227576ed0d20d1bb145d7476d817b80e20c11a")) t.Expect(obj.GetArtifact().Revision).To(Equal("0.1.0")) t.Expect(obj.Status.URL).ToNot(BeEmpty()) t.Expect(obj.Status.ObservedChartName).To(Equal("helmchart")) @@ -1501,7 +1501,7 @@ func TestHelmChartReconciler_reconcileArtifact(t *testing.T) { }, afterFunc: func(t *WithT, obj *helmv1.HelmChart) { t.Expect(obj.GetArtifact()).ToNot(BeNil()) - t.Expect(obj.GetArtifact().Checksum).To(Equal("bbdf96023c912c393b49d5238e227576ed0d20d1bb145d7476d817b80e20c11a")) + t.Expect(obj.GetArtifact().Digest).To(Equal("sha256:bbdf96023c912c393b49d5238e227576ed0d20d1bb145d7476d817b80e20c11a")) t.Expect(obj.GetArtifact().Revision).To(Equal("0.1.0")) t.Expect(obj.Status.URL).ToNot(BeEmpty()) t.Expect(obj.Status.ObservedChartName).To(Equal("helmchart")) @@ -2088,7 +2088,7 @@ func TestHelmChartReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, newObjBeforeFunc: func(obj *helmv1.HelmChart) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} }, wantEvent: "Normal ChartPackageSucceeded packaged", }, @@ -2097,12 +2097,12 @@ func TestHelmChartReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *helmv1.HelmChart) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *helmv1.HelmChart) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, wantEvent: "Normal ChartPackageSucceeded packaged", @@ -2112,12 +2112,12 @@ func TestHelmChartReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *helmv1.HelmChart) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *helmv1.HelmChart) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Checksum: "bbb"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, wantEvent: "Normal ChartPackageSucceeded packaged", @@ -2127,11 +2127,11 @@ func TestHelmChartReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *helmv1.HelmChart) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, newObjBeforeFunc: func(obj *helmv1.HelmChart) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, }, diff --git a/controllers/helmrepository_controller.go b/controllers/helmrepository_controller.go index 6ae7a731..bd4d0077 100644 --- a/controllers/helmrepository_controller.go +++ b/controllers/helmrepository_controller.go @@ -292,10 +292,7 @@ func (r *HelmRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *h if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil { annotations := map[string]string{ fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaRevisionKey): newObj.Status.Artifact.Revision, - fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, - } - if newObj.Status.Artifact.Digest != "" { - annotations[sourcev1.GroupVersion.Group+"/"+eventv1.MetaDigestKey] = newObj.Status.Artifact.Digest + fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest, } humanReadableSize := "unknown size" @@ -303,15 +300,10 @@ func (r *HelmRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *h humanReadableSize = fmt.Sprintf("size %s", units.HumanSize(float64(*size))) } - var oldChecksum string - if oldObj.GetArtifact() != nil { - oldChecksum = oldObj.GetArtifact().Checksum - } - message := fmt.Sprintf("stored fetched index of %s from '%s'", humanReadableSize, chartRepo.URL) // Notify on new artifact and failure recovery. - if oldChecksum != newObj.GetArtifact().Checksum { + if !oldObj.GetArtifact().HasDigest(newObj.GetArtifact().Digest) { r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal, "NewArtifact", message) ctrl.LoggerFrom(ctx).Info(message) @@ -471,9 +463,6 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc // Early comparison to current Artifact. if curArtifact := obj.GetArtifact(); curArtifact != nil { curDig := digest.Digest(curArtifact.Digest) - if curDig == "" { - curDig = digest.Digest(sourcev1.TransformLegacyRevision(curArtifact.Checksum)) - } if curDig.Validate() == nil { // Short-circuit based on the fetched index being an exact match to the // stored Artifact. @@ -532,7 +521,7 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc *artifact = r.Storage.NewArtifactFor(obj.Kind, obj.ObjectMeta.GetObjectMeta(), revision.String(), - fmt.Sprintf("index-%s.yaml", revision.Hex()), + fmt.Sprintf("index-%s.yaml", revision.Encoded()), ) return sreconcile.ResultSuccess, nil @@ -560,7 +549,7 @@ func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pa } }() - if obj.GetArtifact().HasRevision(artifact.Revision) && obj.GetArtifact().HasChecksum(artifact.Checksum) { + if obj.GetArtifact().HasRevision(artifact.Revision) && obj.GetArtifact().HasDigest(artifact.Digest) { // Extend TTL of the Index in the cache (if present). if r.Cache != nil { r.Cache.SetExpiration(artifact.Path, r.TTL) diff --git a/controllers/helmrepository_controller_test.go b/controllers/helmrepository_controller_test.go index 1a6d7a6b..1dd9e141 100644 --- a/controllers/helmrepository_controller_test.go +++ b/controllers/helmrepository_controller_test.go @@ -170,7 +170,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/reconcile-storage/d.txt", Revision: "d", - Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", + Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", URL: testStorage.Hostname + "/reconcile-storage/d.txt", Size: int64p(int64(len("d"))), }, @@ -218,7 +218,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) { obj.Status.Artifact = &sourcev1.Artifact{ Path: "/reconcile-storage/hostname.txt", Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: "http://outdated.com/reconcile-storage/hostname.txt", } if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { @@ -237,7 +237,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/reconcile-storage/hostname.txt", Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: testStorage.Hostname + "/reconcile-storage/hostname.txt", Size: int64p(int64(len("file"))), }, @@ -317,7 +317,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { server options url string secret *corev1.Secret - beforeFunc func(t *WithT, obj *helmv1.HelmRepository, revision, digest digest.Digest) + beforeFunc func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) afterFunc func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) want sreconcile.Result wantErr bool @@ -352,7 +352,6 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) { t.Expect(chartRepo.Path).ToNot(BeEmpty()) t.Expect(chartRepo.Index).ToNot(BeNil()) - t.Expect(artifact.Checksum).To(BeEmpty()) t.Expect(artifact.Revision).ToNot(BeEmpty()) }, }, @@ -372,7 +371,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { "password": []byte("1234"), }, }, - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, checksum digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "basic-auth"} }, want: sreconcile.ResultSuccess, @@ -383,7 +382,6 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) { t.Expect(chartRepo.Path).ToNot(BeEmpty()) t.Expect(chartRepo.Index).ToNot(BeNil()) - t.Expect(artifact.Checksum).To(BeEmpty()) t.Expect(artifact.Revision).ToNot(BeEmpty()) }, }, @@ -403,7 +401,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { "caFile": tlsCA, }, }, - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, checksum digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "ca-file"} }, want: sreconcile.ResultSuccess, @@ -414,7 +412,6 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) { t.Expect(chartRepo.Path).ToNot(BeEmpty()) t.Expect(chartRepo.Index).ToNot(BeNil()) - t.Expect(artifact.Checksum).To(BeEmpty()) t.Expect(artifact.Revision).ToNot(BeEmpty()) }, }, @@ -434,7 +431,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { "caFile": []byte("invalid"), }, }, - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, checksum digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "invalid-ca"} conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") @@ -449,14 +446,13 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { // No repo index due to fetch fail. t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Index).To(BeNil()) - t.Expect(artifact.Checksum).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty()) }, }, { name: "Invalid URL makes FetchFailed=True and returns stalling error", protocol: "http", - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, checksum digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Spec.URL = strings.ReplaceAll(obj.Spec.URL, "http://", "") conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") @@ -472,14 +468,13 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { // No repo index due to fetch fail. t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Index).To(BeNil()) - t.Expect(artifact.Checksum).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty()) }, }, { name: "Unsupported scheme makes FetchFailed=True and returns stalling error", protocol: "http", - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, checksum digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Spec.URL = strings.ReplaceAll(obj.Spec.URL, "http://", "ftp://") conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") @@ -495,14 +490,13 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { // No repo index due to fetch fail. t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Index).To(BeNil()) - t.Expect(artifact.Checksum).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty()) }, }, { name: "Missing secret returns FetchFailed=True and returns error", protocol: "http", - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, checksum digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "non-existing"} conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") @@ -517,7 +511,6 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { // No repo index due to fetch fail. t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Index).To(BeNil()) - t.Expect(artifact.Checksum).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty()) }, }, @@ -532,7 +525,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { "username": []byte("git"), }, }, - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, checksum digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "malformed-basic-auth"} conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") @@ -547,43 +540,16 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { // No repo index due to fetch fail. t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Index).To(BeNil()) - t.Expect(artifact.Checksum).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty()) }, }, { name: "Stored index with same digest and revision", protocol: "http", - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, digest digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Status.Artifact = &sourcev1.Artifact{ - Revision: revision.String(), - Digest: digest.String(), - Checksum: digest.Hex(), - } - - conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") - conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") - conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, "foo", "bar") - }, - assertConditions: []metav1.Condition{ - *conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"), - *conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"), - }, - afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) { - t.Expect(chartRepo.Path).ToNot(BeEmpty()) - t.Expect(chartRepo.Index).To(BeNil()) - - t.Expect(&artifact).To(BeEquivalentTo(obj.Status.Artifact)) - }, - want: sreconcile.ResultSuccess, - }, - { - name: "Stored index with same checksum and (legacy) revision", - protocol: "http", - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, digest digest.Digest) { - obj.Status.Artifact = &sourcev1.Artifact{ - Revision: revision.Hex(), - Checksum: digest.Hex(), + Revision: rev.String(), + Digest: dig.String(), } conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") @@ -605,11 +571,10 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { { name: "Stored index with different digest and same revision", protocol: "http", - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, digest digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Status.Artifact = &sourcev1.Artifact{ - Revision: revision.String(), + Revision: rev.String(), Digest: "sha256:80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86", - Checksum: "80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86", } conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") @@ -626,17 +591,15 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { t.Expect(artifact.Revision).To(Equal(obj.Status.Artifact.Revision)) t.Expect(artifact.Digest).ToNot(Equal(obj.Status.Artifact.Digest)) - t.Expect(artifact.Checksum).ToNot(Equal(obj.Status.Artifact.Checksum)) }, want: sreconcile.ResultSuccess, }, { name: "Stored index with different revision and digest", protocol: "http", - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, checksum digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Status.Artifact = &sourcev1.Artifact{ Revision: "80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86", - Checksum: "80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86", Digest: "sha256:80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86", } conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") @@ -654,14 +617,13 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { t.Expect(artifact.Path).To(Not(BeEmpty())) t.Expect(artifact.Revision).ToNot(Equal(obj.Status.Artifact.Revision)) t.Expect(artifact.Digest).ToNot(Equal(obj.Status.Artifact.Digest)) - t.Expect(artifact.Checksum).ToNot(Equal(obj.Status.Artifact.Checksum)) }, want: sreconcile.ResultSuccess, }, { name: "Existing artifact makes ArtifactOutdated=True", protocol: "http", - beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, revision, checksum digest.Digest) { + beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev, dig digest.Digest) { obj.Status.Artifact = &sourcev1.Artifact{ Path: "some-path", Revision: "some-rev", @@ -736,7 +698,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { builder.WithObjects(secret.DeepCopy()) } - // Calculate the artifact checksum for valid repos configurations. + // Calculate the artifact digest for valid repos configurations. clientOpts := []helmgetter.Option{ helmgetter.WithURL(server.URL()), } @@ -745,7 +707,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { validSecret := true if secret != nil { // Extract the client options from secret, ignoring any invalid - // value. validSecret is used to determine if the indexChecksum + // value. validSecret is used to determine if the index digest // should be calculated below. var cOpts []helmgetter.Option var serr error @@ -768,18 +730,18 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) { } g.Expect(err).ToNot(HaveOccurred()) - // NOTE: checksum will be empty in beforeFunc for invalid repo + // NOTE: digest will be empty in beforeFunc for invalid repo // configurations as the client can't get the repo. - var revision, checksum digest.Digest + var rev, dig digest.Digest if validSecret { g.Expect(newChartRepo.CacheIndex()).To(Succeed()) - checksum = newChartRepo.Digest(intdigest.Canonical) + dig = newChartRepo.Digest(intdigest.Canonical) g.Expect(newChartRepo.LoadFromPath()).To(Succeed()) - revision = newChartRepo.Digest(intdigest.Canonical) + rev = newChartRepo.Digest(intdigest.Canonical) } if tt.beforeFunc != nil { - tt.beforeFunc(g, obj, revision, checksum) + tt.beforeFunc(g, obj, rev, dig) } r := &HelmRepositoryReconciler{ @@ -942,8 +904,8 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) { chartRepo.Path = cachePath artifact := testStorage.NewArtifactFor(obj.Kind, obj, "existing", "foo.tar.gz") - // Checksum of the index file calculated by the ChartRepository. - artifact.Checksum = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + // Digest of the index file calculated by the ChartRepository. + artifact.Digest = "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" if tt.beforeFunc != nil { tt.beforeFunc(g, obj, artifact, chartRepo) @@ -1218,7 +1180,7 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, newObjBeforeFunc: func(obj *helmv1.HelmRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy", Size: nil} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: nil} }, wantEvent: "Normal NewArtifact stored fetched index of unknown size", }, @@ -1227,7 +1189,7 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, newObjBeforeFunc: func(obj *helmv1.HelmRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy", Size: &aSize} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize} }, wantEvent: "Normal NewArtifact stored fetched index of size", }, @@ -1236,12 +1198,12 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *helmv1.HelmRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy", Size: &aSize} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *helmv1.HelmRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy", Size: &aSize} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, wantEvent: "Normal Succeeded stored fetched index of size", @@ -1251,12 +1213,12 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *helmv1.HelmRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy", Size: &aSize} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *helmv1.HelmRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Checksum: "bbb", Size: &aSize} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb", Size: &aSize} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, wantEvent: "Normal NewArtifact stored fetched index of size", @@ -1266,11 +1228,11 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *helmv1.HelmRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy", Size: &aSize} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, newObjBeforeFunc: func(obj *helmv1.HelmRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy", Size: &aSize} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, }, diff --git a/controllers/ocirepository_controller.go b/controllers/ocirepository_controller.go index c547a6b2..0b6dc2a2 100644 --- a/controllers/ocirepository_controller.go +++ b/controllers/ocirepository_controller.go @@ -1139,15 +1139,7 @@ func (r *OCIRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *oc if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil { annotations := map[string]string{ fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaRevisionKey): newObj.Status.Artifact.Revision, - fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, - } - if newObj.Status.Artifact.Digest != "" { - annotations[sourcev1.GroupVersion.Group+"/"+eventv1.MetaDigestKey] = newObj.Status.Artifact.Digest - } - - var oldChecksum string - if oldObj.GetArtifact() != nil { - oldChecksum = oldObj.GetArtifact().Checksum + fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest, } message := fmt.Sprintf("stored artifact with revision '%s' from '%s'", newObj.Status.Artifact.Revision, newObj.Spec.URL) @@ -1167,7 +1159,7 @@ func (r *OCIRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *oc } // Notify on new artifact and failure recovery. - if oldChecksum != newObj.GetArtifact().Checksum { + if !oldObj.GetArtifact().HasDigest(newObj.GetArtifact().Digest) { r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal, "NewArtifact", message) ctrl.LoggerFrom(ctx).Info(message) diff --git a/controllers/ocirepository_controller_test.go b/controllers/ocirepository_controller_test.go index e2aa67c1..7f3b172f 100644 --- a/controllers/ocirepository_controller_test.go +++ b/controllers/ocirepository_controller_test.go @@ -66,6 +66,7 @@ import ( sourcev1 "github.com/fluxcd/source-controller/api/v1" ociv1 "github.com/fluxcd/source-controller/api/v1beta2" + intdigest "github.com/fluxcd/source-controller/internal/digest" serror "github.com/fluxcd/source-controller/internal/error" sreconcile "github.com/fluxcd/source-controller/internal/reconcile" ) @@ -210,9 +211,9 @@ func TestOCIRepository_Reconcile(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) defer f2.Close() - h := testStorage.Checksum(f2) - t.Logf("file %q hash: %q", expectedFile, h) - g.Expect(h).To(Equal(af.expectedChecksum)) + d, err := intdigest.Canonical.FromReader(f2) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(d.Encoded()).To(Equal(af.expectedChecksum)) } // Check if the object status is valid @@ -1483,7 +1484,7 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) { "latest.tar.gz", }, afterFunc: func(g *WithT, obj *ociv1.OCIRepository) { - g.Expect(obj.Status.Artifact.Checksum).To(Equal("de37cb640bfe6c789f2b131416d259747d5757f7fe5e1d9d48f32d8c30af5934")) + g.Expect(obj.Status.Artifact.Digest).To(Equal("sha256:de37cb640bfe6c789f2b131416d259747d5757f7fe5e1d9d48f32d8c30af5934")) }, assertConditions: []metav1.Condition{ *conditions.TrueCondition(sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "stored artifact for digest"), @@ -1501,7 +1502,7 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) { "latest.tar.gz", }, afterFunc: func(g *WithT, obj *ociv1.OCIRepository) { - g.Expect(obj.Status.Artifact.Checksum).To(Equal("05aada03e3e3e96f5f85a8f31548d833974ce862be14942fb3313eef2df861ec")) + g.Expect(obj.Status.Artifact.Digest).To(Equal("sha256:05aada03e3e3e96f5f85a8f31548d833974ce862be14942fb3313eef2df861ec")) }, assertConditions: []metav1.Condition{ *conditions.TrueCondition(sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "stored artifact for digest"), @@ -1876,7 +1877,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/oci-reconcile-storage/d.txt", Revision: "d", - Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", + Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", URL: testStorage.Hostname + "/oci-reconcile-storage/d.txt", Size: int64p(int64(len("d"))), }, @@ -1924,7 +1925,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) { obj.Status.Artifact = &sourcev1.Artifact{ Path: "/oci-reconcile-storage/hostname.txt", Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: "http://outdated.com/oci-reconcile-storage/hostname.txt", } if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { @@ -1943,7 +1944,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) { assertArtifact: &sourcev1.Artifact{ Path: "/oci-reconcile-storage/hostname.txt", Revision: "f", - Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", + Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", URL: testStorage.Hostname + "/oci-reconcile-storage/hostname.txt", Size: int64p(int64(len("file"))), }, @@ -2071,7 +2072,7 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) { obj.Spec.URL = "oci://newurl.io" obj.Status.Artifact = &sourcev1.Artifact{ Revision: "xxx", - Checksum: "yyy", + Digest: "yyy", Metadata: map[string]string{ oci.SourceAnnotation: "https://github.com/stefanprodan/podinfo", oci.RevisionAnnotation: "6.1.8/b3b00fe35424a45d373bf4c7214178bc36fd7872", @@ -2085,13 +2086,13 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *ociv1.OCIRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.ReadOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *ociv1.OCIRepository) { obj.Spec.URL = "oci://newurl.io" - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, wantEvent: "Normal Succeeded stored artifact with revision 'xxx' from 'oci://newurl.io'", @@ -2101,13 +2102,13 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *ociv1.OCIRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.ReadOperationFailedReason, "fail") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") }, newObjBeforeFunc: func(obj *ociv1.OCIRepository) { obj.Spec.URL = "oci://newurl.io" - obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Checksum: "bbb"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, wantEvent: "Normal NewArtifact stored artifact with revision 'aaa' from 'oci://newurl.io'", @@ -2117,11 +2118,11 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultSuccess, resErr: nil, oldObjBeforeFunc: func(obj *ociv1.OCIRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, newObjBeforeFunc: func(obj *ociv1.OCIRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready") }, }, @@ -2130,7 +2131,7 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) { res: sreconcile.ResultRequeue, resErr: nil, oldObjBeforeFunc: func(obj *ociv1.OCIRepository) { - obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Checksum: "yyy"} + obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy"} conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.URLInvalidReason, "ready") }, }, diff --git a/controllers/storage.go b/controllers/storage.go index a482ac7b..43a78e98 100644 --- a/controllers/storage.go +++ b/controllers/storage.go @@ -20,9 +20,7 @@ import ( "archive/tar" "compress/gzip" "context" - "crypto/sha256" "fmt" - "hash" "io" "io/fs" "net/url" @@ -34,7 +32,6 @@ import ( securejoin "github.com/cyphar/filepath-securejoin" "github.com/fluxcd/go-git/v5/plumbing/format/gitignore" - "github.com/opencontainers/go-digest" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kerrors "k8s.io/apimachinery/pkg/util/errors" @@ -349,7 +346,7 @@ func SourceIgnoreFilter(ps []gitignore.Pattern, domain []string) ArchiveFileFilt // Archive atomically archives the given directory as a tarball to the given v1beta1.Artifact path, excluding // directories and any ArchiveFileFilter matches. While archiving, any environment specific data (for example, // the user and group name) is stripped from file headers. -// If successful, it sets the checksum and last update time on the artifact. +// If successful, it sets the digest and last update time on the artifact. func (s *Storage) Archive(artifact *sourcev1.Artifact, dir string, filter ArchiveFileFilter) (err error) { if f, err := os.Stat(dir); os.IsNotExist(err) || !f.IsDir() { return fmt.Errorf("invalid dir path: %s", dir) @@ -367,12 +364,9 @@ func (s *Storage) Archive(artifact *sourcev1.Artifact, dir string, filter Archiv } }() - md, err := intdigest.NewMultiDigester(intdigest.Canonical, digest.SHA256) - if err != nil { - return fmt.Errorf("failed to create digester: %w", err) - } + d := intdigest.Canonical.Digester() sz := &writeCounter{} - mw := io.MultiWriter(md, tf, sz) + mw := io.MultiWriter(d.Hash(), tf, sz) gw := gzip.NewWriter(mw) tw := tar.NewWriter(gw) @@ -466,8 +460,7 @@ func (s *Storage) Archive(artifact *sourcev1.Artifact, dir string, filter Archiv return err } - artifact.Digest = md.Digest(intdigest.Canonical).String() - artifact.Checksum = md.Digest(digest.SHA256).Encoded() + artifact.Digest = d.Digest().String() artifact.LastUpdateTime = metav1.Now() artifact.Size = &sz.written @@ -475,7 +468,7 @@ func (s *Storage) Archive(artifact *sourcev1.Artifact, dir string, filter Archiv } // AtomicWriteFile atomically writes the io.Reader contents to the v1beta1.Artifact path. -// If successful, it sets the checksum and last update time on the artifact. +// If successful, it sets the digest and last update time on the artifact. func (s *Storage) AtomicWriteFile(artifact *sourcev1.Artifact, reader io.Reader, mode os.FileMode) (err error) { localPath := s.LocalPath(*artifact) tf, err := os.CreateTemp(filepath.Split(localPath)) @@ -489,12 +482,9 @@ func (s *Storage) AtomicWriteFile(artifact *sourcev1.Artifact, reader io.Reader, } }() - md, err := intdigest.NewMultiDigester(intdigest.Canonical, digest.SHA256) - if err != nil { - return fmt.Errorf("failed to create digester: %w", err) - } + d := intdigest.Canonical.Digester() sz := &writeCounter{} - mw := io.MultiWriter(md, tf, sz) + mw := io.MultiWriter(tf, d.Hash(), sz) if _, err := io.Copy(mw, reader); err != nil { tf.Close() @@ -512,8 +502,7 @@ func (s *Storage) AtomicWriteFile(artifact *sourcev1.Artifact, reader io.Reader, return err } - artifact.Digest = md.Digest(intdigest.Canonical).String() - artifact.Checksum = md.Digest(digest.SHA256).Encoded() + artifact.Digest = d.Digest().String() artifact.LastUpdateTime = metav1.Now() artifact.Size = &sz.written @@ -521,7 +510,7 @@ func (s *Storage) AtomicWriteFile(artifact *sourcev1.Artifact, reader io.Reader, } // Copy atomically copies the io.Reader contents to the v1beta1.Artifact path. -// If successful, it sets the checksum and last update time on the artifact. +// If successful, it sets the digest and last update time on the artifact. func (s *Storage) Copy(artifact *sourcev1.Artifact, reader io.Reader) (err error) { localPath := s.LocalPath(*artifact) tf, err := os.CreateTemp(filepath.Split(localPath)) @@ -535,12 +524,9 @@ func (s *Storage) Copy(artifact *sourcev1.Artifact, reader io.Reader) (err error } }() - md, err := intdigest.NewMultiDigester(intdigest.Canonical, digest.SHA256) - if err != nil { - return fmt.Errorf("failed to create digester: %w", err) - } + d := intdigest.Canonical.Digester() sz := &writeCounter{} - mw := io.MultiWriter(md, tf, sz) + mw := io.MultiWriter(tf, d.Hash(), sz) if _, err := io.Copy(mw, reader); err != nil { tf.Close() @@ -554,8 +540,7 @@ func (s *Storage) Copy(artifact *sourcev1.Artifact, reader io.Reader) (err error return err } - artifact.Digest = md.Digest(intdigest.Canonical).String() - artifact.Checksum = md.Digest(digest.SHA256).Encoded() + artifact.Digest = d.Digest().String() artifact.LastUpdateTime = metav1.Now() artifact.Size = &sz.written @@ -563,7 +548,7 @@ func (s *Storage) Copy(artifact *sourcev1.Artifact, reader io.Reader) (err error } // CopyFromPath atomically copies the contents of the given path to the path of the v1beta1.Artifact. -// If successful, the checksum and last update time on the artifact is set. +// If successful, the digest and last update time on the artifact is set. func (s *Storage) CopyFromPath(artifact *sourcev1.Artifact, path string) (err error) { f, err := os.Open(path) if err != nil { @@ -640,13 +625,6 @@ func (s *Storage) Symlink(artifact sourcev1.Artifact, linkName string) (string, return url, nil } -// Checksum returns the SHA256 checksum for the data of the given io.Reader as a string. -func (s *Storage) Checksum(reader io.Reader) string { - h := newHash() - _, _ = io.Copy(h, reader) - return fmt.Sprintf("%x", h.Sum(nil)) -} - // Lock creates a file lock for the given v1beta1.Artifact. func (s *Storage) Lock(artifact sourcev1.Artifact) (unlock func(), err error) { lockFile := s.LocalPath(artifact) + ".lock" @@ -666,11 +644,6 @@ func (s *Storage) LocalPath(artifact sourcev1.Artifact) string { return path } -// newHash returns a new SHA256 hash. -func newHash() hash.Hash { - return sha256.New() -} - // writecounter is an implementation of io.Writer that only records the number // of bytes written. type writeCounter struct { diff --git a/docs/api/v1/source.md b/docs/api/v1/source.md index 2210f1b6..77e2f5e4 100644 --- a/docs/api/v1/source.md +++ b/docs/api/v1/source.md @@ -301,19 +301,6 @@ system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.

-checksum
- -string - - - -(Optional) -

Checksum is the SHA256 checksum of the Artifact file. -Deprecated: use Artifact.Digest instead.

- - - - digest
string diff --git a/internal/helm/repository/chart_repository.go b/internal/helm/repository/chart_repository.go index 3960f18f..3dcd265d 100644 --- a/internal/helm/repository/chart_repository.go +++ b/internal/helm/repository/chart_repository.go @@ -282,7 +282,6 @@ func (r *ChartRepository) DownloadChart(chart *repo.ChartVersion) (*bytes.Buffer // CacheIndex attempts to write the index from the remote into a new temporary file // using DownloadIndex, and sets Path and cached. -// It returns the SHA256 checksum of the downloaded index bytes, or an error. // The caller is expected to handle the garbage collection of Path, and to // load the Index separately using LoadFromPath if required. func (r *ChartRepository) CacheIndex() error {