-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
*: pluggable transports #216
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs a test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And another test: For There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isn't this https://github.com/containers/image/pull/216/files#diff-38040ba06b5a45464a80ca2fb88302c2R249 testing this code path? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That tests parsing the policy into a data structure, not using the data structure to look up the relevant rules to evaluate for a particular image ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added a test, hopefully done correctly (pretty late here now) |
||
if err := m.transport.ValidatePolicyConfigurationScope(key); err != nil { | ||
return nil | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO this should be done in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The underlying idea is that the strings are exposed to the users, so they should always mean the same thing; we should not have (More specialized users of |
||
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]) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With this being a private variable of a private type, it’s really not obvious to me what defining the type and methods adds right now. I guess it allows writing tests? Except that those tests don’t exist. (But this does work, feel free to leave it as it is.) |
||
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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also please update the comment at
policyTransportScopesWithTransport
:while validating using a specific ImageTransport
if not nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done