Skip to content

Commit 9514429

Browse files
committed
refactor: sha256 and tag parser refactored. Digest's hash value moved to function parse_docker_uri
1 parent 4db8316 commit 9514429

File tree

3 files changed

+25
-18
lines changed

3 files changed

+25
-18
lines changed

lib/cloud_controller/diego/docker/docker_uri_converter.rb

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@ module VCAP::CloudController
44
class DockerURIConverter
55
def convert(docker_uri)
66
raise UriUtils::InvalidDockerURI.new "Docker URI [#{docker_uri}] should not contain scheme" if docker_uri.include? '://'
7+
host, path, tag_digest = UriUtils.parse_docker_uri(docker_uri)
78

8-
host, path, tag = UriUtils.parse_docker_uri(docker_uri)
9-
10-
if !tag.nil? && tag.start_with?('@sha256:')
11-
path = "#{path}@sha256"
12-
tag.slice!('@sha256:')
13-
end
14-
15-
Addressable::URI.new(scheme: 'docker', host: host, path: path, fragment: tag).to_s
9+
# add tag or digest part as fragment to the uri, since ruby uri parser confuses with ':'
10+
# when it presented in path. We convert user's uri to, for example;
11+
# docker://docker.io/publish/ubuntu:latest -> docker://docker.io/publish/ubuntu#latest
12+
Addressable::URI.new(scheme: 'docker', host: host, path: path, fragment: tag_digest).to_s
1613
end
1714
end
1815
end

lib/utils/uri_utils.rb

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ module UriUtils
44
SSH_REGEX = %r{ \A (?:ssh://)? git@ .+? : .+? \.git \z }x
55
GIT_REGEX = %r{ \A git:// .+? : .+? \.git \z }x
66
DOCKER_INDEX_SERVER = 'docker.io'.freeze
7+
DOCKER_PATH_REGEX = %r{\A[a-z0-9_\-\.\/]{2,255}\Z}
8+
DOCKER_TAG_REGEX = %r{[a-zA-Z0-9_\-\.]{1,128}}
9+
DOCKER_DIGEST_REGEX = %r{sha256:[a-z0-9]{64}}
10+
DOCKER_TAG_DIGEST_REGEX = Regexp.new("\\A(#{DOCKER_TAG_REGEX.source} | (#{DOCKER_TAG_REGEX.source}@#{DOCKER_DIGEST_REGEX.source}) | #{DOCKER_DIGEST_REGEX.source})\\Z", Regexp::EXTENDED)
711

812
class InvalidDockerURI < StandardError; end
913

@@ -62,13 +66,20 @@ def self.parse_docker_uri(docker_uri)
6266
end
6367

6468
path = 'library/' + path if (official_docker_registry(name_parts[0]) || missing_registry(name_parts)) && path.exclude?('/')
69+
path, tag_digest = parse_docker_tag_or_digest_from_path(path)
6570

66-
path, tag = parse_docker_repository_tag(path)
71+
raise InvalidDockerURI.new "Invalid image name [#{path}]" unless DOCKER_PATH_REGEX =~ path
72+
raise InvalidDockerURI.new "Invalid image tag [#{tag_digest}]" if tag_digest && !(DOCKER_TAG_DIGEST_REGEX =~ tag_digest)
6773

68-
raise InvalidDockerURI.new "Invalid image name [#{path}]" unless %r{\A[a-z0-9_\-\.\/]{2,255}\Z} =~ path
69-
raise InvalidDockerURI.new "Invalid image tag [#{tag}]" if tag && !(/\A(([a-zA-Z0-9_\-\.]{1,128})|(([a-zA-Z0-9_\-\.]{0,128})(@sha256:[a-z0-9]{64})))\Z/ =~ tag)
74+
# if only sha256 presented, we add hash value as fragment to the uri,
75+
# since the ruby uri parser confuses because of second ':' in uri's path part.
76+
if tag_digest && tag_digest.start_with?("sha256:")
77+
hash_algo, hash_value = tag_digest.split(":")
78+
path = path + "@sha256"
79+
tag_digest = hash_value
80+
end
7081

71-
[host, path, tag]
82+
[host, path, tag_digest]
7283
end
7384

7485
private_class_method def self.official_docker_registry(host)
@@ -78,13 +89,12 @@ def self.parse_docker_uri(docker_uri)
7889
private_class_method def self.missing_registry(name_parts)
7990
host = name_parts[0]
8091
name_parts.length == 1 ||
81-
(host.exclude?('.') && host.exclude?(':') && host != 'localhost')
92+
(host.exclude?('.') && host.exclude?(':') && host != 'localhost')
8293
end
8394

84-
private_class_method def self.parse_docker_repository_tag(path)
85-
path, tag = path.split(/(?=@)|:/, 2)
86-
87-
return [path, tag] unless tag && tag.include?('/')
95+
private_class_method def self.parse_docker_tag_or_digest_from_path(path)
96+
path, tag_digest = path.split(/@|:/, 2)
97+
return [path, tag_digest] unless tag_digest && tag_digest.include?('/')
8898

8999
[path, 'latest']
90100
end

spec/unit/lib/utils/uri_utils_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@
159159
expect(UriUtils.parse_docker_uri('publish/buildpack:tag')).to eq ['', 'publish/buildpack', 'tag']
160160

161161
actual_result = UriUtils.parse_docker_uri('publish/buildpack@sha256:e118d023acaee5cf13471ead39f68416ad6172ff0899f3257ce1481cd2b28a6a')
162-
expected_result = ['', 'publish/buildpack', '@sha256:e118d023acaee5cf13471ead39f68416ad6172ff0899f3257ce1481cd2b28a6a']
162+
expected_result = ['', 'publish/buildpack@sha256', 'e118d023acaee5cf13471ead39f68416ad6172ff0899f3257ce1481cd2b28a6a']
163163
expect(actual_result).to eq expected_result
164164

165165
actual_result = UriUtils.parse_docker_uri('publish/buildpack:tag@sha256:e118d023acaee5cf13471ead39f68416ad6172ff0899f3257ce1481cd2b28a6a')

0 commit comments

Comments
 (0)