api: Remove deprecated `Checksum` from `Artifact`

Signed-off-by: Hidde Beydals <hidde@hhh.computer>
This commit is contained in:
Hidde Beydals 2023-03-24 11:32:35 +01:00
parent 9c80a66273
commit b2da6f0647
No known key found for this signature in database
GPG Key ID: 979F380FC2341744
20 changed files with 145 additions and 306 deletions

View File

@ -43,11 +43,6 @@ type Artifact struct {
// +optional // +optional
Revision string `json:"revision"` 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 '<algorithm>:<checksum>'. // Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
// +optional // +optional
// +kubebuilder:validation:Pattern="^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$" // +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) return TransformLegacyRevision(in.Revision) == TransformLegacyRevision(revision)
} }
// HasChecksum returns if the given checksum matches the current Checksum of // HasDigest returns if the given digest matches the current Digest of the
// the Artifact. // Artifact.
func (in *Artifact) HasChecksum(checksum string) bool { func (in *Artifact) HasDigest(digest string) bool {
if in == nil { if in == nil {
return false return false
} }
return in.Checksum == checksum return in.Digest == digest
} }
// ArtifactDir returns the artifact dir path in the form of // ArtifactDir returns the artifact dir path in the form of

View File

@ -376,10 +376,6 @@ spec:
artifact: artifact:
description: Artifact represents the last successful Bucket reconciliation. description: Artifact represents the last successful Bucket reconciliation.
properties: properties:
checksum:
description: 'Checksum is the SHA256 checksum of the Artifact
file. Deprecated: use Artifact.Digest instead.'
type: string
digest: digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$

View File

@ -198,10 +198,6 @@ spec:
description: Artifact represents the last successful GitRepository description: Artifact represents the last successful GitRepository
reconciliation. reconciliation.
properties: properties:
checksum:
description: 'Checksum is the SHA256 checksum of the Artifact
file. Deprecated: use Artifact.Digest instead.'
type: string
digest: digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
@ -325,10 +321,6 @@ spec:
items: items:
description: Artifact represents the output of a Source reconciliation. description: Artifact represents the output of a Source reconciliation.
properties: properties:
checksum:
description: 'Checksum is the SHA256 checksum of the Artifact
file. Deprecated: use Artifact.Digest instead.'
type: string
digest: digest:
description: Digest is the digest of the file in the form of description: Digest is the digest of the file in the form of
'<algorithm>:<checksum>'. '<algorithm>:<checksum>'.
@ -973,10 +965,6 @@ spec:
description: Artifact represents the last successful GitRepository description: Artifact represents the last successful GitRepository
reconciliation. reconciliation.
properties: properties:
checksum:
description: 'Checksum is the SHA256 checksum of the Artifact
file. Deprecated: use Artifact.Digest instead.'
type: string
digest: digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
@ -1100,10 +1088,6 @@ spec:
items: items:
description: Artifact represents the output of a Source reconciliation. description: Artifact represents the output of a Source reconciliation.
properties: properties:
checksum:
description: 'Checksum is the SHA256 checksum of the Artifact
file. Deprecated: use Artifact.Digest instead.'
type: string
digest: digest:
description: Digest is the digest of the file in the form of description: Digest is the digest of the file in the form of
'<algorithm>:<checksum>'. '<algorithm>:<checksum>'.

View File

@ -451,10 +451,6 @@ spec:
description: Artifact represents the output of the last successful description: Artifact represents the output of the last successful
reconciliation. reconciliation.
properties: properties:
checksum:
description: 'Checksum is the SHA256 checksum of the Artifact
file. Deprecated: use Artifact.Digest instead.'
type: string
digest: digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$

View File

@ -368,10 +368,6 @@ spec:
description: Artifact represents the last successful HelmRepository description: Artifact represents the last successful HelmRepository
reconciliation. reconciliation.
properties: properties:
checksum:
description: 'Checksum is the SHA256 checksum of the Artifact
file. Deprecated: use Artifact.Digest instead.'
type: string
digest: digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$

View File

@ -194,10 +194,6 @@ spec:
description: Artifact represents the output of the last successful description: Artifact represents the output of the last successful
OCI Repository sync. OCI Repository sync.
properties: properties:
checksum:
description: 'Checksum is the SHA256 checksum of the Artifact
file. Deprecated: use Artifact.Digest instead.'
type: string
digest: digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'. description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$

View File

@ -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 { if ok, err = Equal(m.expected.Revision).Match(actualArtifact.Revision); !ok {
return ok, err 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 { if ok, err = Equal(m.expected.Size).Match(actualArtifact.Size); !ok {
return ok, err return ok, err
} }

View File

@ -329,21 +329,13 @@ func (r *BucketReconciler) notify(ctx context.Context, oldObj, newObj *bucketv1.
if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil { if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil {
annotations := map[string]string{ 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.MetaRevisionKey): newObj.Status.Artifact.Revision,
fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest,
}
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
} }
message := fmt.Sprintf("stored artifact with %d fetched files from '%s' bucket", index.Len(), newObj.Spec.BucketName) message := fmt.Sprintf("stored artifact with %d fetched files from '%s' bucket", index.Len(), newObj.Spec.BucketName)
// Notify on new artifact and failure recovery. // 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, r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal,
"NewArtifact", message) "NewArtifact", message)
ctrl.LoggerFrom(ctx).Info(message) ctrl.LoggerFrom(ctx).Info(message)

View File

