2016-07-14 09:37:11 +08:00
|
|
|
|
package directory
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2018-02-23 17:45:56 +08:00
|
|
|
|
"context"
|
2016-07-14 09:37:11 +08:00
|
|
|
|
"os"
|
2016-07-12 23:10:03 +08:00
|
|
|
|
"path/filepath"
|
2016-07-14 09:37:11 +08:00
|
|
|
|
"testing"
|
|
|
|
|
|
|
2019-10-26 04:27:45 +08:00
|
|
|
|
_ "github.com/containers/image/v5/internal/testing/explicitfilepath-tmpdir"
|
|
|
|
|
|
"github.com/containers/image/v5/types"
|
Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.
Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.
Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.
Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.
When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.
When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made). If
neither has changed, then we don't need to change the encoded value of
the manifest.
When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.
When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.
When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.
Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.
Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.
Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.
Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context. The logic is
already in place to enable locating an image using any of multiple
manifest digests.
When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name. That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.
Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.
Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.
Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2018-01-09 14:03:18 +08:00
|
|
|
|
digest "github.com/opencontainers/go-digest"
|
2016-07-14 09:37:11 +08:00
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func TestTransportName(t *testing.T) {
|
|
|
|
|
|
assert.Equal(t, "dir", Transport.Name())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestTransportParseReference(t *testing.T) {
|
|
|
|
|
|
testNewReference(t, Transport.ParseReference)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-19 01:16:06 +08:00
|
|
|
|
func TestTransportValidatePolicyConfigurationScope(t *testing.T) {
|
|
|
|
|
|
for _, scope := range []string{
|
|
|
|
|
|
"/etc",
|
|
|
|
|
|
"/this/does/not/exist",
|
|
|
|
|
|
} {
|
|
|
|
|
|
err := Transport.ValidatePolicyConfigurationScope(scope)
|
|
|
|
|
|
assert.NoError(t, err, scope)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, scope := range []string{
|
|
|
|
|
|
"relative/path",
|
2016-08-02 23:03:24 +08:00
|
|
|
|
"/double//slashes",
|
|
|
|
|
|
"/has/./dot",
|
|
|
|
|
|
"/has/dot/../dot",
|
|
|
|
|
|
"/trailing/slash/",
|
2016-07-19 01:16:06 +08:00
|
|
|
|
"/",
|
|
|
|
|
|
} {
|
|
|
|
|
|
err := Transport.ValidatePolicyConfigurationScope(scope)
|
|
|
|
|
|
assert.Error(t, err, scope)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-14 09:37:11 +08:00
|
|
|
|
func TestNewReference(t *testing.T) {
|
2016-07-12 23:10:03 +08:00
|
|
|
|
testNewReference(t, NewReference)
|
2016-07-14 09:37:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// testNewReference is a test shared for Transport.ParseReference and NewReference.
|
|
|
|
|
|
func testNewReference(t *testing.T, fn func(string) (types.ImageReference, error)) {
|
2022-03-16 07:36:21 +08:00
|
|
|
|
tmpDir := t.TempDir()
|
2016-07-14 09:37:11 +08:00
|
|
|
|
|
|
|
|
|
|
for _, path := range []string{
|
|
|
|
|
|
"/",
|
|
|
|
|
|
"/etc",
|
|
|
|
|
|
tmpDir,
|
|
|
|
|
|
"relativepath",
|
|
|
|
|
|
tmpDir + "/thisdoesnotexist",
|
|
|
|
|
|
} {
|
|
|
|
|
|
ref, err := fn(path)
|
|
|
|
|
|
require.NoError(t, err, path)
|
|
|
|
|
|
dirRef, ok := ref.(dirReference)
|
|
|
|
|
|
require.True(t, ok)
|
|
|
|
|
|
assert.Equal(t, path, dirRef.path, path)
|
|
|
|
|
|
}
|
2016-07-12 23:10:03 +08:00
|
|
|
|
|
2022-03-16 07:36:21 +08:00
|
|
|
|
_, err := fn(tmpDir + "/thisparentdoesnotexist/something")
|
2016-07-12 23:10:03 +08:00
|
|
|
|
assert.Error(t, err)
|
2016-07-14 09:37:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// refToTempDir creates a temporary directory and returns a reference to it.
|
2022-03-16 07:36:21 +08:00
|
|
|
|
func refToTempDir(t *testing.T) (types.ImageReference, string) {
|
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
|
ref, err := NewReference(tmpDir)
|
2016-07-12 23:10:03 +08:00
|
|
|
|
require.NoError(t, err)
|
2016-07-14 09:37:11 +08:00
|
|
|
|
return ref, tmpDir
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestReferenceTransport(t *testing.T) {
|
2022-03-16 07:36:21 +08:00
|
|
|
|
ref, _ := refToTempDir(t)
|
2016-07-14 09:37:11 +08:00
|
|
|
|
assert.Equal(t, Transport, ref.Transport())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestReferenceStringWithinTransport(t *testing.T) {
|
|
|
|
|
|
ref, tmpDir := refToTempDir(t)
|
|
|
|
|
|
assert.Equal(t, tmpDir, ref.StringWithinTransport())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-14 09:38:27 +08:00
|
|
|
|
func TestReferenceDockerReference(t *testing.T) {
|
2022-03-16 07:36:21 +08:00
|
|
|
|
ref, _ := refToTempDir(t)
|
2016-07-14 09:38:27 +08:00
|
|
|
|
assert.Nil(t, ref.DockerReference())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-15 01:55:37 +08:00
|
|
|
|
func TestReferencePolicyConfigurationIdentity(t *testing.T) {
|
|
|
|
|
|
ref, tmpDir := refToTempDir(t)
|
2016-07-12 23:10:03 +08:00
|
|
|
|
|
|
|
|
|
|
assert.Equal(t, tmpDir, ref.PolicyConfigurationIdentity())
|
|
|
|
|
|
// A non-canonical path. Test just one, the various other cases are
|
|
|
|
|
|
// tested in explicitfilepath.ResolvePathToFullyExplicit.
|
|
|
|
|
|
ref, err := NewReference(tmpDir + "/.")
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, tmpDir, ref.PolicyConfigurationIdentity())
|
|
|
|
|
|
|
|
|
|
|
|
// "/" as a corner case.
|
|
|
|
|
|
ref, err = NewReference("/")
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, "/", ref.PolicyConfigurationIdentity())
|
2016-07-15 01:55:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestReferencePolicyConfigurationNamespaces(t *testing.T) {
|
|
|
|
|
|
ref, tmpDir := refToTempDir(t)
|
2016-07-12 23:10:03 +08:00
|
|
|
|
// We don't really know enough to make a full equality test here.
|
|
|
|
|
|
ns := ref.PolicyConfigurationNamespaces()
|
|
|
|
|
|
require.NotNil(t, ns)
|
|
|
|
|
|
assert.NotEmpty(t, ns)
|
|
|
|
|
|
assert.Equal(t, filepath.Dir(tmpDir), ns[0])
|
|
|
|
|
|
|
|
|
|
|
|
// Test with a known path which should exist. Test just one non-canonical
|
|
|
|
|
|
// path, the various other cases are tested in explicitfilepath.ResolvePathToFullyExplicit.
|
|
|
|
|
|
//
|
|
|
|
|
|
// It would be nice to test a deeper hierarchy, but it is not obvious what
|
|
|
|
|
|
// deeper path is always available in the various distros, AND is not likely
|
|
|
|
|
|
// to contains a symbolic link.
|
2017-08-30 03:26:23 +08:00
|
|
|
|
for _, path := range []string{"/usr/share", "/usr/share/./."} {
|
2016-07-12 23:10:03 +08:00
|
|
|
|
_, err := os.Lstat(path)
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
ref, err := NewReference(path)
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
ns := ref.PolicyConfigurationNamespaces()
|
|
|
|
|
|
require.NotNil(t, ns)
|
2017-08-30 03:26:23 +08:00
|
|
|
|
assert.Equal(t, []string{"/usr"}, ns)
|
2016-07-12 23:10:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// "/" as a corner case.
|
|
|
|
|
|
ref, err := NewReference("/")
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, []string{}, ref.PolicyConfigurationNamespaces())
|
2016-07-15 01:55:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-14 09:37:11 +08:00
|
|
|
|
func TestReferenceNewImage(t *testing.T) {
|
2022-03-16 07:36:21 +08:00
|
|
|
|
ref, _ := refToTempDir(t)
|
2016-10-07 04:49:16 +08:00
|
|
|
|
|
2018-02-23 17:45:56 +08:00
|
|
|
|
dest, err := ref.NewImageDestination(context.Background(), nil)
|
2016-10-07 04:49:16 +08:00
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
defer dest.Close()
|
2022-04-14 01:33:42 +08:00
|
|
|
|
mFixture, err := os.ReadFile("../manifest/fixtures/v2s1.manifest.json")
|
2016-10-29 00:07:29 +08:00
|
|
|
|
require.NoError(t, err)
|
Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.
Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.
Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.
Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.
When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.
When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made). If
neither has changed, then we don't need to change the encoded value of
the manifest.
When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.
When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.
When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.
Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.
Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.
Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.
Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context. The logic is
already in place to enable locating an image using any of multiple
manifest digests.
When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name. That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.
Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.
Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.
Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2018-01-09 14:03:18 +08:00
|
|
|
|
err = dest.PutManifest(context.Background(), mFixture, nil)
|
2016-10-07 04:49:16 +08:00
|
|
|
|
assert.NoError(t, err)
|
2021-06-12 23:23:45 +08:00
|
|
|
|
err = dest.Commit(context.Background(), nil) // nil unparsedToplevel is invalid, we don’t currently use the value
|
2016-10-07 04:49:16 +08:00
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
2018-02-23 17:45:56 +08:00
|
|
|
|
img, err := ref.NewImage(context.Background(), nil)
|
2016-07-14 09:37:11 +08:00
|
|
|
|
assert.NoError(t, err)
|
2016-08-27 05:24:39 +08:00
|
|
|
|
defer img.Close()
|
2016-07-14 09:37:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-29 00:07:29 +08:00
|
|
|
|
func TestReferenceNewImageNoValidManifest(t *testing.T) {
|
2022-03-16 07:36:21 +08:00
|
|
|
|
ref, _ := refToTempDir(t)
|
2016-10-29 00:07:29 +08:00
|
|
|
|
|
2018-02-23 17:45:56 +08:00
|
|
|
|
dest, err := ref.NewImageDestination(context.Background(), nil)
|
2016-10-29 00:07:29 +08:00
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
defer dest.Close()
|
Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.
Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.
Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.
Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.
When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.
When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made). If
neither has changed, then we don't need to change the encoded value of
the manifest.
When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.
When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.
When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.
Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.
Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.
Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.
Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context. The logic is
already in place to enable locating an image using any of multiple
manifest digests.
When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name. That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.
Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.
Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.
Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2018-01-09 14:03:18 +08:00
|
|
|
|
err = dest.PutManifest(context.Background(), []byte(`{"schemaVersion":1}`), nil)
|
2016-10-29 00:07:29 +08:00
|
|
|
|
assert.NoError(t, err)
|
2021-06-12 23:23:45 +08:00
|
|
|
|
err = dest.Commit(context.Background(), nil) // nil unparsedToplevel is invalid, we don’t currently use the value
|
2016-10-29 00:07:29 +08:00
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
2018-02-23 17:45:56 +08:00
|
|
|
|
_, err = ref.NewImage(context.Background(), nil)
|
2016-10-29 00:07:29 +08:00
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-14 09:37:11 +08:00
|
|
|
|
func TestReferenceNewImageSource(t *testing.T) {
|
2022-03-16 07:36:21 +08:00
|
|
|
|
ref, _ := refToTempDir(t)
|
2018-02-23 17:45:56 +08:00
|
|
|
|
src, err := ref.NewImageSource(context.Background(), nil)
|
2016-07-14 09:37:11 +08:00
|
|
|
|
assert.NoError(t, err)
|
2016-08-27 05:24:39 +08:00
|
|
|
|
defer src.Close()
|
2016-07-14 09:37:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestReferenceNewImageDestination(t *testing.T) {
|
2022-03-16 07:36:21 +08:00
|
|
|
|
ref, _ := refToTempDir(t)
|
2018-02-23 17:45:56 +08:00
|
|
|
|
dest, err := ref.NewImageDestination(context.Background(), nil)
|
2016-07-14 09:37:11 +08:00
|
|
|
|
assert.NoError(t, err)
|
2016-09-06 04:10:47 +08:00
|
|
|
|
defer dest.Close()
|
2016-07-14 09:37:11 +08:00
|
|
|
|
}
|
2016-07-09 11:24:41 +08:00
|
|
|
|
|
2016-08-25 06:07:47 +08:00
|
|
|
|
func TestReferenceDeleteImage(t *testing.T) {
|
2022-03-16 07:36:21 +08:00
|
|
|
|
ref, _ := refToTempDir(t)
|
2018-02-23 17:45:56 +08:00
|
|
|
|
err := ref.DeleteImage(context.Background(), nil)
|
2016-08-25 06:07:47 +08:00
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-09 11:24:41 +08:00
|
|
|
|
func TestReferenceManifestPath(t *testing.T) {
|
Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.
Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.
Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.
Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.
When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.
When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made). If
neither has changed, then we don't need to change the encoded value of
the manifest.
When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.
When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.
When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.
Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.
Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.
Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.
Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context. The logic is
already in place to enable locating an image using any of multiple
manifest digests.
When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name. That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.
Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.
Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.
Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2018-01-09 14:03:18 +08:00
|
|
|
|
dhex := digest.Digest("sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
|
|
|
|
|
|
|
2016-07-09 11:24:41 +08:00
|
|
|
|
ref, tmpDir := refToTempDir(t)
|
|
|
|
|
|
dirRef, ok := ref.(dirReference)
|
|
|
|
|
|
require.True(t, ok)
|
2024-04-18 04:26:46 +08:00
|
|
|
|
res, err := dirRef.manifestPath(nil)
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, tmpDir+"/manifest.json", res)
|
|
|
|
|
|
res, err = dirRef.manifestPath(&dhex)
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, tmpDir+"/"+dhex.Encoded()+".manifest.json", res)
|
|
|
|
|
|
invalidDigest := digest.Digest("sha256:../hello")
|
|
|
|
|
|
_, err = dirRef.manifestPath(&invalidDigest)
|
|
|
|
|
|
assert.Error(t, err)
|
2016-07-09 11:24:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestReferenceLayerPath(t *testing.T) {
|
|
|
|
|
|
const hex = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
|
|
|
|
|
|
|
|
|
|
ref, tmpDir := refToTempDir(t)
|
|
|
|
|
|
dirRef, ok := ref.(dirReference)
|
|
|
|
|
|
require.True(t, ok)
|
2024-04-18 04:26:46 +08:00
|
|
|
|
res, err := dirRef.layerPath("sha256:" + hex)
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, tmpDir+"/"+hex, res)
|
|
|
|
|
|
_, err = dirRef.layerPath(digest.Digest("sha256:../hello"))
|
|
|
|
|
|
assert.Error(t, err)
|
2016-07-09 11:24:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestReferenceSignaturePath(t *testing.T) {
|
Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.
Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.
Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.
Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.
When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.
When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made). If
neither has changed, then we don't need to change the encoded value of
the manifest.
When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.
When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.
When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.
Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.
Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.
Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.
Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context. The logic is
already in place to enable locating an image using any of multiple
manifest digests.
When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name. That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.
Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.
Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.
Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2018-01-09 14:03:18 +08:00
|
|
|
|
dhex := digest.Digest("sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
|
|
|
|
|
|
|
2016-07-09 11:24:41 +08:00
|
|
|
|
ref, tmpDir := refToTempDir(t)
|
|
|
|
|
|
dirRef, ok := ref.(dirReference)
|
|
|
|
|
|
require.True(t, ok)
|
2024-04-18 04:26:46 +08:00
|
|
|
|
res, err := dirRef.signaturePath(0, nil)
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, tmpDir+"/signature-1", res)
|
|
|
|
|
|
res, err = dirRef.signaturePath(9, nil)
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, tmpDir+"/signature-10", res)
|
|
|
|
|
|
res, err = dirRef.signaturePath(0, &dhex)
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, tmpDir+"/"+dhex.Encoded()+".signature-1", res)
|
|
|
|
|
|
res, err = dirRef.signaturePath(9, &dhex)
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
assert.Equal(t, tmpDir+"/"+dhex.Encoded()+".signature-10", res)
|
|
|
|
|
|
invalidDigest := digest.Digest("sha256:../hello")
|
|
|
|
|
|
_, err = dirRef.signaturePath(0, &invalidDigest)
|
|
|
|
|
|
assert.Error(t, err)
|
2016-07-09 11:24:41 +08:00
|
|
|
|
}
|
2017-11-07 04:58:55 +08:00
|
|
|
|
|
|
|
|
|
|
func TestReferenceVersionPath(t *testing.T) {
|
|
|
|
|
|
ref, tmpDir := refToTempDir(t)
|
|
|
|
|
|
dirRef, ok := ref.(dirReference)
|
|
|
|
|
|
require.True(t, ok)
|
|
|
|
|
|
assert.Equal(t, tmpDir+"/version", dirRef.versionPath())
|
|
|
|
|
|
}
|