@@ -68,18 +68,19 @@ type Runtime struct {
6868 storageConfig storage.StoreOptions
6969 storageSet storageSet
7070
71- state State
72- store storage.Store
73- storageService * storageService
74- imageContext types.SystemContext
75- defaultOCIRuntime OCIRuntime
76- ociRuntimes map [string ]OCIRuntime
77- runtimeFlags []string
78- network nettypes.ContainerNetwork
79- conmonPath string
80- libimageRuntime * libimage.Runtime
81- libimageEventsShutdown chan bool
82- lockManager lock.Manager
71+ state State
72+ store storage.Store
73+ storageService * storageService
74+ imageContext types.SystemContext
75+ defaultOCIRuntime OCIRuntime
76+ ociRuntimes map [string ]OCIRuntime
77+ runtimeFlags []string
78+ network nettypes.ContainerNetwork
79+ conmonPath string
80+ libimageRuntime * libimage.Runtime
81+ libimageEventsShutdown chan bool
82+ libartifactEventsShutdown chan bool
83+ lockManager lock.Manager
8384
8485 // ArtifactStore returns the artifact store created from the runtime.
8586 ArtifactStore func () (* artStore.ArtifactStore , error )
@@ -501,7 +502,12 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
501502
502503 // Using sync once value to only init the store exactly once and only when it will be actually be used.
503504 runtime .ArtifactStore = sync .OnceValues (func () (* artStore.ArtifactStore , error ) {
504- return artStore .NewArtifactStore (filepath .Join (runtime .storageConfig .GraphRoot , "artifacts" ), runtime .SystemContext ())
505+ artifactStore , err := artStore .NewArtifactStore (filepath .Join (runtime .storageConfig .GraphRoot , "artifacts" ), runtime .SystemContext ())
506+ if err != nil {
507+ return nil , err
508+ }
509+ runtime .libartifactEvents (artifactStore )
510+ return artifactStore , nil
505511 })
506512 }
507513
@@ -722,6 +728,66 @@ func (r *Runtime) libimageEvents() {
722728 }()
723729}
724730
731+ // libartifactEventsMap translates a libartifact event type to a libpod event status.
732+ var libartifactEventsMap = map [artStore.EventType ]events.Status {
733+ artStore .EventTypeArtifactPull : events .Pull ,
734+ artStore .EventTypeArtifactPush : events .Push ,
735+ artStore .EventTypeArtifactRemove : events .Remove ,
736+ artStore .EventTypeArtifactAdd : events .Create ,
737+ }
738+
739+ // libartifactEvents spawns a goroutine which will listen for events on
740+ // the artStore.ArtifactStore. The goroutine will be cleaned up implicitly
741+ // when the main() exists.
742+ func (r * Runtime ) libartifactEvents (store * artStore.ArtifactStore ) {
743+ r .libartifactEventsShutdown = make (chan bool )
744+
745+ toLibpodEventStatus := func (e * artStore.Event ) events.Status {
746+ status , found := libartifactEventsMap [e .Type ]
747+ if ! found {
748+ return "Unknown"
749+ }
750+ return status
751+ }
752+
753+ eventChannel := store .EventChannel ()
754+
755+ go func () {
756+ sawShutdown := false
757+ for {
758+ // Make sure to read and write all events before
759+ // shutting down.
760+ for len (eventChannel ) > 0 {
761+ libartifactEvent := <- eventChannel
762+ e := events.Event {
763+ ID : libartifactEvent .ID ,
764+ Name : libartifactEvent .Name ,
765+ Status : toLibpodEventStatus (libartifactEvent ),
766+ Time : libartifactEvent .Time ,
767+ Type : events .Artifact ,
768+ }
769+ if libartifactEvent .Error != nil {
770+ e .Error = libartifactEvent .Error .Error ()
771+ }
772+ if err := r .eventer .Write (e ); err != nil {
773+ logrus .Errorf ("Unable to write artifact event: %q" , err )
774+ }
775+ }
776+
777+ if sawShutdown {
778+ close (r .libartifactEventsShutdown )
779+ return
780+ }
781+
782+ select {
783+ case <- r .libartifactEventsShutdown :
784+ sawShutdown = true
785+ case <- time .After (100 * time .Millisecond ):
786+ }
787+ }
788+ }()
789+ }
790+
725791// DeferredShutdown shuts down the runtime without exposing any
726792// errors. This is only meant to be used when the runtime is being
727793// shutdown within a defer statement; else use Shutdown
@@ -771,6 +837,13 @@ func (r *Runtime) Shutdown(force bool) error {
771837 <- r .libimageEventsShutdown
772838 }
773839
840+ if r .libartifactEventsShutdown != nil {
841+ // Tell loop to shutdown
842+ r .libartifactEventsShutdown <- true
843+ // Wait for close to signal shutdown
844+ <- r .libartifactEventsShutdown
845+ }
846+
774847 // Note that the libimage runtime shuts down the store.
775848 if err := r .libimageRuntime .Shutdown (force ); err != nil {
776849 lastError = fmt .Errorf ("shutting down container storage: %w" , err )
0 commit comments