Skip to content

Commit 612d162

Browse files
author
zhouhao
committed
Modify the ref optiont
Signed-off-by: zhouhao <[email protected]>
1 parent f1c9348 commit 612d162

File tree

9 files changed

+177
-89
lines changed

9 files changed

+177
-89
lines changed

cmd/oci-image-tool/create.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ var bundleTypes = []string{
3131

3232
type bundleCmd struct {
3333
typ string // the type to bundle, can be empty string
34-
ref string
34+
refs []string
3535
root string
3636
platform string
3737
}
@@ -43,11 +43,15 @@ func createHandle(context *cli.Context) error {
4343

4444
v := bundleCmd{
4545
typ: context.String("type"),
46-
ref: context.String("ref"),
46+
refs: context.StringSlice("ref"),
4747
root: context.String("rootfs"),
4848
platform: context.String("platform"),
4949
}
5050

51+
if len(v.refs) == 0 {
52+
return fmt.Errorf("ref must be provided")
53+
}
54+
5155
if v.typ == "" {
5256
typ, err := image.Autodetect(context.Args()[0])
5357
if err != nil {
@@ -59,13 +63,13 @@ func createHandle(context *cli.Context) error {
5963
var err error
6064
switch v.typ {
6165
case image.TypeImageLayout:
62-
err = image.CreateRuntimeBundleLayout(context.Args()[0], context.Args()[1], v.ref, v.root, v.platform)
66+
err = image.CreateRuntimeBundleLayout(context.Args()[0], context.Args()[1], v.root, v.platform, v.refs)
6367

6468
case image.TypeImageZip:
65-
err = image.CreateRuntimeBundleZip(context.Args()[0], context.Args()[1], v.ref, v.root, v.platform)
69+
err = image.CreateRuntimeBundleZip(context.Args()[0], context.Args()[1], v.root, v.platform, v.refs)
6670

6771
case image.TypeImage:
68-
err = image.CreateRuntimeBundleFile(context.Args()[0], context.Args()[1], v.ref, v.root, v.platform)
72+
err = image.CreateRuntimeBundleFile(context.Args()[0], context.Args()[1], v.root, v.platform, v.refs)
6973

7074
default:
7175
err = fmt.Errorf("cannot create %q", v.typ)
@@ -87,10 +91,9 @@ var createCommand = cli.Command{
8791
strings.Join(bundleTypes, ","),
8892
),
8993
},
90-
cli.StringFlag{
94+
cli.StringSliceFlag{
9195
Name: "ref",
92-
Value: "v1.0",
93-
Usage: "The ref pointing to the manifest of the OCI image. This must be present in the 'refs' subdirectory of the image.",
96+
Usage: "A set of ref specify the search criteria for the validated reference, format is A=B. Only support 'name', 'platform.os' and 'digest' three cases.",
9497
},
9598
cli.StringFlag{
9699
Name: "rootfs",

cmd/oci-image-tool/unpack.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ var unpackTypes = []string{
3131

3232
type unpackCmd struct {
3333
typ string // the type to unpack, can be empty string
34-
ref string
34+
refs []string
3535
platform string
3636
}
3737

@@ -42,10 +42,14 @@ func unpackHandle(context *cli.Context) error {
4242

4343
v := unpackCmd{
4444
typ: context.String("type"),
45-
ref: context.String("ref"),
45+
refs: context.StringSlice("ref"),
4646
platform: context.String("platform"),
4747
}
4848

49+
if len(v.refs) == 0 {
50+
return fmt.Errorf("ref must be provided")
51+
}
52+
4953
if v.typ == "" {
5054
typ, err := image.Autodetect(context.Args()[0])
5155
if err != nil {
@@ -57,13 +61,13 @@ func unpackHandle(context *cli.Context) error {
5761
var err error
5862
switch v.typ {
5963
case image.TypeImageLayout:
60-
err = image.UnpackLayout(context.Args()[0], context.Args()[1], v.ref, v.platform)
64+
err = image.UnpackLayout(context.Args()[0], context.Args()[1], v.platform, v.refs)
6165

6266
case image.TypeImageZip:
63-
err = image.UnpackZip(context.Args()[0], context.Args()[1], v.ref, v.platform)
67+
err = image.UnpackZip(context.Args()[0], context.Args()[1], v.platform, v.refs)
6468

6569
case image.TypeImage:
66-
err = image.UnpackFile(context.Args()[0], context.Args()[1], v.ref, v.platform)
70+
err = image.UnpackFile(context.Args()[0], context.Args()[1], v.platform, v.refs)
6771

6872
default:
6973
err = fmt.Errorf("cannot unpack %q", v.typ)
@@ -84,10 +88,9 @@ var unpackCommand = cli.Command{
8488
strings.Join(unpackTypes, ","),
8589
),
8690
},
87-
cli.StringFlag{
91+
cli.StringSliceFlag{
8892
Name: "ref",
89-
Value: "v1.0",
90-
Usage: "The ref pointing to the manifest of the OCI image. This must be present in the 'refs' subdirectory of the image.",
93+
Usage: "A set of ref specify the search criteria for the validated reference, format is A=B. Only support 'name', 'platform.os' and 'digest' three cases.",
9194
},
9295
cli.StringFlag{
9396
Name: "platform",

cmd/oci-image-tool/validate.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func validatePath(name string) error {
108108
}
109109

110110
if len(v.refs) != 0 {
111-
fmt.Printf("WARNING: type %q does not support refs, which are only appropriate if type is image or imageLayout.\n", typ)
111+
fmt.Printf("WARNING: type %q does not support ref, which are only appropriate if type is image or imageLayout.\n", typ)
112112
}
113113

114114
f, err := os.Open(name)
@@ -143,7 +143,7 @@ var validateCommand = cli.Command{
143143
},
144144
cli.StringSliceFlag{
145145
Name: "ref",
146-
Usage: "A set of refs pointing to the manifests to be validated. Each reference must be present in the refs subdirectory of the image. Only applicable if type is image or imageLayout.",
146+
Usage: "A set of ref specify the search criteria for the validated reference. Format is A=B. Only support 'name', 'platform.os' and 'digest' three cases. Only applicable if type is image or imageLayout.",
147147
},
148148
},
149149
}

image/descriptor.go

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,23 @@ import (
2020
"io"
2121
"os"
2222
"path/filepath"
23+
"strings"
2324

2425
"github.com/opencontainers/image-spec/specs-go/v1"
2526
"github.com/pkg/errors"
2627
)
2728

29+
type reference struct {
30+
name string
31+
os string
32+
digest string
33+
manifest *v1.Descriptor
34+
}
35+
2836
const indexPath = "index.json"
2937

30-
func listReferences(w walker) (map[string]*v1.Descriptor, error) {
31-
refs := make(map[string]*v1.Descriptor)
38+
func listReferences(w walker) ([]reference, error) {
39+
var refs []reference
3240
var index v1.Index
3341

3442
if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
@@ -41,23 +49,33 @@ func listReferences(w walker) (map[string]*v1.Descriptor, error) {
4149
}
4250

4351
for i := 0; i < len(index.Manifests); i++ {
52+
var ref reference
4453
if index.Manifests[i].Annotations[v1.AnnotationRefName] != "" {
45-
refs[index.Manifests[i].Annotations[v1.AnnotationRefName]] = &index.Manifests[i]
54+
ref.name = index.Manifests[i].Annotations[v1.AnnotationRefName]
55+
}
56+
57+
if index.Manifests[i].Platform != nil && index.Manifests[i].Platform.OS != "" {
58+
ref.os = index.Manifests[i].Platform.OS
4659
}
60+
61+
ref.digest = string(index.Manifests[i].Digest)
62+
ref.manifest = &index.Manifests[i]
63+
refs = append(refs, ref)
4764
}
4865

4966
return nil
5067
}); err != nil {
5168
return nil, err
5269
}
70+
5371
return refs, nil
5472
}
5573

56-
func findDescriptor(w walker, name string) (*v1.Descriptor, error) {
57-
var d v1.Descriptor
74+
func findDescriptor(w walker, names []string) (*v1.Descriptor, error) {
75+
var descs []v1.Descriptor
5876
var index v1.Index
5977

60-
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
78+
if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
6179
if info.IsDir() || filepath.Clean(path) != indexPath {
6280
return nil
6381
}
@@ -66,22 +84,49 @@ func findDescriptor(w walker, name string) (*v1.Descriptor, error) {
6684
return err
6785
}
6886

69-
for i := 0; i < len(index.Manifests); i++ {
70-
if index.Manifests[i].Annotations[v1.AnnotationRefName] == name {
71-
d = index.Manifests[i]
72-
return errEOW
87+
descs = index.Manifests
88+
for _, name := range names {
89+
argsParts := strings.Split(name, "=")
90+
if len(argsParts) != 2 {
91+
return fmt.Errorf("each ref must contain two parts")
92+
}
93+
94+
switch argsParts[0] {
95+
case "name":
96+
for i := 0; i < len(descs); i++ {
97+
if descs[i].Annotations[v1.AnnotationRefName] != argsParts[1] {
98+
descs = append(descs[:i], descs[i+1:]...)
99+
}
100+
}
101+
case "platform.os":
102+
for i := 0; i < len(descs); i++ {
103+
if descs[i].Platform != nil && index.Manifests[i].Platform.OS != argsParts[1] {
104+
descs = append(descs[:i], descs[i+1:]...)
105+
}
106+
}
107+
case "digest":
108+
for i := 0; i < len(descs); i++ {
109+
if string(descs[i].Digest) != argsParts[1] {
110+
descs = append(descs[:i], descs[i+1:]...)
111+
}
112+
}
113+
default:
114+
return fmt.Errorf("criteria %q unimplemented", argsParts[0])
73115
}
74116
}
75117

76118
return nil
77-
}); err {
78-
case nil:
79-
return nil, fmt.Errorf("index.json: descriptor %q not found", name)
80-
case errEOW:
81-
return &d, nil
82-
default:
119+
}); err != nil {
83120
return nil, err
84121
}
122+
123+
if len(descs) == 0 {
124+
return nil, fmt.Errorf("index.json: descriptor retrieved by refs %v is not match", names)
125+
} else if len(descs) > 1 {
126+
return nil, fmt.Errorf("index.json: descriptor retrieved by refs %v is not unique", names)
127+
}
128+
129+
return &descs[0], nil
85130
}
86131

87132
func validateDescriptor(d *v1.Descriptor, w walker, mts []string) error {

0 commit comments

Comments
 (0)