@@ -41,6 +41,7 @@ type ArtifactStore struct {
4141 SystemContext * types.SystemContext
4242 storePath string
4343 lock * lockfile.LockFile
44+ eventChannel chan * Event
4445}
4546
4647// NewArtifactStore is a constructor for artifact stores. Most artifact dealings depend on this. Store path is
@@ -81,6 +82,18 @@ func NewArtifactStore(storePath string, sc *types.SystemContext) (*ArtifactStore
8182 return artifactStore , nil
8283}
8384
85+ // EventChannel creates a buffered channel for events that the ArtifactStore will use
86+ // to write events to. Callers are expected to read from the channel in a
87+ // timely manner.
88+ // Can be called once for a given ArtifactStore.
89+ func (as * ArtifactStore ) EventChannel () chan * Event {
90+ if as .eventChannel != nil {
91+ return as .eventChannel
92+ }
93+ as .eventChannel = make (chan * Event , 100 )
94+ return as .eventChannel
95+ }
96+
8497// lookupArtifactLocked looks up an artifact by fully qualified name,
8598// or name@digest, full ID, or partial ID.
8699// note: lookupArtifactLocked must be called while under a store lock
@@ -146,19 +159,30 @@ func (as ArtifactStore) lookupArtifactLocked(ctx context.Context, asr ArtifactSt
146159}
147160
148161// Remove an artifact from the local artifact store.
149- func (as ArtifactStore ) Remove (ctx context.Context , asr ArtifactStoreReference ) (* digest.Digest , error ) {
162+ func (as ArtifactStore ) Remove (ctx context.Context , asr ArtifactStoreReference ) (_ * digest.Digest , removeErr error ) {
150163 as .lock .Lock ()
151164 defer as .lock .Unlock ()
152165
153166 arty , err := as .lookupArtifactLocked (ctx , asr )
154167 if err != nil {
155168 return nil , err
156169 }
170+
171+ defer func () {
172+ if removeErr != nil {
173+ as .writeEvent (& Event {ID : arty .Digest .String (), Name : arty .Name , Time : time .Now (), Type : EventTypeArtifactRemoveError , Error : removeErr })
174+ }
175+ }()
176+
157177 ir , err := layout .NewReference (as .storePath , arty .Name )
158178 if err != nil {
159179 return nil , err
160180 }
161- return & arty .Digest , ir .DeleteImage (ctx , as .SystemContext )
181+ if err := ir .DeleteImage (ctx , as .SystemContext ); err != nil {
182+ return nil , err
183+ }
184+ as .writeEvent (& Event {ID : arty .Digest .String (), Name : arty .Name , Time : time .Now (), Type : EventTypeArtifactRemove })
185+ return & arty .Digest , nil
162186}
163187
164188// Inspect an artifact in a local store.
@@ -178,7 +202,13 @@ func (as ArtifactStore) List(ctx context.Context) (ArtifactList, error) {
178202}
179203
180204// Pull an artifact from an image registry to a local store.
181- func (as ArtifactStore ) Pull (ctx context.Context , ref ArtifactReference , opts libimage.CopyOptions ) (digest.Digest , error ) {
205+ func (as ArtifactStore ) Pull (ctx context.Context , ref ArtifactReference , opts libimage.CopyOptions ) (_ digest.Digest , pullErr error ) {
206+ defer func () {
207+ if pullErr != nil {
208+ as .writeEvent (& Event {Name : ref .String (), Time : time .Now (), Type : EventTypeArtifactPullError , Error : pullErr })
209+ }
210+ }()
211+
182212 srcRef , err := docker .NewReference (ref .ref )
183213 if err != nil {
184214 return "" , err
@@ -202,11 +232,19 @@ func (as ArtifactStore) Pull(ctx context.Context, ref ArtifactReference, opts li
202232 if err != nil {
203233 return "" , err
204234 }
205- return digest .FromBytes (artifactBytes ), nil
235+ artifactDigest := digest .FromBytes (artifactBytes )
236+ as .writeEvent (& Event {ID : artifactDigest .String (), Name : ref .String (), Time : time .Now (), Type : EventTypeArtifactPull })
237+ return artifactDigest , nil
206238}
207239
208240// Push an artifact to an image registry.
209- func (as ArtifactStore ) Push (ctx context.Context , src , dest ArtifactReference , opts libimage.CopyOptions ) (digest.Digest , error ) {
241+ func (as ArtifactStore ) Push (ctx context.Context , src , dest ArtifactReference , opts libimage.CopyOptions ) (_ digest.Digest , pushErr error ) {
242+ defer func () {
243+ if pushErr != nil {
244+ as .writeEvent (& Event {Name : dest .String (), Time : time .Now (), Type : EventTypeArtifactPushError , Error : pushErr })
245+ }
246+ }()
247+
210248 destRef , err := docker .NewReference (dest .ref )
211249 if err != nil {
212250 return "" , err
@@ -233,6 +271,7 @@ func (as ArtifactStore) Push(ctx context.Context, src, dest ArtifactReference, o
233271 return "" , err
234272 }
235273 artifactDigest := digest .FromBytes (artifactBytes )
274+ as .writeEvent (& Event {ID : artifactDigest .String (), Name : dest .String (), Time : time .Now (), Type : EventTypeArtifactPush })
236275 return artifactDigest , nil
237276}
238277
@@ -279,7 +318,13 @@ func cleanupAfterAppend(ctx context.Context, oldDigest digest.Digest, as Artifac
279318
280319// Add takes one or more artifact blobs and add them to the local artifact store. The empty
281320// string input is for possible custom artifact types.
282- func (as ArtifactStore ) Add (ctx context.Context , dest ArtifactReference , artifactBlobs []libartTypes.ArtifactBlob , options * libartTypes.AddOptions ) (* digest.Digest , error ) {
321+ func (as ArtifactStore ) Add (ctx context.Context , dest ArtifactReference , artifactBlobs []libartTypes.ArtifactBlob , options * libartTypes.AddOptions ) (_ * digest.Digest , addErr error ) {
322+ defer func () {
323+ if addErr != nil {
324+ as .writeEvent (& Event {Name : dest .String (), Time : time .Now (), Type : EventTypeArtifactAddError , Error : addErr })
325+ }
326+ }()
327+
283328 if options .Append && len (options .ArtifactMIMEType ) > 0 {
284329 return nil , errors .New ("append option is not compatible with type option" )
285330 }
@@ -447,6 +492,7 @@ func (as ArtifactStore) Add(ctx context.Context, dest ArtifactReference, artifac
447492 return nil , err
448493 }
449494 }
495+ as .writeEvent (& Event {ID : artifactManifestDigest .String (), Name : dest .String (), Time : time .Now (), Type : EventTypeArtifactAdd })
450496 return & artifactManifestDigest , nil
451497}
452498
0 commit comments