Skip to content

Commit 0aafcef

Browse files
committed
Merge pull request #81 from s-urbaniak/validate-config
schema: add config/image JSON schema and validation
2 parents ab86716 + 114d12a commit 0aafcef

File tree

8 files changed

+191
-19
lines changed

8 files changed

+191
-19
lines changed

cmd/oci-image-tool/validate.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ func (v *validateCmd) validatePath(name string) error {
140140
return err
141141
}
142142

143+
return nil
144+
case typeConfig:
145+
if err := schema.MediaTypeImageSerializationConfig.Validate(f); err != nil {
146+
return err
147+
}
148+
143149
return nil
144150
}
145151

schema/config-schema.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"description": "OpenContainer Config Specification",
3+
"$schema": "http://json-schema.org/draft-04/schema#",
4+
"id": "https://opencontainers.org/schema/image/config",
5+
"type": "object",
6+
"properties": {
7+
"created": {
8+
"type": "string",
9+
"format": "date-time"
10+
},
11+
"author": {
12+
"type": "string"
13+
},
14+
"architecture": {
15+
"type": "string"
16+
},
17+
"os": {
18+
"type": "string"
19+
},
20+
"config": {
21+
"$ref": "defs-config.json#/definitions/config"
22+
},
23+
"rootfs": {
24+
"$ref": "defs-config.json#/definitions/rootfs"
25+
},
26+
"history": {
27+
"type": "array",
28+
"items": {
29+
"$ref": "defs-config.json#/definitions/history"
30+
}
31+
}
32+
}
33+
}

schema/defs-config.json

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
{
2+
"description": "Definitions particular to OpenContainer Config Specification",
3+
"definitions": {
4+
"config": {
5+
"type": "object",
6+
"properties": {
7+
"User": {
8+
"type": "string"
9+
},
10+
"Memory": {
11+
"$ref": "defs.json#/definitions/int64"
12+
},
13+
"MemorySwap": {
14+
"$ref": "defs.json#/definitions/int64"
15+
},
16+
"CpuShares": {
17+
"$ref": "defs.json#/definitions/int64"
18+
},
19+
"ExposedPorts": {
20+
"$ref": "defs.json#/definitions/mapStringObject"
21+
},
22+
"Env": {
23+
"type": "array",
24+
"items": {
25+
"type": "string"
26+
}
27+
},
28+
"Entrypoint": {
29+
"type": "array",
30+
"items": {
31+
"type": "string"
32+
}
33+
},
34+
"Cmd": {
35+
"type": "array",
36+
"items": {
37+
"type": "string"
38+
}
39+
},
40+
"Volumes": {
41+
"$ref": "defs.json#/definitions/mapStringObject"
42+
},
43+
"WorkingDir": {
44+
"type": "string"
45+
}
46+
}
47+
},
48+
"rootfs": {
49+
"type": "object",
50+
"properties": {
51+
"diff_ids": {
52+
"type": "array",
53+
"items": {
54+
"type": "string"
55+
}
56+
},
57+
"layers": {
58+
"type": "string"
59+
}
60+
}
61+
},
62+
"history": {
63+
"type": "object",
64+
"properties": {
65+
"created": {
66+
"type": "string",
67+
"format": "date-time"
68+
},
69+
"author": {
70+
"type": "string"
71+
},
72+
"created_by": {
73+
"type": "string"
74+
},
75+
"comment": {
76+
"type": "string"
77+
},
78+
"empty_layer": {
79+
"type": "boolean"
80+
}
81+
}
82+
}
83+
}
84+
}

schema/defs.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@
7979
}
8080
}
8181
},
82+
"mapStringObject": {
83+
"type": "object",
84+
"patternProperties": {
85+
".{1,}": {
86+
"type": "object"
87+
}
88+
}
89+
},
8290
"UID": {
8391
"$ref": "#/definitions/uint32"
8492
},

