Skip to content

Commit

Permalink
validate: type is requried for validation
Browse files Browse the repository at this point in the history
1. spec says any extra fields in json file can be ignored, so I think
we can't clearly distingish which type the text file is, we'd better remove
autodetect for text files.
2. without audotdetect, we must requrie to user to set file type for validation

Signed-off-by: Ma Shimiao <[email protected]>
  • Loading branch information
Ma Shimiao committed Jan 24, 2018
1 parent 003e33b commit c02c3c7
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 70 deletions.
44 changes: 23 additions & 21 deletions cmd/oci-image-tool/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ import (

// supported validation types
var validateTypes = []string{
image.TypeImageLayout,
image.TypeImage,
image.TypeImageZip,
image.TypeManifest,
image.TypeImageIndex,
image.TypeConfig,
Expand All @@ -54,6 +52,10 @@ func validateAction(context *cli.Context) error {
refs: context.StringSlice("ref"),
}

if v.typ == "" {
return fmt.Errorf("--type must be set")
}

for index, ref := range v.refs {
for i := index + 1; i < len(v.refs); i++ {
if ref == v.refs[i] {
Expand All @@ -74,9 +76,9 @@ func validateAction(context *cli.Context) error {
if verr, ok := errors.Cause(err).(schema.ValidationError); ok {
errs = append(errs, fmt.Sprintf("%v", verr.Errs))
} else if serr, ok := errors.Cause(err).(*schema.SyntaxError); ok {
errs = append(errs, fmt.Sprintf("%s:%d:%d: validation failed: %v", arg, serr.Line, serr.Col, err))
errs = append(errs, fmt.Sprintf("%s:%d:%d: %v", arg, serr.Line, serr.Col, err))
} else {
errs = append(errs, fmt.Sprintf("%s: validation failed: %v", arg, err))
errs = append(errs, fmt.Sprintf("%s: %v", arg, err))
}

}
Expand All @@ -95,29 +97,29 @@ func validatePath(name string) error {
typ = v.typ
)

if typ == "" {
if typ, err = image.Autodetect(name); err != nil {
return errors.Wrap(err, "unable to determine type")
}
}

if v.stdout == nil {
v.stdout = log.New(os.Stdout, "oci-image-tool: ", 0)
}

switch typ {
case image.TypeImageLayout:
return image.ValidateLayout(name, v.refs, v.stdout)
case image.TypeImageZip:
return image.ValidateZip(name, v.refs, v.stdout)
case image.TypeImage:
return image.ValidateFile(name, v.refs, v.stdout)
if typ == image.TypeImage {
imageType, err := image.Autodetect(name)
if err != nil {
return errors.Wrap(err, "unable to determine image type")
}
fmt.Println("autodetected image file type is:", imageType)
switch imageType {
case image.TypeImageLayout:
return image.ValidateLayout(name, v.refs, v.stdout)
case image.TypeImageZip:
return image.ValidateZip(name, v.refs, v.stdout)
case image.TypeImage:
return image.ValidateFile(name, v.refs, v.stdout)
}
}

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

f, err := os.Open(name)
if err != nil {
return errors.Wrap(err, "unable to open file")
Expand All @@ -144,13 +146,13 @@ var validateCommand = cli.Command{
cli.StringFlag{
Name: "type",
Usage: fmt.Sprintf(
`Type of the file to validate. If unset, oci-image-tool will try to auto-detect the type. One of "%s".`,
`Type of the file to validate. One of "%s".`,
strings.Join(validateTypes, ","),
),
},
cli.StringSliceFlag{
Name: "ref",
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.",
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",
},
},
}
2 changes: 0 additions & 2 deletions completions/bash/oci-image-tool
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ __oci-image-tool_complete_validate_types() {
config
image
imageIndex
imageLayout
imageZip
manifest
" -- "$cur" ) )
}
Expand Down
45 changes: 1 addition & 44 deletions image/autodetect.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@
package image

import (
"encoding/json"
"io"
"io/ioutil"
"net/http"
"os"

"github.com/opencontainers/image-spec/schema"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -65,48 +63,7 @@ func Autodetect(path string) (string, error) {
return TypeImage, nil
case "application/zip":
return TypeImageZip, nil

case "text/plain; charset=utf-8":
// might be a JSON file, will be handled below

default:
return "", errors.New("unknown file type")
}

if _, err := f.Seek(0, io.SeekStart); err != nil {
return "", errors.Wrap(err, "unable to seek")
}

header := struct {
SchemaVersion int `json:"schemaVersion"`
MediaType string `json:"mediaType"`
Config interface{} `json:"config"`
}{}

if err := json.NewDecoder(f).Decode(&header); err != nil {
if _, errSeek := f.Seek(0, io.SeekStart); errSeek != nil {
return "", errors.Wrap(err, "unable to seek")
}

e := errors.Wrap(
schema.WrapSyntaxError(f, err),
"unable to parse JSON",
)

return "", e
}

switch {
case header.MediaType == string(schema.ValidatorMediaTypeManifest):
return TypeManifest, nil

case header.MediaType == string(schema.ValidatorMediaTypeImageIndex):
return TypeImageIndex, nil

case header.MediaType == "" && header.SchemaVersion == 0 && header.Config != nil:
// config files don't have mediaType/schemaVersion header
return TypeConfig, nil
}

return "", errors.New("unknown media type")
return "", errors.New("unknown file type")
}
6 changes: 3 additions & 3 deletions man/oci-image-tool-validate.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ oci-image-tool validate \- Validate one or more image files
Reference should point to a manifest or index.
e.g. --ref name=v1.0 --ref platform.os=latest
Only support `name`, `platform.os` and `digest` three cases.
Only applicable if type is image or imageLayout.
Only applicable if type is image.

**--type**=""
Type of the file to validate. If unset, oci-image-tool will try to auto-detect the type. One of "imageLayout,image,imageZip,manifest,imageIndex,config"
Type of the file to validate. One of "image,manifest,imageIndex,config"

# EXAMPLES
```
$ skopeo copy docker://busybox oci:busybox-oci:latest
$ oci-image-tool validate --type imageLayout --ref name=latest busybox-oci
$ oci-image-tool validate --type image --ref name=latest busybox-oci
busybox-oci: OK
```

Expand Down

0 comments on commit c02c3c7

Please sign in to comment.