@ -194,7 +194,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/reconcile-storage/d.txt", Path: "/reconcile-storage/d.txt",
Revision: "d", Revision: "d",
Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
URL: testStorage.Hostname + "/reconcile-storage/d.txt", URL: testStorage.Hostname + "/reconcile-storage/d.txt",
Size: int64p(int64(len("d"))), Size: int64p(int64(len("d"))),
}, },
@ -242,7 +242,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
obj.Status.Artifact = &sourcev1.Artifact{ obj.Status.Artifact = &sourcev1.Artifact{
Path: fmt.Sprintf("/reconcile-storage/hostname.txt"), Path: fmt.Sprintf("/reconcile-storage/hostname.txt"),
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: "http://outdated.com/reconcile-storage/hostname.txt", URL: "http://outdated.com/reconcile-storage/hostname.txt",
} }
if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil {
@ -261,7 +261,7 @@ func TestBucketReconciler_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/reconcile-storage/hostname.txt", Path: "/reconcile-storage/hostname.txt",
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: testStorage.Hostname + "/reconcile-storage/hostname.txt", URL: testStorage.Hostname + "/reconcile-storage/hostname.txt",
Size: int64p(int64(len("file"))), Size: int64p(int64(len("file"))),
}, },
@ -1293,7 +1293,7 @@ func TestBucketReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
newObjBeforeFunc: func(obj *bucketv1.Bucket) { 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", wantEvent: "Normal NewArtifact stored artifact with 2 fetched files from",
}, },
@ -1302,12 +1302,12 @@ func TestBucketReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *bucketv1.Bucket) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *bucketv1.Bucket) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
wantEvent: "Normal Succeeded stored artifact with 2 fetched files from", wantEvent: "Normal Succeeded stored artifact with 2 fetched files from",
@ -1317,12 +1317,12 @@ func TestBucketReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *bucketv1.Bucket) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *bucketv1.Bucket) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
wantEvent: "Normal NewArtifact stored artifact with 2 fetched files from", wantEvent: "Normal NewArtifact stored artifact with 2 fetched files from",
@ -1332,11 +1332,11 @@ func TestBucketReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *bucketv1.Bucket) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
newObjBeforeFunc: func(obj *bucketv1.Bucket) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
}, },

View File

@ -325,15 +325,7 @@ func (r *GitRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *so
if r.shouldNotify(oldObj, newObj, res, resErr) { if r.shouldNotify(oldObj, newObj, res, resErr) {
annotations := map[string]string{ 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.MetaRevisionKey): newObj.Status.Artifact.Revision,
fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest,
}
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
} }
// A partial commit due to no-op clone doesn't contain the commit // 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. // 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, r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal,
"NewArtifact", message) "NewArtifact", message)
ctrl.LoggerFrom(ctx).Info(message) ctrl.LoggerFrom(ctx).Info(message)
@ -1019,7 +1011,7 @@ func gitContentConfigChanged(obj *sourcev1.GitRepository, includes *artifactSet)
observedInclArtifact := obj.Status.IncludedArtifacts[index] observedInclArtifact := obj.Status.IncludedArtifacts[index]
currentIncl := artifacts[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) { if !gitRepositoryIncludeEqual(incl, observedIncl) {
return true return true
} }
@ -1028,7 +1020,7 @@ func gitContentConfigChanged(obj *sourcev1.GitRepository, includes *artifactSet)
if !observedInclArtifact.HasRevision(currentIncl.Revision) { if !observedInclArtifact.HasRevision(currentIncl.Revision) {
return true return true
} }
if observedInclArtifact.Checksum != currentIncl.Checksum { if !observedInclArtifact.HasDigest(currentIncl.Digest) {
return true return true
} }
} }

View File

