Skip to content

Commit d2834a6

Browse files
committed
image: Refactor to use cas/ref engines instead of walkers
The validation/unpacking code doesn't really care what the reference and CAS implemenations are. And the new generic interfaces in image/refs and image/cas will scale better as we add new backends than the walker interface. Signed-off-by: W. Trevor King <[email protected]>
1 parent c8e4b53 commit d2834a6

File tree

9 files changed

+119
-355
lines changed

9 files changed

+119
-355
lines changed

cmd/oci-image-tool/autodetect.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727

2828
// supported autodetection types
2929
const (
30-
typeImageLayout = "imageLayout"
3130
typeImage = "image"
3231
typeManifest = "manifest"
3332
typeManifestList = "manifestList"
@@ -43,7 +42,7 @@ func autodetect(path string) (string, error) {
4342
}
4443

4544
if fi.IsDir() {
46-
return typeImageLayout, nil
45+
return typeImage, nil
4746
}
4847

4948
f, err := os.Open(path)

cmd/oci-image-tool/create_runtime_bundle.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626

2727
// supported bundle types
2828
var bundleTypes = []string{
29-
typeImageLayout,
3029
typeImage,
3130
}
3231

@@ -93,9 +92,6 @@ func (v *bundleCmd) Run(cmd *cobra.Command, args []string) {
9392

9493
var err error
9594
switch v.typ {
96-
case typeImageLayout:
97-
err = image.CreateRuntimeBundleLayout(args[0], args[1], v.ref, v.root)
98-
9995
case typeImage:
10096
err = image.CreateRuntimeBundle(args[0], args[1], v.ref, v.root)
10197
}

cmd/oci-image-tool/unpack.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626

2727
// supported unpack types
2828
var unpackTypes = []string{
29-
typeImageLayout,
3029
typeImage,
3130
}
3231

@@ -45,8 +44,8 @@ func newUnpackCmd(stdout, stderr *log.Logger) *cobra.Command {
4544

4645
cmd := &cobra.Command{
4746
Use: "unpack [src] [dest]",
48-
Short: "Unpack an image or image source layout",
49-
Long: `Unpack the OCI image .tar file or OCI image layout directory present at [src] to the destination directory [dest].`,
47+
Short: "Unpack an image",
48+
Long: `Unpack the OCI image present at [src] to the destination directory [dest].`,
5049
Run: v.Run,
5150
}
5251

@@ -86,9 +85,6 @@ func (v *unpackCmd) Run(cmd *cobra.Command, args []string) {
8685

8786
var err error
8887
switch v.typ {
89-
case typeImageLayout:
90-
err = image.UnpackLayout(args[0], args[1], v.ref)
91-
9288
case typeImage:
9389
err = image.Unpack(args[0], args[1], v.ref)
9490
}

cmd/oci-image-tool/validate.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828

2929
// supported validation types
3030
var validateTypes = []string{
31-
typeImageLayout,
3231
typeImage,
3332
typeManifest,
3433
typeManifestList,
@@ -64,7 +63,7 @@ func newValidateCmd(stdout, stderr *log.Logger) *cobra.Command {
6463

6564
cmd.Flags().StringVar(
6665
&v.ref, "ref", "v1.0",
67-
`The ref pointing to the manifest to be validated. This must be present in the "refs" subdirectory of the image. Only applicable if type is image or imageLayout.`,
66+
`The ref pointing to the manifest to be validated. This must be present in the "refs" subdirectory of the image. Only applicable if type is image.`,
6867
)
6968

7069
return cmd
@@ -122,8 +121,6 @@ func (v *validateCmd) validatePath(name string) error {
122121
}
123122

124123
switch typ {
125-
case typeImageLayout:
126-
return image.ValidateLayout(name, v.ref)
127124
case typeImage:
128125
return image.Validate(name, v.ref)
129126
}

image/config.go

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@ import (
1818
"bytes"
1919
"encoding/json"
2020
"fmt"
21-
"io"
2221
"io/ioutil"
23-
"os"
24-
"path/filepath"
2522
"strconv"
2623
"strings"
2724

25+
"github.com/opencontainers/image-spec/image/cas"
26+
"github.com/opencontainers/image-spec/image/structure"
2827
"github.com/opencontainers/image-spec/schema"
2928
"github.com/opencontainers/runtime-spec/specs-go"
3029
"github.com/pkg/errors"
@@ -49,41 +48,23 @@ type config struct {
4948
Config cfg `json:"config"`
5049
}
5150

52-
func findConfig(w walker, d *descriptor) (*config, error) {
53-
var c config
54-
cpath := filepath.Join("blobs", d.Digest)
55-
56-
f := func(path string, info os.FileInfo, r io.Reader) error {
57-
if info.IsDir() {
58-
return nil
59-
}
60-
61-
if filepath.Clean(path) != cpath {
62-
return nil
63-
}
64-
65-
buf, err := ioutil.ReadAll(r)
66-
if err != nil {
67-
return errors.Wrapf(err, "%s: error reading config", path)
68-
}
69-
70-
if err := schema.MediaTypeImageSerializationConfig.Validate(bytes.NewReader(buf)); err != nil {
71-
return errors.Wrapf(err, "%s: config validation failed", path)
72-
}
51+
func findConfig(engine cas.Engine, descriptor *structure.Descriptor) (*config, error) {
52+
reader, err := engine.Get(descriptor.Digest)
53+
if err != nil {
54+
return nil, err
55+
}
7356

74-
if err := json.Unmarshal(buf, &c); err != nil {
75-
return err
76-
}
57+
buf, err := ioutil.ReadAll(reader)
58+
if err != nil {
59+
return nil, errors.Wrapf(err, "%s: error reading manifest", descriptor.Digest)
60+
}
7761

78-
return errEOW
62+
if err := schema.MediaTypeImageSerializationConfig.Validate(bytes.NewReader(buf)); err != nil {
63+
return nil, errors.Wrapf(err, "%s: config validation failed", descriptor.Digest)
7964
}
8065

81-
switch err := w.walk(f); err {
82-
case nil:
83-
return nil, fmt.Errorf("%s: config not found", cpath)
84-
case errEOW:
85-
// found, continue below
86-
default:
66+
var c config
67+
if err := json.Unmarshal(buf, &c); err != nil {
8768
return nil, err
8869
}
8970

image/descriptor.go

Lines changed: 11 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -17,81 +17,23 @@ package image
1717
import (
1818
"crypto/sha256"
1919
"encoding/hex"
20-
"encoding/json"
21-
"fmt"
2220
"io"
23-
"os"
24-
"path/filepath"
2521

22+
"github.com/opencontainers/image-spec/image/cas"
2623
"github.com/opencontainers/image-spec/image/structure"
2724
"github.com/pkg/errors"
2825
)
2926

30-
type descriptor structure.Descriptor
31-
32-
func findDescriptor(w walker, name string) (*descriptor, error) {
33-
var d descriptor
34-
dpath := filepath.Join("refs", name)
35-
36-
f := func(path string, info os.FileInfo, r io.Reader) error {
37-
if info.IsDir() {
38-
return nil
39-
}
40-
41-
if filepath.Clean(path) != dpath {
42-
return nil
43-
}
44-
45-
if err := json.NewDecoder(r).Decode(&d); err != nil {
46-
return err
47-
}
48-
49-
return errEOW
50-
}
51-
52-
switch err := w.walk(f); err {
53-
case nil:
54-
return nil, fmt.Errorf("%s: descriptor not found", dpath)
55-
case errEOW:
56-
// found, continue below
57-
default:
58-
return nil, err
59-
}
60-
61-
return &d, nil
62-
}
63-
64-
func (d *descriptor) validate(w walker) error {
65-
f := func(path string, info os.FileInfo, r io.Reader) error {
66-
if info.IsDir() {
67-
return nil
68-
}
69-
70-
digest, err := filepath.Rel("blobs", filepath.Clean(path))
71-
if err != nil || d.Digest != digest {
72-
return nil // ignore
73-
}
74-
75-
if err := d.validateContent(r); err != nil {
76-
return err
77-
}
78-
79-
return errEOW
80-
}
81-
82-
switch err := w.walk(f); err {
83-
case nil:
84-
return fmt.Errorf("%s: not found", d.Digest)
85-
case errEOW:
86-
// found, continue below
87-
default:
88-
return errors.Wrapf(err, "%s: validation failed", d.Digest)
27+
func validateDescriptor(engine cas.Engine, descriptor *structure.Descriptor) error {
28+
reader, err := engine.Get(descriptor.Digest)
29+
if err != nil {
30+
return err
8931
}
9032

91-
return nil
33+
return validateContent(descriptor, reader)
9234
}
9335

94-
func (d *descriptor) validateContent(r io.Reader) error {
36+
func validateContent(descriptor *structure.Descriptor, r io.Reader) error {
9537
h := sha256.New()
9638
n, err := io.Copy(h, r)
9739
if err != nil {
@@ -100,13 +42,15 @@ func (d *descriptor) validateContent(r io.Reader) error {
10042

10143
digest := "sha256:" + hex.EncodeToString(h.Sum(nil))
10244

103-
if digest != d.Digest {
45+
if digest != descriptor.Digest {
10446
return errors.New("digest mismatch")
10547
}
10648

107-
if n != d.Size {
49+
if n != descriptor.Size {
10850
return errors.New("size mismatch")
10951
}
11052

53+
// FIXME: check descriptor.MediaType, when possible
54+
11155
return nil
11256
}

0 commit comments

Comments
 (0)