-
Notifications
You must be signed in to change notification settings - Fork 2.1k
image: Add convert command
#4983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| package image | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
|
|
||
| "github.com/containerd/platforms" | ||
| "github.com/distribution/reference" | ||
| "github.com/docker/cli/cli" | ||
| "github.com/docker/cli/cli/command" | ||
| imagetypes "github.com/docker/docker/api/types/image" | ||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| type convertArgs struct { | ||
| Src string | ||
| Dst []string | ||
| Platforms []string | ||
| NoAttestations bool | ||
| OnlyAvailablePlatforms bool | ||
| } | ||
|
|
||
| func NewConvertCommand(dockerCli command.Cli) *cobra.Command { | ||
| var args convertArgs | ||
|
|
||
| cmd := &cobra.Command{ | ||
| Use: "convert [OPTIONS]", | ||
| Short: "Convert multi-platform images", | ||
| Args: cli.ExactArgs(0), | ||
| RunE: func(cmd *cobra.Command, _ []string) error { | ||
| return runConvert(cmd.Context(), dockerCli, args) | ||
| }, | ||
| Aliases: []string{"convert"}, | ||
| Annotations: map[string]string{ | ||
| "aliases": "docker image convert, docker convert", | ||
| }, | ||
| } | ||
|
|
||
| flags := cmd.Flags() | ||
| flags.StringArrayVar(&args.Platforms, "platforms", nil, "Include only the specified platforms in the destination image") | ||
| flags.BoolVar(&args.NoAttestations, "no-attestations", false, "Do not include image attestations") | ||
| flags.BoolVar(&args.OnlyAvailablePlatforms, "available", false, "Only include platforms locally available to the daemon") | ||
| flags.StringArrayVar(&args.Dst, "to", nil, "Target image references") | ||
| flags.StringVar(&args.Src, "from", "", "Source image reference") | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nerdctl already has Would it be possible to adopt the same syntax as
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think in general, the purpose is the same. Unfortunately I don't have any better idea for a name... Do you have any suggestions? We deliberately chose the src and dst to be flag arguments instead of positional arguments as it gives more clarity, especially when multiple destinations might be specified.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we should change our syntax (esp. since we settled on this one as the most user-friendly/better option) just for compatibility's sake. Unless there's a more explicit/as clear name, I also don't think we should change the name to avoid "colliding" with
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What about making it
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Definitely a fan of positional for this but I haven't looked at the PR yet, just this thread.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @tianon - I think you had a strong opinion on it being a flag argument 😄
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Took me a minute, but I remember now what my thoughts were. 😅 IMO, this command should match (I think we could make the same argument for In the case of convert, we might have multiple inputs as well, right? For example, if we have a way to remove things from an index, wouldn't it make sense to also have a way to add things to one / create one? That could then be multiple positional arguments (now unambiguous if we avoid destination being positional). |
||
|
|
||
| return cmd | ||
| } | ||
|
|
||
| func runConvert(ctx context.Context, dockerCLI command.Cli, args convertArgs) error { | ||
| if len(args.Dst) == 0 { | ||
| return fmt.Errorf("No destination image specified") | ||
| } | ||
| if args.Src == "" { | ||
| return fmt.Errorf("No source image specified") | ||
| } | ||
|
|
||
| var dstRefs []reference.NamedTagged | ||
| for _, dst := range args.Dst { | ||
| dstRef, err := reference.ParseNormalizedNamed(dst) | ||
| if err != nil { | ||
| return fmt.Errorf("invalid destination image reference: %s: %w", dst, err) | ||
| } | ||
|
|
||
| dstRef = reference.TagNameOnly(dstRef) | ||
| dstRefTagged := dstRef.(reference.NamedTagged) | ||
| dstRefs = append(dstRefs, dstRefTagged) | ||
| } | ||
|
|
||
| opts := imagetypes.ConvertOptions{ | ||
| NoAttestations: args.NoAttestations, | ||
| OnlyAvailablePlatforms: args.OnlyAvailablePlatforms, | ||
| } | ||
|
|
||
| for _, platform := range args.Platforms { | ||
| p, err := platforms.Parse(platform) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| opts.Platforms = append(opts.Platforms, p) | ||
| } | ||
|
|
||
| return dockerCLI.Client().ImageConvert(ctx, args.Src, dstRefs, opts) | ||
| } | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is named "platform" rather than "platforms" in nerdctl and ctr