Merge pull request #2786 from thaJeztah/add_normalize_util
Add reference. ParseDockerRef utility functionmaster
						commit
						411d6bcfd2
					
				|  | @ -56,6 +56,35 @@ func ParseNormalizedNamed(s string) (Named, error) { | ||||||
| 	return named, nil | 	return named, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // ParseDockerRef normalizes the image reference following the docker convention. This is added
 | ||||||
|  | // mainly for backward compatibility.
 | ||||||
|  | // The reference returned can only be either tagged or digested. For reference contains both tag
 | ||||||
|  | // and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@
 | ||||||
|  | // sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as
 | ||||||
|  | // docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa.
 | ||||||
|  | func ParseDockerRef(ref string) (Named, error) { | ||||||
|  | 	named, err := ParseNormalizedNamed(ref) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	if _, ok := named.(NamedTagged); ok { | ||||||
|  | 		if canonical, ok := named.(Canonical); ok { | ||||||
|  | 			// The reference is both tagged and digested, only
 | ||||||
|  | 			// return digested.
 | ||||||
|  | 			newNamed, err := WithName(canonical.Name()) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 			newCanonical, err := WithDigest(newNamed, canonical.Digest()) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 			return newCanonical, nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return TagNameOnly(named), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // splitDockerDomain splits a repository name to domain and remotename string.
 | // splitDockerDomain splits a repository name to domain and remotename string.
 | ||||||
| // If no valid domain is found, the default domain is used. Repository name
 | // If no valid domain is found, the default domain is used. Repository name
 | ||||||
| // needs to be already validated before.
 | // needs to be already validated before.
 | ||||||
|  |  | ||||||
|  | @ -623,3 +623,83 @@ func TestMatch(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func TestParseDockerRef(t *testing.T) { | ||||||
|  | 	testcases := []struct { | ||||||
|  | 		name     string | ||||||
|  | 		input    string | ||||||
|  | 		expected string | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			name:     "nothing", | ||||||
|  | 			input:    "busybox", | ||||||
|  | 			expected: "docker.io/library/busybox:latest", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "tag only", | ||||||
|  | 			input:    "busybox:latest", | ||||||
|  | 			expected: "docker.io/library/busybox:latest", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "digest only", | ||||||
|  | 			input:    "busybox@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582", | ||||||
|  | 			expected: "docker.io/library/busybox@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "path only", | ||||||
|  | 			input:    "library/busybox", | ||||||
|  | 			expected: "docker.io/library/busybox:latest", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "hostname only", | ||||||
|  | 			input:    "docker.io/busybox", | ||||||
|  | 			expected: "docker.io/library/busybox:latest", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "no tag", | ||||||
|  | 			input:    "docker.io/library/busybox", | ||||||
|  | 			expected: "docker.io/library/busybox:latest", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "no path", | ||||||
|  | 			input:    "docker.io/busybox:latest", | ||||||
|  | 			expected: "docker.io/library/busybox:latest", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "no hostname", | ||||||
|  | 			input:    "library/busybox:latest", | ||||||
|  | 			expected: "docker.io/library/busybox:latest", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "full reference with tag", | ||||||
|  | 			input:    "docker.io/library/busybox:latest", | ||||||
|  | 			expected: "docker.io/library/busybox:latest", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "gcr reference without tag", | ||||||
|  | 			input:    "gcr.io/library/busybox", | ||||||
|  | 			expected: "gcr.io/library/busybox:latest", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:     "both tag and digest", | ||||||
|  | 			input:    "gcr.io/library/busybox:latest@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582", | ||||||
|  | 			expected: "gcr.io/library/busybox@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	for _, test := range testcases { | ||||||
|  | 		t.Run(test.name, func(t *testing.T) { | ||||||
|  | 			normalized, err := ParseDockerRef(test.input) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatal(err) | ||||||
|  | 			} | ||||||
|  | 			output := normalized.String() | ||||||
|  | 			if output != test.expected { | ||||||
|  | 				t.Fatalf("expected %q to be parsed as %v, got %v", test.input, test.expected, output) | ||||||
|  | 			} | ||||||
|  | 			_, err = Parse(output) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("%q should be a valid reference, but got an error: %v", output, err) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue