From 6b12e34a4b2a90ddcde127495ece523222f7b544 Mon Sep 17 00:00:00 2001 From: Andy Goldstein Date: Wed, 4 Mar 2015 20:32:22 +0000 Subject: [PATCH] Expose Signatures() on Repository Add a SignatureService and expose it via Signatures() on Repository so external integrations wrapping the registry can access signatures. Move signature related code from revisionstore.go to signaturestore.go. Signed-off-by: Andy Goldstein --- registry.go | 12 +++++ registry/storage/registry.go | 6 +++ registry/storage/revisionstore.go | 68 ++------------------------- registry/storage/signaturestore.go | 75 ++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 65 deletions(-) create mode 100644 registry/storage/signaturestore.go diff --git a/registry.go b/registry.go index cd3fb802..ef63a24a 100644 --- a/registry.go +++ b/registry.go @@ -27,6 +27,9 @@ type Repository interface { // Layers returns a reference to this repository's layers service. Layers() LayerService + + // Signatures returns a reference to this repository's signatures service. + Signatures() SignatureService } // ManifestService provides operations on image manifests. @@ -122,3 +125,12 @@ type LayerUpload interface { // Cancel the layer upload process. Cancel() error } + +// SignatureService provides operations on signatures. +type SignatureService interface { + // Get retrieves all of the signature blobs for the specified digest. + Get(dgst digest.Digest) ([][]byte, error) + + // Put stores the signature for the provided digest. + Put(dgst digest.Digest, signatures ...[]byte) error +} diff --git a/registry/storage/registry.go b/registry/storage/registry.go index 1a402f36..8d7ea16e 100644 --- a/registry/storage/registry.go +++ b/registry/storage/registry.go @@ -87,3 +87,9 @@ func (repo *repository) Layers() distribution.LayerService { repository: repo, } } + +func (repo *repository) Signatures() distribution.SignatureService { + return &signatureStore{ + repository: repo, + } +} diff --git a/registry/storage/revisionstore.go b/registry/storage/revisionstore.go index e7122f3e..ac605360 100644 --- a/registry/storage/revisionstore.go +++ b/registry/storage/revisionstore.go @@ -2,7 +2,6 @@ package storage import ( "encoding/json" - "path" "github.com/Sirupsen/logrus" "github.com/docker/distribution" @@ -53,7 +52,7 @@ func (rs *revisionStore) get(revision digest.Digest) (*manifest.SignedManifest, } // Fetch the signatures for the manifest - signatures, err := rs.getSignatures(revision) + signatures, err := rs.Signatures().Get(revision) if err != nil { return nil, err } @@ -104,10 +103,8 @@ func (rs *revisionStore) put(sm *manifest.SignedManifest) (digest.Digest, error) return "", err } - for _, signature := range signatures { - if err := rs.putSignature(revision, signature); err != nil { - return "", err - } + if err := rs.Signatures().Put(revision, signatures...); err != nil { + return "", err } return revision, nil @@ -147,62 +144,3 @@ func (rs *revisionStore) delete(revision digest.Digest) error { return rs.driver.Delete(revisionPath) } - -// getSignatures retrieves all of the signature blobs for the specified -// manifest revision. -func (rs *revisionStore) getSignatures(revision digest.Digest) ([][]byte, error) { - signaturesPath, err := rs.pm.path(manifestSignaturesPathSpec{ - name: rs.Name(), - revision: revision, - }) - - if err != nil { - return nil, err - } - - // Need to append signature digest algorithm to path to get all items. - // Perhaps, this should be in the pathMapper but it feels awkward. This - // can be eliminated by implementing listAll on drivers. - signaturesPath = path.Join(signaturesPath, "sha256") - - signaturePaths, err := rs.driver.List(signaturesPath) - if err != nil { - return nil, err - } - - var signatures [][]byte - for _, sigPath := range signaturePaths { - // Append the link portion - sigPath = path.Join(sigPath, "link") - - // TODO(stevvooe): These fetches should be parallelized for performance. - p, err := rs.blobStore.linked(sigPath) - if err != nil { - return nil, err - } - - signatures = append(signatures, p) - } - - return signatures, nil -} - -// putSignature stores the signature for the provided manifest revision. -func (rs *revisionStore) putSignature(revision digest.Digest, signature []byte) error { - signatureDigest, err := rs.blobStore.put(signature) - if err != nil { - return err - } - - signaturePath, err := rs.pm.path(manifestSignatureLinkPathSpec{ - name: rs.Name(), - revision: revision, - signature: signatureDigest, - }) - - if err != nil { - return err - } - - return rs.blobStore.link(signaturePath, signatureDigest) -} diff --git a/registry/storage/signaturestore.go b/registry/storage/signaturestore.go new file mode 100644 index 00000000..abc52ca6 --- /dev/null +++ b/registry/storage/signaturestore.go @@ -0,0 +1,75 @@ +package storage + +import ( + "path" + + "github.com/docker/distribution" + "github.com/docker/distribution/digest" +) + +type signatureStore struct { + *repository +} + +var _ distribution.SignatureService = &signatureStore{} + +func (s *signatureStore) Get(dgst digest.Digest) ([][]byte, error) { + signaturesPath, err := s.pm.path(manifestSignaturesPathSpec{ + name: s.Name(), + revision: dgst, + }) + + if err != nil { + return nil, err + } + + // Need to append signature digest algorithm to path to get all items. + // Perhaps, this should be in the pathMapper but it feels awkward. This + // can be eliminated by implementing listAll on drivers. + signaturesPath = path.Join(signaturesPath, "sha256") + + signaturePaths, err := s.driver.List(signaturesPath) + if err != nil { + return nil, err + } + + var signatures [][]byte + for _, sigPath := range signaturePaths { + // Append the link portion + sigPath = path.Join(sigPath, "link") + + // TODO(stevvooe): These fetches should be parallelized for performance. + p, err := s.blobStore.linked(sigPath) + if err != nil { + return nil, err + } + + signatures = append(signatures, p) + } + + return signatures, nil +} + +func (s *signatureStore) Put(dgst digest.Digest, signatures ...[]byte) error { + for _, signature := range signatures { + signatureDigest, err := s.blobStore.put(signature) + if err != nil { + return err + } + + signaturePath, err := s.pm.path(manifestSignatureLinkPathSpec{ + name: s.Name(), + revision: dgst, + signature: signatureDigest, + }) + + if err != nil { + return err + } + + if err := s.blobStore.link(signaturePath, signatureDigest); err != nil { + return err + } + } + return nil +}