forked from TrueCloudLab/distribution
Remove pathMapper object
The use of the pathMapper is no longer needed the way we have organized the code base. The extra level of indirection has proved unnecessary and confusing so we've opted to clean it up. In the future, we may require more flexibility, but now it is simply not required. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
9174fc62d2
commit
614e8c8277
15 changed files with 93 additions and 91 deletions
|
@ -13,7 +13,6 @@ import (
|
||||||
// creating and traversing backend links.
|
// creating and traversing backend links.
|
||||||
type blobStore struct {
|
type blobStore struct {
|
||||||
driver driver.StorageDriver
|
driver driver.StorageDriver
|
||||||
pm *pathMapper
|
|
||||||
statter distribution.BlobStatter
|
statter distribution.BlobStatter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +93,7 @@ func (bs *blobStore) Put(ctx context.Context, mediaType string, p []byte) (distr
|
||||||
// path returns the canonical path for the blob identified by digest. The blob
|
// path returns the canonical path for the blob identified by digest. The blob
|
||||||
// may or may not exist.
|
// may or may not exist.
|
||||||
func (bs *blobStore) path(dgst digest.Digest) (string, error) {
|
func (bs *blobStore) path(dgst digest.Digest) (string, error) {
|
||||||
bp, err := bs.pm.path(blobDataPathSpec{
|
bp, err := pathFor(blobDataPathSpec{
|
||||||
digest: dgst,
|
digest: dgst,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -140,7 +139,6 @@ func (bs *blobStore) resolve(ctx context.Context, path string) (string, error) {
|
||||||
|
|
||||||
type blobStatter struct {
|
type blobStatter struct {
|
||||||
driver driver.StorageDriver
|
driver driver.StorageDriver
|
||||||
pm *pathMapper
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ distribution.BlobDescriptorService = &blobStatter{}
|
var _ distribution.BlobDescriptorService = &blobStatter{}
|
||||||
|
@ -149,9 +147,10 @@ var _ distribution.BlobDescriptorService = &blobStatter{}
|
||||||
// in the main blob store. If this method returns successfully, there is
|
// in the main blob store. If this method returns successfully, there is
|
||||||
// strong guarantee that the blob exists and is available.
|
// strong guarantee that the blob exists and is available.
|
||||||
func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
|
func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
|
||||||
path, err := bs.pm.path(blobDataPathSpec{
|
path, err := pathFor(blobDataPathSpec{
|
||||||
digest: dgst,
|
digest: dgst,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return distribution.Descriptor{}, err
|
return distribution.Descriptor{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,7 +266,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri
|
||||||
// identified by dgst. The layer should be validated before commencing the
|
// identified by dgst. The layer should be validated before commencing the
|
||||||
// move.
|
// move.
|
||||||
func (bw *blobWriter) moveBlob(ctx context.Context, desc distribution.Descriptor) error {
|
func (bw *blobWriter) moveBlob(ctx context.Context, desc distribution.Descriptor) error {
|
||||||
blobPath, err := bw.blobStore.pm.path(blobDataPathSpec{
|
blobPath, err := pathFor(blobDataPathSpec{
|
||||||
digest: desc.Digest,
|
digest: desc.Digest,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ func (bw *blobWriter) moveBlob(ctx context.Context, desc distribution.Descriptor
|
||||||
// instance. An error will be returned if the clean up cannot proceed. If the
|
// instance. An error will be returned if the clean up cannot proceed. If the
|
||||||
// resources are already not present, no error will be returned.
|
// resources are already not present, no error will be returned.
|
||||||
func (bw *blobWriter) removeResources(ctx context.Context) error {
|
func (bw *blobWriter) removeResources(ctx context.Context) error {
|
||||||
dataPath, err := bw.blobStore.pm.path(uploadDataPathSpec{
|
dataPath, err := pathFor(uploadDataPathSpec{
|
||||||
name: bw.blobStore.repository.Name(),
|
name: bw.blobStore.repository.Name(),
|
||||||
id: bw.id,
|
id: bw.id,
|
||||||
})
|
})
|
||||||
|
|
|
@ -111,12 +111,13 @@ type hashStateEntry struct {
|
||||||
|
|
||||||
// getStoredHashStates returns a slice of hashStateEntries for this upload.
|
// getStoredHashStates returns a slice of hashStateEntries for this upload.
|
||||||
func (bw *blobWriter) getStoredHashStates(ctx context.Context) ([]hashStateEntry, error) {
|
func (bw *blobWriter) getStoredHashStates(ctx context.Context) ([]hashStateEntry, error) {
|
||||||
uploadHashStatePathPrefix, err := bw.blobStore.pm.path(uploadHashStatePathSpec{
|
uploadHashStatePathPrefix, err := pathFor(uploadHashStatePathSpec{
|
||||||
name: bw.blobStore.repository.Name(),
|
name: bw.blobStore.repository.Name(),
|
||||||
id: bw.id,
|
id: bw.id,
|
||||||
alg: bw.digester.Digest().Algorithm(),
|
alg: bw.digester.Digest().Algorithm(),
|
||||||
list: true,
|
list: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -156,12 +157,13 @@ func (bw *blobWriter) storeHashState(ctx context.Context) error {
|
||||||
return errResumableDigestNotAvailable
|
return errResumableDigestNotAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadHashStatePath, err := bw.blobStore.pm.path(uploadHashStatePathSpec{
|
uploadHashStatePath, err := pathFor(uploadHashStatePathSpec{
|
||||||
name: bw.blobStore.repository.Name(),
|
name: bw.blobStore.repository.Name(),
|
||||||
id: bw.id,
|
id: bw.id,
|
||||||
alg: bw.digester.Digest().Algorithm(),
|
alg: bw.digester.Digest().Algorithm(),
|
||||||
offset: int64(h.Len()),
|
offset: int64(h.Len()),
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func (reg *registry) Repositories(ctx context.Context, repos []string, last stri
|
||||||
return 0, errors.New("no space in slice")
|
return 0, errors.New("no space in slice")
|
||||||
}
|
}
|
||||||
|
|
||||||
root, err := defaultPathMapper.path(repositoriesRootPathSpec{})
|
root, err := pathFor(repositoriesRootPathSpec{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ func setupFS(t *testing.T) *setupEnv {
|
||||||
c := []byte("")
|
c := []byte("")
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
registry := NewRegistryWithDriver(ctx, d, memory.NewInMemoryBlobDescriptorCacheProvider(), false, true, false)
|
registry := NewRegistryWithDriver(ctx, d, memory.NewInMemoryBlobDescriptorCacheProvider(), false, true, false)
|
||||||
rootpath, _ := defaultPathMapper.path(repositoriesRootPathSpec{})
|
rootpath, _ := pathFor(repositoriesRootPathSpec{})
|
||||||
|
|
||||||
repos := []string{
|
repos := []string{
|
||||||
"/foo/a/_layers/1",
|
"/foo/a/_layers/1",
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
// linkPathFunc describes a function that can resolve a link based on the
|
// linkPathFunc describes a function that can resolve a link based on the
|
||||||
// repository name and digest.
|
// repository name and digest.
|
||||||
type linkPathFunc func(pm *pathMapper, name string, dgst digest.Digest) (string, error)
|
type linkPathFunc func(name string, dgst digest.Digest) (string, error)
|
||||||
|
|
||||||
// linkedBlobStore provides a full BlobService that namespaces the blobs to a
|
// linkedBlobStore provides a full BlobService that namespaces the blobs to a
|
||||||
// given repository. Effectively, it manages the links in a given repository
|
// given repository. Effectively, it manages the links in a given repository
|
||||||
|
@ -104,7 +104,7 @@ func (lbs *linkedBlobStore) Create(ctx context.Context) (distribution.BlobWriter
|
||||||
uuid := uuid.Generate().String()
|
uuid := uuid.Generate().String()
|
||||||
startedAt := time.Now().UTC()
|
startedAt := time.Now().UTC()
|
||||||
|
|
||||||
path, err := lbs.blobStore.pm.path(uploadDataPathSpec{
|
path, err := pathFor(uploadDataPathSpec{
|
||||||
name: lbs.repository.Name(),
|
name: lbs.repository.Name(),
|
||||||
id: uuid,
|
id: uuid,
|
||||||
})
|
})
|
||||||
|
@ -113,7 +113,7 @@ func (lbs *linkedBlobStore) Create(ctx context.Context) (distribution.BlobWriter
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
startedAtPath, err := lbs.blobStore.pm.path(uploadStartedAtPathSpec{
|
startedAtPath, err := pathFor(uploadStartedAtPathSpec{
|
||||||
name: lbs.repository.Name(),
|
name: lbs.repository.Name(),
|
||||||
id: uuid,
|
id: uuid,
|
||||||
})
|
})
|
||||||
|
@ -133,7 +133,7 @@ func (lbs *linkedBlobStore) Create(ctx context.Context) (distribution.BlobWriter
|
||||||
func (lbs *linkedBlobStore) Resume(ctx context.Context, id string) (distribution.BlobWriter, error) {
|
func (lbs *linkedBlobStore) Resume(ctx context.Context, id string) (distribution.BlobWriter, error) {
|
||||||
context.GetLogger(ctx).Debug("(*linkedBlobStore).Resume")
|
context.GetLogger(ctx).Debug("(*linkedBlobStore).Resume")
|
||||||
|
|
||||||
startedAtPath, err := lbs.blobStore.pm.path(uploadStartedAtPathSpec{
|
startedAtPath, err := pathFor(uploadStartedAtPathSpec{
|
||||||
name: lbs.repository.Name(),
|
name: lbs.repository.Name(),
|
||||||
id: id,
|
id: id,
|
||||||
})
|
})
|
||||||
|
@ -157,7 +157,7 @@ func (lbs *linkedBlobStore) Resume(ctx context.Context, id string) (distribution
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
path, err := lbs.pm.path(uploadDataPathSpec{
|
path, err := pathFor(uploadDataPathSpec{
|
||||||
name: lbs.repository.Name(),
|
name: lbs.repository.Name(),
|
||||||
id: id,
|
id: id,
|
||||||
})
|
})
|
||||||
|
@ -228,7 +228,7 @@ func (lbs *linkedBlobStore) linkBlob(ctx context.Context, canonical distribution
|
||||||
}
|
}
|
||||||
seenDigests[dgst] = struct{}{}
|
seenDigests[dgst] = struct{}{}
|
||||||
|
|
||||||
blobLinkPath, err := linkPathFn(lbs.pm, lbs.repository.Name(), dgst)
|
blobLinkPath, err := linkPathFn(lbs.repository.Name(), dgst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ func (lbs *linkedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (dis
|
||||||
func (lbs *linkedBlobStatter) Clear(ctx context.Context, dgst digest.Digest) (err error) {
|
func (lbs *linkedBlobStatter) Clear(ctx context.Context, dgst digest.Digest) (err error) {
|
||||||
// clear any possible existence of a link described in linkPathFns
|
// clear any possible existence of a link described in linkPathFns
|
||||||
for _, linkPathFn := range lbs.linkPathFns {
|
for _, linkPathFn := range lbs.linkPathFns {
|
||||||
blobLinkPath, err := linkPathFn(lbs.pm, lbs.repository.Name(), dgst)
|
blobLinkPath, err := linkPathFn(lbs.repository.Name(), dgst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ func (lbs *linkedBlobStatter) Clear(ctx context.Context, dgst digest.Digest) (er
|
||||||
// linkPathFuncs to let us try a few different paths before returning not
|
// linkPathFuncs to let us try a few different paths before returning not
|
||||||
// found.
|
// found.
|
||||||
func (lbs *linkedBlobStatter) resolveWithLinkFunc(ctx context.Context, dgst digest.Digest, linkPathFn linkPathFunc) (digest.Digest, error) {
|
func (lbs *linkedBlobStatter) resolveWithLinkFunc(ctx context.Context, dgst digest.Digest, linkPathFn linkPathFunc) (digest.Digest, error) {
|
||||||
blobLinkPath, err := linkPathFn(lbs.pm, lbs.repository.Name(), dgst)
|
blobLinkPath, err := linkPathFn(lbs.repository.Name(), dgst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -335,11 +335,11 @@ func (lbs *linkedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Dig
|
||||||
}
|
}
|
||||||
|
|
||||||
// blobLinkPath provides the path to the blob link, also known as layers.
|
// blobLinkPath provides the path to the blob link, also known as layers.
|
||||||
func blobLinkPath(pm *pathMapper, name string, dgst digest.Digest) (string, error) {
|
func blobLinkPath(name string, dgst digest.Digest) (string, error) {
|
||||||
return pm.path(layerLinkPathSpec{name: name, digest: dgst})
|
return pathFor(layerLinkPathSpec{name: name, digest: dgst})
|
||||||
}
|
}
|
||||||
|
|
||||||
// manifestRevisionLinkPath provides the path to the manifest revision link.
|
// manifestRevisionLinkPath provides the path to the manifest revision link.
|
||||||
func manifestRevisionLinkPath(pm *pathMapper, name string, dgst digest.Digest) (string, error) {
|
func manifestRevisionLinkPath(name string, dgst digest.Digest) (string, error) {
|
||||||
return pm.path(manifestRevisionLinkPathSpec{name: name, revision: dgst})
|
return pathFor(manifestRevisionLinkPathSpec{name: name, revision: dgst})
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ func TestLinkPathFuncs(t *testing.T) {
|
||||||
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/revisions/sha256/deadbeaf/link",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/revisions/sha256/deadbeaf/link",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p, err := testcase.linkPathFn(defaultPathMapper, testcase.repo, testcase.digest)
|
p, err := testcase.linkPathFn(testcase.repo, testcase.digest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error calling linkPathFn(pm, %q, %q): %v", testcase.repo, testcase.digest, err)
|
t.Fatalf("unexpected error calling linkPathFn(pm, %q, %q): %v", testcase.repo, testcase.digest, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,18 @@ import (
|
||||||
"github.com/docker/distribution/digest"
|
"github.com/docker/distribution/digest"
|
||||||
)
|
)
|
||||||
|
|
||||||
const storagePathVersion = "v2"
|
const (
|
||||||
|
storagePathVersion = "v2" // fixed storage layout version
|
||||||
|
storagePathRoot = "/docker/registry/" // all driver paths have a prefix
|
||||||
|
|
||||||
// pathMapper maps paths based on "object names" and their ids. The "object
|
// TODO(stevvooe): Get rid of the "storagePathRoot". Initially, we though
|
||||||
// names" mapped by pathMapper are internal to the storage system.
|
// storage path root would configurable for all drivers through this
|
||||||
|
// package. In reality, we've found it simpler to do this on a per driver
|
||||||
|
// basis.
|
||||||
|
)
|
||||||
|
|
||||||
|
// pathFor maps paths based on "object names" and their ids. The "object
|
||||||
|
// names" mapped by are internal to the storage system.
|
||||||
//
|
//
|
||||||
// The path layout in the storage backend is roughly as follows:
|
// The path layout in the storage backend is roughly as follows:
|
||||||
//
|
//
|
||||||
|
@ -37,7 +45,7 @@ const storagePathVersion = "v2"
|
||||||
// -> blob/<algorithm>
|
// -> blob/<algorithm>
|
||||||
// <split directory content addressable storage>
|
// <split directory content addressable storage>
|
||||||
//
|
//
|
||||||
// The storage backend layout is broken up into a content- addressable blob
|
// The storage backend layout is broken up into a content-addressable blob
|
||||||
// store and repositories. The content-addressable blob store holds most data
|
// store and repositories. The content-addressable blob store holds most data
|
||||||
// throughout the backend, keyed by algorithm and digests of the underlying
|
// throughout the backend, keyed by algorithm and digests of the underlying
|
||||||
// content. Access to the blob store is controled through links from the
|
// content. Access to the blob store is controled through links from the
|
||||||
|
@ -98,18 +106,7 @@ const storagePathVersion = "v2"
|
||||||
//
|
//
|
||||||
// For more information on the semantic meaning of each path and their
|
// For more information on the semantic meaning of each path and their
|
||||||
// contents, please see the path spec documentation.
|
// contents, please see the path spec documentation.
|
||||||
type pathMapper struct {
|
func pathFor(spec pathSpec) (string, error) {
|
||||||
root string
|
|
||||||
version string // should be a constant?
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultPathMapper = &pathMapper{
|
|
||||||
root: "/docker/registry/",
|
|
||||||
version: storagePathVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
// path returns the path identified by spec.
|
|
||||||
func (pm *pathMapper) path(spec pathSpec) (string, error) {
|
|
||||||
|
|
||||||
// Switch on the path object type and return the appropriate path. At
|
// Switch on the path object type and return the appropriate path. At
|
||||||
// first glance, one may wonder why we don't use an interface to
|
// first glance, one may wonder why we don't use an interface to
|
||||||
|
@ -123,7 +120,7 @@ func (pm *pathMapper) path(spec pathSpec) (string, error) {
|
||||||
// to an intermediate path object, than can be consumed and mapped by the
|
// to an intermediate path object, than can be consumed and mapped by the
|
||||||
// other version.
|
// other version.
|
||||||
|
|
||||||
rootPrefix := []string{pm.root, pm.version}
|
rootPrefix := []string{storagePathRoot, storagePathVersion}
|
||||||
repoPrefix := append(rootPrefix, "repositories")
|
repoPrefix := append(rootPrefix, "repositories")
|
||||||
|
|
||||||
switch v := spec.(type) {
|
switch v := spec.(type) {
|
||||||
|
@ -136,7 +133,7 @@ func (pm *pathMapper) path(spec pathSpec) (string, error) {
|
||||||
|
|
||||||
return path.Join(append(append(repoPrefix, v.name, "_manifests", "revisions"), components...)...), nil
|
return path.Join(append(append(repoPrefix, v.name, "_manifests", "revisions"), components...)...), nil
|
||||||
case manifestRevisionLinkPathSpec:
|
case manifestRevisionLinkPathSpec:
|
||||||
root, err := pm.path(manifestRevisionPathSpec{
|
root, err := pathFor(manifestRevisionPathSpec{
|
||||||
name: v.name,
|
name: v.name,
|
||||||
revision: v.revision,
|
revision: v.revision,
|
||||||
})
|
})
|
||||||
|
@ -147,7 +144,7 @@ func (pm *pathMapper) path(spec pathSpec) (string, error) {
|
||||||
|
|
||||||
return path.Join(root, "link"), nil
|
return path.Join(root, "link"), nil
|
||||||
case manifestSignaturesPathSpec:
|
case manifestSignaturesPathSpec:
|
||||||
root, err := pm.path(manifestRevisionPathSpec{
|
root, err := pathFor(manifestRevisionPathSpec{
|
||||||
name: v.name,
|
name: v.name,
|
||||||
revision: v.revision,
|
revision: v.revision,
|
||||||
})
|
})
|
||||||
|
@ -158,10 +155,11 @@ func (pm *pathMapper) path(spec pathSpec) (string, error) {
|
||||||
|
|
||||||
return path.Join(root, "signatures"), nil
|
return path.Join(root, "signatures"), nil
|
||||||
case manifestSignatureLinkPathSpec:
|
case manifestSignatureLinkPathSpec:
|
||||||
root, err := pm.path(manifestSignaturesPathSpec{
|
root, err := pathFor(manifestSignaturesPathSpec{
|
||||||
name: v.name,
|
name: v.name,
|
||||||
revision: v.revision,
|
revision: v.revision,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -175,50 +173,55 @@ func (pm *pathMapper) path(spec pathSpec) (string, error) {
|
||||||
case manifestTagsPathSpec:
|
case manifestTagsPathSpec:
|
||||||
return path.Join(append(repoPrefix, v.name, "_manifests", "tags")...), nil
|
return path.Join(append(repoPrefix, v.name, "_manifests", "tags")...), nil
|
||||||
case manifestTagPathSpec:
|
case manifestTagPathSpec:
|
||||||
root, err := pm.path(manifestTagsPathSpec{
|
root, err := pathFor(manifestTagsPathSpec{
|
||||||
name: v.name,
|
name: v.name,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return path.Join(root, v.tag), nil
|
return path.Join(root, v.tag), nil
|
||||||
case manifestTagCurrentPathSpec:
|
case manifestTagCurrentPathSpec:
|
||||||
root, err := pm.path(manifestTagPathSpec{
|
root, err := pathFor(manifestTagPathSpec{
|
||||||
name: v.name,
|
name: v.name,
|
||||||
tag: v.tag,
|
tag: v.tag,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return path.Join(root, "current", "link"), nil
|
return path.Join(root, "current", "link"), nil
|
||||||
case manifestTagIndexPathSpec:
|
case manifestTagIndexPathSpec:
|
||||||
root, err := pm.path(manifestTagPathSpec{
|
root, err := pathFor(manifestTagPathSpec{
|
||||||
name: v.name,
|
name: v.name,
|
||||||
tag: v.tag,
|
tag: v.tag,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return path.Join(root, "index"), nil
|
return path.Join(root, "index"), nil
|
||||||
case manifestTagIndexEntryLinkPathSpec:
|
case manifestTagIndexEntryLinkPathSpec:
|
||||||
root, err := pm.path(manifestTagIndexEntryPathSpec{
|
root, err := pathFor(manifestTagIndexEntryPathSpec{
|
||||||
name: v.name,
|
name: v.name,
|
||||||
tag: v.tag,
|
tag: v.tag,
|
||||||
revision: v.revision,
|
revision: v.revision,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return path.Join(root, "link"), nil
|
return path.Join(root, "link"), nil
|
||||||
case manifestTagIndexEntryPathSpec:
|
case manifestTagIndexEntryPathSpec:
|
||||||
root, err := pm.path(manifestTagIndexPathSpec{
|
root, err := pathFor(manifestTagIndexPathSpec{
|
||||||
name: v.name,
|
name: v.name,
|
||||||
tag: v.tag,
|
tag: v.tag,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPathMapper(t *testing.T) {
|
func TestPathMapper(t *testing.T) {
|
||||||
pm := &pathMapper{
|
|
||||||
root: "/pathmapper-test",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, testcase := range []struct {
|
for _, testcase := range []struct {
|
||||||
spec pathSpec
|
spec pathSpec
|
||||||
expected string
|
expected string
|
||||||
|
@ -21,14 +17,14 @@ func TestPathMapper(t *testing.T) {
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
revision: "sha256:abcdef0123456789",
|
revision: "sha256:abcdef0123456789",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/revisions/sha256/abcdef0123456789",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/revisions/sha256/abcdef0123456789",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: manifestRevisionLinkPathSpec{
|
spec: manifestRevisionLinkPathSpec{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
revision: "sha256:abcdef0123456789",
|
revision: "sha256:abcdef0123456789",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/revisions/sha256/abcdef0123456789/link",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/revisions/sha256/abcdef0123456789/link",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: manifestSignatureLinkPathSpec{
|
spec: manifestSignatureLinkPathSpec{
|
||||||
|
@ -36,41 +32,41 @@ func TestPathMapper(t *testing.T) {
|
||||||
revision: "sha256:abcdef0123456789",
|
revision: "sha256:abcdef0123456789",
|
||||||
signature: "sha256:abcdef0123456789",
|
signature: "sha256:abcdef0123456789",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/revisions/sha256/abcdef0123456789/signatures/sha256/abcdef0123456789/link",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/revisions/sha256/abcdef0123456789/signatures/sha256/abcdef0123456789/link",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: manifestSignaturesPathSpec{
|
spec: manifestSignaturesPathSpec{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
revision: "sha256:abcdef0123456789",
|
revision: "sha256:abcdef0123456789",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/revisions/sha256/abcdef0123456789/signatures",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/revisions/sha256/abcdef0123456789/signatures",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: manifestTagsPathSpec{
|
spec: manifestTagsPathSpec{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/tags",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/tags",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: manifestTagPathSpec{
|
spec: manifestTagPathSpec{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
tag: "thetag",
|
tag: "thetag",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/tags/thetag",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/tags/thetag",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: manifestTagCurrentPathSpec{
|
spec: manifestTagCurrentPathSpec{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
tag: "thetag",
|
tag: "thetag",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/tags/thetag/current/link",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/tags/thetag/current/link",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: manifestTagIndexPathSpec{
|
spec: manifestTagIndexPathSpec{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
tag: "thetag",
|
tag: "thetag",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/tags/thetag/index",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/tags/thetag/index",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: manifestTagIndexEntryPathSpec{
|
spec: manifestTagIndexEntryPathSpec{
|
||||||
|
@ -78,7 +74,7 @@ func TestPathMapper(t *testing.T) {
|
||||||
tag: "thetag",
|
tag: "thetag",
|
||||||
revision: "sha256:abcdef0123456789",
|
revision: "sha256:abcdef0123456789",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/tags/thetag/index/sha256/abcdef0123456789",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/tags/thetag/index/sha256/abcdef0123456789",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: manifestTagIndexEntryLinkPathSpec{
|
spec: manifestTagIndexEntryLinkPathSpec{
|
||||||
|
@ -86,26 +82,26 @@ func TestPathMapper(t *testing.T) {
|
||||||
tag: "thetag",
|
tag: "thetag",
|
||||||
revision: "sha256:abcdef0123456789",
|
revision: "sha256:abcdef0123456789",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_manifests/tags/thetag/index/sha256/abcdef0123456789/link",
|
expected: "/docker/registry/v2/repositories/foo/bar/_manifests/tags/thetag/index/sha256/abcdef0123456789/link",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: layerLinkPathSpec{
|
spec: layerLinkPathSpec{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
digest: "tarsum.v1+test:abcdef",
|
digest: "tarsum.v1+test:abcdef",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_layers/tarsum/v1/test/abcdef/link",
|
expected: "/docker/registry/v2/repositories/foo/bar/_layers/tarsum/v1/test/abcdef/link",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: blobDataPathSpec{
|
spec: blobDataPathSpec{
|
||||||
digest: digest.Digest("tarsum.dev+sha512:abcdefabcdefabcdef908909909"),
|
digest: digest.Digest("tarsum.dev+sha512:abcdefabcdefabcdef908909909"),
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/blobs/tarsum/dev/sha512/ab/abcdefabcdefabcdef908909909/data",
|
expected: "/docker/registry/v2/blobs/tarsum/dev/sha512/ab/abcdefabcdefabcdef908909909/data",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: blobDataPathSpec{
|
spec: blobDataPathSpec{
|
||||||
digest: digest.Digest("tarsum.v1+sha256:abcdefabcdefabcdef908909909"),
|
digest: digest.Digest("tarsum.v1+sha256:abcdefabcdefabcdef908909909"),
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/blobs/tarsum/v1/sha256/ab/abcdefabcdefabcdef908909909/data",
|
expected: "/docker/registry/v2/blobs/tarsum/v1/sha256/ab/abcdefabcdefabcdef908909909/data",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -113,17 +109,17 @@ func TestPathMapper(t *testing.T) {
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
id: "asdf-asdf-asdf-adsf",
|
id: "asdf-asdf-asdf-adsf",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_uploads/asdf-asdf-asdf-adsf/data",
|
expected: "/docker/registry/v2/repositories/foo/bar/_uploads/asdf-asdf-asdf-adsf/data",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec: uploadStartedAtPathSpec{
|
spec: uploadStartedAtPathSpec{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
id: "asdf-asdf-asdf-adsf",
|
id: "asdf-asdf-asdf-adsf",
|
||||||
},
|
},
|
||||||
expected: "/pathmapper-test/repositories/foo/bar/_uploads/asdf-asdf-asdf-adsf/startedat",
|
expected: "/docker/registry/v2/repositories/foo/bar/_uploads/asdf-asdf-asdf-adsf/startedat",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p, err := pm.path(testcase.spec)
|
p, err := pathFor(testcase.spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected generating path (%T): %v", testcase.spec, err)
|
t.Fatalf("unexpected generating path (%T): %v", testcase.spec, err)
|
||||||
}
|
}
|
||||||
|
@ -136,9 +132,10 @@ func TestPathMapper(t *testing.T) {
|
||||||
// Add a few test cases to ensure we cover some errors
|
// Add a few test cases to ensure we cover some errors
|
||||||
|
|
||||||
// Specify a path that requires a revision and get a digest validation error.
|
// Specify a path that requires a revision and get a digest validation error.
|
||||||
badpath, err := pm.path(manifestSignaturesPathSpec{
|
badpath, err := pathFor(manifestSignaturesPathSpec{
|
||||||
name: "foo/bar",
|
name: "foo/bar",
|
||||||
})
|
})
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected an error when mapping an invalid revision: %s", badpath)
|
t.Fatalf("expected an error when mapping an invalid revision: %s", badpath)
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,10 +62,11 @@ func getOutstandingUploads(ctx context.Context, driver storageDriver.StorageDriv
|
||||||
uploads := make(map[string]uploadData, 0)
|
uploads := make(map[string]uploadData, 0)
|
||||||
|
|
||||||
inUploadDir := false
|
inUploadDir := false
|
||||||
root, err := defaultPathMapper.path(repositoriesRootPathSpec{})
|
root, err := pathFor(repositoriesRootPathSpec{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return uploads, append(errors, err)
|
return uploads, append(errors, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = Walk(ctx, driver, root, func(fileInfo storageDriver.FileInfo) error {
|
err = Walk(ctx, driver, root, func(fileInfo storageDriver.FileInfo) error {
|
||||||
filePath := fileInfo.Path()
|
filePath := fileInfo.Path()
|
||||||
_, file := path.Split(filePath)
|
_, file := path.Split(filePath)
|
||||||
|
|
|
@ -12,8 +12,6 @@ import (
|
||||||
"github.com/docker/distribution/uuid"
|
"github.com/docker/distribution/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pm = defaultPathMapper
|
|
||||||
|
|
||||||
func testUploadFS(t *testing.T, numUploads int, repoName string, startedAt time.Time) (driver.StorageDriver, context.Context) {
|
func testUploadFS(t *testing.T, numUploads int, repoName string, startedAt time.Time) (driver.StorageDriver, context.Context) {
|
||||||
d := inmemory.New()
|
d := inmemory.New()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
@ -24,7 +22,7 @@ func testUploadFS(t *testing.T, numUploads int, repoName string, startedAt time.
|
||||||
}
|
}
|
||||||
|
|
||||||
func addUploads(ctx context.Context, t *testing.T, d driver.StorageDriver, uploadID, repo string, startedAt time.Time) {
|
func addUploads(ctx context.Context, t *testing.T, d driver.StorageDriver, uploadID, repo string, startedAt time.Time) {
|
||||||
dataPath, err := pm.path(uploadDataPathSpec{name: repo, id: uploadID})
|
dataPath, err := pathFor(uploadDataPathSpec{name: repo, id: uploadID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to resolve path")
|
t.Fatalf("Unable to resolve path")
|
||||||
}
|
}
|
||||||
|
@ -32,7 +30,7 @@ func addUploads(ctx context.Context, t *testing.T, d driver.StorageDriver, uploa
|
||||||
t.Fatalf("Unable to write data file")
|
t.Fatalf("Unable to write data file")
|
||||||
}
|
}
|
||||||
|
|
||||||
startedAtPath, err := pm.path(uploadStartedAtPathSpec{name: repo, id: uploadID})
|
startedAtPath, err := pathFor(uploadStartedAtPathSpec{name: repo, id: uploadID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to resolve path")
|
t.Fatalf("Unable to resolve path")
|
||||||
}
|
}
|
||||||
|
@ -115,7 +113,7 @@ func TestPurgeOnlyUploads(t *testing.T) {
|
||||||
|
|
||||||
// Create a directory tree outside _uploads and ensure
|
// Create a directory tree outside _uploads and ensure
|
||||||
// these files aren't deleted.
|
// these files aren't deleted.
|
||||||
dataPath, err := pm.path(uploadDataPathSpec{name: "test-repo", id: uuid.Generate().String()})
|
dataPath, err := pathFor(uploadDataPathSpec{name: "test-repo", id: uuid.Generate().String()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf(err.Error())
|
t.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ func NewRegistryWithDriver(ctx context.Context, driver storagedriver.StorageDriv
|
||||||
// create global statter, with cache.
|
// create global statter, with cache.
|
||||||
var statter distribution.BlobDescriptorService = &blobStatter{
|
var statter distribution.BlobDescriptorService = &blobStatter{
|
||||||
driver: driver,
|
driver: driver,
|
||||||
pm: defaultPathMapper,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if blobDescriptorCacheProvider != nil {
|
if blobDescriptorCacheProvider != nil {
|
||||||
|
@ -39,7 +38,6 @@ func NewRegistryWithDriver(ctx context.Context, driver storagedriver.StorageDriv
|
||||||
|
|
||||||
bs := &blobStore{
|
bs := &blobStore{
|
||||||
driver: driver,
|
driver: driver,
|
||||||
pm: defaultPathMapper,
|
|
||||||
statter: statter,
|
statter: statter,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ func newSignatureStore(ctx context.Context, repo *repository, blobStore *blobSto
|
||||||
var _ distribution.SignatureService = &signatureStore{}
|
var _ distribution.SignatureService = &signatureStore{}
|
||||||
|
|
||||||
func (s *signatureStore) Get(dgst digest.Digest) ([][]byte, error) {
|
func (s *signatureStore) Get(dgst digest.Digest) ([][]byte, error) {
|
||||||
signaturesPath, err := s.blobStore.pm.path(manifestSignaturesPathSpec{
|
signaturesPath, err := pathFor(manifestSignaturesPathSpec{
|
||||||
name: s.repository.Name(),
|
name: s.repository.Name(),
|
||||||
revision: dgst,
|
revision: dgst,
|
||||||
})
|
})
|
||||||
|
@ -119,12 +119,13 @@ func (s *signatureStore) Put(dgst digest.Digest, signatures ...[]byte) error {
|
||||||
// manifest with the given digest. Effectively, each signature link path
|
// manifest with the given digest. Effectively, each signature link path
|
||||||
// layout is a unique linked blob store.
|
// layout is a unique linked blob store.
|
||||||
func (s *signatureStore) linkedBlobStore(ctx context.Context, revision digest.Digest) *linkedBlobStore {
|
func (s *signatureStore) linkedBlobStore(ctx context.Context, revision digest.Digest) *linkedBlobStore {
|
||||||
linkpath := func(pm *pathMapper, name string, dgst digest.Digest) (string, error) {
|
linkpath := func(name string, dgst digest.Digest) (string, error) {
|
||||||
return pm.path(manifestSignatureLinkPathSpec{
|
return pathFor(manifestSignatureLinkPathSpec{
|
||||||
name: name,
|
name: name,
|
||||||
revision: revision,
|
revision: revision,
|
||||||
signature: dgst,
|
signature: dgst,
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &linkedBlobStore{
|
return &linkedBlobStore{
|
||||||
|
|
|
@ -18,9 +18,10 @@ type tagStore struct {
|
||||||
|
|
||||||
// tags lists the manifest tags for the specified repository.
|
// tags lists the manifest tags for the specified repository.
|
||||||
func (ts *tagStore) tags() ([]string, error) {
|
func (ts *tagStore) tags() ([]string, error) {
|
||||||
p, err := ts.blobStore.pm.path(manifestTagPathSpec{
|
p, err := pathFor(manifestTagPathSpec{
|
||||||
name: ts.repository.Name(),
|
name: ts.repository.Name(),
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -47,10 +48,11 @@ func (ts *tagStore) tags() ([]string, error) {
|
||||||
|
|
||||||
// exists returns true if the specified manifest tag exists in the repository.
|
// exists returns true if the specified manifest tag exists in the repository.
|
||||||
func (ts *tagStore) exists(tag string) (bool, error) {
|
func (ts *tagStore) exists(tag string) (bool, error) {
|
||||||
tagPath, err := ts.blobStore.pm.path(manifestTagCurrentPathSpec{
|
tagPath, err := pathFor(manifestTagCurrentPathSpec{
|
||||||
name: ts.repository.Name(),
|
name: ts.repository.Name(),
|
||||||
tag: tag,
|
tag: tag,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -66,7 +68,7 @@ func (ts *tagStore) exists(tag string) (bool, error) {
|
||||||
// tag tags the digest with the given tag, updating the the store to point at
|
// tag tags the digest with the given tag, updating the the store to point at
|
||||||
// the current tag. The digest must point to a manifest.
|
// the current tag. The digest must point to a manifest.
|
||||||
func (ts *tagStore) tag(tag string, revision digest.Digest) error {
|
func (ts *tagStore) tag(tag string, revision digest.Digest) error {
|
||||||
currentPath, err := ts.blobStore.pm.path(manifestTagCurrentPathSpec{
|
currentPath, err := pathFor(manifestTagCurrentPathSpec{
|
||||||
name: ts.repository.Name(),
|
name: ts.repository.Name(),
|
||||||
tag: tag,
|
tag: tag,
|
||||||
})
|
})
|
||||||
|
@ -87,10 +89,11 @@ func (ts *tagStore) tag(tag string, revision digest.Digest) error {
|
||||||
|
|
||||||
// resolve the current revision for name and tag.
|
// resolve the current revision for name and tag.
|
||||||
func (ts *tagStore) resolve(tag string) (digest.Digest, error) {
|
func (ts *tagStore) resolve(tag string) (digest.Digest, error) {
|
||||||
currentPath, err := ts.blobStore.pm.path(manifestTagCurrentPathSpec{
|
currentPath, err := pathFor(manifestTagCurrentPathSpec{
|
||||||
name: ts.repository.Name(),
|
name: ts.repository.Name(),
|
||||||
tag: tag,
|
tag: tag,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -111,10 +114,11 @@ func (ts *tagStore) resolve(tag string) (digest.Digest, error) {
|
||||||
// delete removes the tag from repository, including the history of all
|
// delete removes the tag from repository, including the history of all
|
||||||
// revisions that have the specified tag.
|
// revisions that have the specified tag.
|
||||||
func (ts *tagStore) delete(tag string) error {
|
func (ts *tagStore) delete(tag string) error {
|
||||||
tagPath, err := ts.blobStore.pm.path(manifestTagPathSpec{
|
tagPath, err := pathFor(manifestTagPathSpec{
|
||||||
name: ts.repository.Name(),
|
name: ts.repository.Name(),
|
||||||
tag: tag,
|
tag: tag,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -131,12 +135,13 @@ func (ts *tagStore) linkedBlobStore(ctx context.Context, tag string) *linkedBlob
|
||||||
blobStore: ts.blobStore,
|
blobStore: ts.blobStore,
|
||||||
repository: ts.repository,
|
repository: ts.repository,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
linkPathFns: []linkPathFunc{func(pm *pathMapper, name string, dgst digest.Digest) (string, error) {
|
linkPathFns: []linkPathFunc{func(name string, dgst digest.Digest) (string, error) {
|
||||||
return pm.path(manifestTagIndexEntryLinkPathSpec{
|
return pathFor(manifestTagIndexEntryLinkPathSpec{
|
||||||
name: name,
|
name: name,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
revision: dgst,
|
revision: dgst,
|
||||||
})
|
})
|
||||||
|
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,11 @@ func NewVacuum(ctx context.Context, driver driver.StorageDriver) Vacuum {
|
||||||
return Vacuum{
|
return Vacuum{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
driver: driver,
|
driver: driver,
|
||||||
pm: defaultPathMapper,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vacuum removes content from the filesystem
|
// Vacuum removes content from the filesystem
|
||||||
type Vacuum struct {
|
type Vacuum struct {
|
||||||
pm *pathMapper
|
|
||||||
driver driver.StorageDriver
|
driver driver.StorageDriver
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
@ -36,7 +34,7 @@ func (v Vacuum) RemoveBlob(dgst string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
blobPath, err := v.pm.path(blobDataPathSpec{digest: d})
|
blobPath, err := pathFor(blobDataPathSpec{digest: d})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -52,7 +50,7 @@ func (v Vacuum) RemoveBlob(dgst string) error {
|
||||||
// RemoveRepository removes a repository directory from the
|
// RemoveRepository removes a repository directory from the
|
||||||
// filesystem
|
// filesystem
|
||||||
func (v Vacuum) RemoveRepository(repoName string) error {
|
func (v Vacuum) RemoveRepository(repoName string) error {
|
||||||
rootForRepository, err := v.pm.path(repositoriesRootPathSpec{})
|
rootForRepository, err := pathFor(repositoriesRootPathSpec{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue