diff --git a/oci/layout/oci_dest.go b/oci/layout/oci_dest.go index 7201c9061a..5ea52fd394 100644 --- a/oci/layout/oci_dest.go +++ b/oci/layout/oci_dest.go @@ -4,6 +4,7 @@ import ( "crypto/sha256" "encoding/hex" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -106,12 +107,12 @@ func createManifest(m []byte) ([]byte, string, error) { om := imgspecv1.Manifest{} mt := manifest.GuessMIMEType(m) switch mt { - case manifest.DockerV2Schema1MediaType: + case manifest.DockerV2Schema1MediaType, manifest.DockerV2Schema1SignedMediaType: // There a simple reason about not yet implementing this. // OCI image-spec assure about backward compatibility with docker v2s2 but not v2s1 // generating a v2s2 is a migration docker does when upgrading to 1.10.3 // and I don't think we should bother about this now (I don't want to have migration code here in skopeo) - return nil, "", fmt.Errorf("can't create OCI manifest from Docker V2 schema 1 manifest") + return nil, "", errors.New("can't create an OCI manifest from Docker V2 schema 1 manifest") case manifest.DockerV2Schema2MediaType: if err := json.Unmarshal(m, &om); err != nil { return nil, "", err @@ -127,13 +128,13 @@ func createManifest(m []byte) ([]byte, string, error) { } return b, om.MediaType, nil case manifest.DockerV2ListMediaType: - return nil, "", fmt.Errorf("can't create OCI manifest from Docker V2 schema 2 manifest list") + return nil, "", errors.New("can't create an OCI manifest from Docker V2 schema 2 manifest list") case imgspecv1.MediaTypeImageManifestList: - return nil, "", fmt.Errorf("can't create OCI manifest from OCI manifest list") + return nil, "", errors.New("can't create an OCI manifest from OCI manifest list") case imgspecv1.MediaTypeImageManifest: return m, mt, nil } - return nil, "", fmt.Errorf("Unrecognized manifest media type: %q", mt) + return nil, "", fmt.Errorf("unrecognized manifest media type %q", mt) } func (d *ociImageDestination) PutManifest(m []byte) error { diff --git a/oci/layout/oci_dest_test.go b/oci/layout/oci_dest_test.go index 346743eef1..880df86e56 100644 --- a/oci/layout/oci_dest_test.go +++ b/oci/layout/oci_dest_test.go @@ -68,9 +68,26 @@ func TestPutManifestUnrecognizedMediaType(t *testing.T) { ociDest, err := dirRef.NewImageDestination(nil) require.NoError(t, err) + m := `{"name":"puerapuliae/busybox","tag":"latest","architecture":"amd64","fsLayers":[{"blobSum":"sha256:04f18047a28f8dea4a3b3872a2ad345cbb6f0eae28d99a60d3df844d6eaae571"},{"blobSum":"sha256:04f18047a28f8dea4a3b3872a2ad345cbb6f0eae28d99a60d3df844d6eaae571"}],"history":[{"v1Compatibility":"{\"id\":\"b46e47334e74d687019107dbec32559dd598db58fe90d2a0c5473bda8b59829d\",\"comment\":\"Imported from -\",\"created\":\"2015-07-03T07:56:02.57018886Z\",\"container_config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":9356886}\n"},{"v1Compatibility":"{\"id\":\"b46e47334e74d687019107dbec32559dd598db58fe90d2a0c5473bda8b59829d\",\"comment\":\"Imported from -\",\"created\":\"2015-07-03T07:56:02.57018886Z\",\"container_config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":9356886}\n"}],"signatures":[{"header":{"jwk":{"crv":"P-256","kid":"SVJ4:Q6G3:SXTN:H6LT:7PXH:DHUZ:SGTB:5TMV:YPIV:UPHY:MRHO:PN6V","kty":"EC","x":"qrSsA2UAKEFlDhLk12zoWpnHgYcTNfEOWGZU46pzhfk","y":"RtD_vGFtagPlheiunLvZL02LOssnu7DqShuBwc6Ml44"},"alg":"ES256"},"signature":"YzfU_rKQLWqG74uilltTiV3O92lfEjaG5wJkVt_dCtjH_C5AeghfQttnbtceJOyiaU7xP2yEnjdultutsxkQKQ","protected":"eyJmb3JtYXRMZW5ndGgiOjI4NDgsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNi0wOS0xMFQwODoyMDowOFoifQ"}]}` + + err = ociDest.PutManifest([]byte(m)) + require.Error(t, err) + assert.Equal(t, `unrecognized manifest media type ""`, err.Error()) +} + +// regression test for projectatomic/skopeo#198 +func TestPutManifestDockerV2Schema1Signed(t *testing.T) { + ref, tmpDir := refToTempOCI(t) + defer os.RemoveAll(tmpDir) + dirRef, ok := ref.(ociReference) + require.True(t, ok) + + ociDest, err := dirRef.NewImageDestination(nil) + require.NoError(t, err) + m := `{"name":"puerapuliae/busybox","tag":"latest","architecture":"amd64","fsLayers":[{"blobSum":"sha256:04f18047a28f8dea4a3b3872a2ad345cbb6f0eae28d99a60d3df844d6eaae571"},{"blobSum":"sha256:04f18047a28f8dea4a3b3872a2ad345cbb6f0eae28d99a60d3df844d6eaae571"}],"history":[{"v1Compatibility":"{\"id\":\"b46e47334e74d687019107dbec32559dd598db58fe90d2a0c5473bda8b59829d\",\"comment\":\"Imported from -\",\"created\":\"2015-07-03T07:56:02.57018886Z\",\"container_config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":9356886}\n"},{"v1Compatibility":"{\"id\":\"b46e47334e74d687019107dbec32559dd598db58fe90d2a0c5473bda8b59829d\",\"comment\":\"Imported from -\",\"created\":\"2015-07-03T07:56:02.57018886Z\",\"container_config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":9356886}\n"}],"schemaVersion":1,"signatures":[{"header":{"jwk":{"crv":"P-256","kid":"SVJ4:Q6G3:SXTN:H6LT:7PXH:DHUZ:SGTB:5TMV:YPIV:UPHY:MRHO:PN6V","kty":"EC","x":"qrSsA2UAKEFlDhLk12zoWpnHgYcTNfEOWGZU46pzhfk","y":"RtD_vGFtagPlheiunLvZL02LOssnu7DqShuBwc6Ml44"},"alg":"ES256"},"signature":"YzfU_rKQLWqG74uilltTiV3O92lfEjaG5wJkVt_dCtjH_C5AeghfQttnbtceJOyiaU7xP2yEnjdultutsxkQKQ","protected":"eyJmb3JtYXRMZW5ndGgiOjI4NDgsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNi0wOS0xMFQwODoyMDowOFoifQ"}]}` err = ociDest.PutManifest([]byte(m)) require.Error(t, err) - assert.Contains(t, `Unrecognized manifest media type: "application/vnd.docker.distribution.manifest.v1+prettyjws"`, err.Error()) + assert.Equal(t, `can't create an OCI manifest from Docker V2 schema 1 manifest`, err.Error()) }