@@ -26,14 +26,42 @@ import (
2626 "github.com/xeipuuv/gojsonschema"
2727)
2828
29+ type validateRefMediaFunc func (r io.Reader ) error
30+
31+ var vlidateRefMediaMap = map [Validator ]validateRefMediaFunc {
32+ ValidatorMediaTypeImageIndex : validateImageIndexRefObject ,
33+ ValidatorMediaTypeManifest : validateManifestRefObject ,
34+ }
35+
36+ // ValidateFunc provides the type of function to validate specific object.
37+ type ValidateFunc func (r io.Reader , v Validator ) error
38+
2939// Validator wraps a media type string identifier
3040// and implements validation against a JSON schema.
3141type Validator string
3242
33- type validateDescendantsFunc func (r io.Reader ) error
43+ // Validate validates the given reader against the schema and OCI format defined in spec.
44+ // r: the given reader.
45+ // funcList: the optional functions to validate the wrapped media type.
46+ func (v Validator ) Validate (r io.Reader , funcList []ValidateFunc ) error {
47+ buf , err := ioutil .ReadAll (r )
48+ if err != nil {
49+ return errors .Wrap (err , "unable to read the document file" )
50+ }
51+
52+ for _ , f := range funcList {
53+ err := f (bytes .NewReader (buf ), v )
54+ if err != nil {
55+ return err
56+ }
57+ }
58+ return nil
59+ }
60+
61+ type unimplemented string
3462
35- var mapValidateDescendants = map [ Validator ] validateDescendantsFunc {
36- ValidatorMediaTypeManifest : validateManifestDescendants ,
63+ func ( v unimplemented ) Validate ( src io. Reader ) error {
64+ return fmt . Errorf ( "%s: unimplemented" , v )
3765}
3866
3967// ValidationError contains all the errors that happened during validation.
@@ -45,23 +73,15 @@ func (e ValidationError) Error() string {
4573 return fmt .Sprintf ("%v" , e .Errs )
4674}
4775
48- // Validate validates the given reader against the schema of the wrapped media type.
49- func (v Validator ) Validate (src io.Reader ) error {
76+ // ValidateSchema validates the given reader against the schema of the wrapped media type.
77+ // src: the given reader.
78+ // v: the expected media type.
79+ func ValidateSchema (src io.Reader , v Validator ) error {
5080 buf , err := ioutil .ReadAll (src )
5181 if err != nil {
5282 return errors .Wrap (err , "unable to read the document file" )
5383 }
5484
55- if f , ok := mapValidateDescendants [v ]; ok {
56- if f == nil {
57- return fmt .Errorf ("internal error: mapValidateDescendents[%q] is nil" , v )
58- }
59- err = f (bytes .NewReader (buf ))
60- if err != nil {
61- return err
62- }
63- }
64-
6585 sl := gojsonschema .NewReferenceLoaderFileSystem ("file:///" + specs [v ], fs )
6686 ml := gojsonschema .NewStringLoader (string (buf ))
6787
@@ -86,13 +106,28 @@ func (v Validator) Validate(src io.Reader) error {
86106 }
87107}
88108
89- type unimplemented string
109+ // ValidateRefMedia validates the referenced objects against OCI media type defined in spec.
110+ // r: the given reader.
111+ // v: the expected media type.
112+ func ValidateRefMedia (r io.Reader , v Validator ) error {
113+ f , ok := vlidateRefMediaMap [v ]
114+ if ok {
115+ if f == nil {
116+ return fmt .Errorf ("referenced media type validation %q unimplemented" , v )
117+ }
90118
91- func (v unimplemented ) Validate (src io.Reader ) error {
92- return fmt .Errorf ("%s: unimplemented" , v )
119+ buf , err := ioutil .ReadAll (r )
120+ if err != nil {
121+ return errors .Wrap (err , "unable to read the document file" )
122+ }
123+
124+ return f (bytes .NewReader (buf ))
125+ }
126+
127+ return nil
93128}
94129
95- func validateManifestDescendants (r io.Reader ) error {
130+ func validateManifestRefObject (r io.Reader ) error {
96131 header := v1.Manifest {}
97132
98133 buf , err := ioutil .ReadAll (r )
@@ -117,3 +152,24 @@ func validateManifestDescendants(r io.Reader) error {
117152 }
118153 return nil
119154}
155+
156+ func validateImageIndexRefObject (r io.Reader ) error {
157+ header := v1.ImageIndex {}
158+
159+ buf , err := ioutil .ReadAll (r )
160+ if err != nil {
161+ return errors .Wrapf (err , "error reading the io stream" )
162+ }
163+
164+ err = json .Unmarshal (buf , & header )
165+ if err != nil {
166+ return errors .Wrap (err , "manifest list format mismatch" )
167+ }
168+
169+ for _ , manifest := range header .Manifests {
170+ if manifest .MediaType != string (v1 .MediaTypeImageManifest ) {
171+ return fmt .Errorf ("manifest %s has an unknown media type: %s" , manifest .Digest , manifest .MediaType )
172+ }
173+ }
174+ return nil
175+ }
0 commit comments