Skip to content
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

serialization: add test, make volumes null #151

Closed
Closed
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
5 changes: 4 additions & 1 deletion schema/defs-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
}
},
"Volumes": {
"$ref": "defs.json#/definitions/mapStringObject"
"oneOf": [
{"$ref": "defs.json#/definitions/mapStringObject"},
{"type": "null"}
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't look like jq ;). Did you run make fmt (with the fix from #148)?

]
},
"WorkingDir": {
"type": "string"
Expand Down
31 changes: 16 additions & 15 deletions schema/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ var _escData = map[string]*_escFile{
"/config-schema.json": {
local: "config-schema.json",
size: 707,
modtime: 1464139547,
modtime: 1464121931,
compressed: `
H4sIAAAJbogA/5SRPW7DMAyF5/oUhpOxjjp0ytoDdOgJVJmKGcCiQDJDUPju1U/c2kvhLobx+L73JOqr
adtuAHGMUZFCd2679wjhjYJaDMBt+vN4aT8iOPTobHE9Z+woboTJZmRUjWdjrkKhr+qJ+GIGtl77l1dT
Expand All @@ -216,7 +216,7 @@ T4aE9IoTdGU2V0tnbzoS/xG1dbMbUdPhbgx7GZK9zscuVu4jgy+HBy99HZ/yKxxMUjBgfi1ZdrjJYiL1
"/content-descriptor.json": {
local: "content-descriptor.json",
size: 616,
modtime: 1464914956,
modtime: 1466030773,
compressed: `
H4sIAAAJbogA/4yRMVPDMAyF9/wKXdqR1gxMXWFngI1jcG0lVe9iG1kMhet/x4oTSGGgW/L8vvck+7MB
aD1mx5SEYmh30D4mDPcxiKWADPqFQeBhMkWGp4SOOnJ2JG40Yp3dAQer+EEk7Yw55hg2Vd1G7o1n28nm
Expand All @@ -228,23 +228,24 @@ AmOHXKZBD4uOEV+XM+U8dnlDg+1xq8uuyj8F0tRsfnpH6lzhNtPHf5OoBSjA/iSYr5hmvgkqz9QjX/Z5

"/defs-config.json": {
local: "defs-config.json",
size: 1755,
modtime: 1464139547,
size: 1822,
modtime: 1466096871,
compressed: `
H4sIAAAJbogA/7xUzc7TMBA8N09hBY6BXhAHri1HVKQIOFZusm63xF5rvQEi1HfHSauS/qRKKV8PVeOx
Z2bXY/t3olRaQigYvSC59INK52DQYTsKymsWLOpKsxJSCw9uRk40OmAVvwyuVe6hQIOF7vjZXvCoEAVb
jwgW3fLjOCLSeGgNabWFQjpqh3smD9EXQm91xL8E4BOkpxGE0a3T49Qu+8v7BJa4OWe+ZjAtMxYb3m4D
uVfTXt1TdPL+3S29/Kf2/09z5ut8o/ms5YckP/7yFKD8TCz3qlrt825DF/toruu7H0NpaGbdpFl/CgXs
eRk38otWA6bCjafY9vO9Z7Z8vulXqmp797EYFeA34u9xyRzH36qk/3/QSplITHjkZpdozBLLiy5ffnsr
3QAP+o7rf4NBTh+YuzegYNACg8frUEeWTCYRNcRWS5d+JL0RtHA9YF3Lhv7pyTzUs1xdPJuj2GQtDN/Q
W1SwXppll8oQfUVUgXaDqSTtb5f8CQAA//8Cok052wYAAA==
H4sIAAAJbogA/7xUzY7TMBA+b57CChwDe0EcuHY5oiJFwAGhyk3G21lijzWeAFGVd8dJS0nTpmop20PV
eOzvx/7sWSdKpSWEgtELkkvfqfQBDDrsRkF5zYJFXWlWQmruwc3IiUYHrOKXwUeVeyjQYKF7fLYh3DFE
wk4jFot++W4cK9J46ARp+QSF9NC+7pk8RF0Ig9Wx/ikA71UGHEEY3WO6m2qzv7gPYImbMfIlg+mQ0Wx4
/RTIvbgf+L5HJ2/fnOLLf2r//zhnvs5Xmkdbvory/S9PAcqPxHIpq9U+7w90vonmOL/7MZWGZtZNmg2n
UMCObZzIL0pNiAo3nuK2b689s+XtRT9TVdvDa0EO5l2CX/fY15cG22Yj/B97rq6qtB1Mfjvq7gvx98j2
gOc/zGT4v+VKmUhMuKY5lGjMAsuDg3r+hCrdAE/qnrf/FQbZ71EXH0DBoAUmb+jWR5bc3cWqIbZa+osS
Qa8ELRx/5LqWFf1T1936WSwPOu9ZaLIWph/5KShYL82iT2UKviSqQLvJVJLu1ya/AwAA//9M4B9rHgcA
AA==
`,
},

"/defs-image.json": {
local: "defs-image.json",
size: 2528,
modtime: 1464914958,
modtime: 1466030773,
compressed: `
H4sIAAAJbogA/7RWy27bMBC8+ysIJUAOfqjXGkGAoEGBnlIgPTVQgY20kphKpLqkgzqB/r2k3k+nrt0b
ueQOZ4Zjym8LxpwAlU8801wKZ8ucOwy54HamWAakub9LgJiW7D5D8UkKDVwgsS8pRMgeMvR5yH0o2lcl
Expand All @@ -263,7 +264,7 @@ Wb7IF38CAAD//wKthPngCQAA
"/defs.json": {
local: "defs.json",
size: 3193,
modtime: 1464139547,
modtime: 1466096269,
compressed: `
H4sIAAAJbogA/7RWTXPaMBC98ys8tEfa2PIX9NYp/cghAzOZnjo9uGYBtSCpstxpmuG/VzLGWPZiMKWH
JPau9r23T6tYzwPHGS4gSyUVinI2fOMMp7CkjJq3zMkzWDhqLXm+WvNc6UdwZgLYO85UQhlI51FASpc0
Expand All @@ -282,7 +283,7 @@ MrVJbn8cB+ZnN/gbAAD//0JyEpx5DAAA
"/image-manifest-schema.json": {
local: "image-manifest-schema.json",
size: 1032,
modtime: 1464914959,
modtime: 1466030773,
compressed: `
H4sIAAAJbogA/6RSPU/zMBDe8ytOacc39TswdWViQAxULIjBJOfkqsYOPoNUVf3v+KMujsoAdMyTez7u
8R0qgLpDbi1Njoyu11A/TKhvjXaSNFq4G2WPcC81KWQHjxO2pKiVcfpfoC+5HXCUgTo4N62F2LLRTUJX
Expand All @@ -297,7 +298,7 @@ X3p8DwgEAAA=
"/manifest-list-schema.json": {
local: "manifest-list-schema.json",
size: 1010,
modtime: 1464139547,
modtime: 1461966159,
compressed: `
H4sIAAAJbogA/6ySMU/7MBDF93yKU9rxn/o/MHWFBQnEQMWCGExyaa5q7OAzSFXV747tS0qiMIDoUqkv
fu9+7+xjBpBXyKWjzpM1+Rryhw7NtTVek0EHt63eItxrQzWyhzsKP48dllRTqZPlX8xYctlgq6O/8b5b
Expand Down
139 changes: 139 additions & 0 deletions schema/manifest_backwards_compatibility_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Copyright 2016 The Linux Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package schema_test

import (
"crypto/sha256"
"encoding/hex"
"fmt"
"strings"
"testing"

"github.com/opencontainers/image-spec/schema"
)

var compatMap = map[string]string{
"application/vnd.docker.distribution.manifest.list.v2+json": "application/vnd.oci.image.manifest.list.v1+json",
"application/vnd.docker.distribution.manifest.v2+json": "application/vnd.oci.image.manifest.v1+json",
"application/vnd.docker.image.rootfs.diff.tar.gzip": "application/vnd.oci.image.rootfs.tar.gzip",
"application/vnd.docker.container.image.v1+json": "application/vnd.oci.image.serialization.config.v1+json",
}

// convertFormats converts Docker v2.2 image format JSON documents to OCI
// format by simply replacing instances of the strings found in the compatMap
// found in the input string.
func convertFormats(input string) string {
out := input
for k, v := range compatMap {
out = strings.Replace(out, v, k, -1)
}
return out
}

func TestBackwardsCompatibilityManifest(t *testing.T) {
for i, tt := range []struct {
manifest string
digest string
fail bool
}{
// manifest pulled from docker hub using hash value
//
// curl -L -H "Authorization: Bearer ..." -H \
// "Accept: application/vnd.docker.distribution.manifest.v2+json" \
// https://registry-1.docker.io/v2/library/docker/manifests/sha256:888206c77cd2811ec47e752ba291e5b7734e3ef137dfd222daadaca39a9f17bc
{
digest: "sha256:888206c77cd2811ec47e752ba291e5b7734e3ef137dfd222daadaca39a9f17bc",
manifest: `{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/octet-stream",
"size": 3210,
"digest": "sha256:5359a4f250650c20227055957e353e8f8a74152f35fe36f00b6b1f9fc19c8861"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 2310272,
"digest": "sha256:fae91920dcd4542f97c9350b3157139a5d901362c2abec284de5ebd1b45b4957"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 913022,
"digest": "sha256:f384f6ab36adad485192f09379c0b58dc612a3cde82c551e082a7c29a87c95da"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 9861668,
"digest": "sha256:ed0d2dd5e1a0e5e650a330a864c8a122e9aa91fa6ba9ac6f0bd1882e59df55e7"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 465,
"digest": "sha256:ec4d00b58417c45f7ddcfde7bcad8c9d62a7d6d5d17cdc1f7d79bcb2e22c1491"
}
]
}`,
fail: false,
},
} {
sum := sha256.Sum256([]byte(tt.manifest))
got := fmt.Sprintf("sha256:%s", hex.EncodeToString(sum[:]))
if tt.digest != got {
t.Errorf("test %d: expected digest %s but got %s", i, tt.digest, got)
}

manifest := convertFormats(tt.manifest)
r := strings.NewReader(manifest)
err := schema.MediaTypeManifest.Validate(r)

if got := err != nil; tt.fail != got {
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
}
}
}

func TestBackwardsCompatibilityConfig(t *testing.T) {
for i, tt := range []struct {
manifest string
digest string
fail bool
}{
// manifest pulled from docker hub blob store
//
// curl -L -H "Authorization: Bearer ..." -H \
// -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
// https://registry-1.docker.io/v2/library/docker/blobs/sha256:5359a4f250650c20227055957e353e8f8a74152f35fe36f00b6b1f9fc19c8861
{
digest: "sha256:5359a4f250650c20227055957e353e8f8a74152f35fe36f00b6b1f9fc19c8861",
manifest: `{"architecture":"amd64","config":{"Hostname":"e5e5b3910a57","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","DOCKER_BUCKET=get.docker.com","DOCKER_VERSION=1.10.3","DOCKER_SHA256=d0df512afa109006a450f41873634951e19ddabf8c7bd419caeb5a526032d86d"],"Cmd":["sh"],"ArgsEscaped":true,"Image":"sha256:bda352ba7ab5823b7dc74b380c5ad1699edee278a6d2ebbe451129b108778742","Volumes":null,"WorkingDir":"","Entrypoint":["docker-entrypoint.sh"],"OnBuild":[],"Labels":{}},"container":"881be788b4387039b52fa195da9fe26f264385aa497ce650cfdcf3806c2d2021","container_config":{"Hostname":"e5e5b3910a57","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","DOCKER_BUCKET=get.docker.com","DOCKER_VERSION=1.10.3","DOCKER_SHA256=d0df512afa109006a450f41873634951e19ddabf8c7bd419caeb5a526032d86d"],"Cmd":["/bin/sh","-c","#(nop) CMD [\"sh\"]"],"ArgsEscaped":true,"Image":"sha256:bda352ba7ab5823b7dc74b380c5ad1699edee278a6d2ebbe451129b108778742","Volumes":null,"WorkingDir":"","Entrypoint":["docker-entrypoint.sh"],"OnBuild":[],"Labels":{}},"created":"2016-06-08T00:52:29.30472774Z","docker_version":"1.10.3","history":[{"created":"2016-06-08T00:48:01.932532048Z","created_by":"/bin/sh -c #(nop) ADD file:bca92e550bd2ce926584aef2032464b6ebf543ce69133b6602c781866165d703 in /"},{"created":"2016-06-08T00:52:10.503417531Z","created_by":"/bin/sh -c apk add --no-cache \t\tca-certificates \t\tcurl \t\topenssl"},{"created":"2016-06-08T00:52:10.700704697Z","created_by":"/bin/sh -c #(nop) ENV DOCKER_BUCKET=get.docker.com","empty_layer":true},{"created":"2016-06-08T00:52:25.746175479Z","created_by":"/bin/sh -c #(nop) ENV DOCKER_VERSION=1.10.3","empty_layer":true},{"created":"2016-06-08T00:52:25.954613633Z","created_by":"/bin/sh -c #(nop) ENV DOCKER_SHA256=d0df512afa109006a450f41873634951e19ddabf8c7bd419caeb5a526032d86d","empty_layer":true},{"created":"2016-06-08T00:52:28.173693898Z","created_by":"/bin/sh -c curl -fSL \"https://${DOCKER_BUCKET}/builds/Linux/x86_64/docker-$DOCKER_VERSION\" -o /usr/local/bin/docker \t\u0026\u0026 echo \"${DOCKER_SHA256} /usr/local/bin/docker\" | sha256sum -c - \t\u0026\u0026 chmod +x /usr/local/bin/docker"},{"created":"2016-06-08T00:52:28.924486515Z","created_by":"/bin/sh -c #(nop) COPY file:50006c902e7677711aeffe4ab7b7042d649618b96dec760f322a8566dd83ab25 in /usr/local/bin/"},{"created":"2016-06-08T00:52:29.121963047Z","created_by":"/bin/sh -c #(nop) ENTRYPOINT \u0026{[\"docker-entrypoint.sh\"]}","empty_layer":true},{"created":"2016-06-08T00:52:29.30472774Z","created_by":"/bin/sh -c #(nop) CMD [\"sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:77f08abee8bf9334407f52d104e1891283018450b3c196118ddfe31505126b87","sha256:707d16737060172b977d5f7eaaddfcfaae1008472193d7e8e5a01111a5f8dd5c","sha256:44da042e7b2458ee0b3877f2321cdf4fd45a49b9b51e00492c2ba68055573eff","sha256:1bc2be83dce13b9bac9476c9c1d2ca6e0db3e07b443f7298fc5a1af75b2cb4ef"]}}`,
fail: false,
},
} {
sum := sha256.Sum256([]byte(tt.manifest))
got := fmt.Sprintf("sha256:%s", hex.EncodeToString(sum[:]))
if tt.digest != got {
t.Errorf("test %d: expected digest %s but got %s", i, tt.digest, got)
}

manifest := convertFormats(tt.manifest)
r := strings.NewReader(manifest)
err := schema.MediaTypeImageSerializationConfig.Validate(r)

if got := err != nil; tt.fail != got {
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
}
}
}
2 changes: 1 addition & 1 deletion serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ Note: whitespace has been added to this example for clarity. Whitespace is OPTIO
Volumes <code>struct</code>
</dt>
<dd>
A set of directories which should be created as data volumes in a container running this image.
A set of directories which should be created as data volumes in a container running this image. This field MAY be "null".
<p>
If a file or folder exists within the image with the same path as a data volume, that file or folder is replaced with the data volume and is never merged.
</p>
Expand Down