152 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
package notifications
 | 
						|
 | 
						|
import (
 | 
						|
	"github.com/Sirupsen/logrus"
 | 
						|
	"github.com/docker/distribution"
 | 
						|
	"github.com/docker/distribution/digest"
 | 
						|
	"github.com/docker/distribution/manifest"
 | 
						|
)
 | 
						|
 | 
						|
// ManifestListener describes a set of methods for listening to events related to manifests.
 | 
						|
type ManifestListener interface {
 | 
						|
	ManifestPushed(repo distribution.Repository, sm *manifest.SignedManifest) error
 | 
						|
	ManifestPulled(repo distribution.Repository, sm *manifest.SignedManifest) error
 | 
						|
 | 
						|
	// TODO(stevvooe): Please note that delete support is still a little shaky
 | 
						|
	// and we'll need to propagate these in the future.
 | 
						|
 | 
						|
	ManifestDeleted(repo distribution.Repository, sm *manifest.SignedManifest) error
 | 
						|
}
 | 
						|
 | 
						|
// LayerListener describes a listener that can respond to layer related events.
 | 
						|
type LayerListener interface {
 | 
						|
	LayerPushed(repo distribution.Repository, layer distribution.Layer) error
 | 
						|
	LayerPulled(repo distribution.Repository, layer distribution.Layer) error
 | 
						|
 | 
						|
	// TODO(stevvooe): Please note that delete support is still a little shaky
 | 
						|
	// and we'll need to propagate these in the future.
 | 
						|
 | 
						|
	LayerDeleted(repo distribution.Repository, layer distribution.Layer) error
 | 
						|
}
 | 
						|
 | 
						|
// Listener combines all repository events into a single interface.
 | 
						|
type Listener interface {
 | 
						|
	ManifestListener
 | 
						|
	LayerListener
 | 
						|
}
 | 
						|
 | 
						|
type repositoryListener struct {
 | 
						|
	distribution.Repository
 | 
						|
	listener Listener
 | 
						|
}
 | 
						|
 | 
						|
// Listen dispatches events on the repository to the listener.
 | 
						|
func Listen(repo distribution.Repository, listener Listener) distribution.Repository {
 | 
						|
	return &repositoryListener{
 | 
						|
		Repository: repo,
 | 
						|
		listener:   listener,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (rl *repositoryListener) Manifests() distribution.ManifestService {
 | 
						|
	return &manifestServiceListener{
 | 
						|
		ManifestService: rl.Repository.Manifests(),
 | 
						|
		parent:          rl,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (rl *repositoryListener) Layers() distribution.LayerService {
 | 
						|
	return &layerServiceListener{
 | 
						|
		LayerService: rl.Repository.Layers(),
 | 
						|
		parent:       rl,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type manifestServiceListener struct {
 | 
						|
	distribution.ManifestService
 | 
						|
	parent *repositoryListener
 | 
						|
}
 | 
						|
 | 
						|
func (msl *manifestServiceListener) Get(dgst digest.Digest) (*manifest.SignedManifest, error) {
 | 
						|
	sm, err := msl.ManifestService.Get(dgst)
 | 
						|
	if err == nil {
 | 
						|
		if err := msl.parent.listener.ManifestPulled(msl.parent.Repository, sm); err != nil {
 | 
						|
			logrus.Errorf("error dispatching manifest pull to listener: %v", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return sm, err
 | 
						|
}
 | 
						|
 | 
						|
func (msl *manifestServiceListener) Put(sm *manifest.SignedManifest) error {
 | 
						|
	err := msl.ManifestService.Put(sm)
 | 
						|
 | 
						|
	if err == nil {
 | 
						|
		if err := msl.parent.listener.ManifestPushed(msl.parent.Repository, sm); err != nil {
 | 
						|
			logrus.Errorf("error dispatching manifest push to listener: %v", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
func (msl *manifestServiceListener) GetByTag(tag string) (*manifest.SignedManifest, error) {
 | 
						|
	sm, err := msl.ManifestService.GetByTag(tag)
 | 
						|
	if err == nil {
 | 
						|
		if err := msl.parent.listener.ManifestPulled(msl.parent.Repository, sm); err != nil {
 | 
						|
			logrus.Errorf("error dispatching manifest pull to listener: %v", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return sm, err
 | 
						|
}
 | 
						|
 | 
						|
type layerServiceListener struct {
 | 
						|
	distribution.LayerService
 | 
						|
	parent *repositoryListener
 | 
						|
}
 | 
						|
 | 
						|
func (lsl *layerServiceListener) Fetch(dgst digest.Digest) (distribution.Layer, error) {
 | 
						|
	layer, err := lsl.LayerService.Fetch(dgst)
 | 
						|
	if err == nil {
 | 
						|
		if err := lsl.parent.listener.LayerPulled(lsl.parent.Repository, layer); err != nil {
 | 
						|
			logrus.Errorf("error dispatching layer pull to listener: %v", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return layer, err
 | 
						|
}
 | 
						|
 | 
						|
func (lsl *layerServiceListener) Upload() (distribution.LayerUpload, error) {
 | 
						|
	lu, err := lsl.LayerService.Upload()
 | 
						|
	return lsl.decorateUpload(lu), err
 | 
						|
}
 | 
						|
 | 
						|
func (lsl *layerServiceListener) Resume(uuid string) (distribution.LayerUpload, error) {
 | 
						|
	lu, err := lsl.LayerService.Resume(uuid)
 | 
						|
	return lsl.decorateUpload(lu), err
 | 
						|
}
 | 
						|
 | 
						|
func (lsl *layerServiceListener) decorateUpload(lu distribution.LayerUpload) distribution.LayerUpload {
 | 
						|
	return &layerUploadListener{
 | 
						|
		LayerUpload: lu,
 | 
						|
		parent:      lsl,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type layerUploadListener struct {
 | 
						|
	distribution.LayerUpload
 | 
						|
	parent *layerServiceListener
 | 
						|
}
 | 
						|
 | 
						|
func (lul *layerUploadListener) Finish(dgst digest.Digest) (distribution.Layer, error) {
 | 
						|
	layer, err := lul.LayerUpload.Finish(dgst)
 | 
						|
	if err == nil {
 | 
						|
		if err := lul.parent.parent.listener.LayerPushed(lul.parent.parent.Repository, layer); err != nil {
 | 
						|
			logrus.Errorf("error dispatching layer push to listener: %v", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return layer, err
 | 
						|
}
 |