schema/fs.go

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,34 @@ func _escFSMustString(useLocal bool, name string) string {
200200

201201
var _escData = map[string]*_escFile{
202202

203+
"/config-schema.json": {
204+
local: "config-schema.json",
205+
size: 707,
206+
modtime: 1463700693,
207+
compressed: `
208+
H4sIAAAJbogA/5SRPW7DMAyF5/oUhpOxjjp0ytoDdOgJVJmKGcCiQDJDUPju1U/c2kvhLobx+L73JOqr
209+
adtuAHGMUZFCd2679wjhjYJaDMBt+vN4aT8iOPTobHE9Z+woboTJZmRUjWdjrkKhr+qJ+GIGtl77l1dT
210+
tUPlcFgQSQylNre0ScGq2+BkL2Bc6a+k3iNklj6v4LRqkVMCK4KkSb5O0hyDVRh+hBUqyhhqXNE98WQ1
211+
T4aE9IoTdGU2V0tnbzoS/xG1dbMbUdPhbgx7GZK9zscuVu4jgy+HBy99HZ/yKxxMUjBgfi1ZdrjJYiL1
212+
8v+sB7fJGlGU+F7CnlZ3sMz2/rvrtJhp3bi7c8l/cHOzfOdmbr4DAAD//1EkCUvDAgAA
213+
`,
214+
},
215+
216+
"/defs-config.json": {
217+
local: "defs-config.json",
218+
size: 1755,
219+
modtime: 1463700704,
220+
compressed: `
221+
H4sIAAAJbogA/7xUzc7TMBA8N09hBY6BXhAHri1HVKQIOFZusm63xF5rvQEi1HfHSauS/qRKKV8PVeOx
222+
Z2bXY/t3olRaQigYvSC59INK52DQYTsKymsWLOpKsxJSCw9uRk40OmAVvwyuVe6hQIOF7vjZXvCoEAVb
223+
jwgW3fLjOCLSeGgNabWFQjpqh3smD9EXQm91xL8E4BOkpxGE0a3T49Qu+8v7BJa4OWe+ZjAtMxYb3m4D
224+
uVfTXt1TdPL+3S29/Kf2/09z5ut8o/ms5YckP/7yFKD8TCz3qlrt825DF/toruu7H0NpaGbdpFl/CgXs
225+
eRk38otWA6bCjafY9vO9Z7Z8vulXqmp797EYFeA34u9xyRzH36qk/3/QSplITHjkZpdozBLLiy5ffnsr
226+
3QAP+o7rf4NBTh+YuzegYNACg8frUEeWTCYRNcRWS5d+JL0RtHA9YF3Lhv7pyTzUs1xdPJuj2GQtDN/Q
227+
W1SwXppll8oQfUVUgXaDqSTtb5f8CQAA//8Cok052wYAAA==
228+
`,
229+
},
230+
203231
"/defs-image.json": {
204232
local: "defs-image.json",
205233
size: 3100,
@@ -221,20 +249,20 @@ dwN3Or48T12UYhfH478BrlWPMiuzfgUAAP//VjUNyBwMAAA=
221249

222250
"/defs.json": {
223251
local: "defs.json",
224-
size: 3044,
225-
modtime: 1463695223,
252+
size: 3193,
253+
modtime: 1463700693,
226254
compressed: `
227-
H4sIAAAJbogA/6xWT3PaPhC98yk8/H5H2tiybENvnaZ/csiEmUxPnR5cs4BakFRZ7jTN8N0rGWMse3Ew
228-
5QBYu9r3dt+usJ5HnjdeQJ4pJjUTfPzGG9/CknFmV7lX5LDw9FqJYrUWhTaP4D1I4O8E1ynjoLxHCRlb
229-
siwtwyd7vBrA4FkKY2RcT+uVWesnCZbN2GEFqowsHVsTuy22xvcqINOjOf1dmQOSlMbdpEYO4qHQIUli
230-
DNzaO/AhGQpPAprQaRhTjKN2dohiOpRoRkgYJsQP42lEkyT2fR9hRHY51MUF3cF4SBR1cAf3BgOOoyjs
231-
Qg/uCwZNyYzO4oTMuviD24HhB1NK44RSPwkTfxZFBBM/iOfC4qomoeDwsDSGL5XBq12l+38F1jv+76Zx
232-
4G4qyeuNuwkefaiGF5tNY3f19BXR4poZGmWvmmGuFeOr4RkeOPbx181pm8rHEnb/jY2S+PYdMn2cJJlq
233-
kz+fKyFBaQZ5I8i4Xz8Hk51j6ith1Pw9JPX57raZyOkOmbPlBH68NPCtUunTw9LE55gEqXUfFWAatq2q
234-
cSqbD1phxbcX/UJKXFOX5wPbwDzVa4yhGXfY/57/elnAVvIOwCchfjQR5IkpkW5SPWx1CdjcG5lW+Xk4
235-
WNZtNHDK7wGzOr0wxBWfFeSqM1UqjDLe3d6nUrZO8akGrEWundPSQ9k8MW3JssMl6xpgOfsDF6KgityL
236-
gutz1MhFobIzqfsH0txTNeNpdU/9Zzgh3StqL9Q5I16N37B/53pKFfwsmIKF87Jyap50RG2Tu++hkf3s
237-
Rn8DAAD//2VgiEzkCwAA
255+
H4sIAAAJbogA/7RWTXPaMBC98ys8tEfa2PIX9NYp/cghAzOZnjo9uGYBtSCpstxpmuG/VzLGWPZiMKWH
256+
JPau9r23T6tYzwPHGS4gSyUVinI2fOMMp7CkjJq3zMkzWDhqLXm+WvNc6UdwZgLYO85UQhlI51FASpc0
257+
TYry0R6vAtB4hkIHKVPj6k2/qycBhk3HYQWyqCwSW127zbc698oj42M4+V2GPRIXwd2oQvaivtA+iSMM
258+
3MRb8D7pC0+8IA7GfhRgHFWyRRQFfYkmhPh+TFw/GodBHEeu6yKMyCqLOr9idzAeEoYt3N57gwFHYei3
259+
oXvvCwYdkEkwiWIyaeP33g4M3xsHQRQHgRv7sTsJQ4KZ70VzbnBlnZAzmC114EsZcKpUkX4pwWSHL+5q
260+
B+6utLxauBvh1YduWL7Z1FaXT18RL26pUDt7U4WZkpSt+is8cOzrb6tpm4jHAnb/Gxsl/u07pOo4SSJR
261+
Wj+bSy5AKgpZrUinXz97o50V6mphUP/bEjXbU/9nUSXWGVGf76d1IafHRh94q/DjtYVvpUyeZktdn2EW
262+
JCZ9dIAq2Da6xqmMHrTDkm9v/ZWU+EbbPB/oBuaJWmMM9brD+vfs13kDG+ItgE+c/6gjiBNTImxRHWxV
263+
C9hh1DatsstwMNVNNLDa7wAzPp0Z4pLPGHLTmSocRhnvpw+JEI1/Lac2YM0zZZ2WDsr6iWlalh5ufrcA
264+
y+gfuBIFdeSB50xd4kbGc5leSN09kPryrChLysvzP8NxYd+bO6EuGfFy/Pp9MqoplfAzpxIW1hfU6nnU
265+
MrVJbn8cB+ZnN/gbAAD//0JyEpx5DAAA
238266
`,
239267
},
240268

schema/schema.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const (
2121
MediaTypeManifest Validator = `application/vnd.oci.image.manifest.v1+json`
2222
MediaTypeManifestList Validator = `application/vnd.oci.image.manifest.list.v1+json`
2323
MediaTypeImageSerialization unimplemented = `application/vnd.oci.image.serialization.rootfs.tar.gzip`
24-
MediaTypeImageSerializationConfig unimplemented = `application/vnd.oci.image.serialization.config.v1+json`
24+
MediaTypeImageSerializationConfig Validator = `application/vnd.oci.image.serialization.config.v1+json`
2525
MediaTypeImageSerializationCombined unimplemented = `application/vnd.oci.image.serialization.combined.v1+json`
2626
)
2727

@@ -32,8 +32,9 @@ var (
3232

3333
// specs maps OCI schema media types to schema files.
3434
specs = map[Validator]string{
35-
MediaTypeManifest: "image-manifest-schema.json",
36-
MediaTypeManifestList: "manifest-list-schema.json",
35+
MediaTypeManifest: "image-manifest-schema.json",
36+
MediaTypeManifestList: "manifest-list-schema.json",
37+
MediaTypeImageSerializationConfig: "config-schema.json",
3738
}
3839
)
3940

schema/spec_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,17 @@ var (
3333
errFormatInvalid = errors.New("format: invalid")
3434
)
3535

36+
func TestValidateManifest(t *testing.T) {
37+
validate(t, "../manifest.md")
38+
}
39+
40+
func TestValidateSerialization(t *testing.T) {
41+
validate(t, "../serialization.md")
42+
}
43+
3644
// TODO(sur): include examples from all specification files
37-
func TestSpecExamples(t *testing.T) {
38-
m, err := os.Open("../manifest.md")
45+
func validate(t *testing.T, name string) {
46+
m, err := os.Open(name)
3947
if err != nil {
4048
t.Fatal(err)
4149
}
@@ -46,6 +54,10 @@ func TestSpecExamples(t *testing.T) {
4654
}
4755

4856
for _, example := range examples {
57+
if example.Err == errFormatInvalid && example.Mediatype == "" { // ignore
58+
continue
59+
}
60+
4961
if example.Err != nil {
5062
printFields(t, "error", example.Mediatype, example.Title, example.Err)
5163
t.Error(err)

serialization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ This specification uses the following terms:
8787

8888
Here is an example image JSON file:
8989

90-
```
90+
```json,title=Image%20JSON&mediatype=application/vnd.oci.image.serialization.config.v1%2Bjson
9191
{
9292
"created": "2015-10-31T22:22:56.015925234Z",
9393
"author": "Alyssa P. Hacker &[email protected]&gt",

0 commit comments

Comments
 (0)