@@ -18,6 +18,7 @@ package controllers
18
18
19
19
import (
20
20
"context"
21
+ "crypto/sha256"
21
22
"crypto/tls"
22
23
"crypto/x509"
23
24
"errors"
@@ -60,6 +61,7 @@ import (
60
61
"github.com/fluxcd/pkg/runtime/events"
61
62
"github.com/fluxcd/pkg/runtime/patch"
62
63
"github.com/fluxcd/pkg/runtime/predicates"
64
+ "github.com/fluxcd/pkg/sourceignore"
63
65
"github.com/fluxcd/pkg/untar"
64
66
"github.com/fluxcd/pkg/version"
65
67
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
@@ -418,8 +420,10 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
418
420
conditions .MarkTrue (obj , sourcev1 .SourceVerifiedCondition , meta .SucceededReason , "verified signature of revision %s" , revision )
419
421
}
420
422
421
- // Skip pulling if the artifact revision hasn't changes
422
- if obj .GetArtifact ().HasRevision (revision ) {
423
+ // Skip pulling if the artifact revision and the content config checksum has
424
+ // not changed.
425
+ if obj .GetArtifact ().HasRevision (revision ) &&
426
+ r .calculateContentConfigChecksum (obj ) == obj .Status .ContentConfigChecksum {
423
427
conditions .Delete (obj , sourcev1 .FetchFailedCondition )
424
428
return sreconcile .ResultSuccess , nil
425
429
}
@@ -922,17 +926,22 @@ func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, obj *so
922
926
artifact := r .Storage .NewArtifactFor (obj .Kind , obj , revision ,
923
927
fmt .Sprintf ("%s.tar.gz" , r .digestFromRevision (revision )))
924
928
929
+ // Calculate the content config checksum.
930
+ ccc := r .calculateContentConfigChecksum (obj )
931
+
925
932
// Set the ArtifactInStorageCondition if there's no drift.
926
933
defer func () {
927
- if obj .GetArtifact ().HasRevision (artifact .Revision ) {
934
+ if obj .GetArtifact ().HasRevision (artifact .Revision ) &&
935
+ obj .Status .ContentConfigChecksum == ccc {
928
936
conditions .Delete (obj , sourcev1 .ArtifactOutdatedCondition )
929
937
conditions .MarkTrue (obj , sourcev1 .ArtifactInStorageCondition , meta .SucceededReason ,
930
938
"stored artifact for digest '%s'" , artifact .Revision )
931
939
}
932
940
}()
933
941
934
942
// The artifact is up-to-date
935
- if obj .GetArtifact ().HasRevision (artifact .Revision ) {
943
+ if obj .GetArtifact ().HasRevision (artifact .Revision ) &&
944
+ obj .Status .ContentConfigChecksum == ccc {
936
945
r .eventLogf (ctx , obj , events .EventTypeTrace , sourcev1 .ArtifactUpToDateReason ,
937
946
"artifact up-to-date with remote revision: '%s'" , artifact .Revision )
938
947
return sreconcile .ResultSuccess , nil
@@ -984,7 +993,20 @@ func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, obj *so
984
993
return sreconcile .ResultEmpty , e
985
994
}
986
995
default :
987
- if err := r .Storage .Archive (& artifact , dir , nil ); err != nil {
996
+ // Load ignore rules for archiving.
997
+ ignoreDomain := strings .Split (dir , string (filepath .Separator ))
998
+ ps , err := sourceignore .LoadIgnorePatterns (dir , ignoreDomain )
999
+ if err != nil {
1000
+ return sreconcile .ResultEmpty , serror .NewGeneric (
1001
+ fmt .Errorf ("failed to load source ignore patterns from repository: %w" , err ),
1002
+ "SourceIgnoreError" ,
1003
+ )
1004
+ }
1005
+ if obj .Spec .Ignore != nil {
1006
+ ps = append (ps , sourceignore .ReadPatterns (strings .NewReader (* obj .Spec .Ignore ), ignoreDomain )... )
1007
+ }
1008
+
1009
+ if err := r .Storage .Archive (& artifact , dir , SourceIgnoreFilter (ps , ignoreDomain )); err != nil {
988
1010
e := serror .NewGeneric (
989
1011
fmt .Errorf ("unable to archive artifact to storage: %s" , err ),
990
1012
sourcev1 .ArchiveOperationFailedReason ,
@@ -997,6 +1019,7 @@ func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, obj *so
997
1019
// Record it on the object
998
1020
obj .Status .Artifact = artifact .DeepCopy ()
999
1021
obj .Status .Artifact .Metadata = metadata .Metadata
1022
+ obj .Status .ContentConfigChecksum = ccc
1000
1023
1001
1024
// Update symlink on a "best effort" basis
1002
1025
url , err := r .Storage .Symlink (artifact , "latest.tar.gz" )
@@ -1125,3 +1148,21 @@ func (r *OCIRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *so
1125
1148
}
1126
1149
}
1127
1150
}
1151
+
1152
+ // calculateContentConfigChecksum calculates a checksum of all the
1153
+ // configurations that result in a change in the source artifact. It can be used
1154
+ // to decide if further reconciliation is needed when an artifact already exists
1155
+ // for a set of configurations.
1156
+ func (r * OCIRepositoryReconciler ) calculateContentConfigChecksum (obj * sourcev1.OCIRepository ) string {
1157
+ c := []byte {}
1158
+ // Consider the ignore rules.
1159
+ if obj .Spec .Ignore != nil {
1160
+ c = append (c , []byte (* obj .Spec .Ignore )... )
1161
+ }
1162
+ // Consider the layer selector.
1163
+ if obj .Spec .LayerSelector != nil {
1164
+ c = append (c , []byte (obj .GetLayerMediaType ()+ obj .GetLayerOperation ())... )
1165
+ }
1166
+
1167
+ return fmt .Sprintf ("sha256:%x" , sha256 .Sum256 (c ))
1168
+ }
0 commit comments