Merge pull request #234 from ncdc/signature-service

Expose Signatures() on Repository
This commit is contained in:
Stephen Day 2015-03-04 18:24:36 -08:00
commit 91403c1b52
4 changed files with 96 additions and 65 deletions

View file

@ -27,6 +27,9 @@ type Repository interface {
// Layers returns a reference to this repository's layers service. // Layers returns a reference to this repository's layers service.
Layers() LayerService Layers() LayerService
// Signatures returns a reference to this repository's signatures service.
Signatures() SignatureService
} }
// ManifestService provides operations on image manifests. // ManifestService provides operations on image manifests.
@ -122,3 +125,12 @@ type LayerUpload interface {
// Cancel the layer upload process. // Cancel the layer upload process.
Cancel() error 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
}

View file

@ -87,3 +87,9 @@ func (repo *repository) Layers() distribution.LayerService {
repository: repo, repository: repo,
} }
} }
func (repo *repository) Signatures() distribution.SignatureService {
return &signatureStore{
repository: repo,
}
}

View file

@ -2,7 +2,6 @@ package storage
import ( import (
"encoding/json" "encoding/json"
"path"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/docker/distribution" "github.com/docker/distribution"
@ -53,7 +52,7 @@ func (rs *revisionStore) get(revision digest.Digest) (*manifest.SignedManifest,
} }
// Fetch the signatures for the manifest // Fetch the signatures for the manifest
signatures, err := rs.getSignatures(revision) signatures, err := rs.Signatures().Get(revision)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -104,11 +103,9 @@ func (rs *revisionStore) put(sm *manifest.SignedManifest) (digest.Digest, error)
return "", err return "", err
} }
for _, signature := range signatures { if err := rs.Signatures().Put(revision, signatures...); err != nil {
if err := rs.putSignature(revision, signature); err != nil {
return "", err return "", err
} }
}
return revision, nil return revision, nil
} }
@ -147,62 +144,3 @@ func (rs *revisionStore) delete(revision digest.Digest) error {
return rs.driver.Delete(revisionPath) 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)
}

View file

@ -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
}