github.com/cloudfoundry-attic/ltc@v0.0.0-20151123212628-098adc7919fc/docker_runner/docker_repository_name_formatter/docker_repository_name_formatter.go (about) 1 package docker_repository_name_formatter 2 3 import ( 4 "fmt" 5 "net/url" 6 "strings" 7 8 "github.com/docker/docker/registry" 9 ) 10 11 const ( 12 DockerScheme = "docker" 13 DockerIndexServer = "docker.io" 14 ) 15 16 func FormatForReceptor(dockerPath string) (string, error) { 17 return convertDockerURI(dockerPath) 18 } 19 20 func ParseRepoNameAndTagFromImageReference(dockerPath string) (string, string, string, error) { 21 return parseDockerRepoUrl(dockerPath) 22 } 23 24 func convertDockerURI(dockerURI string) (string, error) { 25 if strings.Contains(dockerURI, "://") { 26 return "", fmt.Errorf("docker URI [%s] should not contain scheme", dockerURI) 27 } 28 29 indexName, remoteName, tag, err := parseDockerRepoUrl(dockerURI) 30 if err != nil { 31 return "", err 32 } 33 34 return (&url.URL{ 35 Scheme: DockerScheme, 36 Path: indexName + "/" + remoteName, 37 Fragment: tag, 38 }).String(), nil 39 } 40 41 // via https://github.com/docker/docker/blob/a271eaeba224652e3a12af0287afbae6f82a9333/registry/config.go#L295 42 func parseDockerRepoUrl(dockerURI string) (indexName, remoteName, tag string, err error) { 43 nameParts := strings.SplitN(dockerURI, "/", 2) 44 45 if officialRegistry(nameParts) { 46 // URI without host 47 indexName = "" 48 remoteName = dockerURI 49 50 // URI has format docker.io/<path> 51 if nameParts[0] == DockerIndexServer { 52 indexName = DockerIndexServer 53 remoteName = nameParts[1] 54 } 55 56 // Remote name contain no '/' - prefix it with "library/" 57 // via https://github.com/docker/docker/blob/a271eaeba224652e3a12af0287afbae6f82a9333/registry/config.go#L343 58 if strings.IndexRune(remoteName, '/') == -1 { 59 remoteName = "library/" + remoteName 60 } 61 } else { 62 indexName = nameParts[0] 63 remoteName = nameParts[1] 64 } 65 66 remoteName, tag = parseDockerRepositoryTag(remoteName) 67 68 _, err = registry.ParseRepositoryInfo(remoteName) 69 if err != nil { 70 return "", "", "", err 71 } 72 73 return indexName, remoteName, tag, nil 74 } 75 76 func officialRegistry(nameParts []string) bool { 77 return len(nameParts) == 1 || 78 nameParts[0] == DockerIndexServer || 79 (!strings.Contains(nameParts[0], ".") && 80 !strings.Contains(nameParts[0], ":") && 81 nameParts[0] != "localhost") 82 } 83 84 // via https://github.com/docker/docker/blob/4398108/pkg/parsers/parsers.go#L72 85 func parseDockerRepositoryTag(remoteName string) (string, string) { 86 n := strings.LastIndex(remoteName, ":") 87 if n < 0 { 88 return remoteName, "latest" // before: remoteName, "" 89 } 90 91 if tag := remoteName[n+1:]; !strings.Contains(tag, "/") { 92 return remoteName[:n], tag 93 } 94 95 return remoteName, "" 96 }