diff --git a/cmd/skopeo/copy.go b/cmd/skopeo/copy.go index 2baa0ba437..725f74c84b 100644 --- a/cmd/skopeo/copy.go +++ b/cmd/skopeo/copy.go @@ -6,7 +6,7 @@ import ( "os" "github.com/containers/image/copy" - "github.com/containers/image/transports" + "github.com/containers/image/transports/alltransports" "github.com/containers/image/types" "github.com/urfave/cli" ) @@ -37,11 +37,11 @@ func copyHandler(context *cli.Context) error { } defer policyContext.Destroy() - srcRef, err := transports.ParseImageName(context.Args()[0]) + srcRef, err := alltransports.ParseImageName(context.Args()[0]) if err != nil { return fmt.Errorf("Invalid source name %s: %v", context.Args()[0], err) } - destRef, err := transports.ParseImageName(context.Args()[1]) + destRef, err := alltransports.ParseImageName(context.Args()[1]) if err != nil { return fmt.Errorf("Invalid destination name %s: %v", context.Args()[1], err) } diff --git a/cmd/skopeo/delete.go b/cmd/skopeo/delete.go index 935365fcb7..ff2d97adef 100644 --- a/cmd/skopeo/delete.go +++ b/cmd/skopeo/delete.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "github.com/containers/image/transports" + "github.com/containers/image/transports/alltransports" "github.com/urfave/cli" ) @@ -13,7 +13,7 @@ func deleteHandler(context *cli.Context) error { return errors.New("Usage: delete imageReference") } - ref, err := transports.ParseImageName(context.Args()[0]) + ref, err := alltransports.ParseImageName(context.Args()[0]) if err != nil { return fmt.Errorf("Invalid source name %s: %v", context.Args()[0], err) } diff --git a/cmd/skopeo/utils.go b/cmd/skopeo/utils.go index d17efb012c..cd4d8fe554 100644 --- a/cmd/skopeo/utils.go +++ b/cmd/skopeo/utils.go @@ -4,7 +4,7 @@ import ( "errors" "strings" - "github.com/containers/image/transports" + "github.com/containers/image/transports/alltransports" "github.com/containers/image/types" "github.com/urfave/cli" ) @@ -59,7 +59,7 @@ func getDockerAuth(creds string) (*types.DockerAuthConfig, error) { // The caller must call .Close() on the returned Image. func parseImage(c *cli.Context) (types.Image, error) { imgName := c.Args().First() - ref, err := transports.ParseImageName(imgName) + ref, err := alltransports.ParseImageName(imgName) if err != nil { return nil, err } @@ -74,7 +74,7 @@ func parseImage(c *cli.Context) (types.Image, error) { // requestedManifestMIMETypes is as in types.ImageReference.NewImageSource. // The caller must call .Close() on the returned ImageSource. func parseImageSource(c *cli.Context, name string, requestedManifestMIMETypes []string) (types.ImageSource, error) { - ref, err := transports.ParseImageName(name) + ref, err := alltransports.ParseImageName(name) if err != nil { return nil, err } diff --git a/vendor/github.com/containers/image/directory/directory_transport.go b/vendor/github.com/containers/image/directory/directory_transport.go index 89d2565aac..34f7428935 100644 --- a/vendor/github.com/containers/image/directory/directory_transport.go +++ b/vendor/github.com/containers/image/directory/directory_transport.go @@ -10,10 +10,15 @@ import ( "github.com/containers/image/directory/explicitfilepath" "github.com/containers/image/docker/reference" "github.com/containers/image/image" + "github.com/containers/image/transports" "github.com/containers/image/types" "github.com/opencontainers/go-digest" ) +func init() { + transports.Register(Transport) +} + // Transport is an ImageTransport for directory paths. var Transport = dirTransport{} diff --git a/vendor/github.com/containers/image/docker/daemon/daemon_transport.go b/vendor/github.com/containers/image/docker/daemon/daemon_transport.go index d64f088f00..41ccd1f197 100644 --- a/vendor/github.com/containers/image/docker/daemon/daemon_transport.go +++ b/vendor/github.com/containers/image/docker/daemon/daemon_transport.go @@ -5,10 +5,15 @@ import ( "github.com/containers/image/docker/reference" "github.com/containers/image/image" + "github.com/containers/image/transports" "github.com/containers/image/types" "github.com/opencontainers/go-digest" ) +func init() { + transports.Register(Transport) +} + // Transport is an ImageTransport for images managed by a local Docker daemon. var Transport = daemonTransport{} diff --git a/vendor/github.com/containers/image/docker/docker_transport.go b/vendor/github.com/containers/image/docker/docker_transport.go index a8f511a0a5..15d68e993c 100644 --- a/vendor/github.com/containers/image/docker/docker_transport.go +++ b/vendor/github.com/containers/image/docker/docker_transport.go @@ -6,10 +6,15 @@ import ( "github.com/containers/image/docker/policyconfiguration" "github.com/containers/image/docker/reference" + "github.com/containers/image/transports" "github.com/containers/image/types" "github.com/pkg/errors" ) +func init() { + transports.Register(Transport) +} + // Transport is an ImageTransport for Docker registry-hosted images. var Transport = dockerTransport{} diff --git a/vendor/github.com/containers/image/manifest/manifest.go b/vendor/github.com/containers/image/manifest/manifest.go index 430331f0a3..396f811109 100644 --- a/vendor/github.com/containers/image/manifest/manifest.go +++ b/vendor/github.com/containers/image/manifest/manifest.go @@ -54,7 +54,7 @@ func GuessMIMEType(manifest []byte) string { } switch meta.MediaType { - case DockerV2Schema2MediaType, DockerV2ListMediaType, imgspecv1.MediaTypeImageManifest, imgspecv1.MediaTypeImageManifestList: // A recognized type. + case DockerV2Schema2MediaType, DockerV2ListMediaType: // A recognized type. return meta.MediaType } // this is the only way the function can return DockerV2Schema1MediaType, and recognizing that is essential for stripping the JWS signatures = computing the correct manifest digest. diff --git a/vendor/github.com/containers/image/oci/layout/oci_transport.go b/vendor/github.com/containers/image/oci/layout/oci_transport.go index 734af87c0b..007798b4cd 100644 --- a/vendor/github.com/containers/image/oci/layout/oci_transport.go +++ b/vendor/github.com/containers/image/oci/layout/oci_transport.go @@ -9,11 +9,16 @@ import ( "github.com/containers/image/directory/explicitfilepath" "github.com/containers/image/docker/reference" "github.com/containers/image/image" + "github.com/containers/image/transports" "github.com/containers/image/types" "github.com/opencontainers/go-digest" "github.com/pkg/errors" ) +func init() { + transports.Register(Transport) +} + // Transport is an ImageTransport for OCI directories. var Transport = ociTransport{} diff --git a/vendor/github.com/containers/image/openshift/openshift_transport.go b/vendor/github.com/containers/image/openshift/openshift_transport.go index 119385bbc3..108e110232 100644 --- a/vendor/github.com/containers/image/openshift/openshift_transport.go +++ b/vendor/github.com/containers/image/openshift/openshift_transport.go @@ -8,10 +8,15 @@ import ( "github.com/containers/image/docker/policyconfiguration" "github.com/containers/image/docker/reference" genericImage "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 OpenShift registry-hosted images. var Transport = openshiftTransport{} diff --git a/vendor/github.com/containers/image/signature/policy_config.go b/vendor/github.com/containers/image/signature/policy_config.go index ace24fec88..e4c93ed528 100644 --- a/vendor/github.com/containers/image/signature/policy_config.go +++ b/vendor/github.com/containers/image/signature/policy_config.go @@ -122,10 +122,8 @@ func (m *policyTransportsMap) UnmarshalJSON(data []byte) error { // So, use a temporary map of pointers-to-slices and convert. tmpMap := map[string]*PolicyTransportScopes{} if err := paranoidUnmarshalJSONObject(data, func(key string) interface{} { - transport, ok := transports.KnownTransports[key] - if !ok { - return nil - } + // transport can be nil + transport := transports.Get(key) // paranoidUnmarshalJSONObject detects key duplication for us, check just to be safe. if _, ok := tmpMap[key]; ok { return nil @@ -155,7 +153,7 @@ func (m *PolicyTransportScopes) UnmarshalJSON(data []byte) error { } // policyTransportScopesWithTransport is a way to unmarshal a PolicyTransportScopes -// while validating using a specific ImageTransport. +// while validating using a specific ImageTransport if not nil. type policyTransportScopesWithTransport struct { transport types.ImageTransport dest *PolicyTransportScopes @@ -174,7 +172,7 @@ func (m *policyTransportScopesWithTransport) UnmarshalJSON(data []byte) error { if _, ok := tmpMap[key]; ok { return nil } - if key != "" { + if key != "" && m.transport != nil { if err := m.transport.ValidatePolicyConfigurationScope(key); err != nil { return nil } diff --git a/vendor/github.com/containers/image/storage/storage_transport.go b/vendor/github.com/containers/image/storage/storage_transport.go index 78c7ef651a..e9982175fa 100644 --- a/vendor/github.com/containers/image/storage/storage_transport.go +++ b/vendor/github.com/containers/image/storage/storage_transport.go @@ -9,12 +9,17 @@ import ( "github.com/Sirupsen/logrus" "github.com/containers/image/docker/reference" + "github.com/containers/image/transports" "github.com/containers/image/types" "github.com/containers/storage/storage" "github.com/opencontainers/go-digest" ddigest "github.com/opencontainers/go-digest" ) +func init() { + transports.Register(Transport) +} + var ( // Transport is an ImageTransport that uses either a default // storage.Store or one that's it's explicitly told to use. diff --git a/vendor/github.com/containers/image/transports/alltransports/alltransports.go b/vendor/github.com/containers/image/transports/alltransports/alltransports.go new file mode 100644 index 0000000000..eb5ddcd984 --- /dev/null +++ b/vendor/github.com/containers/image/transports/alltransports/alltransports.go @@ -0,0 +1,31 @@ +package alltransports + +import ( + "strings" + + // register all known transports + // NOTE: Make sure docs/policy.json.md is updated when adding or updating + // a transport. + _ "github.com/containers/image/directory" + _ "github.com/containers/image/docker" + _ "github.com/containers/image/docker/daemon" + _ "github.com/containers/image/oci/layout" + _ "github.com/containers/image/openshift" + _ "github.com/containers/image/storage" + "github.com/containers/image/transports" + "github.com/containers/image/types" + "github.com/pkg/errors" +) + +// ParseImageName converts a URL-like image name to a types.ImageReference. +func ParseImageName(imgName string) (types.ImageReference, error) { + parts := strings.SplitN(imgName, ":", 2) + if len(parts) != 2 { + return nil, errors.Errorf(`Invalid image name "%s", expected colon-separated transport:reference`, imgName) + } + transport := transports.Get(parts[0]) + if transport == nil { + return nil, errors.Errorf(`Invalid image name "%s", unknown transport "%s"`, imgName, parts[0]) + } + return transport.ParseReference(parts[1]) +} diff --git a/vendor/github.com/containers/image/transports/transports.go b/vendor/github.com/containers/image/transports/transports.go index 04826c047b..03969be744 100644 --- a/vendor/github.com/containers/image/transports/transports.go +++ b/vendor/github.com/containers/image/transports/transports.go @@ -2,52 +2,61 @@ package transports import ( "fmt" - "strings" - - "github.com/containers/image/directory" - "github.com/containers/image/docker" - "github.com/containers/image/docker/daemon" - ociLayout "github.com/containers/image/oci/layout" - "github.com/containers/image/openshift" - "github.com/containers/image/storage" + "sync" + "github.com/containers/image/types" - "github.com/pkg/errors" ) -// KnownTransports is a registry of known ImageTransport instances. -var KnownTransports map[string]types.ImageTransport +// knownTransports is a registry of known ImageTransport instances. +type knownTransports struct { + transports map[string]types.ImageTransport + mu sync.Mutex +} -func init() { - KnownTransports = make(map[string]types.ImageTransport) - // NOTE: Make sure docs/policy.json.md is updated when adding or updating - // a transport. - for _, t := range []types.ImageTransport{ - directory.Transport, - docker.Transport, - daemon.Transport, - ociLayout.Transport, - openshift.Transport, - storage.Transport, - } { - name := t.Name() - if _, ok := KnownTransports[name]; ok { - panic(fmt.Sprintf("Duplicate image transport name %s", name)) - } - KnownTransports[name] = t - } +func (kt *knownTransports) Get(k string) types.ImageTransport { + kt.mu.Lock() + t := kt.transports[k] + kt.mu.Unlock() + return t } -// ParseImageName converts a URL-like image name to a types.ImageReference. -func ParseImageName(imgName string) (types.ImageReference, error) { - parts := strings.SplitN(imgName, ":", 2) - if len(parts) != 2 { - return nil, errors.Errorf(`Invalid image name "%s", expected colon-separated transport:reference`, imgName) +func (kt *knownTransports) Remove(k string) { + kt.mu.Lock() + delete(kt.transports, k) + kt.mu.Unlock() +} + +func (kt *knownTransports) Add(t types.ImageTransport) { + kt.mu.Lock() + defer kt.mu.Unlock() + name := t.Name() + if t := kt.transports[name]; t != nil { + panic(fmt.Sprintf("Duplicate image transport name %s", name)) } - transport, ok := KnownTransports[parts[0]] - if !ok { - return nil, errors.Errorf(`Invalid image name "%s", unknown transport "%s"`, imgName, parts[0]) + kt.transports[name] = t +} + +var kt *knownTransports + +func init() { + kt = &knownTransports{ + transports: make(map[string]types.ImageTransport), } - return transport.ParseReference(parts[1]) +} + +// Get returns the transport specified by name or nil when unavailable. +func Get(name string) types.ImageTransport { + return kt.Get(name) +} + +// Delete deletes a transport from the registered transports. +func Delete(name string) { + kt.Remove(name) +} + +// Register registers a transport. +func Register(t types.ImageTransport) { + kt.Add(t) } // ImageName converts a types.ImageReference into an URL-like image name, which MUST be such that