From ed1136e00177f2b5cd5602f6e25c3e7786cb7f0a Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Wed, 18 Jan 2017 14:46:30 +0100 Subject: [PATCH] *: pluggable transports Signed-off-by: Antonio Murdaca --- directory/directory_transport.go | 5 +++ docker/docker_transport.go | 5 +++ oci/layout/oci_transport.go | 5 +++ openshift/openshift_transport.go | 5 +++ registeredtransports/registeredtransports.go | 34 ++++++++++++++++++++ signature/policy_config.go | 4 +-- signature/policy_eval_simple.go | 6 ++-- signature/policy_reference_match.go | 4 +-- storage/storage_transport.go | 5 +++ transports/transports.go | 25 +++----------- transports/transports_test.go | 5 +-- 11 files changed, 74 insertions(+), 29 deletions(-) create mode 100644 registeredtransports/registeredtransports.go diff --git a/directory/directory_transport.go b/directory/directory_transport.go index 89d2565aac..73048852ce 100644 --- a/directory/directory_transport.go +++ b/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/registeredtransports" "github.com/containers/image/types" "github.com/opencontainers/go-digest" ) +func init() { + registeredtransports.Register(Transport) +} + // Transport is an ImageTransport for directory paths. var Transport = dirTransport{} diff --git a/docker/docker_transport.go b/docker/docker_transport.go index 00d0b7c9bf..5a78fb1215 100644 --- a/docker/docker_transport.go +++ b/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/registeredtransports" "github.com/containers/image/types" "github.com/pkg/errors" ) +func init() { + registeredtransports.Register(Transport) +} + // Transport is an ImageTransport for Docker registry-hosted images. var Transport = dockerTransport{} diff --git a/oci/layout/oci_transport.go b/oci/layout/oci_transport.go index 734af87c0b..05f0ea126b 100644 --- a/oci/layout/oci_transport.go +++ b/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/registeredtransports" "github.com/containers/image/types" "github.com/opencontainers/go-digest" "github.com/pkg/errors" ) +func init() { + registeredtransports.Register(Transport) +} + // Transport is an ImageTransport for OCI directories. var Transport = ociTransport{} diff --git a/openshift/openshift_transport.go b/openshift/openshift_transport.go index ef92a7cde6..ea0142db68 100644 --- a/openshift/openshift_transport.go +++ b/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/registeredtransports" "github.com/containers/image/types" "github.com/pkg/errors" ) +func init() { + registeredtransports.Register(Transport) +} + // Transport is an ImageTransport for OpenShift registry-hosted images. var Transport = openshiftTransport{} diff --git a/registeredtransports/registeredtransports.go b/registeredtransports/registeredtransports.go new file mode 100644 index 0000000000..f73cbc4840 --- /dev/null +++ b/registeredtransports/registeredtransports.go @@ -0,0 +1,34 @@ +package registeredtransports + +import ( + "fmt" + + "github.com/containers/image/types" +) + +// KnownTransports is a registry of known ImageTransport instances. +var KnownTransports map[string]types.ImageTransport + +func init() { + KnownTransports = make(map[string]types.ImageTransport) +} + +// Register TODO(runcom) +func Register(t types.ImageTransport) { + name := t.Name() + if _, ok := KnownTransports[name]; ok { + panic(fmt.Sprintf("Duplicate image transport name %s", name)) + } + KnownTransports[name] = t +} + +// ImageName converts a types.ImageReference into an URL-like image name, which MUST be such that +// ParseImageName(ImageName(reference)) returns an equivalent reference. +// +// This is the generally recommended way to refer to images in the UI. +// +// NOTE: The returned string is not promised to be equal to the original input to ParseImageName; +// e.g. default attribute values omitted by the user may be filled in in the return value, or vice versa. +func ImageName(ref types.ImageReference) string { + return ref.Transport().Name() + ":" + ref.StringWithinTransport() +} diff --git a/signature/policy_config.go b/signature/policy_config.go index e4525795dc..293cf23aca 100644 --- a/signature/policy_config.go +++ b/signature/policy_config.go @@ -22,7 +22,7 @@ import ( "github.com/pkg/errors" "github.com/containers/image/docker/reference" - "github.com/containers/image/transports" + "github.com/containers/image/registeredtransports" "github.com/containers/image/types" ) @@ -123,7 +123,7 @@ 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] + transport, ok := registeredtransports.KnownTransports[key] if !ok { return nil } diff --git a/signature/policy_eval_simple.go b/signature/policy_eval_simple.go index 19a71e6d99..5a6fc4b158 100644 --- a/signature/policy_eval_simple.go +++ b/signature/policy_eval_simple.go @@ -5,7 +5,7 @@ package signature import ( "fmt" - "github.com/containers/image/transports" + "github.com/containers/image/registeredtransports" "github.com/containers/image/types" ) @@ -20,9 +20,9 @@ func (pr *prInsecureAcceptAnything) isRunningImageAllowed(image types.UnparsedIm } func (pr *prReject) isSignatureAuthorAccepted(image types.UnparsedImage, sig []byte) (signatureAcceptanceResult, *Signature, error) { - return sarRejected, nil, PolicyRequirementError(fmt.Sprintf("Any signatures for image %s are rejected by policy.", transports.ImageName(image.Reference()))) + return sarRejected, nil, PolicyRequirementError(fmt.Sprintf("Any signatures for image %s are rejected by policy.", registeredtransports.ImageName(image.Reference()))) } func (pr *prReject) isRunningImageAllowed(image types.UnparsedImage) (bool, error) { - return false, PolicyRequirementError(fmt.Sprintf("Running image %s is rejected by policy.", transports.ImageName(image.Reference()))) + return false, PolicyRequirementError(fmt.Sprintf("Running image %s is rejected by policy.", registeredtransports.ImageName(image.Reference()))) } diff --git a/signature/policy_reference_match.go b/signature/policy_reference_match.go index ced51e6e07..89c0732325 100644 --- a/signature/policy_reference_match.go +++ b/signature/policy_reference_match.go @@ -6,7 +6,7 @@ import ( "fmt" "github.com/containers/image/docker/reference" - "github.com/containers/image/transports" + "github.com/containers/image/registeredtransports" "github.com/containers/image/types" ) @@ -15,7 +15,7 @@ func parseImageAndDockerReference(image types.UnparsedImage, s2 string) (referen r1 := image.Reference().DockerReference() if r1 == nil { return nil, nil, PolicyRequirementError(fmt.Sprintf("Docker reference match attempted on image %s with no known Docker reference identity", - transports.ImageName(image.Reference()))) + registeredtransports.ImageName(image.Reference()))) } r2, err := reference.ParseNamed(s2) if err != nil { diff --git a/storage/storage_transport.go b/storage/storage_transport.go index 661df1038a..f08e1b628f 100644 --- a/storage/storage_transport.go +++ b/storage/storage_transport.go @@ -9,12 +9,17 @@ import ( "github.com/Sirupsen/logrus" "github.com/containers/image/docker/reference" + "github.com/containers/image/registeredtransports" "github.com/containers/image/types" "github.com/containers/storage/storage" "github.com/opencontainers/go-digest" ddigest "github.com/opencontainers/go-digest" ) +func init() { + registeredtransports.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/transports/transports.go b/transports/transports.go index 04826c047b..b8c6d05f30 100644 --- a/transports/transports.go +++ b/transports/transports.go @@ -1,7 +1,6 @@ package transports import ( - "fmt" "strings" "github.com/containers/image/directory" @@ -9,16 +8,13 @@ import ( "github.com/containers/image/docker/daemon" ociLayout "github.com/containers/image/oci/layout" "github.com/containers/image/openshift" + "github.com/containers/image/registeredtransports" "github.com/containers/image/storage" "github.com/containers/image/types" "github.com/pkg/errors" ) -// KnownTransports is a registry of known ImageTransport instances. -var KnownTransports map[string]types.ImageTransport - 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{ @@ -30,10 +26,10 @@ func init() { storage.Transport, } { name := t.Name() - if _, ok := KnownTransports[name]; ok { - panic(fmt.Sprintf("Duplicate image transport name %s", name)) + if _, ok := registeredtransports.KnownTransports[name]; ok { + continue } - KnownTransports[name] = t + registeredtransports.Register(t) } } @@ -43,20 +39,9 @@ func ParseImageName(imgName string) (types.ImageReference, error) { if len(parts) != 2 { return nil, errors.Errorf(`Invalid image name "%s", expected colon-separated transport:reference`, imgName) } - transport, ok := KnownTransports[parts[0]] + transport, ok := registeredtransports.KnownTransports[parts[0]] if !ok { return nil, errors.Errorf(`Invalid image name "%s", unknown transport "%s"`, imgName, parts[0]) } return transport.ParseReference(parts[1]) } - -// ImageName converts a types.ImageReference into an URL-like image name, which MUST be such that -// ParseImageName(ImageName(reference)) returns an equivalent reference. -// -// This is the generally recommended way to refer to images in the UI. -// -// NOTE: The returned string is not promised to be equal to the original input to ParseImageName; -// e.g. default attribute values omitted by the user may be filled in in the return value, or vice versa. -func ImageName(ref types.ImageReference) string { - return ref.Transport().Name() + ":" + ref.StringWithinTransport() -} diff --git a/transports/transports_test.go b/transports/transports_test.go index 2daec0ddfa..ddef2907ac 100644 --- a/transports/transports_test.go +++ b/transports/transports_test.go @@ -3,13 +3,14 @@ package transports import ( "testing" + "github.com/containers/image/registeredtransports" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestKnownTransports(t *testing.T) { - assert.NotNil(t, KnownTransports) // Ensure that the initialization has actually been run - assert.True(t, len(KnownTransports) > 1) + assert.NotNil(t, registeredtransports.KnownTransports) // Ensure that the initialization has actually been run + assert.True(t, len(registeredtransports.KnownTransports) > 1) } func TestParseImageName(t *testing.T) {