dep: Update containers/image to 1d7e25b91705e4d1cddb5396baf112caeb1119f3

Signed-off-by: Andrew Pilloud <andrewpilloud@igneoussystems.com>
This commit is contained in:
Andrew Pilloud 2017-03-13 09:33:17 -07:00
parent 54c176e336
commit de9995d5f0
84 changed files with 3091 additions and 748 deletions

View file

@ -25,7 +25,7 @@ func SignDockerManifest(m []byte, dockerReference string, mech SigningMechanism,
// using mech.
func VerifyDockerManifestSignature(unverifiedSignature, unverifiedManifest []byte,
expectedDockerReference string, mech SigningMechanism, expectedKeyIdentity string) (*Signature, error) {
expectedRef, err := reference.ParseNamed(expectedDockerReference)
expectedRef, err := reference.ParseNormalizedNamed(expectedDockerReference)
if err != nil {
return nil, err
}
@ -37,7 +37,7 @@ func VerifyDockerManifestSignature(unverifiedSignature, unverifiedManifest []byt
return nil
},
validateSignedDockerReference: func(signedDockerReference string) error {
signedRef, err := reference.ParseNamed(signedDockerReference)
signedRef, err := reference.ParseNormalizedNamed(signedDockerReference)
if err != nil {
return InvalidSignatureError{msg: fmt.Sprintf("Invalid docker reference %s in signature", signedDockerReference)}
}

View file

@ -2,3 +2,5 @@
/.gpg-v21-migrated
/private-keys-v1.d
/random_seed
/gnupg_spawn_agent_sentinel.lock
/.#*

View file

@ -0,0 +1 @@
../v2s1-invalid-signatures.manifest.json

View file

@ -0,0 +1 @@
../dir-img-valid/signature-1

View file

@ -0,0 +1 @@
../dir-img-valid/manifest.json

View file

@ -0,0 +1 @@
../invalid-blob.signature

View file

@ -0,0 +1 @@
../dir-img-valid/signature-1

View file

@ -0,0 +1 @@
../dir-img-valid/signature-1

View file

@ -0,0 +1 @@
../dir-img-valid/signature-1

View file

@ -0,0 +1 @@
../dir-img-valid/manifest.json

View file

@ -0,0 +1 @@
../dir-img-valid/manifest.json

View file

@ -0,0 +1 @@
../dir-img-valid/signature-1

View file

@ -0,0 +1 @@
../image.manifest.json

View file

@ -19,11 +19,10 @@ import (
"io/ioutil"
"path/filepath"
"github.com/pkg/errors"
"github.com/containers/image/docker/reference"
"github.com/containers/image/transports"
"github.com/containers/image/types"
"github.com/pkg/errors"
)
// systemDefaultPolicyPath is the policy path used for DefaultPolicy().
@ -123,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
@ -156,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
@ -175,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
}
@ -634,7 +631,7 @@ func (prm *prmMatchRepository) UnmarshalJSON(data []byte) error {
// newPRMExactReference is NewPRMExactReference, except it resturns the private type.
func newPRMExactReference(dockerReference string) (*prmExactReference, error) {
ref, err := reference.ParseNamed(dockerReference)
ref, err := reference.ParseNormalizedNamed(dockerReference)
if err != nil {
return nil, InvalidPolicyFormatError(fmt.Sprintf("Invalid format of dockerReference %s: %s", dockerReference, err.Error()))
}
@ -686,7 +683,7 @@ func (prm *prmExactReference) UnmarshalJSON(data []byte) error {
// newPRMExactRepository is NewPRMExactRepository, except it resturns the private type.
func newPRMExactRepository(dockerRepository string) (*prmExactRepository, error) {
if _, err := reference.ParseNamed(dockerRepository); err != nil {
if _, err := reference.ParseNormalizedNamed(dockerRepository); err != nil {
return nil, InvalidPolicyFormatError(fmt.Sprintf("Invalid format of dockerRepository %s: %s", dockerRepository, err.Error()))
}
return &prmExactRepository{

View file

@ -9,6 +9,8 @@ import (
"github.com/containers/image/directory"
"github.com/containers/image/docker"
// this import is needed where we use the "atomic" transport in TestPolicyUnmarshalJSON
_ "github.com/containers/image/openshift"
"github.com/containers/image/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -244,6 +246,11 @@ func TestPolicyUnmarshalJSON(t *testing.T) {
xNewPRSignedByKeyData(SBKeyTypeSignedByGPGKeys, []byte("RHatomic"), NewPRMMatchRepository()),
},
},
"unknown": {
"registry.access.redhat.com/rhel7": []PolicyRequirement{
xNewPRSignedByKeyData(SBKeyTypeSignedByGPGKeys, []byte("RHatomic"), NewPRMMatchRepository()),
},
},
},
}
validJSON, err := json.Marshal(validPolicy)
@ -269,9 +276,6 @@ func TestPolicyUnmarshalJSON(t *testing.T) {
func(v mSI) { v["transports"] = []string{} },
// "default" is an invalid PolicyRequirements
func(v mSI) { v["default"] = PolicyRequirements{} },
// A key in "transports" is an invalid transport name
func(v mSI) { x(v, "transports")["this is unknown"] = x(v, "transports")["docker"] },
func(v mSI) { x(v, "transports")[""] = x(v, "transports")["docker"] },
}
for _, fn := range breakFns {
err = tryUnmarshalModifiedPolicy(t, &p, validJSON, fn)

View file

@ -17,7 +17,7 @@ import (
// dirImageMock returns a types.UnparsedImage for a directory, claiming a specified dockerReference.
// The caller must call .Close() on the returned UnparsedImage.
func dirImageMock(t *testing.T, dir, dockerReference string) types.UnparsedImage {
ref, err := reference.ParseNamed(dockerReference)
ref, err := reference.ParseNormalizedNamed(dockerReference)
require.NoError(t, err)
return dirImageMockWithRef(t, dir, refImageReferenceMock{ref})
}

View file

@ -5,8 +5,10 @@ import (
"os"
"testing"
"github.com/containers/image/docker"
"github.com/containers/image/docker/policyconfiguration"
"github.com/containers/image/docker/reference"
"github.com/containers/image/transports"
"github.com/containers/image/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -103,6 +105,37 @@ func (ref pcImageReferenceMock) DeleteImage(ctx *types.SystemContext) error {
panic("unexpected call to a mock function")
}
func TestPolicyContextRequirementsForImageRefNotRegisteredTransport(t *testing.T) {
transports.Delete("docker")
assert.Nil(t, transports.Get("docker"))
defer func() {
assert.Nil(t, transports.Get("docker"))
transports.Register(docker.Transport)
assert.NotNil(t, transports.Get("docker"))
}()
pr := []PolicyRequirement{
xNewPRSignedByKeyData(SBKeyTypeSignedByGPGKeys, []byte("RH"), NewPRMMatchRepository()),
}
policy := &Policy{
Default: PolicyRequirements{NewPRReject()},
Transports: map[string]PolicyTransportScopes{
"docker": {
"registry.access.redhat.com": pr,
},
},
}
pc, err := NewPolicyContext(policy)
require.NoError(t, err)
ref, err := reference.ParseNormalizedNamed("registry.access.redhat.com/rhel7:latest")
require.NoError(t, err)
reqs := pc.requirementsForImageRef(pcImageReferenceMock{"docker", ref})
assert.True(t, &(reqs[0]) == &(pr[0]))
assert.True(t, len(reqs) == len(pr))
}
func TestPolicyContextRequirementsForImageRef(t *testing.T) {
ktGPG := SBKeyTypeGPGKeys
prm := NewPRMMatchRepoDigestOrExact()
@ -159,7 +192,7 @@ func TestPolicyContextRequirementsForImageRef(t *testing.T) {
expected = policy.Default
}
ref, err := reference.ParseNamed(c.input)
ref, err := reference.ParseNormalizedNamed(c.input)
require.NoError(t, err)
reqs := pc.requirementsForImageRef(pcImageReferenceMock{c.inputTransport, ref})
comment := fmt.Sprintf("case %s:%s: %#v", c.inputTransport, c.input, reqs[0])
@ -174,7 +207,7 @@ func TestPolicyContextRequirementsForImageRef(t *testing.T) {
// pcImageMock returns a types.UnparsedImage for a directory, claiming a specified dockerReference and implementing PolicyConfigurationIdentity/PolicyConfigurationNamespaces.
// The caller must call .Close() on the returned Image.
func pcImageMock(t *testing.T, dir, dockerReference string) types.UnparsedImage {
ref, err := reference.ParseNamed(dockerReference)
ref, err := reference.ParseNormalizedNamed(dockerReference)
require.NoError(t, err)
return dirImageMockWithRef(t, dir, pcImageReferenceMock{"docker", ref})
}

View file

@ -17,7 +17,7 @@ func parseImageAndDockerReference(image types.UnparsedImage, s2 string) (referen
return nil, nil, PolicyRequirementError(fmt.Sprintf("Docker reference match attempted on image %s with no known Docker reference identity",
transports.ImageName(image.Reference())))
}
r2, err := reference.ParseNamed(s2)
r2, err := reference.ParseNormalizedNamed(s2)
if err != nil {
return nil, nil, err
}
@ -69,11 +69,11 @@ func (prm *prmMatchRepository) matchesDockerReference(image types.UnparsedImage,
// parseDockerReferences converts two reference strings into parsed entities, failing on any error
func parseDockerReferences(s1, s2 string) (reference.Named, reference.Named, error) {
r1, err := reference.ParseNamed(s1)
r1, err := reference.ParseNormalizedNamed(s1)
if err != nil {
return nil, nil, err
}
r2, err := reference.ParseNamed(s2)
r2, err := reference.ParseNormalizedNamed(s2)
if err != nil {
return nil, nil, err
}

View file

@ -6,7 +6,6 @@ import (
"github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -26,12 +25,12 @@ func TestParseImageAndDockerReference(t *testing.T) {
bad2 = ""
)
// Success
ref, err := reference.ParseNamed(ok1)
ref, err := reference.ParseNormalizedNamed(ok1)
require.NoError(t, err)
r1, r2, err := parseImageAndDockerReference(refImageMock{ref}, ok2)
require.NoError(t, err)
assert.Equal(t, ok1, r1.String())
assert.Equal(t, ok2, r2.String())
assert.Equal(t, ok1, reference.FamiliarString(r1))
assert.Equal(t, ok2, reference.FamiliarString(r2))
// Unidentified images are rejected.
_, _, err = parseImageAndDockerReference(refImageMock{nil}, ok2)
@ -44,7 +43,7 @@ func TestParseImageAndDockerReference(t *testing.T) {
{ok1, bad2},
{bad1, bad2},
} {
ref, err := reference.ParseNamed(refs[0])
ref, err := reference.ParseNormalizedNamed(refs[0])
if err == nil {
_, _, err := parseImageAndDockerReference(refImageMock{ref}, refs[1])
assert.Error(t, err)
@ -58,7 +57,7 @@ type refImageMock struct{ reference.Named }
func (ref refImageMock) Reference() types.ImageReference {
return refImageReferenceMock{ref.Named}
}
func (ref refImageMock) Close() {
func (ref refImageMock) Close() error {
panic("unexpected call to a mock function")
}
func (ref refImageMock) Manifest() ([]byte, string, error) {
@ -72,7 +71,7 @@ func (ref refImageMock) Signatures() ([][]byte, error) {
type refImageReferenceMock struct{ reference.Named }
func (ref refImageReferenceMock) Transport() types.ImageTransport {
// We use this in error messages, so sadly we must return something. But right now we do so only when DockerReference is nil, so restrict to that.
// We use this in error messages, so sady we must return something. But right now we do so only when DockerReference is nil, so restrict to that.
if ref.Named == nil {
return nameImageTransportMock("== Transport mock")
}
@ -148,14 +147,12 @@ var prmExactMatchTestTable = []prmSymmetricTableTest{
{"busybox", "busybox:latest", false},
{"busybox", "busybox" + digestSuffix, false},
{"busybox", "busybox", false},
// References with both tags and digests: `reference.WithName` essentially drops the tag.
// This is not _particularly_ desirable but it is the semantics used throughout containers/image; at least, with the digest it is clear which image the reference means,
// even if the tag may reflect a different user intent.
// References with both tags and digests: We match them exactly (requiring BOTH to match)
// NOTE: Again, this is not documented behavior; the recommendation is to sign tags, not digests, and then tag-and-digest references wont match the signed identity.
{"busybox:latest" + digestSuffix, "busybox:latest" + digestSuffix, true},
{"busybox:latest" + digestSuffix, "busybox:latest" + digestSuffixOther, false},
{"busybox:latest" + digestSuffix, "busybox:notlatest" + digestSuffix, true}, // Ugly. Do not rely on this.
{"busybox:latest" + digestSuffix, "busybox" + digestSuffix, true}, // Ugly. Do not rely on this.
{"busybox:latest" + digestSuffix, "busybox:notlatest" + digestSuffix, false},
{"busybox:latest" + digestSuffix, "busybox" + digestSuffix, false},
{"busybox:latest" + digestSuffix, "busybox:latest", false},
// Invalid format
{"UPPERCASE_IS_INVALID_IN_DOCKER_REFERENCES", "busybox:latest", false},
@ -194,7 +191,7 @@ var prmRepositoryMatchTestTable = []prmSymmetricTableTest{
{"hostname/library/busybox:latest", "busybox:notlatest", false},
{"busybox:latest", fullRHELRef, false},
{"busybox" + digestSuffix, "notbusybox" + digestSuffix, false},
// References with both tags and digests: `reference.WithName` essentially drops the tag, and we ignore both anyway.
// References with both tags and digests: We ignore both anyway.
{"busybox:latest" + digestSuffix, "busybox:latest" + digestSuffix, true},
{"busybox:latest" + digestSuffix, "busybox:latest" + digestSuffixOther, true},
{"busybox:latest" + digestSuffix, "busybox:notlatest" + digestSuffix, true},
@ -209,8 +206,8 @@ var prmRepositoryMatchTestTable = []prmSymmetricTableTest{
func testImageAndSig(t *testing.T, prm PolicyReferenceMatch, imageRef, sigRef string, result bool) {
// This assumes that all ways to obtain a reference.Named perform equivalent validation,
// and therefore values refused by reference.ParseNamed can not happen in practice.
parsedImageRef, err := reference.ParseNamed(imageRef)
// and therefore values refused by reference.ParseNormalizedNamed can not happen in practice.
parsedImageRef, err := reference.ParseNormalizedNamed(imageRef)
if err != nil {
return
}
@ -272,14 +269,12 @@ func TestPMMMatchRepoDigestOrExactMatchesDockerReference(t *testing.T) {
// Digest references accept any signature with matching repository.
{"busybox" + digestSuffix, "busybox:latest", true},
{"busybox" + digestSuffix, "busybox" + digestSuffixOther, true}, // Even this is accepted here. (This could more reasonably happen with two different digest algorithms.)
// References with both tags and digests: `reference.WithName` essentially drops the tag.
// This is not _particularly_ desirable but it is the semantics used throughout containers/image; at least, with the digest it is clear which image the reference means,
// even if the tag may reflect a different user intent.
{"busybox:latest" + digestSuffix, "busybox:latest", true},
{"busybox:latest" + digestSuffix, "busybox:notlatest", true},
// References with both tags and digests: We match them exactly (requiring BOTH to match).
{"busybox:latest" + digestSuffix, "busybox:latest", false},
{"busybox:latest" + digestSuffix, "busybox:notlatest", false},
{"busybox:latest", "busybox:latest" + digestSuffix, false},
{"busybox:latest" + digestSuffix, "busybox:latest" + digestSuffixOther, true}, // Even this is accepted here. (This could more reasonably happen with two different digest algorithms.)
{"busybox:latest" + digestSuffix, "busybox:notlatest" + digestSuffixOther, true}, // Ugly. Do not rely on this.
{"busybox:latest" + digestSuffix, "busybox:latest" + digestSuffixOther, false},
{"busybox:latest" + digestSuffix, "busybox:notlatest" + digestSuffixOther, false},
} {
testImageAndSig(t, prm, test.imageRef, test.sigRef, test.result)
}
@ -307,8 +302,8 @@ func TestParseDockerReferences(t *testing.T) {
// Success
r1, r2, err := parseDockerReferences(ok1, ok2)
require.NoError(t, err)
assert.Equal(t, ok1, r1.String())
assert.Equal(t, ok2, r2.String())
assert.Equal(t, ok1, reference.FamiliarString(r1))
assert.Equal(t, ok2, reference.FamiliarString(r2))
// Failures
for _, refs := range [][]string{
@ -327,7 +322,7 @@ type forbiddenImageMock struct{}
func (ref forbiddenImageMock) Reference() types.ImageReference {
panic("unexpected call to a mock function")
}
func (ref forbiddenImageMock) Close() {
func (ref forbiddenImageMock) Close() error {
panic("unexpected call to a mock function")
}
func (ref forbiddenImageMock) Manifest() ([]byte, string, error) {