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  }