@ -926,7 +926,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
}, },
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { afterFunc: func(t *WithT, obj *sourcev1.GitRepository) {
t.Expect(obj.GetArtifact()).ToNot(BeNil()) 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.IncludedArtifacts).ToNot(BeEmpty())
t.Expect(obj.Status.URL).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", name: "Up-to-date artifact should not update status",
dir: "testdata/git/repository", 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) { beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval} obj.Spec.Interval = metav1.Duration{Duration: interval}
obj.Spec.Include = []sourcev1.GitRepositoryInclude{ obj.Spec.Include = []sourcev1.GitRepositoryInclude{
{GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}}, {GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}},
} }
obj.Status.Artifact = &sourcev1.Artifact{Revision: "main@sha1:b9b3feadba509cb9b22e968a5d27e96c2bc2ff91"} 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 obj.Status.ObservedInclude = obj.Spec.Include
}, },
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { 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", name: "Up-to-date artifact with legacy revision format should not update status",
dir: "testdata/git/repository", 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) { beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval} obj.Spec.Interval = metav1.Duration{Duration: interval}
obj.Spec.Include = []sourcev1.GitRepositoryInclude{ obj.Spec.Include = []sourcev1.GitRepositoryInclude{
{GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}}, {GitRepositoryRef: meta.LocalObjectReference{Name: "foo"}},
} }
obj.Status.Artifact = &sourcev1.Artifact{Revision: "main/b9b3feadba509cb9b22e968a5d27e96c2bc2ff91"} 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 obj.Status.ObservedInclude = obj.Spec.Include
}, },
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { afterFunc: func(t *WithT, obj *sourcev1.GitRepository) {
@ -987,7 +987,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
}, },
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { afterFunc: func(t *WithT, obj *sourcev1.GitRepository) {
t.Expect(obj.GetArtifact()).ToNot(BeNil()) 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, want: sreconcile.ResultSuccess,
assertConditions: []metav1.Condition{ assertConditions: []metav1.Condition{
@ -1002,7 +1002,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
}, },
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { afterFunc: func(t *WithT, obj *sourcev1.GitRepository) {
t.Expect(obj.GetArtifact()).ToNot(BeNil()) 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, want: sreconcile.ResultSuccess,
assertConditions: []metav1.Condition{ assertConditions: []metav1.Condition{
@ -1018,7 +1018,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
}, },
afterFunc: func(t *WithT, obj *sourcev1.GitRepository) { afterFunc: func(t *WithT, obj *sourcev1.GitRepository) {
t.Expect(obj.GetArtifact()).ToNot(BeNil()) 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()) t.Expect(obj.Status.URL).ToNot(BeEmpty())
}, },
want: sreconcile.ResultSuccess, want: sreconcile.ResultSuccess,
@ -1333,7 +1333,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/reconcile-storage/d.txt", Path: "/reconcile-storage/d.txt",
Revision: "d", Revision: "d",
Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
URL: testStorage.Hostname + "/reconcile-storage/d.txt", URL: testStorage.Hostname + "/reconcile-storage/d.txt",
Size: int64p(int64(len("d"))), Size: int64p(int64(len("d"))),
}, },
@ -1381,7 +1381,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
obj.Status.Artifact = &sourcev1.Artifact{ obj.Status.Artifact = &sourcev1.Artifact{
Path: "/reconcile-storage/hostname.txt", Path: "/reconcile-storage/hostname.txt",
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: "http://outdated.com/reconcile-storage/hostname.txt", URL: "http://outdated.com/reconcile-storage/hostname.txt",
} }
if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil {
@ -1400,7 +1400,7 @@ func TestGitRepositoryReconciler_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/reconcile-storage/hostname.txt", Path: "/reconcile-storage/hostname.txt",
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: testStorage.Hostname + "/reconcile-storage/hostname.txt", URL: testStorage.Hostname + "/reconcile-storage/hostname.txt",
Size: int64p(int64(len("file"))), Size: int64p(int64(len("file"))),
}, },
@ -2052,7 +2052,7 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
newObjBeforeFunc: func(obj *sourcev1.GitRepository) { 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, commit: concreteCommit,
wantEvent: "Normal NewArtifact stored artifact for commit 'test commit'", wantEvent: "Normal NewArtifact stored artifact for commit 'test commit'",
@ -2062,12 +2062,12 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.GitRepository) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *sourcev1.GitRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
commit: concreteCommit, commit: concreteCommit,
@ -2078,12 +2078,12 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.GitRepository) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *sourcev1.GitRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
commit: concreteCommit, commit: concreteCommit,
@ -2094,11 +2094,11 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *sourcev1.GitRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
newObjBeforeFunc: func(obj *sourcev1.GitRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
}, },
@ -2107,12 +2107,12 @@ func TestGitRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultEmpty, res: sreconcile.ResultEmpty,
resErr: noopErr, resErr: noopErr,
oldObjBeforeFunc: func(obj *sourcev1.GitRepository) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *sourcev1.GitRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
commit: partialCommit, // no-op will always result in partial commit. commit: partialCommit, // no-op will always result in partial commit.
@ -2484,11 +2484,11 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz", ToPath: "baz",
}, },
}, },
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}}, IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}},
}, },
}, },
artifacts: []*sourcev1.Artifact{ artifacts: []*sourcev1.Artifact{
{Revision: "aaa", Checksum: "bbb"}, {Revision: "aaa", Digest: "bbb"},
}, },
want: false, want: false,
}, },
@ -2512,16 +2512,16 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz", ToPath: "baz",
}, },
}, },
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}}, IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}},
}, },
}, },
artifacts: []*sourcev1.Artifact{ artifacts: []*sourcev1.Artifact{
{Revision: "ccc", Checksum: "bbb"}, {Revision: "ccc", Digest: "bbb"},
}, },
want: true, want: true,
}, },
{ {
name: "observed include but different artifact checksum", name: "observed include but different artifact digest",
obj: sourcev1.GitRepository{ obj: sourcev1.GitRepository{
Spec: sourcev1.GitRepositorySpec{ Spec: sourcev1.GitRepositorySpec{
Include: []sourcev1.GitRepositoryInclude{ Include: []sourcev1.GitRepositoryInclude{
@ -2540,11 +2540,11 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz", ToPath: "baz",
}, },
}, },
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}}, IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}},
}, },
}, },
artifacts: []*sourcev1.Artifact{ artifacts: []*sourcev1.Artifact{
{Revision: "aaa", Checksum: "ddd"}, {Revision: "aaa", Digest: "ddd"},
}, },
want: true, want: true,
}, },
@ -2568,11 +2568,11 @@ func TestGitContentConfigChanged(t *testing.T) {
ToPath: "baz", ToPath: "baz",
}, },
}, },
IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Checksum: "bbb"}}, IncludedArtifacts: []*sourcev1.Artifact{{Revision: "aaa", Digest: "bbb"}},
}, },
}, },
artifacts: []*sourcev1.Artifact{ artifacts: []*sourcev1.Artifact{
{Revision: "aaa", Checksum: "bbb"}, {Revision: "aaa", Digest: "bbb"},
}, },
want: true, want: true,
}, },
@ -2595,14 +2595,14 @@ func TestGitContentConfigChanged(t *testing.T) {
}, },
Status: sourcev1.GitRepositoryStatus{ Status: sourcev1.GitRepositoryStatus{
IncludedArtifacts: []*sourcev1.Artifact{ IncludedArtifacts: []*sourcev1.Artifact{
{Revision: "aaa", Checksum: "bbb"}, {Revision: "aaa", Digest: "bbb"},
{Revision: "ccc", Checksum: "ccc"}, {Revision: "ccc", Digest: "ccc"},
}, },
}, },
}, },
artifacts: []*sourcev1.Artifact{ artifacts: []*sourcev1.Artifact{
{Revision: "aaa", Checksum: "bbb"}, {Revision: "aaa", Digest: "bbb"},
{Revision: "ccc", Checksum: "ddd"}, {Revision: "ccc", Digest: "ddd"},
}, },
want: true, want: true,
}, },
@ -2637,13 +2637,13 @@ func TestGitContentConfigChanged(t *testing.T) {
}, },
}, },
IncludedArtifacts: []*sourcev1.Artifact{ IncludedArtifacts: []*sourcev1.Artifact{
{Revision: "aaa", Checksum: "bbb"}, {Revision: "aaa", Digest: "bbb"},
{Revision: "ccc", Checksum: "ccc"}, {Revision: "ccc", Digest: "ccc"},
}, },
}, },
}, },
artifacts: []*sourcev1.Artifact{ artifacts: []*sourcev1.Artifact{
{Revision: "aaa", Checksum: "bbb"}, {Revision: "aaa", Digest: "bbb"},
}, },
want: true, want: true,
}, },
@ -2678,13 +2678,13 @@ func TestGitContentConfigChanged(t *testing.T) {
}, },
}, },
IncludedArtifacts: []*sourcev1.Artifact{ IncludedArtifacts: []*sourcev1.Artifact{
{Revision: "aaa", Checksum: "bbb"}, {Revision: "aaa", Digest: "bbb"},
}, },
}, },
}, },
artifacts: []*sourcev1.Artifact{ artifacts: []*sourcev1.Artifact{
{Revision: "aaa", Checksum: "bbb"}, {Revision: "aaa", Digest: "bbb"},
{Revision: "ccc", Checksum: "ccc"}, {Revision: "ccc", Digest: "ccc"},
}, },
want: true, want: true,
}, },

