forked from TrueCloudLab/distribution
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 <agoldste@redhat.com>
This commit is contained in:
parent
5b72d32265
commit
6b12e34a4b
4 changed files with 96 additions and 65 deletions
12
registry.go
12
registry.go
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -87,3 +87,9 @@ func (repo *repository) Layers() distribution.LayerService {
|
||||||
repository: repo,
|
repository: repo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *repository) Signatures() distribution.SignatureService {
|
||||||
|
return &signatureStore{
|
||||||
|
repository: repo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
|
|
75
registry/storage/signaturestore.go
Normal file
75
registry/storage/signaturestore.go
Normal 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
|
||||||
|
}
|
Loading…
Reference in a new issue