@@ -73,6 +73,7 @@ var helmChartReadyCondition = summarize.Conditions{
73
73
sourcev1 .FetchFailedCondition ,
74
74
sourcev1 .StorageOperationFailedCondition ,
75
75
sourcev1 .ArtifactOutdatedCondition ,
76
+ sourcev1 .SourceVerifiedCondition ,
76
77
meta .ReadyCondition ,
77
78
meta .ReconcilingCondition ,
78
79
meta .StalledCondition ,
@@ -82,6 +83,7 @@ var helmChartReadyCondition = summarize.Conditions{
82
83
sourcev1 .FetchFailedCondition ,
83
84
sourcev1 .StorageOperationFailedCondition ,
84
85
sourcev1 .ArtifactOutdatedCondition ,
86
+ sourcev1 .SourceVerifiedCondition ,
85
87
meta .StalledCondition ,
86
88
meta .ReconcilingCondition ,
87
89
},
@@ -469,16 +471,20 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
469
471
opts .VersionMetadata = strconv .FormatInt (obj .Generation , 10 )
470
472
}
471
473
472
- var keyring []byte
473
- keyring , err = r .getProvenanceKeyring (ctx , obj )
474
+ keyring , err := r .getProvenanceKeyring (ctx , obj )
474
475
if err != nil {
475
- conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , sourcev1 .AuthenticationFailedReason , err .Error ())
476
- return sreconcile .ResultEmpty , err
476
+ e := & serror.Event {
477
+ Err : fmt .Errorf ("failed to get public key for chart signature verification: %w" , err ),
478
+ Reason : sourcev1 .SourceVerifiedCondition ,
479
+ }
480
+ conditions .MarkFalse (obj , sourcev1 .FetchFailedCondition , sourcev1 .SourceVerifiedCondition , e .Error ())
481
+ return sreconcile .ResultEmpty , e
477
482
}
483
+ opts .Keyring = keyring
478
484
479
485
// Build the chart
480
486
ref := chart.RemoteReference {Name : obj .Spec .Chart , Version : obj .Spec .Version }
481
- build , err := cb .Build (ctx , ref , util .TempPathForObj ("" , ".tgz" , obj ), opts , keyring )
487
+ build , err := cb .Build (ctx , ref , util .TempPathForObj ("" , ".tgz" , obj ), opts )
482
488
483
489
if err != nil {
484
490
return sreconcile .ResultEmpty , err
@@ -599,19 +605,23 @@ func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj
599
605
}
600
606
opts .VersionMetadata += strconv .FormatInt (obj .Generation , 10 )
601
607
}
602
- var keyring []byte
603
- keyring , err = r .getProvenanceKeyring (ctx , obj )
608
+ keyring , err := r .getProvenanceKeyring (ctx , obj )
604
609
if err != nil {
605
- conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , sourcev1 .AuthenticationFailedReason , err .Error ())
606
- return sreconcile .ResultEmpty , err
610
+ e := & serror.Event {
611
+ Err : fmt .Errorf ("failed to get public key for chart signature verification: %w" , err ),
612
+ Reason : sourcev1 .SourceVerifiedCondition ,
613
+ }
614
+ conditions .MarkFalse (obj , sourcev1 .FetchFailedCondition , sourcev1 .SourceVerifiedCondition , e .Error ())
615
+ return sreconcile .ResultEmpty , e
607
616
}
617
+ opts .Keyring = keyring
608
618
609
619
// Build chart
610
620
cb := chart .NewLocalBuilder (dm )
611
621
build , err := cb .Build (ctx , chart.LocalReference {
612
622
WorkDir : sourceDir ,
613
623
Path : chartPath ,
614
- }, util .TempPathForObj ("" , ".tgz" , obj ), opts , keyring )
624
+ }, util .TempPathForObj ("" , ".tgz" , obj ), opts )
615
625
if err != nil {
616
626
return sreconcile .ResultEmpty , err
617
627
}
@@ -641,6 +651,14 @@ func (r *HelmChartReconciler) reconcileArtifact(ctx context.Context, obj *source
641
651
conditions .Delete (obj , sourcev1 .ArtifactOutdatedCondition )
642
652
conditions .MarkTrue (obj , meta .ReadyCondition , reasonForBuild (b ), b .Summary ())
643
653
}
654
+ if b .VerificationSignature != nil && b .ProvFilePath != "" && obj .GetArtifact () != nil {
655
+ var sigVerMsg strings.Builder
656
+ sigVerMsg .WriteString (fmt .Sprintf ("chart signed by: %v" , strings .Join (b .VerificationSignature .Identities [:], "," )))
657
+ sigVerMsg .WriteString (fmt .Sprintf (" using key with fingeprint: %X" , b .VerificationSignature .KeyFingerprint ))
658
+ sigVerMsg .WriteString (fmt .Sprintf (" and hash verified: %s" , b .VerificationSignature .FileHash ))
659
+
660
+ conditions .MarkTrue (obj , sourcev1 .SourceVerifiedCondition , reasonForBuild (b ), sigVerMsg .String ())
661
+ }
644
662
}()
645
663
646
664
// Create artifact from build data
@@ -692,7 +710,7 @@ func (r *HelmChartReconciler) reconcileArtifact(ctx context.Context, obj *source
692
710
if err = r .Storage .CopyFromPath (& provArtifact , b .ProvFilePath ); err != nil {
693
711
return sreconcile .ResultEmpty , & serror.Event {
694
712
Err : fmt .Errorf ("unable to copy Helm chart provenance file to storage: %w" , err ),
695
- Reason : sourcev1 .StorageOperationFailedReason ,
713
+ Reason : sourcev1 .StorageOperationFailedCondition ,
696
714
}
697
715
}
698
716
}
@@ -790,15 +808,23 @@ func (r *HelmChartReconciler) garbageCollect(ctx context.Context, obj *sourcev1.
790
808
obj .Status .Artifact = nil
791
809
return nil
792
810
}
811
+
793
812
if obj .GetArtifact () != nil {
794
- if deleted , err := r .Storage .RemoveAllButCurrent (* obj .GetArtifact ()); err != nil {
813
+ localPath := r .Storage .LocalPath (* obj .GetArtifact ())
814
+ provFilePath := localPath + ".prov"
815
+ dir := filepath .Dir (localPath )
816
+ callbacks := make ([]func (path string , info os.FileInfo ) bool , 0 )
817
+ callbacks = append (callbacks , func (path string , info os.FileInfo ) bool {
818
+ if path != localPath && path != provFilePath && info .Mode ()& os .ModeSymlink != os .ModeSymlink {
819
+ return true
820
+ }
821
+ return false
822
+ })
823
+ if _ , err := r .Storage .RemoveConditionally (dir , callbacks ); err != nil {
795
824
return & serror.Event {
796
825
Err : fmt .Errorf ("garbage collection of old artifacts failed: %w" , err ),
797
826
Reason : "GarbageCollectionFailed" ,
798
827
}
799
- } else if len (deleted ) > 0 {
800
- r .eventLogf (ctx , obj , events .EventTypeTrace , "GarbageCollectionSucceeded" ,
801
- "garbage collected old artifacts" )
802
828
}
803
829
}
804
830
return nil
@@ -1076,20 +1102,12 @@ func (r *HelmChartReconciler) getProvenanceKeyring(ctx context.Context, chart *s
1076
1102
var secret corev1.Secret
1077
1103
err := r .Client .Get (ctx , name , & secret )
1078
1104
if err != nil {
1079
- e := & serror.Event {
1080
- Err : fmt .Errorf ("failed to get secret '%s': %w" , chart .Spec .VerificationKeyring .SecretRef .Name , err ),
1081
- Reason : sourcev1 .AuthenticationFailedReason ,
1082
- }
1083
- return nil , e
1105
+ return nil , err
1084
1106
}
1085
1107
key := chart .Spec .VerificationKeyring .Key
1086
1108
if val , ok := secret .Data [key ]; ! ok {
1087
1109
err = fmt .Errorf ("secret doesn't contain the advertised verification keyring name %s" , key )
1088
- e := & serror.Event {
1089
- Err : fmt .Errorf ("invalid secret '%s': %w" , secret .GetName (), err ),
1090
- Reason : sourcev1 .AuthenticationFailedReason ,
1091
- }
1092
- return nil , e
1110
+ return nil , err
1093
1111
} else {
1094
1112
return val , nil
1095
1113
}
0 commit comments