Skip to content

Commit 19e812c

Browse files
committed
Merge pull request #18 from vbatts/json_schema
Json schema for image manifest and manifest list
2 parents 2273702 + 64b5003 commit 19e812c

File tree

5 files changed

+362
-0
lines changed

5 files changed

+362
-0
lines changed

schema/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
default: help
3+
4+
help:
5+
@echo "Usage: make <target>"
6+
@echo
7+
@echo " * 'fmt' - format the json with indentation"
8+
@echo " * 'validate' - build the validation tool"
9+
10+
fmt:
11+
for i in *.json ; do jq --indent 2 -M . "$${i}" > xx && cat xx > "$${i}" && rm xx ; done
12+
13+
validate: validate.go
14+
go build ./validate.go
15+

schema/defs-image.json

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
{
2+
"description": "Definitions particular to OpenContainer Image Specification",
3+
"definitions": {
4+
"mediaType": {
5+
"id": "https://opencontainers.org/schema/image/mediaType",
6+
"type": "string",
7+
"pattern": "^[a-z]+/[0-9a-zA-Z.+]+$"
8+
},
9+
"digest": {
10+
"description": "the cryptographic checksum digest of the object, in the pattern '<hash>:<hexadecimal digest>'",
11+
"type": "string",
12+
"pattern": "^[a-z0-9]+:[a-fA-F0-9]+$"
13+
},
14+
"blobObject": {
15+
"id": "https://opencontainers.org/schema/image/blobObject",
16+
"type": "object",
17+
"required": [
18+
"mediaType",
19+
"size",
20+
"digest"
21+
],
22+
"properties": {
23+
"mediaType": {
24+
"description": "the mediatype of the referenced object",
25+
"$ref": "#definitions/mediaType"
26+
},
27+
"size": {
28+
"description": "the size in bytes of the referenced object",
29+
"type": "integer"
30+
},
31+
"digest": {
32+
"$ref": "#definitions/digest"
33+
}
34+
}
35+
},
36+
"manifestObject": {
37+
"id": "https://opencontainers.org/schema/image/manifestObject",
38+
"type": "object",
39+
"required": [
40+
"mediaType",
41+
"size",
42+
"digest",
43+
"platform"
44+
],
45+
"properties": {
46+
"mediaType": {
47+
"description": "the mediatype of the referenced object",
48+
"$ref": "#definitions/mediaType"
49+
},
50+
"size": {
51+
"description": "the size in bytes of the referenced object",
52+
"type": "integer"
53+
},
54+
"digest": {
55+
"$ref": "#definitions/digest"
56+
},
57+
"platform": {
58+
"id": "https://opencontainers.org/schema/image/platform",
59+
"type": "object",
60+
"required": [
61+
"architecture",
62+
"os"
63+
],
64+
"properties": {
65+
"architecture": {
66+
"id": "https://opencontainers.org/schema/image/platform/architecture",
67+
"type": "string"
68+
},
69+
"os": {
70+
"id": "https://opencontainers.org/schema/image/platform/os",
71+
"type": "string"
72+
},
73+
"os.version": {
74+
"id": "https://opencontainers.org/schema/image/platform/os.version",
75+
"type": "string"
76+
},
77+
"os.features": {
78+
"id": "https://opencontainers.org/schema/image/platform/os.features",
79+
"type": "array",
80+
"items": {
81+
"type": "string"
82+
}
83+
},
84+
"variant": {
85+
"type": "string"
86+
},
87+
"features": {
88+
"type": "array",
89+
"items": {
90+
"type": "string"
91+
},
92+
"additionalProperties": false
93+
}
94+
}
95+
}
96+
}
97+
}
98+
}
99+
}

