b7d29c1e23
These tests seem to be running fine without being root, so let's not skip them. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
503 lines
14 KiB
Go
503 lines
14 KiB
Go
package registry // import "github.com/docker/docker/registry"
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/distribution/reference"
|
|
"github.com/docker/docker/api/types/registry"
|
|
"gotest.tools/v3/assert"
|
|
is "gotest.tools/v3/assert/cmp"
|
|
)
|
|
|
|
func TestParseRepositoryInfo(t *testing.T) {
|
|
type staticRepositoryInfo struct {
|
|
Index *registry.IndexInfo
|
|
RemoteName string
|
|
CanonicalName string
|
|
LocalName string
|
|
Official bool
|
|
}
|
|
|
|
expectedRepoInfos := map[string]staticRepositoryInfo{
|
|
"fooo/bar": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "fooo/bar",
|
|
LocalName: "fooo/bar",
|
|
CanonicalName: "docker.io/fooo/bar",
|
|
Official: false,
|
|
},
|
|
"library/ubuntu": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "library/ubuntu",
|
|
LocalName: "ubuntu",
|
|
CanonicalName: "docker.io/library/ubuntu",
|
|
Official: true,
|
|
},
|
|
"nonlibrary/ubuntu": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "nonlibrary/ubuntu",
|
|
LocalName: "nonlibrary/ubuntu",
|
|
CanonicalName: "docker.io/nonlibrary/ubuntu",
|
|
Official: false,
|
|
},
|
|
"ubuntu": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "library/ubuntu",
|
|
LocalName: "ubuntu",
|
|
CanonicalName: "docker.io/library/ubuntu",
|
|
Official: true,
|
|
},
|
|
"other/library": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "other/library",
|
|
LocalName: "other/library",
|
|
CanonicalName: "docker.io/other/library",
|
|
Official: false,
|
|
},
|
|
"127.0.0.1:8000/private/moonbase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "127.0.0.1:8000",
|
|
Official: false,
|
|
},
|
|
RemoteName: "private/moonbase",
|
|
LocalName: "127.0.0.1:8000/private/moonbase",
|
|
CanonicalName: "127.0.0.1:8000/private/moonbase",
|
|
Official: false,
|
|
},
|
|
"127.0.0.1:8000/privatebase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "127.0.0.1:8000",
|
|
Official: false,
|
|
},
|
|
RemoteName: "privatebase",
|
|
LocalName: "127.0.0.1:8000/privatebase",
|
|
CanonicalName: "127.0.0.1:8000/privatebase",
|
|
Official: false,
|
|
},
|
|
"localhost:8000/private/moonbase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "localhost:8000",
|
|
Official: false,
|
|
},
|
|
RemoteName: "private/moonbase",
|
|
LocalName: "localhost:8000/private/moonbase",
|
|
CanonicalName: "localhost:8000/private/moonbase",
|
|
Official: false,
|
|
},
|
|
"localhost:8000/privatebase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "localhost:8000",
|
|
Official: false,
|
|
},
|
|
RemoteName: "privatebase",
|
|
LocalName: "localhost:8000/privatebase",
|
|
CanonicalName: "localhost:8000/privatebase",
|
|
Official: false,
|
|
},
|
|
"example.com/private/moonbase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "example.com",
|
|
Official: false,
|
|
},
|
|
RemoteName: "private/moonbase",
|
|
LocalName: "example.com/private/moonbase",
|
|
CanonicalName: "example.com/private/moonbase",
|
|
Official: false,
|
|
},
|
|
"example.com/privatebase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "example.com",
|
|
Official: false,
|
|
},
|
|
RemoteName: "privatebase",
|
|
LocalName: "example.com/privatebase",
|
|
CanonicalName: "example.com/privatebase",
|
|
Official: false,
|
|
},
|
|
"example.com:8000/private/moonbase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "example.com:8000",
|
|
Official: false,
|
|
},
|
|
RemoteName: "private/moonbase",
|
|
LocalName: "example.com:8000/private/moonbase",
|
|
CanonicalName: "example.com:8000/private/moonbase",
|
|
Official: false,
|
|
},
|
|
"example.com:8000/privatebase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "example.com:8000",
|
|
Official: false,
|
|
},
|
|
RemoteName: "privatebase",
|
|
LocalName: "example.com:8000/privatebase",
|
|
CanonicalName: "example.com:8000/privatebase",
|
|
Official: false,
|
|
},
|
|
"localhost/private/moonbase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "localhost",
|
|
Official: false,
|
|
},
|
|
RemoteName: "private/moonbase",
|
|
LocalName: "localhost/private/moonbase",
|
|
CanonicalName: "localhost/private/moonbase",
|
|
Official: false,
|
|
},
|
|
"localhost/privatebase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: "localhost",
|
|
Official: false,
|
|
},
|
|
RemoteName: "privatebase",
|
|
LocalName: "localhost/privatebase",
|
|
CanonicalName: "localhost/privatebase",
|
|
Official: false,
|
|
},
|
|
IndexName + "/public/moonbase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "public/moonbase",
|
|
LocalName: "public/moonbase",
|
|
CanonicalName: "docker.io/public/moonbase",
|
|
Official: false,
|
|
},
|
|
"index." + IndexName + "/public/moonbase": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "public/moonbase",
|
|
LocalName: "public/moonbase",
|
|
CanonicalName: "docker.io/public/moonbase",
|
|
Official: false,
|
|
},
|
|
"ubuntu-12.04-base": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "library/ubuntu-12.04-base",
|
|
LocalName: "ubuntu-12.04-base",
|
|
CanonicalName: "docker.io/library/ubuntu-12.04-base",
|
|
Official: true,
|
|
},
|
|
IndexName + "/ubuntu-12.04-base": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "library/ubuntu-12.04-base",
|
|
LocalName: "ubuntu-12.04-base",
|
|
CanonicalName: "docker.io/library/ubuntu-12.04-base",
|
|
Official: true,
|
|
},
|
|
"index." + IndexName + "/ubuntu-12.04-base": {
|
|
Index: ®istry.IndexInfo{
|
|
Name: IndexName,
|
|
Official: true,
|
|
},
|
|
RemoteName: "library/ubuntu-12.04-base",
|
|
LocalName: "ubuntu-12.04-base",
|
|
CanonicalName: "docker.io/library/ubuntu-12.04-base",
|
|
Official: true,
|
|
},
|
|
}
|
|
|
|
for reposName, expectedRepoInfo := range expectedRepoInfos {
|
|
named, err := reference.ParseNormalizedNamed(reposName)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
repoInfo, err := ParseRepositoryInfo(named)
|
|
if err != nil {
|
|
t.Error(err)
|
|
} else {
|
|
assert.Check(t, is.Equal(repoInfo.Index.Name, expectedRepoInfo.Index.Name), reposName)
|
|
assert.Check(t, is.Equal(reference.Path(repoInfo.Name), expectedRepoInfo.RemoteName), reposName)
|
|
assert.Check(t, is.Equal(reference.FamiliarName(repoInfo.Name), expectedRepoInfo.LocalName), reposName)
|
|
assert.Check(t, is.Equal(repoInfo.Name.Name(), expectedRepoInfo.CanonicalName), reposName)
|
|
assert.Check(t, is.Equal(repoInfo.Index.Official, expectedRepoInfo.Index.Official), reposName)
|
|
assert.Check(t, is.Equal(repoInfo.Official, expectedRepoInfo.Official), reposName)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNewIndexInfo(t *testing.T) {
|
|
testIndexInfo := func(config *serviceConfig, expectedIndexInfos map[string]*registry.IndexInfo) {
|
|
for indexName, expectedIndexInfo := range expectedIndexInfos {
|
|
index, err := newIndexInfo(config, indexName)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else {
|
|
assert.Check(t, is.Equal(index.Name, expectedIndexInfo.Name), indexName+" name")
|
|
assert.Check(t, is.Equal(index.Official, expectedIndexInfo.Official), indexName+" is official")
|
|
assert.Check(t, is.Equal(index.Secure, expectedIndexInfo.Secure), indexName+" is secure")
|
|
assert.Check(t, is.Equal(len(index.Mirrors), len(expectedIndexInfo.Mirrors)), indexName+" mirrors")
|
|
}
|
|
}
|
|
}
|
|
|
|
config := emptyServiceConfig
|
|
var noMirrors []string
|
|
expectedIndexInfos := map[string]*registry.IndexInfo{
|
|
IndexName: {
|
|
Name: IndexName,
|
|
Official: true,
|
|
Secure: true,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"index." + IndexName: {
|
|
Name: IndexName,
|
|
Official: true,
|
|
Secure: true,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"example.com": {
|
|
Name: "example.com",
|
|
Official: false,
|
|
Secure: true,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"127.0.0.1:5000": {
|
|
Name: "127.0.0.1:5000",
|
|
Official: false,
|
|
Secure: false,
|
|
Mirrors: noMirrors,
|
|
},
|
|
}
|
|
testIndexInfo(config, expectedIndexInfos)
|
|
|
|
publicMirrors := []string{"http://mirror1.local", "http://mirror2.local"}
|
|
var err error
|
|
config, err = makeServiceConfig(publicMirrors, []string{"example.com"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expectedIndexInfos = map[string]*registry.IndexInfo{
|
|
IndexName: {
|
|
Name: IndexName,
|
|
Official: true,
|
|
Secure: true,
|
|
Mirrors: publicMirrors,
|
|
},
|
|
"index." + IndexName: {
|
|
Name: IndexName,
|
|
Official: true,
|
|
Secure: true,
|
|
Mirrors: publicMirrors,
|
|
},
|
|
"example.com": {
|
|
Name: "example.com",
|
|
Official: false,
|
|
Secure: false,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"example.com:5000": {
|
|
Name: "example.com:5000",
|
|
Official: false,
|
|
Secure: true,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"127.0.0.1": {
|
|
Name: "127.0.0.1",
|
|
Official: false,
|
|
Secure: false,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"127.0.0.1:5000": {
|
|
Name: "127.0.0.1:5000",
|
|
Official: false,
|
|
Secure: false,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"other.com": {
|
|
Name: "other.com",
|
|
Official: false,
|
|
Secure: true,
|
|
Mirrors: noMirrors,
|
|
},
|
|
}
|
|
testIndexInfo(config, expectedIndexInfos)
|
|
|
|
config, err = makeServiceConfig(nil, []string{"42.42.0.0/16"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
expectedIndexInfos = map[string]*registry.IndexInfo{
|
|
"example.com": {
|
|
Name: "example.com",
|
|
Official: false,
|
|
Secure: false,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"example.com:5000": {
|
|
Name: "example.com:5000",
|
|
Official: false,
|
|
Secure: false,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"127.0.0.1": {
|
|
Name: "127.0.0.1",
|
|
Official: false,
|
|
Secure: false,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"127.0.0.1:5000": {
|
|
Name: "127.0.0.1:5000",
|
|
Official: false,
|
|
Secure: false,
|
|
Mirrors: noMirrors,
|
|
},
|
|
"other.com": {
|
|
Name: "other.com",
|
|
Official: false,
|
|
Secure: true,
|
|
Mirrors: noMirrors,
|
|
},
|
|
}
|
|
testIndexInfo(config, expectedIndexInfos)
|
|
}
|
|
|
|
func TestMirrorEndpointLookup(t *testing.T) {
|
|
containsMirror := func(endpoints []APIEndpoint) bool {
|
|
for _, pe := range endpoints {
|
|
if pe.URL.Host == "my.mirror" {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
cfg, err := makeServiceConfig([]string{"https://my.mirror"}, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s := Service{config: cfg}
|
|
|
|
imageName, err := reference.WithName(IndexName + "/test/image")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pushAPIEndpoints, err := s.LookupPushEndpoints(reference.Domain(imageName))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if containsMirror(pushAPIEndpoints) {
|
|
t.Fatal("Push endpoint should not contain mirror")
|
|
}
|
|
|
|
pullAPIEndpoints, err := s.LookupPullEndpoints(reference.Domain(imageName))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !containsMirror(pullAPIEndpoints) {
|
|
t.Fatal("Pull endpoint should contain mirror")
|
|
}
|
|
}
|
|
|
|
func TestAllowNondistributableArtifacts(t *testing.T) {
|
|
tests := []struct {
|
|
addr string
|
|
registries []string
|
|
expected bool
|
|
}{
|
|
{IndexName, nil, false},
|
|
{"example.com", []string{}, false},
|
|
{"example.com", []string{"example.com"}, true},
|
|
{"localhost", []string{"localhost:5000"}, false},
|
|
{"localhost:5000", []string{"localhost:5000"}, true},
|
|
{"localhost", []string{"example.com"}, false},
|
|
{"127.0.0.1:5000", []string{"127.0.0.1:5000"}, true},
|
|
{"localhost", nil, false},
|
|
{"localhost:5000", nil, false},
|
|
{"127.0.0.1", nil, false},
|
|
{"localhost", []string{"example.com"}, false},
|
|
{"127.0.0.1", []string{"example.com"}, false},
|
|
{"example.com", nil, false},
|
|
{"example.com", []string{"example.com"}, true},
|
|
{"127.0.0.1", []string{"example.com"}, false},
|
|
{"127.0.0.1:5000", []string{"example.com"}, false},
|
|
{"example.com:5000", []string{"42.42.0.0/16"}, true},
|
|
{"example.com", []string{"42.42.0.0/16"}, true},
|
|
{"example.com:5000", []string{"42.42.42.42/8"}, true},
|
|
{"127.0.0.1:5000", []string{"127.0.0.0/8"}, true},
|
|
{"42.42.42.42:5000", []string{"42.1.1.1/8"}, true},
|
|
{"invalid.example.com", []string{"42.42.0.0/16"}, false},
|
|
{"invalid.example.com", []string{"invalid.example.com"}, true},
|
|
{"invalid.example.com:5000", []string{"invalid.example.com"}, false},
|
|
{"invalid.example.com:5000", []string{"invalid.example.com:5000"}, true},
|
|
}
|
|
for _, tt := range tests {
|
|
config, err := newServiceConfig(ServiceOptions{
|
|
AllowNondistributableArtifacts: tt.registries,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if v := config.allowNondistributableArtifacts(tt.addr); v != tt.expected {
|
|
t.Errorf("allowNondistributableArtifacts failed for %q %v, expected %v got %v", tt.addr, tt.registries, tt.expected, v)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIsSecureIndex(t *testing.T) {
|
|
tests := []struct {
|
|
addr string
|
|
insecureRegistries []string
|
|
expected bool
|
|
}{
|
|
{IndexName, nil, true},
|
|
{"example.com", []string{}, true},
|
|
{"example.com", []string{"example.com"}, false},
|
|
{"localhost", []string{"localhost:5000"}, false},
|
|
{"localhost:5000", []string{"localhost:5000"}, false},
|
|
{"localhost", []string{"example.com"}, false},
|
|
{"127.0.0.1:5000", []string{"127.0.0.1:5000"}, false},
|
|
{"localhost", nil, false},
|
|
{"localhost:5000", nil, false},
|
|
{"127.0.0.1", nil, false},
|
|
{"localhost", []string{"example.com"}, false},
|
|
{"127.0.0.1", []string{"example.com"}, false},
|
|
{"example.com", nil, true},
|
|
{"example.com", []string{"example.com"}, false},
|
|
{"127.0.0.1", []string{"example.com"}, false},
|
|
{"127.0.0.1:5000", []string{"example.com"}, false},
|
|
{"example.com:5000", []string{"42.42.0.0/16"}, false},
|
|
{"example.com", []string{"42.42.0.0/16"}, false},
|
|
{"example.com:5000", []string{"42.42.42.42/8"}, false},
|
|
{"127.0.0.1:5000", []string{"127.0.0.0/8"}, false},
|
|
{"42.42.42.42:5000", []string{"42.1.1.1/8"}, false},
|
|
{"invalid.example.com", []string{"42.42.0.0/16"}, true},
|
|
{"invalid.example.com", []string{"invalid.example.com"}, false},
|
|
{"invalid.example.com:5000", []string{"invalid.example.com"}, true},
|
|
{"invalid.example.com:5000", []string{"invalid.example.com:5000"}, false},
|
|
}
|
|
for _, tt := range tests {
|
|
config, err := makeServiceConfig(nil, tt.insecureRegistries)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if sec := config.isSecureIndex(tt.addr); sec != tt.expected {
|
|
t.Errorf("isSecureIndex failed for %q %v, expected %v got %v", tt.addr, tt.insecureRegistries, tt.expected, sec)
|
|
}
|
|
}
|
|
}
|