Skip to content
This repository has been archived by the owner on Aug 26, 2021. It is now read-only.

Commit

Permalink
[Fixes #18] Allow for multiple path segments in image name
Browse files Browse the repository at this point in the history
Typically, the image name of a Docker image consists of two path
segments: namespace/repo. However, official documentation states that
this is not enforced and variable number of path segments might be used:
https://docs.docker.com/registry/spec/api/#overview
For example, namespace/category/repo is also a valid repository name.
With this change we now support docker images with multiple path
segments in the repo name.

Change-Id: I91b928dde0c409c332887a4902bb9f8e703301ec
Reviewed-on: http://bellevue-ci.eng.vmware.com:8080/24267
Reviewed-by: Sergio Sanchez <sanchezs@vmware.com>
Closures-Verified: jenkins <jenkins@vmware.com>
Upgrade-Verified: jenkins <jenkins@vmware.com>
Bellevue-Verified: jenkins <jenkins@vmware.com>
CS-Verified: jenkins <jenkins@vmware.com>
  • Loading branch information
shadjiiski committed Jan 22, 2018
1 parent b51f968 commit 5866277
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 15 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

* The option to [overwrite the public address](https://github.com/vmware/admiral/wiki/Configuration-guide#enable-or-disable-the-option-to-overwrite-the-public-address-for-a-host) for a host is now enabled by default in the standalone version of Admiral.

* Added support for multiple path segments in the names of repositories, e.g. localhost:5000/category/sub-category/repo-name

Docker hub images & tags: https://hub.docker.com/r/vmware/admiral/

* dev - Standalone
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 VMware, Inc. All Rights Reserved.
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
Expand Down Expand Up @@ -81,6 +81,9 @@ public boolean isDockerHubImage() {
public static DockerImage fromImageName(String imageName) {
String[] parts = imageName.split(SECTION_SEPARATOR);
switch (parts.length) {
case 0:
throw new IllegalArgumentException("Invalid image format: " + imageName);

case 1:
// only one section - it is the repository name with optional tag
return fromParts(null, null, parts[0]);
Expand All @@ -93,12 +96,21 @@ public static DockerImage fromImageName(String imageName) {
return fromParts(parts[0], null, parts[1]);
}

case 3:
// all sections present
return fromParts(parts[0], parts[1], parts[2]);

default:
throw new IllegalArgumentException("Invalid image format: " + imageName);
// three or more sections present: host, namespace and repo. According to Docker
// documentation, the most common case is to have two path components in the name of the
// repository, however, it is possible to have a different number of path segments:
// https://docs.docker.com/registry/spec/api/#overview
// We are going to treat the extra path arguments as part of the namespace, e.g. the
// repo name host:port/path/to/repo will have "host:port" for host, "path/to" for
// namespace and "repo" for name.

String host = parts[0];
String repo = parts[parts.length - 1];
String namespace = imageName.substring(host.length() + SECTION_SEPARATOR.length(),
imageName.length() - repo.length() - SECTION_SEPARATOR.length());
return fromParts(host, namespace, repo);

}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 VMware, Inc. All Rights Reserved.
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
Expand Down Expand Up @@ -76,6 +76,14 @@ public static List<String[]> data() {
data.add(new String[] { "official repo with custom namespace",
"docker.io/user/repo:tag", "docker.io", "user", "repo", "user/repo", "tag" });

data.add(new String[] { "host and three path components of repo",
"host/namespace/category/repo", "host", "namespace/category", "repo",
"namespace/category/repo", "latest" });

data.add(new String[] { "host, port, three path components of repo and tag",
"host:5000/namespace/category/repo:tag", "host:5000", "namespace/category", "repo",
"namespace/category/repo", "tag" });

return data;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 VMware, Inc. All Rights Reserved.
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
Expand Down Expand Up @@ -49,6 +49,10 @@ public static List<String[]> data() {
data.add(new String[] { "default repository (library) should be kept, with host",
"foo:5000/library/admiral", "foo:5000/library/admiral:latest" });

data.add(new String[] {
"host should be set for image with multiple path segments in repo name",
"foo:5000/namespace/category/bar", "foo:5000/namespace/category/bar:latest" });

return data;
}

Expand Down
22 changes: 16 additions & 6 deletions ui/app/src/js/core/imageUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 VMware, Inc. All Rights Reserved.
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
Expand Down Expand Up @@ -61,6 +61,8 @@ var imageUtils = {
var imageWithoutScheme = image.replace(REGISTRY_SCHEME_REG_EXP, '');
var parts = imageWithoutScheme.split(SECTION_SEPARATOR);
switch (parts.length) {
case 0:
throw new Error('Invalid image format: ' + image);
case 1:
// only one section - it is the repository name with optional tag
return getImageNamespaceAndNameFromParts(null, parts[0]);
Expand All @@ -72,12 +74,20 @@ var imageUtils = {
}
return getImageNamespaceAndNameFromParts(null, parts[1]);

case 3:
// all sections present
return getImageNamespaceAndNameFromParts(parts[1], parts[2]);

default:
throw new Error('Invalid image format: ' + image);
// three or more sections present: host, namespace and repo. According to Docker
// documentation, the most common case is to have two path components in the name of the
// repository, however, it is possible to have a different number of path segments:
// https://docs.docker.com/registry/spec/api/#overview
// We are going to treat the extra path arguments as part of the namespace, e.g. the
// repo name host:port/path/to/repo will have "host:port" for host, "path/to" for
// namespace and "repo" for name.

let host = parts[0];
let repo = parts[parts.length - 1];
let namespace = imageWithoutScheme.substring(host.length + SECTION_SEPARATOR.length,
imageWithoutScheme.length - repo.length - SECTION_SEPARATOR.length);
return getImageNamespaceAndNameFromParts(namespace, repo);
}
},

Expand Down
3 changes: 2 additions & 1 deletion ui/app/src/test/unit/core/imageUtilsTest.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 VMware, Inc. All Rights Reserved.
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
Expand All @@ -14,6 +14,7 @@ import imageUtils from 'core/imageUtils';
describe('image utils test', function() {
describe('getImageNamespaceAndName', function() {
it('should parse namespace and name', function() {
expect(imageUtils.getImageNamespaceAndName('http://private-registry.com/ns/category/imagename:tag')).toEqual('ns/category/imagename');
expect(imageUtils.getImageNamespaceAndName('http://private-registry.com/ns/imagename:tag')).toEqual('ns/imagename');
expect(imageUtils.getImageNamespaceAndName('http://private-registry.com/imagename:tag')).toEqual('imagename');
expect(imageUtils.getImageNamespaceAndName('ns/imagename:tag')).toEqual('ns/imagename');
Expand Down

0 comments on commit 5866277

Please sign in to comment.