@@ -37,17 +37,24 @@ import (
3737
3838var ErrEmptyArtifactName = errors .New ("artifact name cannot be empty" )
3939
40+ type EventCallback func (eventType , name , digest string , attrs map [string ]string )
41+
4042const ManifestSchemaVersion = 2
4143
4244type ArtifactStore struct {
4345 SystemContext * types.SystemContext
4446 storePath string
4547 lock * lockfile.LockFile
48+ eventCallback EventCallback
4649}
4750
4851// NewArtifactStore is a constructor for artifact stores. Most artifact dealings depend on this. Store path is
4952// the filesystem location.
50- func NewArtifactStore (storePath string , sc * types.SystemContext ) (* ArtifactStore , error ) {
53+ func NewArtifactStore (storePath string , sc * types.SystemContext , eventCallback EventCallback ) (* ArtifactStore , error ) {
54+ return NewArtifactStoreWithEventCallback (storePath , sc , nil )
55+ }
56+
57+ func NewArtifactStoreWithEventCallback (storePath string , sc * types.SystemContext , eventCallback EventCallback ) (* ArtifactStore , error ) {
5158 if storePath == "" {
5259 return nil , errors .New ("store path cannot be empty" )
5360 }
@@ -60,6 +67,7 @@ func NewArtifactStore(storePath string, sc *types.SystemContext) (*ArtifactStore
6067 artifactStore := & ArtifactStore {
6168 storePath : storePath ,
6269 SystemContext : sc ,
70+ eventCallback : eventCallback ,
6371 }
6472
6573 // if the storage dir does not exist, we need to create it.
@@ -113,7 +121,13 @@ func (as ArtifactStore) Remove(ctx context.Context, name string) (*digest.Digest
113121 if err != nil {
114122 return nil , err
115123 }
116- return artifactDigest , ir .DeleteImage (ctx , as .SystemContext )
124+ if err := ir .DeleteImage (ctx , as .SystemContext ); err != nil {
125+ return artifactDigest , err
126+ }
127+ if as .eventCallback != nil {
128+ as .eventCallback ("remove" , name , artifactDigest .String (), nil )
129+ }
130+ return artifactDigest , nil
117131}
118132
119133// Inspect an artifact in a local store.
@@ -170,7 +184,11 @@ func (as ArtifactStore) Pull(ctx context.Context, name string, opts libimage.Cop
170184 if err != nil {
171185 return "" , err
172186 }
173- return digest .FromBytes (artifactBytes ), nil
187+ artifactDigest := digest .FromBytes (artifactBytes )
188+ if as .eventCallback != nil {
189+ as .eventCallback ("pull" , name , artifactDigest .String (), nil )
190+ }
191+ return artifactDigest , nil
174192}
175193
176194// Push an artifact to an image registry.
@@ -204,6 +222,9 @@ func (as ArtifactStore) Push(ctx context.Context, src, dest string, opts libimag
204222 return "" , err
205223 }
206224 artifactDigest := digest .FromBytes (artifactBytes )
225+ if as .eventCallback != nil {
226+ as .eventCallback ("push" , src , artifactDigest .String (), nil )
227+ }
207228 return artifactDigest , nil
208229}
209230
@@ -400,6 +421,11 @@ func (as ArtifactStore) Add(ctx context.Context, dest string, artifactBlobs []li
400421 }
401422 }
402423 }
424+ if as .eventCallback != nil {
425+ as .eventCallback ("add" , dest , artifactManifestDigest .String (), map [string ]string {
426+ "files" : fmt .Sprintf ("%d" , len (artifactBlobs )),
427+ })
428+ }
403429 return & artifactManifestDigest , nil
404430}
405431
@@ -525,10 +551,10 @@ func (as ArtifactStore) Extract(ctx context.Context, nameOrDigest string, target
525551 digest = arty .Manifest .Layers [0 ].Digest
526552 }
527553
528- return copyTrustedImageBlobToFile (ctx , imgSrc , digest , target )
529- }
530-
531- if len (options .Digest ) > 0 || len (options .Title ) > 0 {
554+ if err := copyTrustedImageBlobToFile (ctx , imgSrc , digest , target ); err != nil {
555+ return err
556+ }
557+ } else if len (options .Digest ) > 0 || len (options .Title ) > 0 {
532558 digest , err := findDigest (arty , & options .FilterBlobOptions )
533559 if err != nil {
534560 return err
@@ -542,22 +568,29 @@ func (as ArtifactStore) Extract(ctx context.Context, nameOrDigest string, target
542568 return err
543569 }
544570
545- return copyTrustedImageBlobToFile (ctx , imgSrc , digest , filepath .Join (target , filename ))
546- }
547-
548- for _ , l := range arty .Manifest .Layers {
549- title := l .Annotations [specV1 .AnnotationTitle ]
550- filename , err := generateArtifactBlobName (title , l .Digest )
551- if err != nil {
571+ if err := copyTrustedImageBlobToFile (ctx , imgSrc , digest , filepath .Join (target , filename )); err != nil {
552572 return err
553573 }
574+ } else {
575+ for _ , l := range arty .Manifest .Layers {
576+ title := l .Annotations [specV1 .AnnotationTitle ]
577+ filename , err := generateArtifactBlobName (title , l .Digest )
578+ if err != nil {
579+ return err
580+ }
554581
555- err = copyTrustedImageBlobToFile (ctx , imgSrc , l .Digest , filepath .Join (target , filename ))
556- if err != nil {
557- return err
582+ err = copyTrustedImageBlobToFile (ctx , imgSrc , l .Digest , filepath .Join (target , filename ))
583+ if err != nil {
584+ return err
585+ }
558586 }
559587 }
560588
589+ if as .eventCallback != nil {
590+ attrs := map [string ]string {"target" : target }
591+ as .eventCallback ("extract" , arty .Name , options .Digest , attrs )
592+ }
593+
561594 return nil
562595}
563596
@@ -599,47 +632,51 @@ func (as ArtifactStore) ExtractTarStream(ctx context.Context, w io.Writer, nameO
599632 if err != nil {
600633 return err
601634 }
635+ } else {
602636
603- return nil
604- }
637+ artifactBlobCount := len (arty .Manifest .Layers )
605638
606- artifactBlobCount := len (arty .Manifest .Layers )
639+ type blob struct {
640+ name string
641+ digest digest.Digest
642+ }
643+ blobs := make ([]blob , 0 , artifactBlobCount )
607644
608- type blob struct {
609- name string
610- digest digest. Digest
611- }
612- blobs := make ([] blob , 0 , artifactBlobCount )
645+ // Gather blob details and return error on any illegal names
646+ for _ , l := range arty . Manifest . Layers {
647+ title := l . Annotations [ specV1 . AnnotationTitle ]
648+ digest := l . Digest
649+ var name string
613650
614- // Gather blob details and return error on any illegal names
615- for _ , l := range arty .Manifest .Layers {
616- title := l .Annotations [specV1 .AnnotationTitle ]
617- digest := l .Digest
618- var name string
651+ if artifactBlobCount != 1 || ! options .ExcludeTitle {
652+ name , err = generateArtifactBlobName (title , digest )
653+ if err != nil {
654+ return err
655+ }
656+ }
657+
658+ blobs = append (blobs , blob {
659+ name : name ,
660+ digest : digest ,
661+ })
662+ }
663+
664+ // Wrap io.Writer in a tar.Writer
665+ tw := tar .NewWriter (w )
666+ defer tw .Close ()
619667
620- if artifactBlobCount != 1 || ! options .ExcludeTitle {
621- name , err = generateArtifactBlobName (title , digest )
668+ // Write each blob to tar.Writer then close
669+ for _ , b := range blobs {
670+ err := copyTrustedImageBlobToTarStream (ctx , imgSrc , b .digest , b .name , tw )
622671 if err != nil {
623672 return err
624673 }
625674 }
626-
627- blobs = append (blobs , blob {
628- name : name ,
629- digest : digest ,
630- })
631675 }
632676
633- // Wrap io.Writer in a tar.Writer
634- tw := tar .NewWriter (w )
635- defer tw .Close ()
636-
637- // Write each blob to tar.Writer then close
638- for _ , b := range blobs {
639- err := copyTrustedImageBlobToTarStream (ctx , imgSrc , b .digest , b .name , tw )
640- if err != nil {
641- return err
642- }
677+ if as .eventCallback != nil {
678+ attrs := map [string ]string {"format" : "tar-stream" }
679+ as .eventCallback ("extract" , arty .Name , options .Digest , attrs )
643680 }
644681
645682 return nil
0 commit comments