View File

@ -332,19 +332,11 @@ func (r *HelmChartReconciler) notify(ctx context.Context, oldObj, newObj *helmv1
if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil { if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil {
annotations := map[string]string{ 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.MetaRevisionKey): newObj.Status.Artifact.Revision,
fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest,
}
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
} }
// Notify on new artifact and failure recovery. // 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, r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal,
reasonForBuild(build), build.Summary()) reasonForBuild(build), build.Summary())
ctrl.LoggerFrom(ctx).Info(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 obj.Spec.SourceRef.Kind == helmv1.BucketKind {
if dig := digest.Digest(sourcev1.TransformLegacyRevision(rev)); dig.Validate() == nil { 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 { if kind := obj.Spec.SourceRef.Kind; kind == sourcev1.GitRepositoryKind || kind == helmv1.BucketKind {

View File

@ -315,7 +315,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/reconcile-storage/d.txt", Path: "/reconcile-storage/d.txt",
Revision: "d", Revision: "d",
Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
URL: testStorage.Hostname + "/reconcile-storage/d.txt", URL: testStorage.Hostname + "/reconcile-storage/d.txt",
Size: int64p(int64(len("d"))), Size: int64p(int64(len("d"))),
}, },
@ -363,7 +363,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
obj.Status.Artifact = &sourcev1.Artifact{ obj.Status.Artifact = &sourcev1.Artifact{
Path: "/reconcile-storage/hostname.txt", Path: "/reconcile-storage/hostname.txt",
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: "http://outdated.com/reconcile-storage/hostname.txt", URL: "http://outdated.com/reconcile-storage/hostname.txt",
} }
if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil {
@ -382,7 +382,7 @@ func TestHelmChartReconciler_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/reconcile-storage/hostname.txt", Path: "/reconcile-storage/hostname.txt",
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: testStorage.Hostname + "/reconcile-storage/hostname.txt", URL: testStorage.Hostname + "/reconcile-storage/hostname.txt",
Size: int64p(int64(len("file"))), Size: int64p(int64(len("file"))),
}, },
@ -1440,7 +1440,7 @@ func TestHelmChartReconciler_reconcileArtifact(t *testing.T) {
}, },
afterFunc: func(t *WithT, obj *helmv1.HelmChart) { afterFunc: func(t *WithT, obj *helmv1.HelmChart) {
t.Expect(obj.GetArtifact()).ToNot(BeNil()) 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.GetArtifact().Revision).To(Equal("0.1.0"))
t.Expect(obj.Status.URL).ToNot(BeEmpty()) t.Expect(obj.Status.URL).ToNot(BeEmpty())
t.Expect(obj.Status.ObservedChartName).To(Equal("helmchart")) 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) { afterFunc: func(t *WithT, obj *helmv1.HelmChart) {
t.Expect(obj.GetArtifact()).ToNot(BeNil()) 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.GetArtifact().Revision).To(Equal("0.1.0"))
t.Expect(obj.Status.URL).ToNot(BeEmpty()) t.Expect(obj.Status.URL).ToNot(BeEmpty())
t.Expect(obj.Status.ObservedChartName).To(Equal("helmchart")) t.Expect(obj.Status.ObservedChartName).To(Equal("helmchart"))
@ -2088,7 +2088,7 @@ func TestHelmChartReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
newObjBeforeFunc: func(obj *helmv1.HelmChart) { 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", wantEvent: "Normal ChartPackageSucceeded packaged",
}, },
@ -2097,12 +2097,12 @@ func TestHelmChartReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *helmv1.HelmChart) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *helmv1.HelmChart) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
wantEvent: "Normal ChartPackageSucceeded packaged", wantEvent: "Normal ChartPackageSucceeded packaged",
@ -2112,12 +2112,12 @@ func TestHelmChartReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *helmv1.HelmChart) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *helmv1.HelmChart) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
wantEvent: "Normal ChartPackageSucceeded packaged", wantEvent: "Normal ChartPackageSucceeded packaged",
@ -2127,11 +2127,11 @@ func TestHelmChartReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *helmv1.HelmChart) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
newObjBeforeFunc: func(obj *helmv1.HelmChart) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
}, },

View File

