Bump github.com/containers/image@efae299
Update the vendored copy of github.com/containers/image to revision efae29995d4846ffa6163eb4d466fd61bda43aae. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
parent
7c551964c0
commit
3d15bc571b
26 changed files with 2095 additions and 571 deletions
57
vendor/github.com/containers/image/docker/archive/dest.go
generated
vendored
Normal file
57
vendor/github.com/containers/image/docker/archive/dest.go
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
package archive
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/containers/image/docker/tarfile"
|
||||
"github.com/containers/image/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type archiveImageDestination struct {
|
||||
*tarfile.Destination // Implements most of types.ImageDestination
|
||||
ref archiveReference
|
||||
writer io.Closer
|
||||
}
|
||||
|
||||
func newImageDestination(ctx *types.SystemContext, ref archiveReference) (types.ImageDestination, error) {
|
||||
if ref.destinationRef == nil {
|
||||
return nil, errors.Errorf("docker-archive: destination reference not supplied (must be of form <path>:<reference:tag>)")
|
||||
}
|
||||
fh, err := os.OpenFile(ref.path, os.O_WRONLY|os.O_EXCL|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
// FIXME: It should be possible to modify archives, but the only really
|
||||
// sane way of doing it is to create a copy of the image, modify
|
||||
// it and then do a rename(2).
|
||||
if os.IsExist(err) {
|
||||
err = errors.New("docker-archive doesn't support modifying existing images")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &archiveImageDestination{
|
||||
Destination: tarfile.NewDestination(fh, ref.destinationRef),
|
||||
ref: ref,
|
||||
writer: fh,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Reference returns the reference used to set up this destination. Note that this should directly correspond to user's intent,
|
||||
// e.g. it should use the public hostname instead of the result of resolving CNAMEs or following redirects.
|
||||
func (d *archiveImageDestination) Reference() types.ImageReference {
|
||||
return d.ref
|
||||
}
|
||||
|
||||
// Close removes resources associated with an initialized ImageDestination, if any.
|
||||
func (d *archiveImageDestination) Close() error {
|
||||
return d.writer.Close()
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *archiveImageDestination) Commit() error {
|
||||
return d.Destination.Commit()
|
||||
}
|
BIN
vendor/github.com/containers/image/docker/archive/fixtures/almostempty.tar
generated
vendored
Normal file
BIN
vendor/github.com/containers/image/docker/archive/fixtures/almostempty.tar
generated
vendored
Normal file
Binary file not shown.
36
vendor/github.com/containers/image/docker/archive/src.go
generated
vendored
Normal file
36
vendor/github.com/containers/image/docker/archive/src.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
package archive
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/containers/image/docker/tarfile"
|
||||
"github.com/containers/image/types"
|
||||
)
|
||||
|
||||
type archiveImageSource struct {
|
||||
*tarfile.Source // Implements most of types.ImageSource
|
||||
ref archiveReference
|
||||
}
|
||||
|
||||
// newImageSource returns a types.ImageSource for the specified image reference.
|
||||
// The caller must call .Close() on the returned ImageSource.
|
||||
func newImageSource(ctx *types.SystemContext, ref archiveReference) types.ImageSource {
|
||||
if ref.destinationRef != nil {
|
||||
logrus.Warnf("docker-archive: references are not supported for sources (ignoring)")
|
||||
}
|
||||
src := tarfile.NewSource(ref.path)
|
||||
return &archiveImageSource{
|
||||
Source: src,
|
||||
ref: ref,
|
||||
}
|
||||
}
|
||||
|
||||
// Reference returns the reference used to set up this source, _as specified by the user_
|
||||
// (not as the image itself, or its underlying storage, claims). This can be used e.g. to determine which public keys are trusted for this image.
|
||||
func (s *archiveImageSource) Reference() types.ImageReference {
|
||||
return s.ref
|
||||
}
|
||||
|
||||
// Close removes resources associated with an initialized ImageSource, if any.
|
||||
func (s *archiveImageSource) Close() error {
|
||||
return nil
|
||||
}
|
155
vendor/github.com/containers/image/docker/archive/transport.go
generated
vendored
Normal file
155
vendor/github.com/containers/image/docker/archive/transport.go
generated
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
package archive
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/docker/reference"
|
||||
ctrImage "github.com/containers/image/image"
|
||||
"github.com/containers/image/transports"
|
||||
"github.com/containers/image/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
transports.Register(Transport)
|
||||
}
|
||||
|
||||
// Transport is an ImageTransport for local Docker archives.
|
||||
var Transport = archiveTransport{}
|
||||
|
||||
type archiveTransport struct{}
|
||||
|
||||
func (t archiveTransport) Name() string {
|
||||
return "docker-archive"
|
||||
}
|
||||
|
||||
// ParseReference converts a string, which should not start with the ImageTransport.Name prefix, into an ImageReference.
|
||||
func (t archiveTransport) ParseReference(reference string) (types.ImageReference, error) {
|
||||
return ParseReference(reference)
|
||||
}
|
||||
|
||||
// ValidatePolicyConfigurationScope checks that scope is a valid name for a signature.PolicyTransportScopes keys
|
||||
// (i.e. a valid PolicyConfigurationIdentity() or PolicyConfigurationNamespaces() return value).
|
||||
// It is acceptable to allow an invalid value which will never be matched, it can "only" cause user confusion.
|
||||
// scope passed to this function will not be "", that value is always allowed.
|
||||
func (t archiveTransport) ValidatePolicyConfigurationScope(scope string) error {
|
||||
// See the explanation in archiveReference.PolicyConfigurationIdentity.
|
||||
return errors.New(`docker-archive: does not support any scopes except the default "" one`)
|
||||
}
|
||||
|
||||
// archiveReference is an ImageReference for Docker images.
|
||||
type archiveReference struct {
|
||||
destinationRef reference.NamedTagged // only used for destinations
|
||||
path string
|
||||
}
|
||||
|
||||
// ParseReference converts a string, which should not start with the ImageTransport.Name prefix, into an Docker ImageReference.
|
||||
func ParseReference(refString string) (types.ImageReference, error) {
|
||||
if refString == "" {
|
||||
return nil, errors.Errorf("docker-archive reference %s isn't of the form <path>[:<reference>]", refString)
|
||||
}
|
||||
|
||||
parts := strings.SplitN(refString, ":", 2)
|
||||
path := parts[0]
|
||||
var destinationRef reference.NamedTagged
|
||||
|
||||
// A :tag was specified, which is only necessary for destinations.
|
||||
if len(parts) == 2 {
|
||||
ref, err := reference.ParseNormalizedNamed(parts[1])
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "docker-archive parsing reference")
|
||||
}
|
||||
ref = reference.TagNameOnly(ref)
|
||||
|
||||
if _, isDigest := ref.(reference.Canonical); isDigest {
|
||||
return nil, errors.Errorf("docker-archive doesn't support digest references: %s", refString)
|
||||
}
|
||||
|
||||
refTagged, isTagged := ref.(reference.NamedTagged)
|
||||
if !isTagged {
|
||||
// Really shouldn't be hit...
|
||||
return nil, errors.Errorf("internal error: reference is not tagged even after reference.TagNameOnly: %s", refString)
|
||||
}
|
||||
destinationRef = refTagged
|
||||
}
|
||||
|
||||
return archiveReference{
|
||||
destinationRef: destinationRef,
|
||||
path: path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ref archiveReference) Transport() types.ImageTransport {
|
||||
return Transport
|
||||
}
|
||||
|
||||
// StringWithinTransport returns a string representation of the reference, which MUST be such that
|
||||
// reference.Transport().ParseReference(reference.StringWithinTransport()) returns an equivalent reference.
|
||||
// NOTE: The returned string is not promised to be equal to the original input to ParseReference;
|
||||
// e.g. default attribute values omitted by the user may be filled in in the return value, or vice versa.
|
||||
// WARNING: Do not use the return value in the UI to describe an image, it does not contain the Transport().Name() prefix.
|
||||
func (ref archiveReference) StringWithinTransport() string {
|
||||
if ref.destinationRef == nil {
|
||||
return ref.path
|
||||
}
|
||||
return fmt.Sprintf("%s:%s", ref.path, ref.destinationRef.String())
|
||||
}
|
||||
|
||||
// DockerReference returns a Docker reference associated with this reference
|
||||
// (fully explicit, i.e. !reference.IsNameOnly, but reflecting user intent,
|
||||
// not e.g. after redirect or alias processing), or nil if unknown/not applicable.
|
||||
func (ref archiveReference) DockerReference() reference.Named {
|
||||
return ref.destinationRef
|
||||
}
|
||||
|
||||
// PolicyConfigurationIdentity returns a string representation of the reference, suitable for policy lookup.
|
||||
// This MUST reflect user intent, not e.g. after processing of third-party redirects or aliases;
|
||||
// The value SHOULD be fully explicit about its semantics, with no hidden defaults, AND canonical
|
||||
// (i.e. various references with exactly the same semantics should return the same configuration identity)
|
||||
// It is fine for the return value to be equal to StringWithinTransport(), and it is desirable but
|
||||
// not required/guaranteed that it will be a valid input to Transport().ParseReference().
|
||||
// Returns "" if configuration identities for these references are not supported.
|
||||
func (ref archiveReference) PolicyConfigurationIdentity() string {
|
||||
// Punt, the justification is similar to dockerReference.PolicyConfigurationIdentity.
|
||||
return ""
|
||||
}
|
||||
|
||||
// PolicyConfigurationNamespaces returns a list of other policy configuration namespaces to search
|
||||
// for if explicit configuration for PolicyConfigurationIdentity() is not set. The list will be processed
|
||||
// in order, terminating on first match, and an implicit "" is always checked at the end.
|
||||
// It is STRONGLY recommended for the first element, if any, to be a prefix of PolicyConfigurationIdentity(),
|
||||
// and each following element to be a prefix of the element preceding it.
|
||||
func (ref archiveReference) PolicyConfigurationNamespaces() []string {
|
||||
// TODO
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// NewImage returns a types.Image for this reference, possibly specialized for this ImageTransport.
|
||||
// The caller must call .Close() on the returned Image.
|
||||
// NOTE: If any kind of signature verification should happen, build an UnparsedImage from the value returned by NewImageSource,
|
||||
// verify that UnparsedImage, and convert it into a real Image via image.FromUnparsedImage.
|
||||
func (ref archiveReference) NewImage(ctx *types.SystemContext) (types.Image, error) {
|
||||
src := newImageSource(ctx, ref)
|
||||
return ctrImage.FromSource(src)
|
||||
}
|
||||
|
||||
// NewImageSource returns a types.ImageSource for this reference,
|
||||
// asking the backend to use a manifest from requestedManifestMIMETypes if possible.
|
||||
// nil requestedManifestMIMETypes means manifest.DefaultRequestedManifestMIMETypes.
|
||||
// The caller must call .Close() on the returned ImageSource.
|
||||
func (ref archiveReference) NewImageSource(ctx *types.SystemContext, requestedManifestMIMETypes []string) (types.ImageSource, error) {
|
||||
return newImageSource(ctx, ref), nil
|
||||
}
|
||||
|
||||
// NewImageDestination returns a types.ImageDestination for this reference.
|
||||
// The caller must call .Close() on the returned ImageDestination.
|
||||
func (ref archiveReference) NewImageDestination(ctx *types.SystemContext) (types.ImageDestination, error) {
|
||||
return newImageDestination(ctx, ref)
|
||||
}
|
||||
|
||||
// DeleteImage deletes the named image from the registry, if supported.
|
||||
func (ref archiveReference) DeleteImage(ctx *types.SystemContext) error {
|
||||
// Not really supported, for safety reasons.
|
||||
return errors.New("Deleting images not implemented for docker-archive: images")
|
||||
}
|
198
vendor/github.com/containers/image/docker/archive/transport_test.go
generated
vendored
Normal file
198
vendor/github.com/containers/image/docker/archive/transport_test.go
generated
vendored
Normal file
|
@ -0,0 +1,198 @@
|
|||
package archive
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/containers/image/docker/reference"
|
||||
"github.com/containers/image/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
sha256digestHex = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
sha256digest = "@sha256:" + sha256digestHex
|
||||
tarFixture = "fixtures/almostempty.tar"
|
||||
)
|
||||
|
||||
func TestTransportName(t *testing.T) {
|
||||
assert.Equal(t, "docker-archive", Transport.Name())
|
||||
}
|
||||
|
||||
func TestTransportParseReference(t *testing.T) {
|
||||
testParseReference(t, Transport.ParseReference)
|
||||
}
|
||||
|
||||
func TestTransportValidatePolicyConfigurationScope(t *testing.T) {
|
||||
for _, scope := range []string{ // A semi-representative assortment of values; everything is rejected.
|
||||
"docker.io/library/busybox:notlatest",
|
||||
"docker.io/library/busybox",
|
||||
"docker.io/library",
|
||||
"docker.io",
|
||||
"",
|
||||
} {
|
||||
err := Transport.ValidatePolicyConfigurationScope(scope)
|
||||
assert.Error(t, err, scope)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseReference(t *testing.T) {
|
||||
testParseReference(t, ParseReference)
|
||||
}
|
||||
|
||||
// testParseReference is a test shared for Transport.ParseReference and ParseReference.
|
||||
func testParseReference(t *testing.T, fn func(string) (types.ImageReference, error)) {
|
||||
for _, c := range []struct{ input, expectedPath, expectedRef string }{
|
||||
{"", "", ""}, // Empty input is explicitly rejected
|
||||
{"/path", "/path", ""},
|
||||
{"/path:busybox:notlatest", "/path", "docker.io/library/busybox:notlatest"}, // Explicit tag
|
||||
{"/path:busybox" + sha256digest, "", ""}, // Digest references are forbidden
|
||||
{"/path:busybox", "/path", "docker.io/library/busybox:latest"}, // Default tag
|
||||
// A github.com/distribution/reference value can have a tag and a digest at the same time!
|
||||
{"/path:busybox:latest" + sha256digest, "", ""}, // Both tag and digest is rejected
|
||||
{"/path:docker.io/library/busybox:latest", "/path", "docker.io/library/busybox:latest"}, // All implied values explicitly specified
|
||||
{"/path:UPPERCASEISINVALID", "", ""}, // Invalid input
|
||||
} {
|
||||
ref, err := fn(c.input)
|
||||
if c.expectedPath == "" {
|
||||
assert.Error(t, err, c.input)
|
||||
} else {
|
||||
require.NoError(t, err, c.input)
|
||||
archiveRef, ok := ref.(archiveReference)
|
||||
require.True(t, ok, c.input)
|
||||
assert.Equal(t, c.expectedPath, archiveRef.path, c.input)
|
||||
if c.expectedRef == "" {
|
||||
assert.Nil(t, archiveRef.destinationRef, c.input)
|
||||
} else {
|
||||
require.NotNil(t, archiveRef.destinationRef, c.input)
|
||||
assert.Equal(t, c.expectedRef, archiveRef.destinationRef.String(), c.input)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// refWithTagAndDigest is a reference.NamedTagged and reference.Canonical at the same time.
|
||||
type refWithTagAndDigest struct{ reference.Canonical }
|
||||
|
||||
func (ref refWithTagAndDigest) Tag() string {
|
||||
return "notLatest"
|
||||
}
|
||||
|
||||
// A common list of reference formats to test for the various ImageReference methods.
|
||||
var validReferenceTestCases = []struct{ input, dockerRef, stringWithinTransport string }{
|
||||
{"/pathonly", "", "/pathonly"},
|
||||
{"/path:busybox:notlatest", "docker.io/library/busybox:notlatest", "/path:docker.io/library/busybox:notlatest"}, // Explicit tag
|
||||
{"/path:docker.io/library/busybox:latest", "docker.io/library/busybox:latest", "/path:docker.io/library/busybox:latest"}, // All implied values explicitly specified
|
||||
{"/path:example.com/ns/foo:bar", "example.com/ns/foo:bar", "/path:example.com/ns/foo:bar"}, // All values explicitly specified
|
||||
}
|
||||
|
||||
func TestReferenceTransport(t *testing.T) {
|
||||
ref, err := ParseReference("/tmp/archive.tar")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, Transport, ref.Transport())
|
||||
}
|
||||
|
||||
func TestReferenceStringWithinTransport(t *testing.T) {
|
||||
for _, c := range validReferenceTestCases {
|
||||
ref, err := ParseReference(c.input)
|
||||
require.NoError(t, err, c.input)
|
||||
stringRef := ref.StringWithinTransport()
|
||||
assert.Equal(t, c.stringWithinTransport, stringRef, c.input)
|
||||
// Do one more round to verify that the output can be parsed, to an equal value.
|
||||
ref2, err := Transport.ParseReference(stringRef)
|
||||
require.NoError(t, err, c.input)
|
||||
stringRef2 := ref2.StringWithinTransport()
|
||||
assert.Equal(t, stringRef, stringRef2, c.input)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReferenceDockerReference(t *testing.T) {
|
||||
for _, c := range validReferenceTestCases {
|
||||
ref, err := ParseReference(c.input)
|
||||
require.NoError(t, err, c.input)
|
||||
dockerRef := ref.DockerReference()
|
||||
if c.dockerRef != "" {
|
||||
require.NotNil(t, dockerRef, c.input)
|
||||
assert.Equal(t, c.dockerRef, dockerRef.String(), c.input)
|
||||
} else {
|
||||
require.Nil(t, dockerRef, c.input)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReferencePolicyConfigurationIdentity(t *testing.T) {
|
||||
for _, c := range validReferenceTestCases {
|
||||
ref, err := ParseReference(c.input)
|
||||
require.NoError(t, err, c.input)
|
||||
assert.Equal(t, "", ref.PolicyConfigurationIdentity(), c.input)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReferencePolicyConfigurationNamespaces(t *testing.T) {
|
||||
for _, c := range validReferenceTestCases {
|
||||
ref, err := ParseReference(c.input)
|
||||
require.NoError(t, err, c.input)
|
||||
assert.Empty(t, "", ref.PolicyConfigurationNamespaces(), c.input)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReferenceNewImage(t *testing.T) {
|
||||
for _, suffix := range []string{"", ":thisisignoredbutaccepted"} {
|
||||
ref, err := ParseReference(tarFixture + suffix)
|
||||
require.NoError(t, err, suffix)
|
||||
img, err := ref.NewImage(nil)
|
||||
assert.NoError(t, err, suffix)
|
||||
defer img.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestReferenceNewImageSource(t *testing.T) {
|
||||
for _, suffix := range []string{"", ":thisisignoredbutaccepted"} {
|
||||
ref, err := ParseReference(tarFixture + suffix)
|
||||
require.NoError(t, err, suffix)
|
||||
src, err := ref.NewImageSource(nil, nil)
|
||||
assert.NoError(t, err, suffix)
|
||||
defer src.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestReferenceNewImageDestination(t *testing.T) {
|
||||
tmpDir, err := ioutil.TempDir("", "docker-archive-test")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
ref, err := ParseReference(filepath.Join(tmpDir, "no-reference"))
|
||||
require.NoError(t, err)
|
||||
dest, err := ref.NewImageDestination(nil)
|
||||
assert.Error(t, err)
|
||||
|
||||
ref, err = ParseReference(filepath.Join(tmpDir, "with-reference") + "busybox:latest")
|
||||
require.NoError(t, err)
|
||||
dest, err = ref.NewImageDestination(nil)
|
||||
assert.NoError(t, err)
|
||||
defer dest.Close()
|
||||
}
|
||||
|
||||
func TestReferenceDeleteImage(t *testing.T) {
|
||||
tmpDir, err := ioutil.TempDir("", "docker-archive-test")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
for i, suffix := range []string{"", ":thisisignoredbutaccepted"} {
|
||||
testFile := filepath.Join(tmpDir, fmt.Sprintf("file%d.tar", i))
|
||||
err := ioutil.WriteFile(testFile, []byte("nonempty"), 0644)
|
||||
require.NoError(t, err, suffix)
|
||||
|
||||
ref, err := ParseReference(testFile + suffix)
|
||||
require.NoError(t, err, suffix)
|
||||
err = ref.DeleteImage(nil)
|
||||
assert.Error(t, err, suffix)
|
||||
|
||||
_, err = os.Lstat(testFile)
|
||||
assert.NoError(t, err, suffix)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue