diff --git a/.travis.yml b/.travis.yml index 7f6c11f11..7c2de7e71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,3 +22,4 @@ script: - echo "${TRAVIS_COMMIT_RANGE} -> ${TRAVIS_COMMIT_RANGE/.../..} (travis-ci/travis-ci#4596)" - TRAVIS_COMMIT_RANGE="${TRAVIS_COMMIT_RANGE/.../..}" make .gitvalidation - make docs + - make -C schema test diff --git a/schema/Makefile b/schema/Makefile index 0a0b04084..bc9e30270 100644 --- a/schema/Makefile +++ b/schema/Makefile @@ -1,3 +1,5 @@ +GOOD_TESTS = $(wildcard test/good/*.json) +BAD_TESTS = $(wildcard test/bad/*.json) .PHONY: default default: validate @@ -12,13 +14,42 @@ help: .PHONY: fmt fmt: - for i in *.json ; do jq --indent 4 -M . "$${i}" > xx && cat xx > "$${i}" && rm xx ; done + find . -name '*.json' -exec bash -c 'jq --indent 4 -M . {} > xx && mv xx {} || echo "skipping invalid {}"' \; .PHONY: validate validate: validate.go go get -d ./... go build ./validate.go +.PHONY: test +test: validate $(TESTS) + for TYPE in $$(ls test); \ + do \ + echo "testing $${TYPE}"; \ + for FILE in $$(ls "test/$${TYPE}/good"); \ + do \ + echo " testing test/$${TYPE}/good/$${FILE}"; \ + if ./validate "$${TYPE}-schema.json" "test/$${TYPE}/good/$${FILE}" ; \ + then \ + echo " received expected validation success" ; \ + else \ + echo " received unexpected validation failure" ; \ + exit 1; \ + fi \ + done; \ + for FILE in $$(ls "test/$${TYPE}/bad"); \ + do \ + echo " testing test/$${TYPE}/bad/$${FILE}"; \ + if ./validate "$${TYPE}-schema.json" "test/$${TYPE}/good/$${FILE}" ; \ + then \ + echo " received unexpected validation success" ; \ + exit 1; \ + else \ + echo " received expected validation failure" ; \ + fi \ + done; \ + done + .PHONY: clean clean: rm -f validate diff --git a/schema/test/config/bad/invalid-json.json b/schema/test/config/bad/invalid-json.json new file mode 100644 index 000000000..8e9352830 --- /dev/null +++ b/schema/test/config/bad/invalid-json.json @@ -0,0 +1 @@ +{] diff --git a/schema/test/config/good/minimal.json b/schema/test/config/good/minimal.json new file mode 100644 index 000000000..4d8f177a3 --- /dev/null +++ b/schema/test/config/good/minimal.json @@ -0,0 +1,18 @@ +{ + "ociVersion": "1.0.0", + "platform": { + "os": "linux", + "arch": "amd64" + }, + "root": { + "path": "rootfs" + }, + "process": { + "cwd": "/", + "args": ["sh"], + "user": { + "uid": 0, + "gid": 0 + } + } +} diff --git a/schema/test/config/good/spec-example.json b/schema/test/config/good/spec-example.json new file mode 100644 index 000000000..309183c6f --- /dev/null +++ b/schema/test/config/good/spec-example.json @@ -0,0 +1,372 @@ +{ + "ociVersion": "0.5.0-dev", + "platform": { + "os": "linux", + "arch": "amd64" + }, + "process": { + "terminal": true, + "user": { + "uid": 1, + "gid": 1, + "additionalGids": [ + 5, + 6 + ] + }, + "args": [ + "sh" + ], + "env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "TERM=xterm" + ], + "cwd": "/", + "capabilities": { + "bounding": [ + "CAP_AUDIT_WRITE", + "CAP_KILL", + "CAP_NET_BIND_SERVICE" + ], + "permitted": [ + "CAP_AUDIT_WRITE", + "CAP_KILL", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [ + "CAP_AUDIT_WRITE", + "CAP_KILL", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_AUDIT_WRITE", + "CAP_KILL" + ], + "ambient": [ + "CAP_NET_BIND_SERVICE" + ] + }, + "rlimits": [ + { + "type": "RLIMIT_CORE", + "hard": 1024, + "soft": 1024 + }, + { + "type": "RLIMIT_NOFILE", + "hard": 1024, + "soft": 1024 + } + ], + "apparmorProfile": "acme_secure_profile", + "selinuxLabel": "system_u:system_r:svirt_lxc_net_t:s0:c124,c675", + "noNewPrivileges": true + }, + "root": { + "path": "rootfs", + "readonly": true + }, + "hostname": "slartibartfast", + "mounts": [ + { + "destination": "/proc", + "type": "proc", + "source": "proc" + }, + { + "destination": "/dev", + "type": "tmpfs", + "source": "tmpfs", + "options": [ + "nosuid", + "strictatime", + "mode=755", + "size=65536k" + ] + }, + { + "destination": "/dev/pts", + "type": "devpts", + "source": "devpts", + "options": [ + "nosuid", + "noexec", + "newinstance", + "ptmxmode=0666", + "mode=0620", + "gid=5" + ] + }, + { + "destination": "/dev/shm", + "type": "tmpfs", + "source": "shm", + "options": [ + "nosuid", + "noexec", + "nodev", + "mode=1777", + "size=65536k" + ] + }, + { + "destination": "/dev/mqueue", + "type": "mqueue", + "source": "mqueue", + "options": [ + "nosuid", + "noexec", + "nodev" + ] + }, + { + "destination": "/sys", + "type": "sysfs", + "source": "sysfs", + "options": [ + "nosuid", + "noexec", + "nodev" + ] + }, + { + "destination": "/sys/fs/cgroup", + "type": "cgroup", + "source": "cgroup", + "options": [ + "nosuid", + "noexec", + "nodev", + "relatime", + "ro" + ] + } + ], + "hooks": { + "prestart": [ + { + "path": "/usr/bin/fix-mounts", + "args": [ + "fix-mounts", + "arg1", + "arg2" + ], + "env": [ + "key1=value1" + ] + }, + { + "path": "/usr/bin/setup-network" + } + ], + "poststart": [ + { + "path": "/usr/bin/notify-start", + "timeout": 5 + } + ], + "poststop": [ + { + "path": "/usr/sbin/cleanup.sh", + "args": [ + "cleanup.sh", + "-f" + ] + } + ] + }, + "linux": { + "devices": [ + { + "path": "/dev/fuse", + "type": "c", + "major": 10, + "minor": 229, + "fileMode": 438, + "uid": 0, + "gid": 0 + }, + { + "path": "/dev/sda", + "type": "b", + "major": 8, + "minor": 0, + "fileMode": 432, + "uid": 0, + "gid": 0 + } + ], + "uidMappings": [ + { + "hostID": 1000, + "containerID": 0, + "size": 32000 + } + ], + "gidMappings": [ + { + "hostID": 1000, + "containerID": 0, + "size": 32000 + } + ], + "sysctl": { + "net.ipv4.ip_forward": "1", + "net.core.somaxconn": "256" + }, + "cgroupsPath": "/myRuntime/myContainer", + "resources": { + "network": { + "classID": 1048577, + "priorities": [ + { + "name": "eth0", + "priority": 500 + }, + { + "name": "eth1", + "priority": 1000 + } + ] + }, + "pids": { + "limit": 32771 + }, + "hugepageLimits": [ + { + "pageSize": "2MB", + "limit": 9223372036854772000 + } + ], + "oomScoreAdj": 100, + "memory": { + "limit": 536870912, + "reservation": 536870912, + "swap": 536870912, + "kernel": 0, + "kernelTCP": 0, + "swappiness": 0 + }, + "cpu": { + "shares": 1024, + "quota": 1000000, + "period": 500000, + "realtimeRuntime": 950000, + "realtimePeriod": 1000000, + "cpus": "2-3", + "mems": "0-7" + }, + "disableOOMKiller": false, + "devices": [ + { + "allow": false, + "access": "rwm" + }, + { + "allow": true, + "type": "c", + "major": 10, + "minor": 229, + "access": "rw" + }, + { + "allow": true, + "type": "b", + "major": 8, + "minor": 0, + "access": "r" + } + ], + "blockIO": { + "blkioWeight": 10, + "blkioLeafWeight": 10, + "blkioWeightDevice": [ + { + "major": 8, + "minor": 0, + "weight": 500, + "leafWeight": 300 + }, + { + "major": 8, + "minor": 16, + "weight": 500 + } + ], + "blkioThrottleReadBpsDevice": [ + { + "major": 8, + "minor": 0, + "rate": 600 + } + ], + "blkioThrottleWriteIOPSDevice": [ + { + "major": 8, + "minor": 16, + "rate": 300 + } + ] + } + }, + "rootfsPropagation": "slave", + "seccomp": { + "defaultAction": "SCMP_ACT_ALLOW", + "architectures": [ + "SCMP_ARCH_X86", + "SCMP_ARCH_X32" + ], + "syscalls": [ + { + "names": [ + "getcwd", + "chmod" + ], + "action": "SCMP_ACT_ERRNO" + } + ] + }, + "namespaces": [ + { + "type": "pid" + }, + { + "type": "network" + }, + { + "type": "ipc" + }, + { + "type": "uts" + }, + { + "type": "mount" + }, + { + "type": "user" + }, + { + "type": "cgroup" + } + ], + "maskedPaths": [ + "/proc/kcore", + "/proc/latency_stats", + "/proc/timer_stats", + "/proc/sched_debug" + ], + "readonlyPaths": [ + "/proc/asound", + "/proc/bus", + "/proc/fs", + "/proc/irq", + "/proc/sys", + "/proc/sysrq-trigger" + ], + "mountLabel": "system_u:object_r:svirt_sandbox_file_t:s0:c715,c811" + }, + "annotations": { + "com.example.key1": "value1", + "com.example.key2": "value2" + } +} diff --git a/schema/test/state/bad/invalid-json.json b/schema/test/state/bad/invalid-json.json new file mode 100644 index 000000000..8e9352830 --- /dev/null +++ b/schema/test/state/bad/invalid-json.json @@ -0,0 +1 @@ +{] diff --git a/schema/test/state/good/spec-example.json b/schema/test/state/good/spec-example.json new file mode 100644 index 000000000..a49faee56 --- /dev/null +++ b/schema/test/state/good/spec-example.json @@ -0,0 +1,10 @@ +{ + "ociVersion": "0.2.0", + "id": "oci-container1", + "status": "running", + "pid": 4422, + "bundle": "/containers/redis", + "annotations": { + "myKey": "myValue" + } +}