@@ -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- MediaTypeManifest : validateManifestDescendants ,
35+ var mapValidate = map [Validator ]validateFunc {
36+ MediaTypeImageConfig : validateConfig ,
37+ MediaTypeManifest : validateManifest ,
38+ MediaTypeManifestList : validateManifestList ,
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 )
@@ -117,3 +119,66 @@ func validateManifestDescendants(r io.Reader) error {
117119 }
118120 return nil
119121}
122+
123+ func validateManifestList (r io.Reader ) error {
124+ header := v1.ManifestList {}
125+
126+ buf , err := ioutil .ReadAll (r )
127+ if err != nil {
128+ return errors .Wrapf (err , "error reading the io stream" )
129+ }
130+
131+ err = json .Unmarshal (buf , & header )
132+ if err != nil {
133+ return errors .Wrap (err , "manifestlist format mismatch" )
134+ }
135+
136+ for _ , manifest := range header .Manifests {
137+ checkPlatform (manifest .Platform .OS , manifest .Platform .Architecture )
138+ }
139+
140+ return nil
141+ }
142+
143+ func validateConfig (r io.Reader ) error {
144+ header := v1.Image {}
145+
146+ buf , err := ioutil .ReadAll (r )
147+ if err != nil {
148+ return errors .Wrapf (err , "error reading the io stream" )
149+ }
150+
151+ err = json .Unmarshal (buf , & header )
152+ if err != nil {
153+ return errors .Wrap (err , "config format mismatch" )
154+ }
155+
156+ checkPlatform (header .OS , header .Architecture )
157+
158+ return nil
159+ }
160+
161+ func checkPlatform (OS string , Architecture string ) {
162+ validCombins := map [string ][]string {
163+ "android" : {"arm" },
164+ "darwin" : {"386" , "amd64" , "arm" , "arm64" },
165+ "dragonfly" : {"amd64" },
166+ "freebsd" : {"386" , "amd64" , "arm" },
167+ "linux" : {"386" , "amd64" , "arm" , "arm64" , "ppc64" , "ppc64le" , "mips64" , "mips64le" , "s390x" },
168+ "netbsd" : {"386" , "amd64" , "arm" },
169+ "openbsd" : {"386" , "amd64" , "arm" },
170+ "plan9" : {"386" , "amd64" },
171+ "solaris" : {"amd64" },
172+ "windows" : {"386" , "amd64" }}
173+ for os , archs := range validCombins {
174+ if os == OS {
175+ for _ , arch := range archs {
176+ if arch == Architecture {
177+ break
178+ }
179+ }
180+ fmt .Printf ("warning: combination of %q and %q is invalid." , OS , Architecture )
181+ }
182+ }
183+ fmt .Printf ("warning: operating system %q of the bundle is not supported yet." , OS )
184+ }
0 commit comments