schema/defs.json

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
{
2+
"description": "Definitions used throughout the OpenContainer Specification",
3+
"definitions": {
4+
"int8": {
5+
"type": "integer",
6+
"minimum": -128,
7+
"maximum": 127
8+
},
9+
"int16": {
10+
"type": "integer",
11+
"minimum": -32768,
12+
"maximum": 32767
13+
},
14+
"int32": {
15+
"type": "integer",
16+
"minimum": -2147483648,
17+
"maximum": 2147483647
18+
},
19+
"int64": {
20+
"type": "integer",
21+
"minimum": -9223372036854776000,
22+
"maximum": 9223372036854776000
23+
},
24+
"uint8": {
25+
"type": "integer",
26+
"minimum": 0,
27+
"maximum": 255
28+
},
29+
"uint16": {
30+
"type": "integer",
31+
"minimum": 0,
32+
"maximum": 65535
33+
},
34+
"uint32": {
35+
"type": "integer",
36+
"minimum": 0,
37+
"maximum": 4294967295
38+
},
39+
"uint64": {
40+
"type": "integer",
41+
"minimum": 0,
42+
"maximum": 18446744073709552000
43+
},
44+
"uint16Pointer": {
45+
"oneOf": [
46+
{
47+
"$ref": "#/definitions/uint16"
48+
},
49+
{
50+
"type": "null"
51+
}
52+
]
53+
},
54+
"uint64Pointer": {
55+
"oneOf": [
56+
{
57+
"$ref": "#/definitions/uint64"
58+
},
59+
{
60+
"type": "null"
61+
}
62+
]
63+
},
64+
"stringPointer": {
65+
"oneOf": [
66+
{
67+
"type": "string"
68+
},
69+
{
70+
"type": "null"
71+
}
72+
]
73+
},
74+
"mapStringString": {
75+
"type": "object",
76+
"patternProperties": {
77+
".{1,}": {
78+
"type": "string"
79+
}
80+
}
81+
},
82+
"UID": {
83+
"$ref": "#/definitions/uint32"
84+
},
85+
"GID": {
86+
"$ref": "#/definitions/uint32"
87+
},
88+
"ArrayOfGIDs": {
89+
"type": "array",
90+
"items": {
91+
"$ref": "#/definitions/GID"
92+
}
93+
},
94+
"ArrayOfStrings": {
95+
"type": "array",
96+
"items": {
97+
"type": "string"
98+
}
99+
},
100+
"FilePath": {
101+
"type": "string"
102+
},
103+
"Env": {
104+
"$ref": "#/definitions/ArrayOfStrings"
105+
},
106+
"Hook": {
107+
"properties": {
108+
"path": {
109+
"$ref": "#/definitions/FilePath"
110+
},
111+
"args": {
112+
"$ref": "#/definitions/ArrayOfStrings"
113+
},
114+
"env": {
115+
"$ref": "#/definitions/Env"
116+
}
117+
}
118+
},
119+
"ArrayOfHooks": {
120+
"type": "array",
121+
"items": {
122+
"$ref": "#/definitions/Hook"
123+
}
124+
},
125+
"IDMapping": {
126+
"properties": {
127+
"hostID": {
128+
"$ref": "#/definitions/uint32"
129+
},
130+
"containerID": {
131+
"$ref": "#/definitions/uint32"
132+
},
133+
"size": {
134+
"$ref": "#/definitions/uint32"
135+
}
136+
}
137+
},
138+
"Mount": {
139+
"properties": {
140+
"source": {
141+
"$ref": "#/definitions/FilePath"
142+
},
143+
"destination": {
144+
"$ref": "#/definitions/FilePath"
145+
},
146+
"options": {
147+
"$ref": "#/definitions/ArrayOfStrings"
148+
},
149+
"type": {
150+
"type": "string"
151+
}
152+
},
153+
"required": [
154+
"destination",
155+
"source",
156+
"type"
157+
]
158+
}
159+
}
160+
}

schema/image-manifest-schema.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"description": "OpenContainer Image Manifest Specification",
3+
"$schema": "http://json-schema.org/draft-04/schema#",
4+
"id": "https://opencontainers.org/schema/image/manifest",
5+
"type": "object",
6+
"properties": {
7+
"schemaVersion": {
8+
"description": "This field specifies the image manifest schema version as an integer",
9+
"id": "https://opencontainers.org/schema/image/manifest/schemaVersion",
10+
"type": "integer"
11+
},
12+
"mediaType": {
13+
"id": "https://opencontainers.org/schema/image/manifest/mediaType",
14+
"$ref": "defs-image.json#/definitions/mediaType"
15+
},
16+
"config": {
17+
"$ref": "defs-image.json#/definitions/blobObject"
18+
},
19+
"layers": {
20+
"type": "array",
21+
"items": {
22+
"$ref": "defs-image.json#/definitions/blobObject"
23+
}
24+
},
25+
"annotations": {
26+
"id": "https://opencontainers.org/schema/image/manifest/annotations",
27+
"oneOf": [
28+
{
29+
"$ref": "defs.json#/definitions/mapStringString"
30+
},
31+
{
32+
"type": "null"
33+
}
34+
]
35+
}
36+
},
37+
"required": [
38+
"schemaVersion",
39+
"mediaType",
40+
"config",
41+
"layers"
42+
]
43+
}

schema/validate.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
8+
"github.com/xeipuuv/gojsonschema"
9+
)
10+
11+
func main() {
12+
if len(os.Args[1:]) != 2 {
13+
fmt.Printf("ERROR: usage is: %s <schema.json> <config.json>", os.Args[0])
14+
os.Exit(1)
15+
}
16+
17+
schemaPath, err := filepath.Abs(os.Args[1])
18+
if err != nil {
19+
fmt.Println(err)
20+
os.Exit(1)
21+
}
22+
documentPath, err := filepath.Abs(os.Args[2])
23+
if err != nil {
24+
fmt.Println(err)
25+
os.Exit(1)
26+
}
27+
28+
schemaLoader := gojsonschema.NewReferenceLoader("file://" + schemaPath)
29+
documentLoader := gojsonschema.NewReferenceLoader("file://" + documentPath)
30+
31+
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
32+
if err != nil {
33+
panic(err.Error())
34+
}
35+
36+
if result.Valid() {
37+
fmt.Printf("The document is valid\n")
38+
} else {
39+
fmt.Printf("The document is not valid. see errors :\n")
40+
for _, desc := range result.Errors() {
41+
fmt.Printf("- %s\n", desc)
42+
}
43+
os.Exit(1)
44+
}
45+
}

0 commit comments

Comments
 (0)