Skip to content

Commit 4829194

Browse files
author
zhouhao
committed
Increase platform option
Signed-off-by: zhouhao <[email protected]>
1 parent ca603fc commit 4829194

File tree

7 files changed

+104
-71
lines changed

7 files changed

+104
-71
lines changed

cmd/oci-image-tool/create.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ var bundleTypes = []string{
2929
}
3030

3131
type bundleCmd struct {
32-
typ string // the type to bundle, can be empty string
33-
ref string
34-
root string
32+
typ string // the type to bundle, can be empty string
33+
ref string
34+
root string
35+
platform []string
3536
}
3637

3738
func createHandle(context *cli.Context) error {
@@ -40,9 +41,10 @@ func createHandle(context *cli.Context) error {
4041
}
4142

4243
v := bundleCmd{
43-
typ: context.String("type"),
44-
ref: context.String("ref"),
45-
root: context.String("rootfs"),
44+
typ: context.String("type"),
45+
ref: context.String("ref"),
46+
root: context.String("rootfs"),
47+
platform: context.StringSlice("platform"),
4648
}
4749

4850
if v.typ == "" {
@@ -56,10 +58,10 @@ func createHandle(context *cli.Context) error {
5658
var err error
5759
switch v.typ {
5860
case image.TypeImageLayout:
59-
err = image.CreateRuntimeBundleLayout(context.Args()[0], context.Args()[1], v.ref, v.root)
61+
err = image.CreateRuntimeBundleLayout(context.Args()[0], context.Args()[1], v.ref, v.root, v.platform)
6062

6163
case image.TypeImage:
62-
err = image.CreateRuntimeBundleFile(context.Args()[0], context.Args()[1], v.ref, v.root)
64+
err = image.CreateRuntimeBundleFile(context.Args()[0], context.Args()[1], v.ref, v.root, v.platform)
6365

6466
default:
6567
err = fmt.Errorf("cannot create %q", v.typ)
@@ -95,5 +97,9 @@ var createCommand = cli.Command{
9597
Value: "rootfs",
9698
Usage: "A directory representing the root filesystem of the container in the OCI runtime bundle. It is strongly recommended to keep the default value.",
9799
},
100+
cli.StringSliceFlag{
101+
Name: "platform",
102+
Usage: "The platform contains os and arch. Filter manifests according to the conditions provided. Only applicable if reftype is index.",
103+
},
98104
},
99105
}

cmd/oci-image-tool/unpack.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ var unpackTypes = []string{
2929
}
3030

3131
type unpackCmd struct {
32-
typ string // the type to unpack, can be empty string
33-
ref string
32+
typ string // the type to unpack, can be empty string
33+
ref string
34+
platform []string
3435
}
3536

3637
func unpackHandle(context *cli.Context) error {
@@ -39,8 +40,9 @@ func unpackHandle(context *cli.Context) error {
3940
}
4041

4142
v := unpackCmd{
42-
typ: context.String("type"),
43-
ref: context.String("ref"),
43+
typ: context.String("type"),
44+
ref: context.String("ref"),
45+
platform: context.StringSlice("platform"),
4446
}
4547

4648
if v.typ == "" {
@@ -54,10 +56,10 @@ func unpackHandle(context *cli.Context) error {
5456
var err error
5557
switch v.typ {
5658
case image.TypeImageLayout:
57-
err = image.UnpackLayout(context.Args()[0], context.Args()[1], v.ref)
59+
err = image.UnpackLayout(context.Args()[0], context.Args()[1], v.ref, v.platform)
5860

5961
case image.TypeImage:
60-
err = image.UnpackFile(context.Args()[0], context.Args()[1], v.ref)
62+
err = image.UnpackFile(context.Args()[0], context.Args()[1], v.ref, v.platform)
6163

6264
default:
6365
err = fmt.Errorf("cannot unpack %q", v.typ)
@@ -86,5 +88,9 @@ var unpackCommand = cli.Command{
8688
Value: "v1.0",
8789
Usage: "The ref pointing to the manifest of the OCI image. This must be present in the 'refs' subdirectory of the image.",
8890
},
91+
cli.StringSliceFlag{
92+
Name: "platform",
93+
Usage: "The platform contains os and arch conditions. Filter manifests according to the conditions provided. Only applicable if reftype is index.",
94+
},
8995
},
9096
}

completions/bash/oci-image-tool

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ _oci-image-tool_create() {
150150

151151
case "$cur" in
152152
-*)
153-
COMPREPLY=( $( compgen -W "--type --ref --rootfs --help -h" -- "$cur" ) )
153+
COMPREPLY=( $( compgen -W "--type --ref --rootfs --platform --help -h" -- "$cur" ) )
154154
;;
155155
esac
156156

@@ -166,7 +166,7 @@ _oci-image-tool_unpack() {
166166

167167
case "$cur" in
168168
-*)
169-
COMPREPLY=( $( compgen -W "--type --ref --help -h" -- "$cur" ) )
169+
COMPREPLY=( $( compgen -W "--type --ref --platform --help -h" -- "$cur" ) )
170170
;;
171171
esac
172172

image/image.go

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func validate(w walker, refs []string, out *log.Logger) error {
119119
}
120120

121121
for _, manifest := range index.Manifests {
122-
m, err := findManifest(w, &(manifest.Descriptor))
122+
m, err := findManifest(w, &manifest)
123123
if err != nil {
124124
return err
125125
}
@@ -140,30 +140,30 @@ func validate(w walker, refs []string, out *log.Logger) error {
140140
// UnpackLayout walks through the file tree given by src and, using the layers
141141
// specified in the manifest pointed to by the given ref, unpacks all layers in
142142
// the given destination directory or returns an error if the unpacking failed.
143-
func UnpackLayout(src, dest, ref string) error {
144-
return unpack(newPathWalker(src), dest, ref)
143+
func UnpackLayout(src, dest, ref string, platform []string) error {
144+
return unpack(newPathWalker(src), dest, ref, platform)
145145
}
146146

147147
// UnpackFile opens the file pointed by tarFileName and calls Unpack on it.
148-
func UnpackFile(tarFileName, dest, ref string) error {
148+
func UnpackFile(tarFileName, dest, ref string, platform []string) error {
149149
f, err := os.Open(tarFileName)
150150
if err != nil {
151151
return errors.Wrap(err, "unable to open file")
152152
}
153153
defer f.Close()
154154

155-
return Unpack(f, dest, ref)
155+
return Unpack(f, dest, ref, platform)
156156
}
157157

158158
// Unpack walks through the tar stream and, using the layers specified in
159159
// the manifest pointed to by the given ref, unpacks all layers in the given
160160
// destination directory or returns an error if the unpacking failed.
161161
// The destination will be created if it does not exist.
162-
func Unpack(r io.ReadSeeker, dest, refName string) error {
163-
return unpack(newTarWalker(r), dest, refName)
162+
func Unpack(r io.ReadSeeker, dest, refName string, platform []string) error {
163+
return unpack(newTarWalker(r), dest, refName, platform)
164164
}
165165

166-
func unpack(w walker, dest, refName string) error {
166+
func unpack(w walker, dest, refName string, platform []string) error {
167167
if err := layoutValidate(w); err != nil {
168168
return err
169169
}
@@ -196,28 +196,17 @@ func unpack(w walker, dest, refName string) error {
196196
return err
197197
}
198198

199-
if err := validateIndex(index, w); err != nil {
199+
if err = validateIndex(index, w); err != nil {
200200
return err
201201
}
202202

203-
if len(index.Manifests) == 0 {
204-
fmt.Println("warning: no manifests found")
205-
return nil
203+
manifests, err := filterManifest(w, index.Manifests, platform)
204+
if err != nil {
205+
return err
206206
}
207207

208-
for _, manifest := range index.Manifests {
209-
m, err := findManifest(w, &(manifest.Descriptor))
210-
if err != nil {
211-
return err
212-
}
213-
214-
if err := m.validate(w); err != nil {
215-
return err
216-
}
217-
218-
if err := m.unpack(w, dest); err != nil {
219-
return err
220-
}
208+
for _, m := range manifests {
209+
return m.unpack(w, dest)
221210
}
222211
}
223212

@@ -227,30 +216,30 @@ func unpack(w walker, dest, refName string) error {
227216
// CreateRuntimeBundleLayout walks through the file tree given by src and
228217
// creates an OCI runtime bundle in the given destination dest
229218
// or returns an error if the unpacking failed.
230-
func CreateRuntimeBundleLayout(src, dest, ref, root string) error {
231-
return createRuntimeBundle(newPathWalker(src), dest, ref, root)
219+
func CreateRuntimeBundleLayout(src, dest, ref, root string, platform []string) error {
220+
return createRuntimeBundle(newPathWalker(src), dest, ref, root, platform)
232221
}
233222

234223
// CreateRuntimeBundleFile opens the file pointed by tarFile and calls
235224
// CreateRuntimeBundle.
236-
func CreateRuntimeBundleFile(tarFile, dest, ref, root string) error {
225+
func CreateRuntimeBundleFile(tarFile, dest, ref, root string, platform []string) error {
237226
f, err := os.Open(tarFile)
238227
if err != nil {
239228
return errors.Wrap(err, "unable to open file")
240229
}
241230
defer f.Close()
242231

243-
return createRuntimeBundle(newTarWalker(f), dest, ref, root)
232+
return createRuntimeBundle(newTarWalker(f), dest, ref, root, platform)
244233
}
245234

246235
// CreateRuntimeBundle walks through the given tar stream and
247236
// creates an OCI runtime bundle in the given destination dest
248237
// or returns an error if the unpacking failed.
249-
func CreateRuntimeBundle(r io.ReadSeeker, dest, ref, root string) error {
250-
return createRuntimeBundle(newTarWalker(r), dest, ref, root)
238+
func CreateRuntimeBundle(r io.ReadSeeker, dest, ref, root string, platform []string) error {
239+
return createRuntimeBundle(newTarWalker(r), dest, ref, root, platform)
251240
}
252241

253-
func createRuntimeBundle(w walker, dest, refName, rootfs string) error {
242+
func createRuntimeBundle(w walker, dest, refName, rootfs string, platform []string) error {
254243
if err := layoutValidate(w); err != nil {
255244
return err
256245
}
@@ -274,7 +263,7 @@ func createRuntimeBundle(w walker, dest, refName, rootfs string) error {
274263
return err
275264
}
276265

277-
return createRuntimebundle(w, m, dest, rootfs)
266+
return createBundle(w, m, dest, rootfs)
278267
}
279268

280269
if ref.MediaType == validRefMediaTypes[1] {
@@ -283,35 +272,24 @@ func createRuntimeBundle(w walker, dest, refName, rootfs string) error {
283272
return err
284273
}
285274

286-
if err := validateIndex(index, w); err != nil {
275+
if err = validateIndex(index, w); err != nil {
287276
return err
288277
}
289278

290-
if len(index.Manifests) == 0 {
291-
fmt.Println("warning: no manifests found")
292-
return nil
279+
manifests, err := filterManifest(w, index.Manifests, platform)
280+
if err != nil {
281+
return err
293282
}
294283

295-
for _, manifest := range index.Manifests {
296-
m, err := findManifest(w, &(manifest.Descriptor))
297-
if err != nil {
298-
return err
299-
}
300-
301-
if err := m.validate(w); err != nil {
302-
return err
303-
}
304-
305-
if err := createRuntimebundle(w, m, dest, rootfs); err != nil {
306-
return err
307-
}
284+
for _, m := range manifests {
285+
return createBundle(w, m, dest, rootfs)
308286
}
309287
}
310288

311289
return nil
312290
}
313291

314-
func createRuntimebundle(w walker, m *manifest, dest, rootfs string) error {
292+
func createBundle(w walker, m *manifest, dest, rootfs string) error {
315293
c, err := findConfig(w, &m.Config)
316294
if err != nil {
317295
return err
@@ -344,3 +322,37 @@ func createRuntimebundle(w walker, m *manifest, dest, rootfs string) error {
344322

345323
return json.NewEncoder(f).Encode(spec)
346324
}
325+
326+
// filertManifest returns a filtered list of manifests
327+
func filterManifest(w walker, Manifests []v1.Descriptor, platform []string) ([]*manifest, error) {
328+
var manifests []*manifest
329+
330+
if len(Manifests) == 0 {
331+
fmt.Println("warning: no manifests found")
332+
return manifests, nil
333+
}
334+
335+
if len(platform) != 2 {
336+
return manifests, fmt.Errorf("platform must have os and arch")
337+
}
338+
339+
for _, manifest := range Manifests {
340+
m, err := findManifest(w, &manifest)
341+
if err != nil {
342+
return manifests, err
343+
}
344+
345+
if err := m.validate(w); err != nil {
346+
return manifests, err
347+
}
348+
if manifest.Platform.OS == platform[0] && manifest.Platform.Architecture == platform[1] {
349+
manifests = append(manifests, m)
350+
}
351+
}
352+
353+
if len(manifests) == 0 {
354+
return manifests, fmt.Errorf("There is no matching manifest")
355+
}
356+
357+
return manifests, nil
358+
}

image/index.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ import (
2828
"github.com/pkg/errors"
2929
)
3030

31-
func findIndex(w walker, d *v1.Descriptor) (*v1.ImageIndex, error) {
32-
var index v1.ImageIndex
31+
func findIndex(w walker, d *v1.Descriptor) (*v1.Index, error) {
32+
var index v1.Index
3333

3434
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
3535
if info.IsDir() || filepath.Clean(path) != indexPath {
@@ -60,9 +60,9 @@ func findIndex(w walker, d *v1.Descriptor) (*v1.ImageIndex, error) {
6060
}
6161
}
6262

63-
func validateIndex(index *v1.ImageIndex, w walker) error {
63+
func validateIndex(index *v1.Index, w walker) error {
6464
for _, manifest := range index.Manifests {
65-
if err := validateDescriptor(&manifest.Descriptor, w, []string{v1.MediaTypeImageManifest}); err != nil {
65+
if err := validateDescriptor(&manifest, w, []string{v1.MediaTypeImageManifest}); err != nil {
6666
return errors.Wrap(err, "manifest validation failed")
6767
}
6868
}

man/oci-image-tool-create.1.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ runtime-spec-compatible `dest/config.json`.
2626
**--type**=""
2727
Type of the file to unpack. If unset, oci-image-tool will try to auto-detect the type. One of "imageLayout,image"
2828

29+
**--platform**=""
30+
The platform contains os and arch. Filter manifests according to the conditions provided.
31+
Only applicable if reftype is index.
32+
2933
# EXAMPLES
3034
```
3135
$ skopeo copy docker://busybox oci:busybox-oci

man/oci-image-tool-unpack.1.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ oci-image-tool unpack \- Unpack an image or image source layout
2020
**--type**=""
2121
Type of the file to unpack. If unset, oci-image-tool will try to auto-detect the type. One of "imageLayout,image"
2222

23+
**--platform**=""
24+
The platform contains os and arch. Filter manifests according to the conditions provided.
25+
Only applicable if reftype is index.
26+
27+
2328
# EXAMPLES
2429
```
2530
$ skopeo copy docker://busybox oci:busybox-oci

0 commit comments

Comments
 (0)