@@ -32,11 +32,13 @@ import (
3232// and implements validation against a JSON schema.
3333type Validator string
3434
35- type validateDescendantsFunc func (r io.Reader ) error
35+ type validateFunc func (r io.Reader ) error
3636
37- var mapValidateDescendants = map [Validator ]validateDescendantsFunc {
38- ValidatorMediaTypeManifest : validateManifestDescendants ,
39- ValidatorMediaTypeDescriptor : validateDescriptorDescendants ,
37+ var mapValidate = map [Validator ]validateFunc {
38+ ValidatorMediaTypeImageConfig : validateConfig ,
39+ ValidatorMediaTypeDescriptor : validateDescriptor ,
40+ ValidatorMediaTypeImageIndex : validateIndex ,
41+ ValidatorMediaTypeManifest : validateManifest ,
4042}
4143
4244// ValidationError contains all the errors that happened during validation.
@@ -55,9 +57,9 @@ func (v Validator) Validate(src io.Reader) error {
5557 return errors .Wrap (err , "unable to read the document file" )
5658 }
5759
58- if f , ok := mapValidateDescendants [v ]; ok {
60+ if f , ok := mapValidate [v ]; ok {
5961 if f == nil {
60- return fmt .Errorf ("internal error: mapValidateDescendents [%q] is nil" , v )
62+ return fmt .Errorf ("internal error: mapValidate [%q] is nil" , v )
6163 }
6264 err = f (bytes .NewReader (buf ))
6365 if err != nil {
@@ -95,7 +97,7 @@ func (v unimplemented) Validate(src io.Reader) error {
9597 return fmt .Errorf ("%s: unimplemented" , v )
9698}
9799
98- func validateManifestDescendants (r io.Reader ) error {
100+ func validateManifest (r io.Reader ) error {
99101 header := v1.Manifest {}
100102
101103 buf , err := ioutil .ReadAll (r )
@@ -128,7 +130,7 @@ var (
128130 sha512EncodedRegexp = regexp .MustCompile (`^[a-f0-9]{128}$` )
129131)
130132
131- func validateDescriptorDescendants (r io.Reader ) error {
133+ func validateDescriptor (r io.Reader ) error {
132134 header := v1.Descriptor {}
133135
134136 buf , err := ioutil .ReadAll (r )
@@ -158,3 +160,69 @@ func validateDescriptorDescendants(r io.Reader) error {
158160 }
159161 return nil
160162}
163+
164+ func validateIndex (r io.Reader ) error {
165+ header := v1.Index {}
166+
167+ buf , err := ioutil .ReadAll (r )
168+ if err != nil {
169+ return errors .Wrapf (err , "error reading the io stream" )
170+ }
171+
172+ err = json .Unmarshal (buf , & header )
173+ if err != nil {
174+ return errors .Wrap (err , "manifestlist format mismatch" )
175+ }
176+
177+ for _ , manifest := range header .Manifests {
178+ if manifest .MediaType != string (v1 .MediaTypeImageManifest ) {
179+ fmt .Printf ("warning: manifest %s has an unknown media type: %s\n " , manifest .Digest , manifest .MediaType )
180+ }
181+
182+ }
183+
184+ return nil
185+ }
186+
187+ func validateConfig (r io.Reader ) error {
188+ header := v1.Image {}
189+
190+ buf , err := ioutil .ReadAll (r )
191+ if err != nil {
192+ return errors .Wrapf (err , "error reading the io stream" )
193+ }
194+
195+ err = json .Unmarshal (buf , & header )
196+ if err != nil {
197+ return errors .Wrap (err , "config format mismatch" )
198+ }
199+
200+ checkPlatform (header .OS , header .Architecture )
201+
202+ return nil
203+ }
204+
205+ func checkPlatform (OS string , Architecture string ) {
206+ validCombins := map [string ][]string {
207+ "android" : {"arm" },
208+ "darwin" : {"386" , "amd64" , "arm" , "arm64" },
209+ "dragonfly" : {"amd64" },
210+ "freebsd" : {"386" , "amd64" , "arm" },
211+ "linux" : {"386" , "amd64" , "arm" , "arm64" , "ppc64" , "ppc64le" , "mips64" , "mips64le" , "s390x" },
212+ "netbsd" : {"386" , "amd64" , "arm" },
213+ "openbsd" : {"386" , "amd64" , "arm" },
214+ "plan9" : {"386" , "amd64" },
215+ "solaris" : {"amd64" },
216+ "windows" : {"386" , "amd64" }}
217+ for os , archs := range validCombins {
218+ if os == OS {
219+ for _ , arch := range archs {
220+ if arch == Architecture {
221+ return
222+ }
223+ }
224+ fmt .Printf ("warning: combination of %q and %q is invalid." , OS , Architecture )
225+ }
226+ }
227+ fmt .Printf ("warning: operating system %q of the bundle is not supported yet." , OS )
228+ }
0 commit comments