@ -292,10 +292,7 @@ func (r *HelmRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *h
if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil { if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil {
annotations := map[string]string{ 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.MetaRevisionKey): newObj.Status.Artifact.Revision,
fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest,
}
if newObj.Status.Artifact.Digest != "" {
annotations[sourcev1.GroupVersion.Group+"/"+eventv1.MetaDigestKey] = newObj.Status.Artifact.Digest
} }
humanReadableSize := "unknown size" 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))) 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) message := fmt.Sprintf("stored fetched index of %s from '%s'", humanReadableSize, chartRepo.URL)
// Notify on new artifact and failure recovery. // 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, r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal,
"NewArtifact", message) "NewArtifact", message)
ctrl.LoggerFrom(ctx).Info(message) ctrl.LoggerFrom(ctx).Info(message)
@ -471,9 +463,6 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
// Early comparison to current Artifact. // Early comparison to current Artifact.
if curArtifact := obj.GetArtifact(); curArtifact != nil { if curArtifact := obj.GetArtifact(); curArtifact != nil {
curDig := digest.Digest(curArtifact.Digest) curDig := digest.Digest(curArtifact.Digest)
if curDig == "" {
curDig = digest.Digest(sourcev1.TransformLegacyRevision(curArtifact.Checksum))
}
if curDig.Validate() == nil { if curDig.Validate() == nil {
// Short-circuit based on the fetched index being an exact match to the // Short-circuit based on the fetched index being an exact match to the
// stored Artifact. // stored Artifact.
@ -532,7 +521,7 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
*artifact = r.Storage.NewArtifactFor(obj.Kind, *artifact = r.Storage.NewArtifactFor(obj.Kind,
obj.ObjectMeta.GetObjectMeta(), obj.ObjectMeta.GetObjectMeta(),
revision.String(), revision.String(),
fmt.Sprintf("index-%s.yaml", revision.Hex()), fmt.Sprintf("index-%s.yaml", revision.Encoded()),
) )
return sreconcile.ResultSuccess, nil 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). // Extend TTL of the Index in the cache (if present).
if r.Cache != nil { if r.Cache != nil {
r.Cache.SetExpiration(artifact.Path, r.TTL) r.Cache.SetExpiration(artifact.Path, r.TTL)

View File

@ -170,7 +170,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/reconcile-storage/d.txt", Path: "/reconcile-storage/d.txt",
Revision: "d", Revision: "d",
Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
URL: testStorage.Hostname + "/reconcile-storage/d.txt", URL: testStorage.Hostname + "/reconcile-storage/d.txt",
Size: int64p(int64(len("d"))), Size: int64p(int64(len("d"))),
}, },
@ -218,7 +218,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
obj.Status.Artifact = &sourcev1.Artifact{ obj.Status.Artifact = &sourcev1.Artifact{
Path: "/reconcile-storage/hostname.txt", Path: "/reconcile-storage/hostname.txt",
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: "http://outdated.com/reconcile-storage/hostname.txt", URL: "http://outdated.com/reconcile-storage/hostname.txt",
} }
if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil {
@ -237,7 +237,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/reconcile-storage/hostname.txt", Path: "/reconcile-storage/hostname.txt",
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: testStorage.Hostname + "/reconcile-storage/hostname.txt", URL: testStorage.Hostname + "/reconcile-storage/hostname.txt",
Size: int64p(int64(len("file"))), Size: int64p(int64(len("file"))),
}, },
@ -317,7 +317,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
server options server options
url string url string
secret *corev1.Secret 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) afterFunc func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository)
want sreconcile.Result want sreconcile.Result
wantErr bool 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) { afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty()) t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil()) t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Checksum).To(BeEmpty())
t.Expect(artifact.Revision).ToNot(BeEmpty()) t.Expect(artifact.Revision).ToNot(BeEmpty())
}, },
}, },
@ -372,7 +371,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"password": []byte("1234"), "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"} obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "basic-auth"}
}, },
want: sreconcile.ResultSuccess, 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) { afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty()) t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil()) t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Checksum).To(BeEmpty())
t.Expect(artifact.Revision).ToNot(BeEmpty()) t.Expect(artifact.Revision).ToNot(BeEmpty())
}, },
}, },
@ -403,7 +401,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"caFile": tlsCA, "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"} obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "ca-file"}
}, },
want: sreconcile.ResultSuccess, 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) { afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty()) t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil()) t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Checksum).To(BeEmpty())
t.Expect(artifact.Revision).ToNot(BeEmpty()) t.Expect(artifact.Revision).ToNot(BeEmpty())
}, },
}, },
@ -434,7 +431,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"caFile": []byte("invalid"), "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"} obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "invalid-ca"}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -449,14 +446,13 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
// No repo index due to fetch fail. // No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil()) t.Expect(chartRepo.Index).To(BeNil())
t.Expect(artifact.Checksum).To(BeEmpty())
t.Expect(artifact.Revision).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty())
}, },
}, },
{ {
name: "Invalid URL makes FetchFailed=True and returns stalling error", name: "Invalid URL makes FetchFailed=True and returns stalling error",
protocol: "http", 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://", "") obj.Spec.URL = strings.ReplaceAll(obj.Spec.URL, "http://", "")
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -472,14 +468,13 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
// No repo index due to fetch fail. // No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil()) t.Expect(chartRepo.Index).To(BeNil())
t.Expect(artifact.Checksum).To(BeEmpty())
t.Expect(artifact.Revision).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty())
}, },
}, },
{ {
name: "Unsupported scheme makes FetchFailed=True and returns stalling error", name: "Unsupported scheme makes FetchFailed=True and returns stalling error",
protocol: "http", 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://") obj.Spec.URL = strings.ReplaceAll(obj.Spec.URL, "http://", "ftp://")
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -495,14 +490,13 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
// No repo index due to fetch fail. // No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil()) t.Expect(chartRepo.Index).To(BeNil())
t.Expect(artifact.Checksum).To(BeEmpty())
t.Expect(artifact.Revision).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty())
}, },
}, },
{ {
name: "Missing secret returns FetchFailed=True and returns error", name: "Missing secret returns FetchFailed=True and returns error",
protocol: "http", 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"} obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "non-existing"}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -517,7 +511,6 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
// No repo index due to fetch fail. // No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil()) t.Expect(chartRepo.Index).To(BeNil())
t.Expect(artifact.Checksum).To(BeEmpty())
t.Expect(artifact.Revision).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty())
}, },
}, },
@ -532,7 +525,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"username": []byte("git"), "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"} obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "malformed-basic-auth"}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar") conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -547,43 +540,16 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
// No repo index due to fetch fail. // No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty()) t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil()) t.Expect(chartRepo.Index).To(BeNil())
t.Expect(artifact.Checksum).To(BeEmpty())
t.Expect(artifact.Revision).To(BeEmpty()) t.Expect(artifact.Revision).To(BeEmpty())
}, },
}, },
{ {
name: "Stored index with same digest and revision", name: "Stored index with same digest and revision",
protocol: "http", 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{ obj.Status.Artifact = &sourcev1.Artifact{
Revision: revision.String(), Revision: rev.String(),
Digest: digest.String(), Digest: dig.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(),
} }
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") 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", name: "Stored index with different digest and same revision",
protocol: "http", 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{ obj.Status.Artifact = &sourcev1.Artifact{
Revision: revision.String(), Revision: rev.String(),
Digest: "sha256:80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86", Digest: "sha256:80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86",
Checksum: "80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86",
} }
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") 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.Revision).To(Equal(obj.Status.Artifact.Revision))
t.Expect(artifact.Digest).ToNot(Equal(obj.Status.Artifact.Digest)) t.Expect(artifact.Digest).ToNot(Equal(obj.Status.Artifact.Digest))
t.Expect(artifact.Checksum).ToNot(Equal(obj.Status.Artifact.Checksum))
}, },
want: sreconcile.ResultSuccess, want: sreconcile.ResultSuccess,
}, },
{ {
name: "Stored index with different revision and digest", name: "Stored index with different revision and digest",
protocol: "http", 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{ obj.Status.Artifact = &sourcev1.Artifact{
Revision: "80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86", Revision: "80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86",
Checksum: "80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86",
Digest: "sha256:80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86", Digest: "sha256:80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86",
} }
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo") 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.Path).To(Not(BeEmpty()))
t.Expect(artifact.Revision).ToNot(Equal(obj.Status.Artifact.Revision)) t.Expect(artifact.Revision).ToNot(Equal(obj.Status.Artifact.Revision))
t.Expect(artifact.Digest).ToNot(Equal(obj.Status.Artifact.Digest)) t.Expect(artifact.Digest).ToNot(Equal(obj.Status.Artifact.Digest))
t.Expect(artifact.Checksum).ToNot(Equal(obj.Status.Artifact.Checksum))
}, },
want: sreconcile.ResultSuccess, want: sreconcile.ResultSuccess,
}, },
{ {
name: "Existing artifact makes ArtifactOutdated=True", name: "Existing artifact makes ArtifactOutdated=True",
protocol: "http", 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{ obj.Status.Artifact = &sourcev1.Artifact{
Path: "some-path", Path: "some-path",
Revision: "some-rev", Revision: "some-rev",
@ -736,7 +698,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
builder.WithObjects(secret.DeepCopy()) builder.WithObjects(secret.DeepCopy())
} }
// Calculate the artifact checksum for valid repos configurations. // Calculate the artifact digest for valid repos configurations.
clientOpts := []helmgetter.Option{ clientOpts := []helmgetter.Option{
helmgetter.WithURL(server.URL()), helmgetter.WithURL(server.URL()),
} }
@ -745,7 +707,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
validSecret := true validSecret := true
if secret != nil { if secret != nil {
// Extract the client options from secret, ignoring any invalid // 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. // should be calculated below.
var cOpts []helmgetter.Option var cOpts []helmgetter.Option
var serr error var serr error
@ -768,18 +730,18 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
} }
g.Expect(err).ToNot(HaveOccurred()) 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. // configurations as the client can't get the repo.
var revision, checksum digest.Digest var rev, dig digest.Digest
if validSecret { if validSecret {
g.Expect(newChartRepo.CacheIndex()).To(Succeed()) g.Expect(newChartRepo.CacheIndex()).To(Succeed())
checksum = newChartRepo.Digest(intdigest.Canonical) dig = newChartRepo.Digest(intdigest.Canonical)
g.Expect(newChartRepo.LoadFromPath()).To(Succeed()) g.Expect(newChartRepo.LoadFromPath()).To(Succeed())
revision = newChartRepo.Digest(intdigest.Canonical) rev = newChartRepo.Digest(intdigest.Canonical)
} }
if tt.beforeFunc != nil { if tt.beforeFunc != nil {
tt.beforeFunc(g, obj, revision, checksum) tt.beforeFunc(g, obj, rev, dig)
} }
r := &HelmRepositoryReconciler{ r := &HelmRepositoryReconciler{
@ -942,8 +904,8 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
chartRepo.Path = cachePath chartRepo.Path = cachePath
artifact := testStorage.NewArtifactFor(obj.Kind, obj, "existing", "foo.tar.gz") artifact := testStorage.NewArtifactFor(obj.Kind, obj, "existing", "foo.tar.gz")
// Checksum of the index file calculated by the ChartRepository. // Digest of the index file calculated by the ChartRepository.
artifact.Checksum = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" artifact.Digest = "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
if tt.beforeFunc != nil { if tt.beforeFunc != nil {
tt.beforeFunc(g, obj, artifact, chartRepo) tt.beforeFunc(g, obj, artifact, chartRepo)
@ -1218,7 +1180,7 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
newObjBeforeFunc: func(obj *helmv1.HelmRepository) { 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", wantEvent: "Normal NewArtifact stored fetched index of unknown size",
}, },
@ -1227,7 +1189,7 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
newObjBeforeFunc: func(obj *helmv1.HelmRepository) { 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", wantEvent: "Normal NewArtifact stored fetched index of size",
}, },
@ -1236,12 +1198,12 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *helmv1.HelmRepository) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *helmv1.HelmRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
wantEvent: "Normal Succeeded stored fetched index of size", wantEvent: "Normal Succeeded stored fetched index of size",
@ -1251,12 +1213,12 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *helmv1.HelmRepository) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *helmv1.HelmRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
wantEvent: "Normal NewArtifact stored fetched index of size", wantEvent: "Normal NewArtifact stored fetched index of size",
@ -1266,11 +1228,11 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *helmv1.HelmRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
newObjBeforeFunc: func(obj *helmv1.HelmRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
}, },

View File

@ -1139,15 +1139,7 @@ func (r *OCIRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *oc
if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil { if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil {
annotations := map[string]string{ 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.MetaRevisionKey): newObj.Status.Artifact.Revision,
fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaChecksumKey): newObj.Status.Artifact.Checksum, fmt.Sprintf("%s/%s", sourcev1.GroupVersion.Group, eventv1.MetaDigestKey): newObj.Status.Artifact.Digest,
}
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
} }
message := fmt.Sprintf("stored artifact with revision '%s' from '%s'", newObj.Status.Artifact.Revision, newObj.Spec.URL) 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. // 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, r.AnnotatedEventf(newObj, annotations, corev1.EventTypeNormal,
"NewArtifact", message) "NewArtifact", message)
ctrl.LoggerFrom(ctx).Info(message) ctrl.LoggerFrom(ctx).Info(message)

