Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions oci/layout/oci_dest.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand Down
19 changes: 18 additions & 1 deletion oci/layout/oci_dest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's ok not to differentiate between signed and not-signed here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes; the users don’t even want to know about schema versions, let alone the pointless signatures.

}