From f9eaf54eae539996e7ade06b86deb4ee5353c6fb Mon Sep 17 00:00:00 2001 From: zhouhao Date: Mon, 21 Nov 2016 15:11:37 +0800 Subject: [PATCH] schema: add checkPlatform Signed-off-by: zhouhao --- schema/validator.go | 84 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/schema/validator.go b/schema/validator.go index 8a4ef75fa..1729d8afb 100644 --- a/schema/validator.go +++ b/schema/validator.go @@ -32,11 +32,13 @@ import ( // and implements validation against a JSON schema. type Validator string -type validateDescendantsFunc func(r io.Reader) error +type validateFunc func(r io.Reader) error -var mapValidateDescendants = map[Validator]validateDescendantsFunc{ - ValidatorMediaTypeManifest: validateManifestDescendants, - ValidatorMediaTypeDescriptor: validateDescriptorDescendants, +var mapValidate = map[Validator]validateFunc{ + ValidatorMediaTypeImageConfig: validateConfig, + ValidatorMediaTypeDescriptor: validateDescriptor, + ValidatorMediaTypeImageIndex: validateIndex, + ValidatorMediaTypeManifest: validateManifest, } // ValidationError contains all the errors that happened during validation. @@ -55,9 +57,9 @@ func (v Validator) Validate(src io.Reader) error { return errors.Wrap(err, "unable to read the document file") } - if f, ok := mapValidateDescendants[v]; ok { + if f, ok := mapValidate[v]; ok { if f == nil { - return fmt.Errorf("internal error: mapValidateDescendents[%q] is nil", v) + return fmt.Errorf("internal error: mapValidate[%q] is nil", v) } err = f(bytes.NewReader(buf)) if err != nil { @@ -95,7 +97,7 @@ func (v unimplemented) Validate(src io.Reader) error { return fmt.Errorf("%s: unimplemented", v) } -func validateManifestDescendants(r io.Reader) error { +func validateManifest(r io.Reader) error { header := v1.Manifest{} buf, err := ioutil.ReadAll(r) @@ -128,7 +130,7 @@ var ( sha512EncodedRegexp = regexp.MustCompile(`^[a-f0-9]{128}$`) ) -func validateDescriptorDescendants(r io.Reader) error { +func validateDescriptor(r io.Reader) error { header := v1.Descriptor{} buf, err := ioutil.ReadAll(r) @@ -158,3 +160,69 @@ func validateDescriptorDescendants(r io.Reader) error { } return nil } + +func validateIndex(r io.Reader) error { + header := v1.Index{} + + buf, err := ioutil.ReadAll(r) + if err != nil { + return errors.Wrapf(err, "error reading the io stream") + } + + err = json.Unmarshal(buf, &header) + if err != nil { + return errors.Wrap(err, "manifestlist format mismatch") + } + + for _, manifest := range header.Manifests { + if manifest.MediaType != string(v1.MediaTypeImageManifest) { + fmt.Printf("warning: manifest %s has an unknown media type: %s\n", manifest.Digest, manifest.MediaType) + } + + } + + return nil +} + +func validateConfig(r io.Reader) error { + header := v1.Image{} + + buf, err := ioutil.ReadAll(r) + if err != nil { + return errors.Wrapf(err, "error reading the io stream") + } + + err = json.Unmarshal(buf, &header) + if err != nil { + return errors.Wrap(err, "config format mismatch") + } + + checkPlatform(header.OS, header.Architecture) + + return nil +} + +func checkPlatform(OS string, Architecture string) { + validCombins := map[string][]string{ + "android": {"arm"}, + "darwin": {"386", "amd64", "arm", "arm64"}, + "dragonfly": {"amd64"}, + "freebsd": {"386", "amd64", "arm"}, + "linux": {"386", "amd64", "arm", "arm64", "ppc64", "ppc64le", "mips64", "mips64le", "s390x"}, + "netbsd": {"386", "amd64", "arm"}, + "openbsd": {"386", "amd64", "arm"}, + "plan9": {"386", "amd64"}, + "solaris": {"amd64"}, + "windows": {"386", "amd64"}} + for os, archs := range validCombins { + if os == OS { + for _, arch := range archs { + if arch == Architecture { + return + } + } + fmt.Printf("warning: combination of %q and %q is invalid.", OS, Architecture) + } + } + fmt.Printf("warning: operating system %q of the bundle is not supported yet.", OS) +}