mirror of
https://github.com/containers/podman.git
synced 2026-03-17 22:28:22 -04:00
Add imageParts.referenceWithRegistry
This is the primary goal of decompose()+assemble(), to support qualifying an image name. Does not have any users yet, so does not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/docker/reference"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// imageParts describes the parts of an image's name
|
||||
@@ -76,6 +77,23 @@ func decompose(input string) (imageParts, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// referenceWithRegistry returns a (normalized) reference.Named composed of ip (with !ip.hasRegistry)
|
||||
// qualified with registry.
|
||||
func (ip *imageParts) referenceWithRegistry(registry string) (reference.Named, error) {
|
||||
if ip.hasRegistry {
|
||||
return nil, errors.Errorf("internal error: referenceWithRegistry called on imageParts with a registry (%#v)", *ip)
|
||||
}
|
||||
// We could build a reference.WithName+WithTag/WithDigest here, but we need to round-trip via a string
|
||||
// and a ParseNormalizedNamed anyway to get the right normalization of docker.io/library, so
|
||||
// just use a string directly.
|
||||
qualified := registry + "/" + ip.unnormalizedRef.String()
|
||||
ref, err := reference.ParseNormalizedNamed(qualified)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error normalizing registry+unqualified reference %#v", qualified)
|
||||
}
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
// assemble concatenates an image's parts into a string
|
||||
func (ip *imageParts) assemble() string {
|
||||
spec := fmt.Sprintf("%s:%s", ip.name, ip.tag)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDecompose(t *testing.T) {
|
||||
@@ -62,3 +63,44 @@ func TestDecompose(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestImagePartsReferenceWithRegistry(t *testing.T) {
|
||||
const digestSuffix = "@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
|
||||
for _, c := range []struct {
|
||||
input string
|
||||
withDocker, withNonDocker string
|
||||
}{
|
||||
{"example.com/ns/busybox", "", ""}, // Fully-qualified input is invalid.
|
||||
{"busybox", "docker.io/library/busybox", "example.com/busybox"}, // Single-name input
|
||||
{"ns/busybox", "docker.io/ns/busybox", "example.com/ns/busybox"}, // Namespaced input
|
||||
{"ns/busybox:notlatest", "docker.io/ns/busybox:notlatest", "example.com/ns/busybox:notlatest"}, // name:tag
|
||||
{"ns/busybox" + digestSuffix, "docker.io/ns/busybox" + digestSuffix, "example.com/ns/busybox" + digestSuffix}, // name@digest
|
||||
{ // name:tag@digest
|
||||
"ns/busybox:notlatest" + digestSuffix,
|
||||
"docker.io/ns/busybox:notlatest" + digestSuffix, "example.com/ns/busybox:notlatest" + digestSuffix,
|
||||
},
|
||||
} {
|
||||
parts, err := decompose(c.input)
|
||||
require.NoError(t, err)
|
||||
if c.withDocker == "" {
|
||||
_, err := parts.referenceWithRegistry("docker.io")
|
||||
assert.Error(t, err, c.input)
|
||||
_, err = parts.referenceWithRegistry("example.com")
|
||||
assert.Error(t, err, c.input)
|
||||
} else {
|
||||
ref, err := parts.referenceWithRegistry("docker.io")
|
||||
require.NoError(t, err, c.input)
|
||||
assert.Equal(t, c.withDocker, ref.String())
|
||||
ref, err = parts.referenceWithRegistry("example.com")
|
||||
require.NoError(t, err, c.input)
|
||||
assert.Equal(t, c.withNonDocker, ref.String())
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid registry value
|
||||
parts, err := decompose("busybox")
|
||||
require.NoError(t, err)
|
||||
_, err = parts.referenceWithRegistry("invalid@domain")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user