github.com/lusis/distribution@v2.0.1+incompatible/notifications/listener.go (about) 1 package notifications 2 3 import ( 4 "github.com/Sirupsen/logrus" 5 "github.com/docker/distribution" 6 "github.com/docker/distribution/digest" 7 "github.com/docker/distribution/manifest" 8 ) 9 10 // ManifestListener describes a set of methods for listening to events related to manifests. 11 type ManifestListener interface { 12 ManifestPushed(repo distribution.Repository, sm *manifest.SignedManifest) error 13 ManifestPulled(repo distribution.Repository, sm *manifest.SignedManifest) error 14 15 // TODO(stevvooe): Please note that delete support is still a little shaky 16 // and we'll need to propagate these in the future. 17 18 ManifestDeleted(repo distribution.Repository, sm *manifest.SignedManifest) error 19 } 20 21 // LayerListener describes a listener that can respond to layer related events. 22 type LayerListener interface { 23 LayerPushed(repo distribution.Repository, layer distribution.Layer) error 24 LayerPulled(repo distribution.Repository, layer distribution.Layer) error 25 26 // TODO(stevvooe): Please note that delete support is still a little shaky 27 // and we'll need to propagate these in the future. 28 29 LayerDeleted(repo distribution.Repository, layer distribution.Layer) error 30 } 31 32 // Listener combines all repository events into a single interface. 33 type Listener interface { 34 ManifestListener 35 LayerListener 36 } 37 38 type repositoryListener struct { 39 distribution.Repository 40 listener Listener 41 } 42 43 // Listen dispatches events on the repository to the listener. 44 func Listen(repo distribution.Repository, listener Listener) distribution.Repository { 45 return &repositoryListener{ 46 Repository: repo, 47 listener: listener, 48 } 49 } 50 51 func (rl *repositoryListener) Manifests() distribution.ManifestService { 52 return &manifestServiceListener{ 53 ManifestService: rl.Repository.Manifests(), 54 parent: rl, 55 } 56 } 57 58 func (rl *repositoryListener) Layers() distribution.LayerService { 59 return &layerServiceListener{ 60 LayerService: rl.Repository.Layers(), 61 parent: rl, 62 } 63 } 64 65 type manifestServiceListener struct { 66 distribution.ManifestService 67 parent *repositoryListener 68 } 69 70 func (msl *manifestServiceListener) Get(dgst digest.Digest) (*manifest.SignedManifest, error) { 71 sm, err := msl.ManifestService.Get(dgst) 72 if err == nil { 73 if err := msl.parent.listener.ManifestPulled(msl.parent.Repository, sm); err != nil { 74 logrus.Errorf("error dispatching manifest pull to listener: %v", err) 75 } 76 } 77 78 return sm, err 79 } 80 81 func (msl *manifestServiceListener) Put(sm *manifest.SignedManifest) error { 82 err := msl.ManifestService.Put(sm) 83 84 if err == nil { 85 if err := msl.parent.listener.ManifestPushed(msl.parent.Repository, sm); err != nil { 86 logrus.Errorf("error dispatching manifest push to listener: %v", err) 87 } 88 } 89 90 return err 91 } 92 93 func (msl *manifestServiceListener) GetByTag(tag string) (*manifest.SignedManifest, error) { 94 sm, err := msl.ManifestService.GetByTag(tag) 95 if err == nil { 96 if err := msl.parent.listener.ManifestPulled(msl.parent.Repository, sm); err != nil { 97 logrus.Errorf("error dispatching manifest pull to listener: %v", err) 98 } 99 } 100 101 return sm, err 102 } 103 104 type layerServiceListener struct { 105 distribution.LayerService 106 parent *repositoryListener 107 } 108 109 func (lsl *layerServiceListener) Fetch(dgst digest.Digest) (distribution.Layer, error) { 110 layer, err := lsl.LayerService.Fetch(dgst) 111 if err == nil { 112 if err := lsl.parent.listener.LayerPulled(lsl.parent.Repository, layer); err != nil { 113 logrus.Errorf("error dispatching layer pull to listener: %v", err) 114 } 115 } 116 117 return layer, err 118 } 119 120 func (lsl *layerServiceListener) Upload() (distribution.LayerUpload, error) { 121 lu, err := lsl.LayerService.Upload() 122 return lsl.decorateUpload(lu), err 123 } 124 125 func (lsl *layerServiceListener) Resume(uuid string) (distribution.LayerUpload, error) { 126 lu, err := lsl.LayerService.Resume(uuid) 127 return lsl.decorateUpload(lu), err 128 } 129 130 func (lsl *layerServiceListener) decorateUpload(lu distribution.LayerUpload) distribution.LayerUpload { 131 return &layerUploadListener{ 132 LayerUpload: lu, 133 parent: lsl, 134 } 135 } 136 137 type layerUploadListener struct { 138 distribution.LayerUpload 139 parent *layerServiceListener 140 } 141 142 func (lul *layerUploadListener) Finish(dgst digest.Digest) (distribution.Layer, error) { 143 layer, err := lul.LayerUpload.Finish(dgst) 144 if err == nil { 145 if err := lul.parent.parent.listener.LayerPushed(lul.parent.parent.Repository, layer); err != nil { 146 logrus.Errorf("error dispatching layer push to listener: %v", err) 147 } 148 } 149 150 return layer, err 151 }