@@ -30,10 +30,12 @@ import (
3030// and implements validation against a JSON schema.
3131type Validator string
3232
33- type validateDescendantsFunc func (r io.Reader ) error
33+ type validateFunc func (r io.Reader ) error
3434
35- var mapValidateDescendants = map [Validator ]validateDescendantsFunc {
36- ValidatorMediaTypeManifest : validateManifestDescendants ,
35+ var mapValidate = map [Validator ]validateFunc {
36+ ValidatorMediaTypeImageConfig : validateConfig ,
37+ ValidatorMediaTypeManifest : validateManifest ,
38+ ValidatorMediaTypeImageIndex : validateIndex ,
3739}
3840
3941// ValidationError contains all the errors that happened during validation.
@@ -52,9 +54,9 @@ func (v Validator) Validate(src io.Reader) error {
5254 return errors .Wrap (err , "unable to read the document file" )
5355 }
5456
55- if f , ok := mapValidateDescendants [v ]; ok {
57+ if f , ok := mapValidate [v ]; ok {
5658 if f == nil {
57- return fmt .Errorf ("internal error: mapValidateDescendents [%q] is nil" , v )
59+ return fmt .Errorf ("internal error: mapValidate [%q] is nil" , v )
5860 }
5961 err = f (bytes .NewReader (buf ))
6062 if err != nil {
@@ -92,7 +94,7 @@ func (v unimplemented) Validate(src io.Reader) error {
9294 return fmt .Errorf ("%s: unimplemented" , v )
9395}
9496
95- func validateManifestDescendants (r io.Reader ) error {
97+ func validateManifest (r io.Reader ) error {
9698 header := v1.Manifest {}
9799
98100 buf , err := ioutil .ReadAll (r )
@@ -119,3 +121,66 @@ func validateManifestDescendants(r io.Reader) error {
119121 }
120122 return nil
121123}
124+
125+ func validateIndex (r io.Reader ) error {
126+ header := v1.Index {}
127+
128+ buf , err := ioutil .ReadAll (r )
129+ if err != nil {
130+ return errors .Wrapf (err , "error reading the io stream" )
131+ }
132+
133+ err = json .Unmarshal (buf , & header )
134+ if err != nil {
135+ return errors .Wrap (err , "manifestlist format mismatch" )
136+ }
137+
138+ for _ , manifest := range header .Manifests {
139+ checkPlatform (manifest .Platform .OS , manifest .Platform .Architecture )
140+ }
141+
142+ return nil
143+ }
144+
145+ func validateConfig (r io.Reader ) error {
146+ header := v1.Image {}
147+
148+ buf , err := ioutil .ReadAll (r )
149+ if err != nil {
150+ return errors .Wrapf (err , "error reading the io stream" )
151+ }
152+
153+ err = json .Unmarshal (buf , & header )
154+ if err != nil {
155+ return errors .Wrap (err , "config format mismatch" )
156+ }
157+
158+ checkPlatform (header .OS , header .Architecture )
159+
160+ return nil
161+ }
162+
163+ func checkPlatform (OS string , Architecture string ) {
164+ validCombins := map [string ][]string {
165+ "android" : {"arm" },
166+ "darwin" : {"386" , "amd64" , "arm" , "arm64" },
167+ "dragonfly" : {"amd64" },
168+ "freebsd" : {"386" , "amd64" , "arm" },
169+ "linux" : {"386" , "amd64" , "arm" , "arm64" , "ppc64" , "ppc64le" , "mips64" , "mips64le" , "s390x" },
170+ "netbsd" : {"386" , "amd64" , "arm" },
171+ "openbsd" : {"386" , "amd64" , "arm" },
172+ "plan9" : {"386" , "amd64" },
173+ "solaris" : {"amd64" },
174+ "windows" : {"386" , "amd64" }}
175+ for os , archs := range validCombins {
176+ if os == OS {
177+ for _ , arch := range archs {
178+ if arch == Architecture {
179+ break
180+ }
181+ }
182+ fmt .Printf ("warning: combination of %q and %q is invalid." , OS , Architecture )
183+ }
184+ }
185+ fmt .Printf ("warning: operating system %q of the bundle is not supported yet." , OS )
186+ }
0 commit comments