Skip to content

Commit

Permalink
Add --platform CLI option for crane (#788)
Browse files Browse the repository at this point in the history
* Add --platform CLI option for crane

* Allow to set variant in platform CLI flag

* Update docs
  • Loading branch information
dvob committed Oct 22, 2020
1 parent 6344e57 commit 25dfb32
Show file tree
Hide file tree
Showing 24 changed files with 136 additions and 43 deletions.
4 changes: 4 additions & 0 deletions cmd/crane/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ import (
func init() {
Root.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable debug logs")
Root.PersistentFlags().BoolVar(&insecure, "insecure", false, "Allow image references to be fetched without TLS")
Root.PersistentFlags().Var(platform, "platform", "Specifies the platform in the form os/arch[/variant] (e.g. linux/amd64).")
}

var (
verbose = false
insecure = false
platform = &platformValue{}

// Crane options for this invocation.
options = []crane.Option{}
Expand All @@ -48,6 +50,8 @@ var (
options = append(options, crane.Insecure)
}

options = append(options, crane.WithPlatform(platform.platform))

// Add any http headers if they are set in the config file.
cf, err := config.Load(os.Getenv("DOCKER_CONFIG"))
if err != nil {
Expand Down
67 changes: 67 additions & 0 deletions cmd/crane/cmd/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package cmd

import (
"fmt"
"strings"

v1 "github.com/google/go-containerregistry/pkg/v1"
)

type platformValue struct {
platform *v1.Platform
}

func (pv *platformValue) Set(platform string) error {
p, err := parsePlatform(platform)
if err != nil {
return err
}
pv.platform = p
return nil
}

func (pv *platformValue) String() string {
return platformToString(pv.platform)
}

func (pv *platformValue) Type() string {
return "platform"
}

func platformToString(p *v1.Platform) string {
if p == nil {
return "all"
}
platform := ""
if p.OS != "" && p.Architecture != "" {
platform = p.OS + "/" + p.Architecture
}
if p.Variant != "" {
platform += "/" + p.Variant
}
return platform
}

func parsePlatform(platform string) (*v1.Platform, error) {
if platform == "all" {
return nil, nil
}

p := &v1.Platform{}
parts := strings.Split(platform, "/")

if len(parts) < 2 {
return nil, fmt.Errorf("failed to parse platform '%s': expected format os/arch[/variant]", platform)
}
if len(parts) > 3 {
return nil, fmt.Errorf("failed to parse platform '%s': too many slashes", platform)
}

p.OS = parts[0]
p.Architecture = parts[1]
if len(parts) > 2 {
p.Variant = parts[2]
}

return p, nil
}
7 changes: 4 additions & 3 deletions cmd/crane/doc/crane.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_append.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_auth.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_auth_get.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_auth_login.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_blob.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_catalog.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_config.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_copy.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_delete.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_digest.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_export.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_ls.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_manifest.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_pull.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_push.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_rebase.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_tag.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_validate.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cmd/crane/doc/crane_version.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion pkg/crane/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ func Insecure(o *options) {
// WithPlatform is an Option to specify the platform.
func WithPlatform(platform *v1.Platform) Option {
return func(o *options) {
o.remote = append(o.remote, remote.WithPlatform(*platform))
if platform != nil {
o.remote = append(o.remote, remote.WithPlatform(*platform))
}
o.platform = platform
}
}
2 changes: 1 addition & 1 deletion pkg/v1/remote/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (r *remoteIndex) childByPlatform(platform v1.Platform) (*Descriptor, error)
return r.childDescriptor(childDesc, platform)
}
}
return nil, fmt.Errorf("no child with platform %s/%s in index %s", platform.Architecture, platform.OS, r.Ref)
return nil, fmt.Errorf("no child with platform %s/%s in index %s", platform.OS, platform.Architecture, r.Ref)
}

func (r *remoteIndex) childByHash(h v1.Hash) (*Descriptor, error) {
Expand Down

0 comments on commit 25dfb32

Please sign in to comment.