Skip to content

Commit ca603fc

Browse files
author
zhouhao
committed
Add index validation
Signed-off-by: zhouhao <[email protected]>
1 parent dae3162 commit ca603fc

File tree

3 files changed

+194
-18
lines changed

3 files changed

+194
-18
lines changed

image/descriptor.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ import (
2525
"github.com/pkg/errors"
2626
)
2727

28+
const indexPath = "index.json"
29+
2830
func listReferences(w walker) (map[string]*v1.Descriptor, error) {
2931
refs := make(map[string]*v1.Descriptor)
3032
var index v1.Index
3133

3234
if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
33-
if info.IsDir() || filepath.Clean(path) != "index.json" {
35+
if info.IsDir() || filepath.Clean(path) != indexPath {
3436
return nil
3537
}
3638

@@ -56,7 +58,7 @@ func findDescriptor(w walker, name string) (*v1.Descriptor, error) {
5658
var index v1.Index
5759

5860
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
59-
if info.IsDir() || filepath.Clean(path) != "index.json" {
61+
if info.IsDir() || filepath.Clean(path) != indexPath {
6062
return nil
6163
}
6264

image/image.go

Lines changed: 120 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,44 @@ func validate(w walker, refs []string, out *log.Logger) error {
9292
return err
9393
}
9494

95-
m, err := findManifest(w, d)
96-
if err != nil {
97-
return err
95+
if d.MediaType == validRefMediaTypes[0] {
96+
m, err := findManifest(w, d)
97+
if err != nil {
98+
return err
99+
}
100+
101+
if err := m.validate(w); err != nil {
102+
return err
103+
}
98104
}
99105

100-
if err := m.validate(w); err != nil {
101-
return err
106+
if d.MediaType == validRefMediaTypes[1] {
107+
index, err := findIndex(w, d)
108+
if err != nil {
109+
return err
110+
}
111+
112+
if err := validateIndex(index, w); err != nil {
113+
return err
114+
}
115+
116+
if len(index.Manifests) == 0 {
117+
fmt.Println("warning: no manifests found")
118+
return nil
119+
}
120+
121+
for _, manifest := range index.Manifests {
122+
m, err := findManifest(w, &(manifest.Descriptor))
123+
if err != nil {
124+
return err
125+
}
126+
127+
if err := m.validate(w); err != nil {
128+
return err
129+
}
130+
}
102131
}
132+
103133
if out != nil {
104134
out.Printf("reference %q: OK", ref)
105135
}
@@ -147,16 +177,51 @@ func unpack(w walker, dest, refName string) error {
147177
return err
148178
}
149179

150-
m, err := findManifest(w, ref)
151-
if err != nil {
152-
return err
180+
if ref.MediaType == validRefMediaTypes[0] {
181+
m, err := findManifest(w, ref)
182+
if err != nil {
183+
return err
184+
}
185+
186+
if err := m.validate(w); err != nil {
187+
return err
188+
}
189+
190+
return m.unpack(w, dest)
153191
}
154192

155-
if err = m.validate(w); err != nil {
156-
return err
193+
if ref.MediaType == validRefMediaTypes[1] {
194+
index, err := findIndex(w, ref)
195+
if err != nil {
196+
return err
197+
}
198+
199+
if err := validateIndex(index, w); err != nil {
200+
return err
201+
}
202+
203+
if len(index.Manifests) == 0 {
204+
fmt.Println("warning: no manifests found")
205+
return nil
206+
}
207+
208+
for _, manifest := range index.Manifests {
209+
m, err := findManifest(w, &(manifest.Descriptor))
210+
if err != nil {
211+
return err
212+
}
213+
214+
if err := m.validate(w); err != nil {
215+
return err
216+
}
217+
218+
if err := m.unpack(w, dest); err != nil {
219+
return err
220+
}
221+
}
157222
}
158223

159-
return m.unpack(w, dest)
224+
return nil
160225
}
161226

162227
// CreateRuntimeBundleLayout walks through the file tree given by src and
@@ -199,15 +264,54 @@ func createRuntimeBundle(w walker, dest, refName, rootfs string) error {
199264
return err
200265
}
201266

202-
m, err := findManifest(w, ref)
203-
if err != nil {
204-
return err
267+
if ref.MediaType == validRefMediaTypes[0] {
268+
m, err := findManifest(w, ref)
269+
if err != nil {
270+
return err
271+
}
272+
273+
if err := m.validate(w); err != nil {
274+
return err
275+
}
276+
277+
return createRuntimebundle(w, m, dest, rootfs)
205278
}
206279

207-
if err = m.validate(w); err != nil {
208-
return err
280+
if ref.MediaType == validRefMediaTypes[1] {
281+
index, err := findIndex(w, ref)
282+
if err != nil {
283+
return err
284+
}
285+
286+
if err := validateIndex(index, w); err != nil {
287+
return err
288+
}
289+
290+
if len(index.Manifests) == 0 {
291+
fmt.Println("warning: no manifests found")
292+
return nil
293+
}
294+
295+
for _, manifest := range index.Manifests {
296+
m, err := findManifest(w, &(manifest.Descriptor))
297+
if err != nil {
298+
return err
299+
}
300+
301+
if err := m.validate(w); err != nil {
302+
return err
303+
}
304+
305+
if err := createRuntimebundle(w, m, dest, rootfs); err != nil {
306+
return err
307+
}
308+
}
209309
}
210310

311+
return nil
312+
}
313+
314+
func createRuntimebundle(w walker, m *manifest, dest, rootfs string) error {
211315
c, err := findConfig(w, &m.Config)
212316
if err != nil {
213317
return err

image/index.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2016 The Linux Foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package image
16+
17+
import (
18+
"bytes"
19+
"encoding/json"
20+
"fmt"
21+
"io"
22+
"io/ioutil"
23+
"os"
24+
"path/filepath"
25+
26+
"github.com/opencontainers/image-spec/schema"
27+
"github.com/opencontainers/image-spec/specs-go/v1"
28+
"github.com/pkg/errors"
29+
)
30+
31+
func findIndex(w walker, d *v1.Descriptor) (*v1.ImageIndex, error) {
32+
var index v1.ImageIndex
33+
34+
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
35+
if info.IsDir() || filepath.Clean(path) != indexPath {
36+
return nil
37+
}
38+
39+
buf, err := ioutil.ReadAll(r)
40+
if err != nil {
41+
return errors.Wrapf(err, "%s: error reading index", path)
42+
}
43+
44+
if err := schema.ValidatorMediaTypeImageIndex.Validate(bytes.NewReader(buf)); err != nil {
45+
return errors.Wrapf(err, "%s: index validation failed", path)
46+
}
47+
48+
if err := json.Unmarshal(buf, &index); err != nil {
49+
return err
50+
}
51+
52+
return errEOW
53+
}); err {
54+
case errEOW:
55+
return &index, nil
56+
case nil:
57+
return nil, fmt.Errorf("index.json not found")
58+
default:
59+
return nil, err
60+
}
61+
}
62+
63+
func validateIndex(index *v1.ImageIndex, w walker) error {
64+
for _, manifest := range index.Manifests {
65+
if err := validateDescriptor(&manifest.Descriptor, w, []string{v1.MediaTypeImageManifest}); err != nil {
66+
return errors.Wrap(err, "manifest validation failed")
67+
}
68+
}
69+
return nil
70+
}

0 commit comments

Comments
 (0)