Merge pull request #780 from stevvooe/manifest-storage

Initial implementation of image manifest storage
This commit is contained in:
Olivier Gambier 2014-11-24 15:27:48 -08:00
commit d825559473
15 changed files with 519 additions and 133 deletions

View file

@ -12,17 +12,18 @@ import (
"github.com/docker/docker-registry"
"github.com/docker/docker-registry/digest"
"github.com/docker/docker-registry/storage"
)
// 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) (*registry.ImageManifest, error)
GetImageManifest(name, tag string) (*storage.SignedManifest, error)
// PutImageManifest uploads an image manifest for the image at the given
// name, tag pair.
PutImageManifest(name, tag string, imageManifest *registry.ImageManifest) error
PutImageManifest(name, tag string, imageManifest *storage.SignedManifest) error
// DeleteImage removes the image at the given name, tag pair.
DeleteImage(name, tag string) error
@ -81,7 +82,7 @@ type clientImpl struct {
// TODO(bbland): use consistent route generation between server and client
func (r *clientImpl) GetImageManifest(name, tag string) (*registry.ImageManifest, error) {
func (r *clientImpl) GetImageManifest(name, tag string) (*storage.SignedManifest, error) {
response, err := http.Get(r.imageManifestURL(name, tag))
if err != nil {
return nil, err
@ -108,7 +109,7 @@ func (r *clientImpl) GetImageManifest(name, tag string) (*registry.ImageManifest
decoder := json.NewDecoder(response.Body)
manifest := new(registry.ImageManifest)
manifest := new(storage.SignedManifest)
err = decoder.Decode(manifest)
if err != nil {
return nil, err
@ -116,7 +117,7 @@ func (r *clientImpl) GetImageManifest(name, tag string) (*registry.ImageManifest
return manifest, nil
}
func (r *clientImpl) PutImageManifest(name, tag string, manifest *registry.ImageManifest) error {
func (r *clientImpl) PutImageManifest(name, tag string, manifest *storage.SignedManifest) error {
manifestBytes, err := json.Marshal(manifest)
if err != nil {
return err

View file

@ -9,9 +9,9 @@ import (
"sync"
"testing"
"github.com/docker/docker-registry"
"github.com/docker/docker-registry/common/testutil"
"github.com/docker/docker-registry/digest"
"github.com/docker/docker-registry/storage"
)
type testBlob struct {
@ -33,8 +33,8 @@ func TestPush(t *testing.T) {
},
}
uploadLocations := make([]string, len(testBlobs))
blobs := make([]registry.FSLayer, len(testBlobs))
history := make([]registry.ManifestHistory, len(testBlobs))
blobs := make([]storage.FSLayer, len(testBlobs))
history := make([]storage.ManifestHistory, len(testBlobs))
for i, blob := range testBlobs {
// TODO(bbland): this is returning the same location for all uploads,
@ -42,17 +42,21 @@ 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/blob/test-uuid", name)
blobs[i] = registry.FSLayer{BlobSum: blob.digest}
history[i] = registry.ManifestHistory{V1Compatibility: blob.digest.String()}
blobs[i] = storage.FSLayer{BlobSum: blob.digest}
history[i] = storage.ManifestHistory{V1Compatibility: blob.digest.String()}
}
manifest := &registry.ImageManifest{
Name: name,
Tag: tag,
Architecture: "x86",
FSLayers: blobs,
History: history,
SchemaVersion: 1,
manifest := &storage.SignedManifest{
Manifest: storage.Manifest{
Name: name,
Tag: tag,
Architecture: "x86",
FSLayers: blobs,
History: history,
Versioned: storage.Versioned{
SchemaVersion: 1,
},
},
}
manifestBytes, err := json.Marshal(manifest)
@ -102,7 +106,7 @@ func TestPush(t *testing.T) {
client := New(server.URL)
objectStore := &memoryObjectStore{
mutex: new(sync.Mutex),
manifestStorage: make(map[string]*registry.ImageManifest),
manifestStorage: make(map[string]*storage.SignedManifest),
layerStorage: make(map[digest.Digest]Layer),
}
@ -143,21 +147,25 @@ func TestPull(t *testing.T) {
contents: []byte("some other contents"),
},
}
blobs := make([]registry.FSLayer, len(testBlobs))
history := make([]registry.ManifestHistory, len(testBlobs))
blobs := make([]storage.FSLayer, len(testBlobs))
history := make([]storage.ManifestHistory, len(testBlobs))
for i, blob := range testBlobs {
blobs[i] = registry.FSLayer{BlobSum: blob.digest}
history[i] = registry.ManifestHistory{V1Compatibility: blob.digest.String()}
blobs[i] = storage.FSLayer{BlobSum: blob.digest}
history[i] = storage.ManifestHistory{V1Compatibility: blob.digest.String()}
}
manifest := &registry.ImageManifest{
Name: name,
Tag: tag,
Architecture: "x86",
FSLayers: blobs,
History: history,
SchemaVersion: 1,
manifest := &storage.SignedManifest{
Manifest: storage.Manifest{
Name: name,
Tag: tag,
Architecture: "x86",
FSLayers: blobs,
History: history,
Versioned: storage.Versioned{
SchemaVersion: 1,
},
},
}
manifestBytes, err := json.Marshal(manifest)
@ -191,7 +199,7 @@ func TestPull(t *testing.T) {
client := New(server.URL)
objectStore := &memoryObjectStore{
mutex: new(sync.Mutex),
manifestStorage: make(map[string]*registry.ImageManifest),
manifestStorage: make(map[string]*storage.SignedManifest),
layerStorage: make(map[digest.Digest]Layer),
}

View file

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

View file

@ -4,7 +4,7 @@ import (
"fmt"
"io"
"github.com/docker/docker-registry"
"github.com/docker/docker-registry/storage"
log "github.com/Sirupsen/logrus"
)
@ -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 registry.FSLayer) error {
func pullLayer(c Client, objectStore ObjectStore, name string, fsLayer storage.FSLayer) error {
log.WithField("layer", fsLayer).Info("Pulling layer")
layer, err := objectStore.Layer(fsLayer.BlobSum)

View file

@ -3,7 +3,7 @@ package client
import (
"errors"
"github.com/docker/docker-registry"
"github.com/docker/docker-registry/storage"
log "github.com/Sirupsen/logrus"
)
@ -13,7 +13,7 @@ import (
// push window has been successfully pushed.
const simultaneousLayerPushWindow = 4
type pushFunction func(fsLayer registry.FSLayer) error
type pushFunction func(fsLayer storage.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
@ -72,7 +72,7 @@ func Push(c Client, objectStore ObjectStore, name, tag string) error {
return nil
}
func pushLayer(c Client, objectStore ObjectStore, name string, fsLayer registry.FSLayer) error {
func pushLayer(c Client, objectStore ObjectStore, name string, fsLayer storage.FSLayer) error {
log.WithField("layer", fsLayer).Info("Pushing layer")
layer, err := objectStore.Layer(fsLayer.BlobSum)