Skip to content

Commit 4882fc1

Browse files
author
Ma Shimiao
authored
Merge pull request #197 from wking/json-schema
validate: Check configuration against JSON Schema
2 parents 6073aff + 3935592 commit 4882fc1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+6880
-494
lines changed

Diff for: Godeps/Godeps.json

+32-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: validate/validate.go

+47
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/syndtr/gocapability/capability"
2525

2626
"github.com/opencontainers/runtime-tools/specerror"
27+
"github.com/xeipuuv/gojsonschema"
2728
)
2829

2930
const specConfig = "config.json"
@@ -47,6 +48,8 @@ var (
4748
"RLIMIT_SIGPENDING",
4849
"RLIMIT_STACK",
4950
}
51+
52+
configSchemaTemplate = "https://raw.githubusercontent.com/opencontainers/runtime-spec/v%s/schema/config-schema.json"
5053
)
5154

5255
// Validator represents a validator for runtime bundle
@@ -102,6 +105,7 @@ func NewValidatorFromPath(bundlePath string, hostSpecific bool, platform string)
102105
// CheckAll checks all parts of runtime bundle
103106
func (v *Validator) CheckAll() error {
104107
var errs *multierror.Error
108+
errs = multierror.Append(errs, v.CheckJSONSchema())
105109
errs = multierror.Append(errs, v.CheckPlatform())
106110
errs = multierror.Append(errs, v.CheckRoot())
107111
errs = multierror.Append(errs, v.CheckMandatoryFields())
@@ -114,6 +118,49 @@ func (v *Validator) CheckAll() error {
114118
return errs.ErrorOrNil()
115119
}
116120

121+
// JSONSchemaURL returns the URL for the JSON Schema specifying the
122+
// configuration format. It consumes configSchemaTemplate, but we
123+
// provide it as a function to isolate consumers from inconsistent
124+
// naming as runtime-spec evolves.
125+
func JSONSchemaURL(version string) (url string, err error) {
126+
ver, err := semver.Parse(version)
127+
if err != nil {
128+
return "", err
129+
}
130+
configRenamedToConfigSchemaVersion, err := semver.Parse("1.0.0-rc2") // config.json became config-schema.json in 1.0.0-rc2
131+
if ver.Compare(configRenamedToConfigSchemaVersion) == -1 {
132+
return "", fmt.Errorf("unsupported configuration version (older than %s)", configRenamedToConfigSchemaVersion)
133+
}
134+
return fmt.Sprintf(configSchemaTemplate, version), nil
135+
}
136+
137+
// CheckJSONSchema validates the configuration against the
138+
// runtime-spec JSON Schema, using the version of the schema that
139+
// matches the configuration's declared version.
140+
func (v *Validator) CheckJSONSchema() (errs error) {
141+
url, err := JSONSchemaURL(v.spec.Version)
142+
if err != nil {
143+
errs = multierror.Append(errs, err)
144+
return errs
145+
}
146+
147+
schemaLoader := gojsonschema.NewReferenceLoader(url)
148+
documentLoader := gojsonschema.NewGoLoader(v.spec)
149+
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
150+
if err != nil {
151+
errs = multierror.Append(errs, err)
152+
return errs
153+
}
154+
155+
if !result.Valid() {
156+
for _, resultError := range result.Errors() {
157+
errs = multierror.Append(errs, errors.New(resultError.String()))
158+
}
159+
}
160+
161+
return errs
162+
}
163+
117164
// CheckRoot checks status of v.spec.Root
118165
func (v *Validator) CheckRoot() (errs error) {
119166
logrus.Debugf("check root")

Diff for: validate/validate_test.go

+57
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"runtime"
99
"testing"
1010

11+
"github.com/hashicorp/go-multierror"
1112
rspec "github.com/opencontainers/runtime-spec/specs-go"
1213
"github.com/stretchr/testify/assert"
1314

@@ -32,6 +33,62 @@ func TestNewValidator(t *testing.T) {
3233
}
3334
}
3435

36+
func TestJSONSchema(t *testing.T) {
37+
for _, tt := range []struct {
38+
config *rspec.Spec
39+
error string
40+
}{
41+
{
42+
config: &rspec.Spec{},
43+
error: "Version string empty",
44+
},
45+
{
46+
config: &rspec.Spec{
47+
Version: "1.0.1-rc1",
48+
},
49+
error: "Could not read schema from HTTP, response status is 404 Not Found",
50+
},
51+
{
52+
config: &rspec.Spec{
53+
Version: "1.0.0",
54+
},
55+
error: "",
56+
},
57+
{
58+
config: &rspec.Spec{
59+
Version: "1.0.0",
60+
Process: &rspec.Process{},
61+
},
62+
error: "process.args: Invalid type. Expected: array, given: null",
63+
},
64+
{
65+
config: &rspec.Spec{
66+
Version: "1.0.0-rc5",
67+
},
68+
error: "process: process is required",
69+
},
70+
} {
71+
t.Run(tt.error, func(t *testing.T) {
72+
v := &Validator{spec: tt.config}
73+
errs := v.CheckJSONSchema()
74+
if tt.error == "" {
75+
assert.Equal(t, nil, errs)
76+
return
77+
}
78+
merr, ok := errs.(*multierror.Error)
79+
if !ok {
80+
t.Fatalf("non-multierror returned by CheckJSONSchema: %s", errs.Error())
81+
}
82+
for _, err := range merr.Errors {
83+
if err.Error() == tt.error {
84+
return
85+
}
86+
}
87+
assert.Equal(t, tt.error, errs.Error())
88+
})
89+
}
90+
}
91+
3592
func TestCheckRoot(t *testing.T) {
3693
tmpBundle, err := ioutil.TempDir("", "oci-check-rootfspath")
3794
if err != nil {

Diff for: vendor/github.com/davecgh/go-spew/LICENSE

+4-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: vendor/github.com/davecgh/go-spew/spew/bypass.go

+8-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: vendor/github.com/davecgh/go-spew/spew/bypasssafe.go

+5-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: vendor/github.com/davecgh/go-spew/spew/common.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: vendor/github.com/davecgh/go-spew/spew/config.go

+11-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: vendor/github.com/davecgh/go-spew/spew/doc.go

+10-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)