Add a new reference package abstracting repositories, tags and digests

There seems to be a need for a type that represents a way of pointing
to an image, irrespective of the implementation.

This patch defines a Reference interface and provides 3 implementations:
- TagReference: when only a tag is provided
- DigestReference: when a digest (according to the digest package) is
  provided, can include optional tag as well

Validation of references are purely syntactic.

There is also a strong type for tags, analogous to digests, as well
as a strong type for Repository from which clients can access the
hostname alone, or the repository name without the hostname, or both
together via the String() method.

For Repository, the files names.go and names_test.go were moved from
the v2 package.

Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
Tibor Vass 2015-07-10 14:36:04 -04:00 committed by Derek McGowan
parent 1d266b00e1
commit f8c09b6a7d
11 changed files with 495 additions and 143 deletions

View file

@ -0,0 +1,56 @@
package reference
/*
var refRegex = regexp.MustCompile(`^([a-z0-9]+(?:[-._][a-z0-9]+)*(?::[0-9]+(?:/[a-z0-9]+(?:[-._][a-z0-9]+)*)+|(?:/[a-z0-9]+(?:[-._][a-z0-9]+)*)+)?)(:[\w][\w.-]{0,127})?(@` + digest.DigestRegexp.String() + `)?$`)
func getRepo(s string) string {
matches := refRegex.FindStringSubmatch(s)
if len(matches) == 0 {
return ""
}
return matches[1]
}
func testRepository(prefix string) error {
for _, s := range []string{
prefix + `@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`,
prefix + `:frozen@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`,
prefix + `:latest`,
prefix,
} {
expected := getRepo(s)
ref, err := Parse(s)
if err != nil {
if expected == "" {
continue
}
return err
}
if repo := ref.Repository(); repo.String() != expected {
return fmt.Errorf("repository string: expected %q, got: %q", expected, repo)
}
if refStr := ref.String(); refStr != s {
return fmt.Errorf("reference string: expected %q, got: %q", s, refStr)
}
}
return nil
}
func TestSimpleRepository(t *testing.T) {
if err := testRepository(`busybox`); err != nil {
t.Fatal(err)
}
}
func TestUrlRepository(t *testing.T) {
if err := testRepository(`docker.io/library/busybox`); err != nil {
t.Fatal(err)
}
}
func TestPort(t *testing.T) {
if err := testRepository(`busybox:1234`); err != nil {
t.Fatal(err)
}
}
*/