Merge pull request #780 from stevvooe/manifest-storage
Initial implementation of image manifest storage
This commit is contained in:
commit
d825559473
15 changed files with 519 additions and 133 deletions
|
@ -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
|
||||
|
|
|
@ -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 := ®istry.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 := ®istry.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),
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue