@@ -2,6 +2,7 @@ package imagebuildah
22
33import (
44 "context"
5+ "encoding/json"
56 "errors"
67 "fmt"
78 "io"
@@ -15,6 +16,7 @@ import (
1516 "github.com/containers/buildah"
1617 "github.com/containers/buildah/define"
1718 "github.com/containers/buildah/internal"
19+ "github.com/containers/buildah/internal/metadata"
1820 internalUtil "github.com/containers/buildah/internal/util"
1921 "github.com/containers/buildah/pkg/parse"
2022 "github.com/containers/buildah/pkg/sshagent"
@@ -172,6 +174,7 @@ type executor struct {
172174 sourceDateEpoch * time.Time
173175 rewriteTimestamp bool
174176 createdAnnotation types.OptionalBool
177+ metadataFile string
175178}
176179
177180type imageTypeAndHistoryAndDiffIDs struct {
@@ -346,6 +349,7 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o
346349 sourceDateEpoch : options .SourceDateEpoch ,
347350 rewriteTimestamp : options .RewriteTimestamp ,
348351 createdAnnotation : options .CreatedAnnotation ,
352+ metadataFile : options .MetadataFile ,
349353 }
350354 // sort unsetAnnotations because we will later write these
351355 // values to the history of the image therefore we want to
@@ -519,7 +523,7 @@ func (b *executor) getImageTypeAndHistoryAndDiffIDs(ctx context.Context, imageID
519523 return oci .OS , oci .Architecture , manifestFormat , oci .History , oci .RootFS .DiffIDs , nil
520524}
521525
522- func (b * executor ) buildStage (ctx context.Context , cleanupStages map [int ]* stageExecutor , stages imagebuilder.Stages , stageIndex int ) (imageID string , ref reference. Canonical , onlyBaseImage bool , err error ) {
526+ func (b * executor ) buildStage (ctx context.Context , cleanupStages map [int ]* stageExecutor , stages imagebuilder.Stages , stageIndex int ) (imageID string , commitResults * buildah. CommitResults , onlyBaseImage bool , err error ) {
523527 stage := stages [stageIndex ]
524528 ib := stage .Builder
525529 node := stage .Node
@@ -616,7 +620,7 @@ func (b *executor) buildStage(ctx context.Context, cleanupStages map[int]*stageE
616620 }
617621
618622 // Build this stage.
619- if imageID , ref , onlyBaseImage , err = stageExecutor .execute (ctx , base ); err != nil {
623+ if imageID , commitResults , onlyBaseImage , err = stageExecutor .execute (ctx , base ); err != nil {
620624 return "" , nil , onlyBaseImage , err
621625 }
622626
@@ -630,7 +634,7 @@ func (b *executor) buildStage(ctx context.Context, cleanupStages map[int]*stageE
630634 b .stagesLock .Unlock ()
631635 }
632636
633- return imageID , ref , onlyBaseImage , nil
637+ return imageID , commitResults , onlyBaseImage , nil
634638}
635639
636640type stageDependencyInfo struct {
@@ -922,7 +926,7 @@ func (b *executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
922926 Index int
923927 ImageID string
924928 OnlyBaseImage bool
925- Ref reference. Canonical
929+ CommitResults buildah. CommitResults
926930 Error error
927931 }
928932
@@ -935,6 +939,7 @@ func (b *executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
935939 var wg sync.WaitGroup
936940 wg .Add (len (stages ))
937941
942+ var commitResults buildah.CommitResults
938943 go func () {
939944 cancel := false
940945 for stageIndex := range stages {
@@ -983,7 +988,7 @@ func (b *executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
983988 return
984989 }
985990 }
986- stageID , stageRef , stageOnlyBaseImage , stageErr := b .buildStage (ctx , cleanupStages , stages , index )
991+ stageID , stageResults , stageOnlyBaseImage , stageErr := b .buildStage (ctx , cleanupStages , stages , index )
987992 if stageErr != nil {
988993 cancel = true
989994 ch <- Result {
@@ -997,7 +1002,7 @@ func (b *executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
9971002 ch <- Result {
9981003 Index : index ,
9991004 ImageID : stageID ,
1000- Ref : stageRef ,
1005+ CommitResults : * stageResults ,
10011006 OnlyBaseImage : stageOnlyBaseImage ,
10021007 Error : nil ,
10031008 }
@@ -1037,7 +1042,8 @@ func (b *executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
10371042 }
10381043 if r .Index == len (stages )- 1 {
10391044 imageID = r .ImageID
1040- ref = r .Ref
1045+ commitResults = r .CommitResults
1046+ ref = commitResults .Canonical
10411047 }
10421048 b .stagesLock .Unlock ()
10431049 }
@@ -1088,7 +1094,11 @@ func (b *executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
10881094 if b .iidfile != "" {
10891095 iid := imageID
10901096 if iid != "" {
1091- iid = "sha256:" + iid // only prepend a digest algorithm name if we actually got a value back
1097+ cdigest , err := digest .Parse ("sha256:" + imageID )
1098+ if err != nil {
1099+ return imageID , ref , fmt .Errorf ("coercing image ID into a digest structure: %w" , err )
1100+ }
1101+ iid = cdigest .String ()
10921102 }
10931103 if err = os .WriteFile (b .iidfile , []byte (iid ), 0o644 ); err != nil {
10941104 return imageID , ref , fmt .Errorf ("failed to write image ID to file %q: %w" , b .iidfile , err )
@@ -1098,6 +1108,29 @@ func (b *executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
10981108 return imageID , ref , fmt .Errorf ("failed to write image ID to stdout: %w" , err )
10991109 }
11001110 }
1111+ if b .metadataFile != "" {
1112+ var cdigest digest.Digest
1113+ if imageID != "" {
1114+ if cdigest , err = digest .Parse ("sha256:" + imageID ); err != nil {
1115+ return imageID , ref , fmt .Errorf ("coercing image ID into a digest structure: %w" , err )
1116+ }
1117+ }
1118+ metadata , err := metadata .Build (cdigest , v1.Descriptor {
1119+ MediaType : commitResults .MediaType ,
1120+ Digest : commitResults .Digest ,
1121+ Size : int64 (len (commitResults .ImageManifest )),
1122+ })
1123+ if err != nil {
1124+ return imageID , ref , fmt .Errorf ("building metadata for metadata file: %w" , err )
1125+ }
1126+ metadataBytes , err := json .Marshal (metadata )
1127+ if err != nil {
1128+ return imageID , ref , fmt .Errorf ("encoding metadata for metadata file: %w" , err )
1129+ }
1130+ if err = os .WriteFile (b .metadataFile , metadataBytes , 0o644 ); err != nil {
1131+ return imageID , ref , fmt .Errorf ("failed to write image metadata to file %q: %w" , b .metadataFile , err )
1132+ }
1133+ }
11011134 return imageID , ref , nil
11021135}
11031136
0 commit comments