forked from TrueCloudLab/distribution
Implement Tags method on ManifestService
This commit is contained in:
parent
45c29be442
commit
c71089c653
5 changed files with 67 additions and 0 deletions
|
@ -13,6 +13,16 @@ import (
|
||||||
"github.com/docker/docker-registry/digest"
|
"github.com/docker/docker-registry/digest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrUnknownRepository is returned if the named repository is not known by
|
||||||
|
// the registry.
|
||||||
|
type ErrUnknownRepository struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrUnknownRepository) Error() string {
|
||||||
|
return fmt.Sprintf("unknown respository name=%s", err.Name)
|
||||||
|
}
|
||||||
|
|
||||||
// ErrUnknownManifest is returned if the manifest is not known by the
|
// ErrUnknownManifest is returned if the manifest is not known by the
|
||||||
// registry.
|
// registry.
|
||||||
type ErrUnknownManifest struct {
|
type ErrUnknownManifest struct {
|
||||||
|
|
|
@ -99,6 +99,20 @@ func TestManifestStorage(t *testing.T) {
|
||||||
if !reflect.DeepEqual(fetchedManifest, sm) {
|
if !reflect.DeepEqual(fetchedManifest, sm) {
|
||||||
t.Fatalf("fetched manifest not equal: %#v != %#v", fetchedManifest, sm)
|
t.Fatalf("fetched manifest not equal: %#v != %#v", fetchedManifest, sm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Grabs the tags and check that this tagged manifest is present
|
||||||
|
tags, err := ms.Tags(name)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error fetching tags: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(tags) != 1 {
|
||||||
|
t.Fatalf("unexpected tags returned: %v", tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tags[0] != tag {
|
||||||
|
t.Fatalf("unexpected tag found in tags: %v != %v", tags, []string{tag})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type layerKey struct {
|
type layerKey struct {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package storage
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
|
|
||||||
"github.com/docker/docker-registry/storagedriver"
|
"github.com/docker/docker-registry/storagedriver"
|
||||||
"github.com/docker/libtrust"
|
"github.com/docker/libtrust"
|
||||||
|
@ -16,6 +17,35 @@ type manifestStore struct {
|
||||||
|
|
||||||
var _ ManifestService = &manifestStore{}
|
var _ ManifestService = &manifestStore{}
|
||||||
|
|
||||||
|
func (ms *manifestStore) Tags(name string) ([]string, error) {
|
||||||
|
p, err := ms.pathMapper.path(manifestTagsPath{
|
||||||
|
name: name,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tags []string
|
||||||
|
entries, err := ms.driver.List(p)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Infof("%#v", err)
|
||||||
|
switch err := err.(type) {
|
||||||
|
case storagedriver.PathNotFoundError:
|
||||||
|
return nil, ErrUnknownRepository{Name: name}
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range entries {
|
||||||
|
_, filename := path.Split(entry)
|
||||||
|
|
||||||
|
tags = append(tags, filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ms *manifestStore) Exists(name, tag string) (bool, error) {
|
func (ms *manifestStore) Exists(name, tag string) (bool, error) {
|
||||||
p, err := ms.path(name, tag)
|
p, err := ms.path(name, tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -64,6 +64,8 @@ func (pm *pathMapper) path(spec pathSpec) (string, error) {
|
||||||
repoPrefix := append(rootPrefix, "repositories")
|
repoPrefix := append(rootPrefix, "repositories")
|
||||||
|
|
||||||
switch v := spec.(type) {
|
switch v := spec.(type) {
|
||||||
|
case manifestTagsPath:
|
||||||
|
return path.Join(append(repoPrefix, v.name, "manifests")...), nil
|
||||||
case manifestPathSpec:
|
case manifestPathSpec:
|
||||||
// TODO(sday): May need to store manifest by architecture.
|
// TODO(sday): May need to store manifest by architecture.
|
||||||
return path.Join(append(repoPrefix, v.name, "manifests", v.tag)...), nil
|
return path.Join(append(repoPrefix, v.name, "manifests", v.tag)...), nil
|
||||||
|
@ -109,6 +111,14 @@ type pathSpec interface {
|
||||||
pathSpec()
|
pathSpec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// manifestTagsPath describes the path elements required to point to the
|
||||||
|
// directory with all manifest tags under the repository.
|
||||||
|
type manifestTagsPath struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (manifestTagsPath) pathSpec() {}
|
||||||
|
|
||||||
// manifestPathSpec describes the path elements used to build a manifest path.
|
// manifestPathSpec describes the path elements used to build a manifest path.
|
||||||
// The contents should be a signed manifest json file.
|
// The contents should be a signed manifest json file.
|
||||||
type manifestPathSpec struct {
|
type manifestPathSpec struct {
|
||||||
|
|
|
@ -52,6 +52,9 @@ func (ss *Services) Manifests() ManifestService {
|
||||||
|
|
||||||
// ManifestService provides operations on image manifests.
|
// ManifestService provides operations on image manifests.
|
||||||
type ManifestService interface {
|
type ManifestService interface {
|
||||||
|
// Tags lists the tags under the named repository.
|
||||||
|
Tags(name string) ([]string, error)
|
||||||
|
|
||||||
// Exists returns true if the layer exists.
|
// Exists returns true if the layer exists.
|
||||||
Exists(name, tag string) (bool, error)
|
Exists(name, tag string) (bool, error)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue