Skip to content

Commit 4badd20

Browse files
author
xiekeyang
committed
verbose output object digest in validate
add a verbose option, to output the object digest. It is for issue #222. Signed-off-by: xiekeyang <[email protected]>
1 parent e6a431f commit 4badd20

File tree

9 files changed

+60
-30
lines changed

9 files changed

+60
-30
lines changed

cmd/oci-image-tool/validate.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ var validateTypes = []string{
3636
}
3737

3838
type validateCmd struct {
39-
stdout *log.Logger
40-
stderr *log.Logger
41-
typ string // the type to validate, can be empty string
42-
refs []string
39+
stdout *log.Logger
40+
stderr *log.Logger
41+
typ string // the type to validate, can be empty string
42+
refs []string
43+
verbose bool
4344
}
4445

4546
func newValidateCmd(stdout, stderr *log.Logger) *cobra.Command {
@@ -67,6 +68,11 @@ func newValidateCmd(stdout, stderr *log.Logger) *cobra.Command {
6768
`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.`,
6869
)
6970

71+
cmd.Flags().BoolVarP(
72+
&v.verbose, "verbose", "v", false,
73+
fmt.Sprintf(`Output verbosely, including all objects digest to be validated. If unset, oci-image-tool will only output a OK or failed result.`),
74+
)
75+
7076
return cmd
7177
}
7278

@@ -125,9 +131,9 @@ func (v *validateCmd) validatePath(name string) error {
125131

126132
switch typ {
127133
case typeImageLayout:
128-
return image.ValidateLayout(name, v.refs, v.stdout)
134+
return image.ValidateLayout(name, v.refs, v.verbose, v.stdout)
129135
case typeImage:
130-
return image.Validate(name, v.refs, v.stdout)
136+
return image.Validate(name, v.refs, v.verbose, v.stdout)
131137
}
132138

133139
f, err := os.Open(name)
@@ -138,11 +144,11 @@ func (v *validateCmd) validatePath(name string) error {
138144

139145
switch typ {
140146
case typeManifest:
141-
return schema.MediaTypeManifest.Validate(f)
147+
return schema.MediaTypeManifest.Validate(f, v.verbose, v.stdout)
142148
case typeManifestList:
143-
return schema.MediaTypeManifestList.Validate(f)
149+
return schema.MediaTypeManifestList.Validate(f, v.verbose, v.stdout)
144150
case typeConfig:
145-
return schema.MediaTypeImageConfig.Validate(f)
151+
return schema.MediaTypeImageConfig.Validate(f, v.verbose, v.stdout)
146152
}
147153

148154
return fmt.Errorf("type %q unimplemented", typ)

image/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func findConfig(w walker, d *descriptor) (*config, error) {
4646
return errors.Wrapf(err, "%s: error reading config", path)
4747
}
4848

49-
if err := schema.MediaTypeImageConfig.Validate(bytes.NewReader(buf)); err != nil {
49+
if err := schema.MediaTypeImageConfig.Validate(bytes.NewReader(buf), false, nil); err != nil {
5050
return errors.Wrapf(err, "%s: config validation failed", path)
5151
}
5252

image/image.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,31 @@ import (
2727
// ValidateLayout walks through the file tree given by src and
2828
// validates the manifest pointed to by the given refs
2929
// or returns an error if the validation failed.
30-
func ValidateLayout(src string, refs []string, out *log.Logger) error {
31-
return validate(newPathWalker(src), refs, out)
30+
func ValidateLayout(src string, refs []string, verbose bool, out *log.Logger) error {
31+
return validate(newPathWalker(src), refs, verbose, out)
3232
}
3333

3434
// Validate walks through the given .tar file and
3535
// validates the manifest pointed to by the given refs
3636
// or returns an error if the validation failed.
37-
func Validate(tarFile string, refs []string, out *log.Logger) error {
37+
func Validate(tarFile string, refs []string, verbose bool, out *log.Logger) error {
3838
f, err := os.Open(tarFile)
3939
if err != nil {
4040
return errors.Wrap(err, "unable to open file")
4141
}
4242
defer f.Close()
4343

44-
return validate(newTarWalker(f), refs, out)
44+
return validate(newTarWalker(f), refs, verbose, out)
4545
}
4646

4747
var validRefMediaTypes = []string{
4848
v1.MediaTypeImageManifest,
4949
v1.MediaTypeImageManifestList,
5050
}
5151

52-
func validate(w walker, refs []string, out *log.Logger) error {
52+
func validate(w walker, refs []string, verbose bool, out *log.Logger) error {
5353
for _, r := range refs {
54+
var digests []string
5455
ref, err := findDescriptor(w, r)
5556
if err != nil {
5657
return err
@@ -64,12 +65,21 @@ func validate(w walker, refs []string, out *log.Logger) error {
6465
if err != nil {
6566
return err
6667
}
68+
digests = append(digests, ref.Digest)
6769

68-
if err := m.validate(w); err != nil {
70+
d, err := m.validate(w)
71+
if err != nil {
6972
return err
7073
}
74+
digests = append(digests, d...)
7175
if out != nil {
7276
out.Printf("reference %q: OK", r)
77+
if verbose && len(digests) > 0 {
78+
out.Printf("validated objects digest:")
79+
for _, digest := range digests {
80+
out.Printf("%s", digest)
81+
}
82+
}
7383
}
7484
}
7585
return nil
@@ -112,7 +122,7 @@ func unpack(w walker, dest, refName string) error {
112122
return err
113123
}
114124

115-
if err = m.validate(w); err != nil {
125+
if _, err = m.validate(w); err != nil {
116126
return err
117127
}
118128

@@ -154,7 +164,7 @@ func createRuntimeBundle(w walker, dest, refName, rootfs string) error {
154164
return err
155165
}
156166

157-
if err = m.validate(w); err != nil {
167+
if _, err = m.validate(w); err != nil {
158168
return err
159169
}
160170

image/manifest.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func findManifest(w walker, d *descriptor) (*manifest, error) {
5151
return errors.Wrapf(err, "%s: error reading manifest", path)
5252
}
5353

54-
if err := schema.MediaTypeManifest.Validate(bytes.NewReader(buf)); err != nil {
54+
if err := schema.MediaTypeManifest.Validate(bytes.NewReader(buf), false, nil); err != nil {
5555
return errors.Wrapf(err, "%s: manifest validation failed", path)
5656
}
5757

@@ -74,18 +74,21 @@ func findManifest(w walker, d *descriptor) (*manifest, error) {
7474
}
7575
}
7676

77-
func (m *manifest) validate(w walker) error {
77+
func (m *manifest) validate(w walker) ([]string, error) {
78+
var digests []string
7879
if err := m.Config.validate(w, []string{v1.MediaTypeImageConfig}); err != nil {
79-
return errors.Wrap(err, "config validation failed")
80+
return nil, errors.Wrap(err, "config validation failed")
8081
}
82+
digests = append(digests, m.Config.Digest)
8183

8284
for _, d := range m.Layers {
8385
if err := d.validate(w, []string{v1.MediaTypeImageLayer}); err != nil {
84-
return errors.Wrap(err, "layer validation failed")
86+
return nil, errors.Wrap(err, "layer validation failed")
8587
}
88+
digests = append(digests, d.Digest)
8689
}
8790

88-
return nil
91+
return digests, nil
8992
}
9093

9194
func (m *manifest) unpack(w walker, dest string) error {

schema/config_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func TestConfig(t *testing.T) {
156156
},
157157
} {
158158
r := strings.NewReader(tt.config)
159-
err := schema.MediaTypeImageConfig.Validate(r)
159+
err := schema.MediaTypeImageConfig.Validate(r, false, nil)
160160

161161
if got := err != nil; tt.fail != got {
162162
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)

schema/manifest_backwards_compatibility_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ func TestBackwardsCompatibilityManifestList(t *testing.T) {
117117

118118
manifest := convertFormats(tt.manifest)
119119
r := strings.NewReader(manifest)
120-
err := schema.MediaTypeManifestList.Validate(r)
120+
err := schema.MediaTypeManifestList.Validate(r, false, nil)
121121

122122
if got := err != nil; tt.fail != got {
123123
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
@@ -180,7 +180,7 @@ func TestBackwardsCompatibilityManifest(t *testing.T) {
180180

181181
manifest := convertFormats(tt.manifest)
182182
r := strings.NewReader(manifest)
183-
err := schema.MediaTypeManifest.Validate(r)
183+
err := schema.MediaTypeManifest.Validate(r, false, nil)
184184

185185
if got := err != nil; tt.fail != got {
186186
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
@@ -220,7 +220,7 @@ func TestBackwardsCompatibilityConfig(t *testing.T) {
220220

221221
manifest := convertFormats(tt.manifest)
222222
r := strings.NewReader(manifest)
223-
err := schema.MediaTypeImageConfig.Validate(r)
223+
err := schema.MediaTypeImageConfig.Validate(r, false, nil)
224224

225225
if got := err != nil; tt.fail != got {
226226
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)

schema/manifest_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func TestManifest(t *testing.T) {
113113
},
114114
} {
115115
r := strings.NewReader(tt.manifest)
116-
err := schema.MediaTypeManifest.Validate(r)
116+
err := schema.MediaTypeManifest.Validate(r, false, nil)
117117

118118
if got := err != nil; tt.fail != got {
119119
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)

schema/spec_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func validate(t *testing.T, name string) {
6969
continue
7070
}
7171

72-
err = schema.Validator(example.Mediatype).Validate(strings.NewReader(example.Body))
72+
err = schema.Validator(example.Mediatype).Validate(strings.NewReader(example.Body), false, nil)
7373
if err == nil {
7474
printFields(t, "ok", example.Mediatype, example.Title)
7575
t.Log(example.Body, "---")

schema/validator.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@ package schema
1616

1717
import (
1818
"bytes"
19+
"crypto/sha256"
20+
"encoding/hex"
1921
"fmt"
2022
"io"
2123
"io/ioutil"
24+
"log"
2225

2326
"github.com/pkg/errors"
2427
"github.com/xeipuuv/gojsonschema"
@@ -38,7 +41,7 @@ func (e ValidationError) Error() string {
3841
}
3942

4043
// Validate validates the given reader against the schema of the wrapped media type.
41-
func (v Validator) Validate(src io.Reader) error {
44+
func (v Validator) Validate(src io.Reader, verbose bool, out *log.Logger) error {
4245
buf, err := ioutil.ReadAll(src)
4346
if err != nil {
4447
return errors.Wrap(err, "unable to read manifest")
@@ -55,6 +58,14 @@ func (v Validator) Validate(src io.Reader) error {
5558
}
5659

5760
if result.Valid() {
61+
if verbose && out != nil {
62+
h := sha256.New()
63+
_, err := io.Copy(h, bytes.NewReader(buf))
64+
if err != nil {
65+
return errors.Wrap(err, "error generating hash")
66+
}
67+
out.Printf("sha256:%s", hex.EncodeToString(h.Sum(nil)))
68+
}
5869
return nil
5970
}
6071

0 commit comments

Comments
 (0)