Move manifest to discrete package

Because manifests and their signatures are a discrete component of the
registry, we are moving the definitions into a separate package. This causes us
to lose some test coverage, but we can fill this in shortly. No changes have
been made to the external interfaces, but they are likely to come.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day 2015-01-02 13:21:29 -08:00
parent cd748f92ab
commit a4024b2f90
14 changed files with 80 additions and 74 deletions

View file

@ -17,7 +17,7 @@ import (
"github.com/docker/distribution/common/testutil"
"github.com/docker/distribution/configuration"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/storage"
"github.com/docker/distribution/manifest"
_ "github.com/docker/distribution/storagedriver/inmemory"
"github.com/docker/libtrust"
"github.com/gorilla/handlers"
@ -268,10 +268,10 @@ func TestManifestAPI(t *testing.T) {
// --------------------------------
// Attempt to push unsigned manifest with missing layers
unsignedManifest := &storage.Manifest{
unsignedManifest := &manifest.Manifest{
Name: imageName,
Tag: tag,
FSLayers: []storage.FSLayer{
FSLayers: []manifest.FSLayer{
{
BlobSum: "asdf",
},
@ -362,7 +362,7 @@ func TestManifestAPI(t *testing.T) {
checkResponse(t, "fetching uploaded manifest", resp, http.StatusOK)
var fetchedManifest storage.SignedManifest
var fetchedManifest manifest.SignedManifest
dec = json.NewDecoder(resp.Body)
if err := dec.Decode(&fetchedManifest); err != nil {
t.Fatalf("error decoding fetched manifest: %v", err)
@ -404,7 +404,7 @@ func TestManifestAPI(t *testing.T) {
func putManifest(t *testing.T, msg, url string, v interface{}) *http.Response {
var body []byte
if sm, ok := v.(*storage.SignedManifest); ok {
if sm, ok := v.(*manifest.SignedManifest); ok {
body = sm.Raw
} else {
var err error

View file

@ -12,18 +12,18 @@ import (
"github.com/docker/distribution/api/v2"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/storage"
"github.com/docker/distribution/manifest"
)
// Client implements the client interface to the registry http api
type Client interface {
// GetImageManifest returns an image manifest for the image at the given
// name, tag pair.
GetImageManifest(name, tag string) (*storage.SignedManifest, error)
GetImageManifest(name, tag string) (*manifest.SignedManifest, error)
// PutImageManifest uploads an image manifest for the image at the given
// name, tag pair.
PutImageManifest(name, tag string, imageManifest *storage.SignedManifest) error
PutImageManifest(name, tag string, imageManifest *manifest.SignedManifest) error
// DeleteImage removes the image at the given name, tag pair.
DeleteImage(name, tag string) error
@ -91,7 +91,7 @@ type clientImpl struct {
// TODO(bbland): use consistent route generation between server and client
func (r *clientImpl) GetImageManifest(name, tag string) (*storage.SignedManifest, error) {
func (r *clientImpl) GetImageManifest(name, tag string) (*manifest.SignedManifest, error) {
manifestURL, err := r.ub.BuildManifestURL(name, tag)
if err != nil {
return nil, err
@ -124,7 +124,7 @@ func (r *clientImpl) GetImageManifest(name, tag string) (*storage.SignedManifest
decoder := json.NewDecoder(response.Body)
manifest := new(storage.SignedManifest)
manifest := new(manifest.SignedManifest)
err = decoder.Decode(manifest)
if err != nil {
return nil, err
@ -132,7 +132,7 @@ func (r *clientImpl) GetImageManifest(name, tag string) (*storage.SignedManifest
return manifest, nil
}
func (r *clientImpl) PutImageManifest(name, tag string, manifest *storage.SignedManifest) error {
func (r *clientImpl) PutImageManifest(name, tag string, manifest *manifest.SignedManifest) error {
manifestURL, err := r.ub.BuildManifestURL(name, tag)
if err != nil {
return err

View file

@ -11,7 +11,7 @@ import (
"github.com/docker/distribution/common/testutil"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/storage"
"github.com/docker/distribution/manifest"
)
type testBlob struct {
@ -33,8 +33,8 @@ func TestPush(t *testing.T) {
},
}
uploadLocations := make([]string, len(testBlobs))
blobs := make([]storage.FSLayer, len(testBlobs))
history := make([]storage.ManifestHistory, len(testBlobs))
blobs := make([]manifest.FSLayer, len(testBlobs))
history := make([]manifest.ManifestHistory, len(testBlobs))
for i, blob := range testBlobs {
// TODO(bbland): this is returning the same location for all uploads,
@ -42,24 +42,24 @@ func TestPush(t *testing.T) {
// It's sort of okay because we're using unique digests, but this needs
// to change at some point.
uploadLocations[i] = fmt.Sprintf("/v2/%s/blobs/test-uuid", name)
blobs[i] = storage.FSLayer{BlobSum: blob.digest}
history[i] = storage.ManifestHistory{V1Compatibility: blob.digest.String()}
blobs[i] = manifest.FSLayer{BlobSum: blob.digest}
history[i] = manifest.ManifestHistory{V1Compatibility: blob.digest.String()}
}
manifest := &storage.SignedManifest{
Manifest: storage.Manifest{
m := &manifest.SignedManifest{
Manifest: manifest.Manifest{
Name: name,
Tag: tag,
Architecture: "x86",
FSLayers: blobs,
History: history,
Versioned: storage.Versioned{
Versioned: manifest.Versioned{
SchemaVersion: 1,
},
},
}
var err error
manifest.Raw, err = json.Marshal(manifest)
m.Raw, err = json.Marshal(m)
blobRequestResponseMappings := make([]testutil.RequestResponseMapping, 2*len(testBlobs))
for i, blob := range testBlobs {
@ -94,7 +94,7 @@ func TestPush(t *testing.T) {
Request: testutil.Request{
Method: "PUT",
Route: "/v2/" + name + "/manifests/" + tag,
Body: manifest.Raw,
Body: m.Raw,
},
Response: testutil.Response{
StatusCode: http.StatusOK,
@ -119,7 +119,7 @@ func TestPush(t *testing.T) {
}
objectStore := &memoryObjectStore{
mutex: new(sync.Mutex),
manifestStorage: make(map[string]*storage.SignedManifest),
manifestStorage: make(map[string]*manifest.SignedManifest),
layerStorage: make(map[digest.Digest]Layer),
}
@ -139,7 +139,7 @@ func TestPush(t *testing.T) {
writer.Close()
}
objectStore.WriteManifest(name, tag, manifest)
objectStore.WriteManifest(name, tag, m)
err = Push(client, objectStore, name, tag)
if err != nil {
@ -160,27 +160,27 @@ func TestPull(t *testing.T) {
contents: []byte("some other contents"),
},
}
blobs := make([]storage.FSLayer, len(testBlobs))
history := make([]storage.ManifestHistory, len(testBlobs))
blobs := make([]manifest.FSLayer, len(testBlobs))
history := make([]manifest.ManifestHistory, len(testBlobs))
for i, blob := range testBlobs {
blobs[i] = storage.FSLayer{BlobSum: blob.digest}
history[i] = storage.ManifestHistory{V1Compatibility: blob.digest.String()}
blobs[i] = manifest.FSLayer{BlobSum: blob.digest}
history[i] = manifest.ManifestHistory{V1Compatibility: blob.digest.String()}
}
manifest := &storage.SignedManifest{
Manifest: storage.Manifest{
m := &manifest.SignedManifest{
Manifest: manifest.Manifest{
Name: name,
Tag: tag,
Architecture: "x86",
FSLayers: blobs,
History: history,
Versioned: storage.Versioned{
Versioned: manifest.Versioned{
SchemaVersion: 1,
},
},
}
manifestBytes, err := json.Marshal(manifest)
manifestBytes, err := json.Marshal(m)
blobRequestResponseMappings := make([]testutil.RequestResponseMapping, len(testBlobs))
for i, blob := range testBlobs {
@ -213,7 +213,7 @@ func TestPull(t *testing.T) {
}
objectStore := &memoryObjectStore{
mutex: new(sync.Mutex),
manifestStorage: make(map[string]*storage.SignedManifest),
manifestStorage: make(map[string]*manifest.SignedManifest),
layerStorage: make(map[digest.Digest]Layer),
}
@ -222,7 +222,7 @@ func TestPull(t *testing.T) {
t.Fatal(err)
}
m, err := objectStore.Manifest(name, tag)
m, err = objectStore.Manifest(name, tag)
if err != nil {
t.Fatal(err)
}
@ -272,25 +272,25 @@ func TestPullResume(t *testing.T) {
contents: []byte("some other contents"),
},
}
layers := make([]storage.FSLayer, len(testBlobs))
history := make([]storage.ManifestHistory, len(testBlobs))
layers := make([]manifest.FSLayer, len(testBlobs))
history := make([]manifest.ManifestHistory, len(testBlobs))
for i, layer := range testBlobs {
layers[i] = storage.FSLayer{BlobSum: layer.digest}
history[i] = storage.ManifestHistory{V1Compatibility: layer.digest.String()}
layers[i] = manifest.FSLayer{BlobSum: layer.digest}
history[i] = manifest.ManifestHistory{V1Compatibility: layer.digest.String()}
}
manifest := &storage.Manifest{
m := &manifest.Manifest{
Name: name,
Tag: tag,
Architecture: "x86",
FSLayers: layers,
History: history,
Versioned: storage.Versioned{
Versioned: manifest.Versioned{
SchemaVersion: 1,
},
}
manifestBytes, err := json.Marshal(manifest)
manifestBytes, err := json.Marshal(m)
layerRequestResponseMappings := make([]testutil.RequestResponseMapping, 2*len(testBlobs))
for i, blob := range testBlobs {
@ -340,7 +340,7 @@ func TestPullResume(t *testing.T) {
}
objectStore := &memoryObjectStore{
mutex: new(sync.Mutex),
manifestStorage: make(map[string]*storage.SignedManifest),
manifestStorage: make(map[string]*manifest.SignedManifest),
layerStorage: make(map[digest.Digest]Layer),
}
@ -355,12 +355,12 @@ func TestPullResume(t *testing.T) {
t.Fatal(err)
}
m, err := objectStore.Manifest(name, tag)
sm, err := objectStore.Manifest(name, tag)
if err != nil {
t.Fatal(err)
}
mBytes, err := json.Marshal(m)
mBytes, err := json.Marshal(sm)
if err != nil {
t.Fatal(err)
}

View file

@ -7,7 +7,7 @@ import (
"sync"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/storage"
"github.com/docker/distribution/manifest"
)
var (
@ -26,11 +26,11 @@ var (
type ObjectStore interface {
// Manifest retrieves the image manifest stored at the given repository name
// and tag
Manifest(name, tag string) (*storage.SignedManifest, error)
Manifest(name, tag string) (*manifest.SignedManifest, error)
// WriteManifest stores an image manifest at the given repository name and
// tag
WriteManifest(name, tag string, manifest *storage.SignedManifest) error
WriteManifest(name, tag string, manifest *manifest.SignedManifest) error
// Layer returns a handle to a layer for reading and writing
Layer(dgst digest.Digest) (Layer, error)
@ -83,11 +83,11 @@ type LayerWriter interface {
// memoryObjectStore is an in-memory implementation of the ObjectStore interface
type memoryObjectStore struct {
mutex *sync.Mutex
manifestStorage map[string]*storage.SignedManifest
manifestStorage map[string]*manifest.SignedManifest
layerStorage map[digest.Digest]Layer
}
func (objStore *memoryObjectStore) Manifest(name, tag string) (*storage.SignedManifest, error) {
func (objStore *memoryObjectStore) Manifest(name, tag string) (*manifest.SignedManifest, error) {
objStore.mutex.Lock()
defer objStore.mutex.Unlock()
@ -98,7 +98,7 @@ func (objStore *memoryObjectStore) Manifest(name, tag string) (*storage.SignedMa
return manifest, nil
}
func (objStore *memoryObjectStore) WriteManifest(name, tag string, manifest *storage.SignedManifest) error {
func (objStore *memoryObjectStore) WriteManifest(name, tag string, manifest *manifest.SignedManifest) error {
objStore.mutex.Lock()
defer objStore.mutex.Unlock()

View file

@ -4,9 +4,9 @@ import (
"fmt"
"io"
"github.com/docker/distribution/storage"
log "github.com/Sirupsen/logrus"
"github.com/docker/distribution/manifest"
)
// simultaneousLayerPullWindow is the size of the parallel layer pull window.
@ -77,7 +77,7 @@ func Pull(c Client, objectStore ObjectStore, name, tag string) error {
return nil
}
func pullLayer(c Client, objectStore ObjectStore, name string, fsLayer storage.FSLayer) error {
func pullLayer(c Client, objectStore ObjectStore, name string, fsLayer manifest.FSLayer) error {
log.WithField("layer", fsLayer).Info("Pulling layer")
layer, err := objectStore.Layer(fsLayer.BlobSum)

View file

@ -4,7 +4,7 @@ import (
"fmt"
log "github.com/Sirupsen/logrus"
"github.com/docker/distribution/storage"
"github.com/docker/distribution/manifest"
)
// simultaneousLayerPushWindow is the size of the parallel layer push window.
@ -12,7 +12,7 @@ import (
// push window has been successfully pushed.
const simultaneousLayerPushWindow = 4
type pushFunction func(fsLayer storage.FSLayer) error
type pushFunction func(fsLayer manifest.FSLayer) error
// Push implements a client push workflow for the image defined by the given
// name and tag pair, using the given ObjectStore for local manifest and layer
@ -71,7 +71,7 @@ func Push(c Client, objectStore ObjectStore, name, tag string) error {
return nil
}
func pushLayer(c Client, objectStore ObjectStore, name string, fsLayer storage.FSLayer) error {
func pushLayer(c Client, objectStore ObjectStore, name string, fsLayer manifest.FSLayer) error {
log.WithField("layer", fsLayer).Info("Pushing layer")
layer, err := objectStore.Layer(fsLayer.BlobSum)

View file

@ -7,6 +7,7 @@ import (
"github.com/docker/distribution/api/v2"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/manifest"
"github.com/docker/distribution/storage"
"github.com/gorilla/handlers"
)
@ -56,7 +57,7 @@ func (imh *imageManifestHandler) PutImageManifest(w http.ResponseWriter, r *http
manifests := imh.services.Manifests()
dec := json.NewDecoder(r.Body)
var manifest storage.SignedManifest
var manifest manifest.SignedManifest
if err := dec.Decode(&manifest); err != nil {
imh.Errors.Push(v2.ErrorCodeManifestInvalid, err)
w.WriteHeader(http.StatusBadRequest)

View file

@ -1,4 +1,4 @@
package storage
package manifest
import (
"crypto/x509"
@ -149,7 +149,7 @@ func (sm *SignedManifest) UnmarshalJSON(b []byte) error {
// MarshalJSON returns the contents of raw. If Raw is nil, marshals the inner
// contents. Applications requiring a marshaled signed manifest should simply
// use Raw directly, since the the content produced by json.Marshal will
// use Raw directly, since the the content produced by json.Marshal will be
// compacted and will fail signature checks.
func (sm *SignedManifest) MarshalJSON() ([]byte, error) {
if len(sm.Raw) > 0 {

View file

@ -6,6 +6,7 @@ import (
"time"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/manifest"
)
// Layer provides a readable and seekable layer object. Typically,
@ -74,7 +75,7 @@ var (
// ErrUnknownLayer returned when layer cannot be found.
type ErrUnknownLayer struct {
FSLayer FSLayer
FSLayer manifest.FSLayer
}
func (err ErrUnknownLayer) Error() string {
@ -83,7 +84,7 @@ func (err ErrUnknownLayer) Error() string {
// ErrLayerInvalidDigest returned when tarsum check fails.
type ErrLayerInvalidDigest struct {
FSLayer FSLayer
FSLayer manifest.FSLayer
}
func (err ErrLayerInvalidDigest) Error() string {

View file

@ -2,6 +2,7 @@ package storage
import (
"github.com/docker/distribution/digest"
"github.com/docker/distribution/manifest"
"github.com/docker/distribution/storagedriver"
)
@ -33,7 +34,7 @@ func (ls *layerStore) Fetch(name string, digest digest.Digest) (Layer, error) {
if err != nil {
switch err := err.(type) {
case storagedriver.PathNotFoundError, *storagedriver.PathNotFoundError:
return nil, ErrUnknownLayer{FSLayer{BlobSum: digest}}
return nil, ErrUnknownLayer{manifest.FSLayer{BlobSum: digest}}
default:
return nil, err
}
@ -43,7 +44,7 @@ func (ls *layerStore) Fetch(name string, digest digest.Digest) (Layer, error) {
if err != nil {
switch err := err.(type) {
case storagedriver.PathNotFoundError, *storagedriver.PathNotFoundError:
return nil, ErrUnknownLayer{FSLayer{BlobSum: digest}}
return nil, ErrUnknownLayer{manifest.FSLayer{BlobSum: digest}}
default:
return nil, err
}

View file

@ -10,6 +10,7 @@ import (
"code.google.com/p/go-uuid/uuid"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/manifest"
"github.com/docker/distribution/storagedriver"
"github.com/docker/docker/pkg/tarsum"
@ -284,7 +285,7 @@ func (luc *layerUploadController) validateLayer(fp layerFile, size int64, dgst d
}
if !digestVerifier.Verified() {
return "", ErrLayerInvalidDigest{FSLayer{BlobSum: dgst}}
return "", ErrLayerInvalidDigest{manifest.FSLayer{BlobSum: dgst}}
}
return dgst, nil

View file

@ -6,6 +6,7 @@ import (
"path"
"strings"
"github.com/docker/distribution/manifest"
"github.com/docker/distribution/storagedriver"
"github.com/docker/libtrust"
)
@ -116,7 +117,7 @@ func (ms *manifestStore) Exists(name, tag string) (bool, error) {
return true, nil
}
func (ms *manifestStore) Get(name, tag string) (*SignedManifest, error) {
func (ms *manifestStore) Get(name, tag string) (*manifest.SignedManifest, error) {
p, err := ms.path(name, tag)
if err != nil {
return nil, err
@ -132,7 +133,7 @@ func (ms *manifestStore) Get(name, tag string) (*SignedManifest, error) {
}
}
var manifest SignedManifest
var manifest manifest.SignedManifest
if err := json.Unmarshal(content, &manifest); err != nil {
// TODO(stevvooe): Corrupted manifest error?
@ -144,7 +145,7 @@ func (ms *manifestStore) Get(name, tag string) (*SignedManifest, error) {
return &manifest, nil
}
func (ms *manifestStore) Put(name, tag string, manifest *SignedManifest) error {
func (ms *manifestStore) Put(name, tag string, manifest *manifest.SignedManifest) error {
p, err := ms.path(name, tag)
if err != nil {
return err
@ -185,7 +186,7 @@ func (ms *manifestStore) path(name, tag string) (string, error) {
})
}
func (ms *manifestStore) verifyManifest(name, tag string, manifest *SignedManifest) error {
func (ms *manifestStore) verifyManifest(name, tag string, manifest *manifest.SignedManifest) error {
// TODO(stevvooe): This verification is present here, but this needs to be
// lifted out of the storage infrastructure and moved into a package
// oriented towards defining verifiers and reporting them with

View file

@ -4,10 +4,10 @@ import (
"reflect"
"testing"
"github.com/docker/libtrust"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/manifest"
"github.com/docker/distribution/storagedriver/inmemory"
"github.com/docker/libtrust"
)
func TestManifestStorage(t *testing.T) {
@ -42,13 +42,13 @@ func TestManifestStorage(t *testing.T) {
}
}
manifest := Manifest{
Versioned: Versioned{
manifest := manifest.Manifest{
Versioned: manifest.Versioned{
SchemaVersion: 1,
},
Name: name,
Tag: tag,
FSLayers: []FSLayer{
FSLayers: []manifest.FSLayer{
{
BlobSum: "asdf",
},

View file

@ -2,6 +2,7 @@ package storage
import (
"github.com/docker/distribution/digest"
"github.com/docker/distribution/manifest"
"github.com/docker/distribution/storagedriver"
)
@ -59,10 +60,10 @@ type ManifestService interface {
Exists(name, tag string) (bool, error)
// Get retrieves the named manifest, if it exists.
Get(name, tag string) (*SignedManifest, error)
Get(name, tag string) (*manifest.SignedManifest, error)
// Put creates or updates the named manifest.
Put(name, tag string, manifest *SignedManifest) error
Put(name, tag string, manifest *manifest.SignedManifest) error
// Delete removes the named manifest, if it exists.
Delete(name, tag string) error