View File

@ -66,6 +66,7 @@ import (
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
ociv1 "github.com/fluxcd/source-controller/api/v1beta2" ociv1 "github.com/fluxcd/source-controller/api/v1beta2"
intdigest "github.com/fluxcd/source-controller/internal/digest"
serror "github.com/fluxcd/source-controller/internal/error" serror "github.com/fluxcd/source-controller/internal/error"
sreconcile "github.com/fluxcd/source-controller/internal/reconcile" sreconcile "github.com/fluxcd/source-controller/internal/reconcile"
) )
@ -210,9 +211,9 @@ func TestOCIRepository_Reconcile(t *testing.T) {
g.Expect(err).ToNot(HaveOccurred()) g.Expect(err).ToNot(HaveOccurred())
defer f2.Close() defer f2.Close()
h := testStorage.Checksum(f2) d, err := intdigest.Canonical.FromReader(f2)
t.Logf("file %q hash: %q", expectedFile, h) g.Expect(err).ToNot(HaveOccurred())
g.Expect(h).To(Equal(af.expectedChecksum)) g.Expect(d.Encoded()).To(Equal(af.expectedChecksum))
} }
// Check if the object status is valid // Check if the object status is valid
@ -1483,7 +1484,7 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
"latest.tar.gz", "latest.tar.gz",
}, },
afterFunc: func(g *WithT, obj *ociv1.OCIRepository) { 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{ assertConditions: []metav1.Condition{
*conditions.TrueCondition(sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "stored artifact for digest"), *conditions.TrueCondition(sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "stored artifact for digest"),
@ -1501,7 +1502,7 @@ func TestOCIRepository_reconcileArtifact(t *testing.T) {
"latest.tar.gz", "latest.tar.gz",
}, },
afterFunc: func(g *WithT, obj *ociv1.OCIRepository) { 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{ assertConditions: []metav1.Condition{
*conditions.TrueCondition(sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "stored artifact for digest"), *conditions.TrueCondition(sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "stored artifact for digest"),
@ -1876,7 +1877,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/oci-reconcile-storage/d.txt", Path: "/oci-reconcile-storage/d.txt",
Revision: "d", Revision: "d",
Checksum: "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", Digest: "sha256:18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4",
URL: testStorage.Hostname + "/oci-reconcile-storage/d.txt", URL: testStorage.Hostname + "/oci-reconcile-storage/d.txt",
Size: int64p(int64(len("d"))), Size: int64p(int64(len("d"))),
}, },
@ -1924,7 +1925,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
obj.Status.Artifact = &sourcev1.Artifact{ obj.Status.Artifact = &sourcev1.Artifact{
Path: "/oci-reconcile-storage/hostname.txt", Path: "/oci-reconcile-storage/hostname.txt",
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: "http://outdated.com/oci-reconcile-storage/hostname.txt", URL: "http://outdated.com/oci-reconcile-storage/hostname.txt",
} }
if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil { if err := testStorage.MkdirAll(*obj.Status.Artifact); err != nil {
@ -1943,7 +1944,7 @@ func TestOCIRepository_reconcileStorage(t *testing.T) {
assertArtifact: &sourcev1.Artifact{ assertArtifact: &sourcev1.Artifact{
Path: "/oci-reconcile-storage/hostname.txt", Path: "/oci-reconcile-storage/hostname.txt",
Revision: "f", Revision: "f",
Checksum: "3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80", Digest: "sha256:3b9c358f36f0a31b6ad3e14f309c7cf198ac9246e8316f9ce543d5b19ac02b80",
URL: testStorage.Hostname + "/oci-reconcile-storage/hostname.txt", URL: testStorage.Hostname + "/oci-reconcile-storage/hostname.txt",
Size: int64p(int64(len("file"))), Size: int64p(int64(len("file"))),
}, },
@ -2071,7 +2072,7 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) {
obj.Spec.URL = "oci://newurl.io" obj.Spec.URL = "oci://newurl.io"
obj.Status.Artifact = &sourcev1.Artifact{ obj.Status.Artifact = &sourcev1.Artifact{
Revision: "xxx", Revision: "xxx",
Checksum: "yyy", Digest: "yyy",
Metadata: map[string]string{ Metadata: map[string]string{
oci.SourceAnnotation: "https://github.com/stefanprodan/podinfo", oci.SourceAnnotation: "https://github.com/stefanprodan/podinfo",
oci.RevisionAnnotation: "6.1.8/b3b00fe35424a45d373bf4c7214178bc36fd7872", oci.RevisionAnnotation: "6.1.8/b3b00fe35424a45d373bf4c7214178bc36fd7872",
@ -2085,13 +2086,13 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultSuccess, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *ociv1.OCIRepository) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.ReadOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *ociv1.OCIRepository) { newObjBeforeFunc: func(obj *ociv1.OCIRepository) {
obj.Spec.URL = "oci://newurl.io" 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
wantEvent: "Normal Succeeded stored artifact with revision 'xxx' from 'oci://newurl.io'", 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, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *ociv1.OCIRepository) { 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.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.ReadOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo") conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
}, },
newObjBeforeFunc: func(obj *ociv1.OCIRepository) { newObjBeforeFunc: func(obj *ociv1.OCIRepository) {
obj.Spec.URL = "oci://newurl.io" 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
wantEvent: "Normal NewArtifact stored artifact with revision 'aaa' from 'oci://newurl.io'", 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, res: sreconcile.ResultSuccess,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *ociv1.OCIRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
newObjBeforeFunc: func(obj *ociv1.OCIRepository) { 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") conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
}, },
}, },
@ -2130,7 +2131,7 @@ func TestOCIRepositoryReconciler_notify(t *testing.T) {
res: sreconcile.ResultRequeue, res: sreconcile.ResultRequeue,
resErr: nil, resErr: nil,
oldObjBeforeFunc: func(obj *ociv1.OCIRepository) { 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") conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.URLInvalidReason, "ready")
}, },
}, },

View File

@ -20,9 +20,7 @@ import (
"archive/tar" "archive/tar"
"compress/gzip" "compress/gzip"
"context" "context"
"crypto/sha256"
"fmt" "fmt"
"hash"
"io" "io"
"io/fs" "io/fs"
"net/url" "net/url"
@ -34,7 +32,6 @@ import (
securejoin "github.com/cyphar/filepath-securejoin" securejoin "github.com/cyphar/filepath-securejoin"
"github.com/fluxcd/go-git/v5/plumbing/format/gitignore" "github.com/fluxcd/go-git/v5/plumbing/format/gitignore"
"github.com/opencontainers/go-digest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kerrors "k8s.io/apimachinery/pkg/util/errors" 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 // 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, // directories and any ArchiveFileFilter matches. While archiving, any environment specific data (for example,
// the user and group name) is stripped from file headers. // 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) { func (s *Storage) Archive(artifact *sourcev1.Artifact, dir string, filter ArchiveFileFilter) (err error) {
if f, err := os.Stat(dir); os.IsNotExist(err) || !f.IsDir() { if f, err := os.Stat(dir); os.IsNotExist(err) || !f.IsDir() {
return fmt.Errorf("invalid dir path: %s", dir) 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) d := intdigest.Canonical.Digester()
if err != nil {
return fmt.Errorf("failed to create digester: %w", err)
}
sz := &writeCounter{} sz := &writeCounter{}
mw := io.MultiWriter(md, tf, sz) mw := io.MultiWriter(d.Hash(), tf, sz)
gw := gzip.NewWriter(mw) gw := gzip.NewWriter(mw)
tw := tar.NewWriter(gw) tw := tar.NewWriter(gw)
@ -466,8 +460,7 @@ func (s *Storage) Archive(artifact *sourcev1.Artifact, dir string, filter Archiv
return err return err
} }
artifact.Digest = md.Digest(intdigest.Canonical).String() artifact.Digest = d.Digest().String()
artifact.Checksum = md.Digest(digest.SHA256).Encoded()
artifact.LastUpdateTime = metav1.Now() artifact.LastUpdateTime = metav1.Now()
artifact.Size = &sz.written 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. // 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) { func (s *Storage) AtomicWriteFile(artifact *sourcev1.Artifact, reader io.Reader, mode os.FileMode) (err error) {
localPath := s.LocalPath(*artifact) localPath := s.LocalPath(*artifact)
tf, err := os.CreateTemp(filepath.Split(localPath)) 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) d := intdigest.Canonical.Digester()
if err != nil {
return fmt.Errorf("failed to create digester: %w", err)
}
sz := &writeCounter{} sz := &writeCounter{}
mw := io.MultiWriter(md, tf, sz) mw := io.MultiWriter(tf, d.Hash(), sz)
if _, err := io.Copy(mw, reader); err != nil { if _, err := io.Copy(mw, reader); err != nil {
tf.Close() tf.Close()
@ -512,8 +502,7 @@ func (s *Storage) AtomicWriteFile(artifact *sourcev1.Artifact, reader io.Reader,
return err return err
} }
artifact.Digest = md.Digest(intdigest.Canonical).String() artifact.Digest = d.Digest().String()
artifact.Checksum = md.Digest(digest.SHA256).Encoded()
artifact.LastUpdateTime = metav1.Now() artifact.LastUpdateTime = metav1.Now()
artifact.Size = &sz.written 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. // 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) { func (s *Storage) Copy(artifact *sourcev1.Artifact, reader io.Reader) (err error) {
localPath := s.LocalPath(*artifact) localPath := s.LocalPath(*artifact)
tf, err := os.CreateTemp(filepath.Split(localPath)) 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) d := intdigest.Canonical.Digester()
if err != nil {
return fmt.Errorf("failed to create digester: %w", err)
}
sz := &writeCounter{} sz := &writeCounter{}
mw := io.MultiWriter(md, tf, sz) mw := io.MultiWriter(tf, d.Hash(), sz)
if _, err := io.Copy(mw, reader); err != nil { if _, err := io.Copy(mw, reader); err != nil {
tf.Close() tf.Close()
@ -554,8 +540,7 @@ func (s *Storage) Copy(artifact *sourcev1.Artifact, reader io.Reader) (err error
return err return err
} }
artifact.Digest = md.Digest(intdigest.Canonical).String() artifact.Digest = d.Digest().String()
artifact.Checksum = md.Digest(digest.SHA256).Encoded()
artifact.LastUpdateTime = metav1.Now() artifact.LastUpdateTime = metav1.Now()
artifact.Size = &sz.written 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. // 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) { func (s *Storage) CopyFromPath(artifact *sourcev1.Artifact, path string) (err error) {
f, err := os.Open(path) f, err := os.Open(path)
if err != nil { if err != nil {
@ -640,13 +625,6 @@ func (s *Storage) Symlink(artifact sourcev1.Artifact, linkName string) (string,
return url, nil 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. // Lock creates a file lock for the given v1beta1.Artifact.
func (s *Storage) Lock(artifact sourcev1.Artifact) (unlock func(), err error) { func (s *Storage) Lock(artifact sourcev1.Artifact) (unlock func(), err error) {
lockFile := s.LocalPath(artifact) + ".lock" lockFile := s.LocalPath(artifact) + ".lock"
@ -666,11 +644,6 @@ func (s *Storage) LocalPath(artifact sourcev1.Artifact) string {
return path 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 // writecounter is an implementation of io.Writer that only records the number
// of bytes written. // of bytes written.
type writeCounter struct { type writeCounter struct {

View File

@ -301,19 +301,6 @@ system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.</p>
</tr> </tr>
<tr> <tr>
<td> <td>
<code>checksum</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>Checksum is the SHA256 checksum of the Artifact file.
Deprecated: use Artifact.Digest instead.</p>
</td>
</tr>
<tr>
<td>
<code>digest</code><br> <code>digest</code><br>
<em> <em>
string string

View File

@ -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 // CacheIndex attempts to write the index from the remote into a new temporary file
// using DownloadIndex, and sets Path and cached. // 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 // The caller is expected to handle the garbage collection of Path, and to
// load the Index separately using LoadFromPath if required. // load the Index separately using LoadFromPath if required.
func (r *ChartRepository) CacheIndex() error { func (r *ChartRepository) CacheIndex() error {