Skip to content

Commit

Permalink
Merge pull request opencontainers#169 from q384566678/select-descs
Browse files Browse the repository at this point in the history
Modify the ref option
  • Loading branch information
Zhou Hao authored Jan 24, 2018
2 parents fa160db + c3ac69c commit dab5ba5
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 104 deletions.
19 changes: 11 additions & 8 deletions cmd/oci-image-tool/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var bundleTypes = []string{

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

v := bundleCmd{
typ: context.String("type"),
ref: context.String("ref"),
refs: context.StringSlice("ref"),
root: context.String("rootfs"),
platform: context.String("platform"),
}

if len(v.refs) == 0 {
return fmt.Errorf("ref must be provided")
}

if v.typ == "" {
typ, err := image.Autodetect(context.Args()[0])
if err != nil {
Expand All @@ -59,13 +63,13 @@ func createHandle(context *cli.Context) error {
var err error
switch v.typ {
case image.TypeImageLayout:
err = image.CreateRuntimeBundleLayout(context.Args()[0], context.Args()[1], v.ref, v.root, v.platform)
err = image.CreateRuntimeBundleLayout(context.Args()[0], context.Args()[1], v.root, v.platform, v.refs)

case image.TypeImageZip:
err = image.CreateRuntimeBundleZip(context.Args()[0], context.Args()[1], v.ref, v.root, v.platform)
err = image.CreateRuntimeBundleZip(context.Args()[0], context.Args()[1], v.root, v.platform, v.refs)

case image.TypeImage:
err = image.CreateRuntimeBundleFile(context.Args()[0], context.Args()[1], v.ref, v.root, v.platform)
err = image.CreateRuntimeBundleFile(context.Args()[0], context.Args()[1], v.root, v.platform, v.refs)

default:
err = fmt.Errorf("cannot create %q", v.typ)
Expand All @@ -87,10 +91,9 @@ var createCommand = cli.Command{
strings.Join(bundleTypes, ","),
),
},
cli.StringFlag{
cli.StringSliceFlag{
Name: "ref",
Value: "v1.0",
Usage: "The ref pointing to the manifest of the OCI image. This must be present in the 'refs' subdirectory of the image.",
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.",
},
cli.StringFlag{
Name: "rootfs",
Expand Down
19 changes: 11 additions & 8 deletions cmd/oci-image-tool/unpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var unpackTypes = []string{

type unpackCmd struct {
typ string // the type to unpack, can be empty string
ref string
refs []string
platform string
}

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

v := unpackCmd{
typ: context.String("type"),
ref: context.String("ref"),
refs: context.StringSlice("ref"),
platform: context.String("platform"),
}

if len(v.refs) == 0 {
return fmt.Errorf("ref must be provided")
}

if v.typ == "" {
typ, err := image.Autodetect(context.Args()[0])
if err != nil {
Expand All @@ -57,13 +61,13 @@ func unpackHandle(context *cli.Context) error {
var err error
switch v.typ {
case image.TypeImageLayout:
err = image.UnpackLayout(context.Args()[0], context.Args()[1], v.ref, v.platform)
err = image.UnpackLayout(context.Args()[0], context.Args()[1], v.platform, v.refs)

case image.TypeImageZip:
err = image.UnpackZip(context.Args()[0], context.Args()[1], v.ref, v.platform)
err = image.UnpackZip(context.Args()[0], context.Args()[1], v.platform, v.refs)

case image.TypeImage:
err = image.UnpackFile(context.Args()[0], context.Args()[1], v.ref, v.platform)
err = image.UnpackFile(context.Args()[0], context.Args()[1], v.platform, v.refs)

default:
err = fmt.Errorf("cannot unpack %q", v.typ)
Expand All @@ -84,10 +88,9 @@ var unpackCommand = cli.Command{
strings.Join(unpackTypes, ","),
),
},
cli.StringFlag{
cli.StringSliceFlag{
Name: "ref",
Value: "v1.0",
Usage: "The ref pointing to the manifest of the OCI image. This must be present in the 'refs' subdirectory of the image.",
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.",
},
cli.StringFlag{
Name: "platform",
Expand Down
4 changes: 2 additions & 2 deletions cmd/oci-image-tool/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func validatePath(name string) error {
}

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

f, err := os.Open(name)
Expand Down Expand Up @@ -142,7 +142,7 @@ var validateCommand = cli.Command{
},
cli.StringSliceFlag{
Name: "ref",
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.",
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.",
},
},
}
68 changes: 46 additions & 22 deletions image/descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ import (
"io"
"os"
"path/filepath"
"strings"

"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)

const indexPath = "index.json"

func listReferences(w walker) (map[string]*v1.Descriptor, error) {
refs := make(map[string]*v1.Descriptor)
func listReferences(w walker) ([]v1.Descriptor, error) {
var descs []v1.Descriptor
var index v1.Index

if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
Expand All @@ -39,25 +40,21 @@ func listReferences(w walker) (map[string]*v1.Descriptor, error) {
if err := json.NewDecoder(r).Decode(&index); err != nil {
return err
}

for i := 0; i < len(index.Manifests); i++ {
if index.Manifests[i].Annotations[v1.AnnotationRefName] != "" {
refs[index.Manifests[i].Annotations[v1.AnnotationRefName]] = &index.Manifests[i]
}
}
descs = index.Manifests

return nil
}); err != nil {
return nil, err
}
return refs, nil

return descs, nil
}

func findDescriptor(w walker, name string) (*v1.Descriptor, error) {
var d v1.Descriptor
func findDescriptor(w walker, names []string) ([]v1.Descriptor, error) {
var descs []v1.Descriptor
var index v1.Index

switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
if info.IsDir() || filepath.Clean(path) != indexPath {
return nil
}
Expand All @@ -66,22 +63,49 @@ func findDescriptor(w walker, name string) (*v1.Descriptor, error) {
return err
}

for i := 0; i < len(index.Manifests); i++ {
if index.Manifests[i].Annotations[v1.AnnotationRefName] == name {
d = index.Manifests[i]
return errEOW
descs = index.Manifests
for _, name := range names {
argsParts := strings.Split(name, "=")
if len(argsParts) != 2 {
return fmt.Errorf("each ref must contain two parts")
}

switch argsParts[0] {
case "name":
for i := 0; i < len(descs); i++ {
if descs[i].Annotations[v1.AnnotationRefName] != argsParts[1] {
descs = append(descs[:i], descs[i+1:]...)
}
}
case "platform.os":
for i := 0; i < len(descs); i++ {
if descs[i].Platform != nil && index.Manifests[i].Platform.OS != argsParts[1] {
descs = append(descs[:i], descs[i+1:]...)
}
}
case "digest":
for i := 0; i < len(descs); i++ {
if string(descs[i].Digest) != argsParts[1] {
descs = append(descs[:i], descs[i+1:]...)
}
}
default:
return fmt.Errorf("criteria %q unimplemented", argsParts[0])
}
}

return nil
}); err {
case nil:
return nil, fmt.Errorf("index.json: descriptor %q not found", name)
case errEOW:
return &d, nil
default:
}); err != nil {
return nil, err
}

if len(descs) == 0 {
return nil, fmt.Errorf("index.json: descriptor retrieved by refs %v is not match", names)
} else if len(descs) > 1 {
return nil, fmt.Errorf("index.json: descriptor retrieved by refs %v is not unique", names)
}

return descs, nil
}

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

0 comments on commit dab5ba5

Please sign in to comment.