mirror of https://github.com/docker/buildx.git
Merge pull request #2482 from rvoh-tismith/fix/single_source_create
Add `--prefer-index` flag for`imagetools create` on a single source
This commit is contained in:
commit
4549283f44
|
@ -608,7 +608,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dt, desc, err := itpull.Combine(ctx, srcs, nil)
|
dt, desc, err := itpull.Combine(ctx, srcs, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ type createOptions struct {
|
||||||
dryrun bool
|
dryrun bool
|
||||||
actionAppend bool
|
actionAppend bool
|
||||||
progress string
|
progress string
|
||||||
|
preferIndex bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, args []string) error {
|
func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, args []string) error {
|
||||||
|
@ -153,7 +154,7 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dt, desc, err := r.Combine(ctx, srcs, in.annotations)
|
dt, desc, err := r.Combine(ctx, srcs, in.annotations, in.preferIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -283,6 +284,7 @@ func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command {
|
||||||
flags.BoolVar(&options.actionAppend, "append", false, "Append to existing manifest")
|
flags.BoolVar(&options.actionAppend, "append", false, "Append to existing manifest")
|
||||||
flags.StringVar(&options.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`)
|
flags.StringVar(&options.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`)
|
||||||
flags.StringArrayVarP(&options.annotations, "annotation", "", []string{}, "Add annotation to the image")
|
flags.StringArrayVarP(&options.annotations, "annotation", "", []string{}, "Add annotation to the image")
|
||||||
|
flags.BoolVar(&options.preferIndex, "prefer-index", true, "When only a single source is specified, prefer outputting an image index or manifest list instead of performing a carbon copy")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,16 @@ Create a new image based on source images
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
|:---------------------------------|:--------------|:--------|:-----------------------------------------------------------------------------------------|
|
|:---------------------------------|:--------------|:--------|:------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [`--annotation`](#annotation) | `stringArray` | | Add annotation to the image |
|
| [`--annotation`](#annotation) | `stringArray` | | Add annotation to the image |
|
||||||
| [`--append`](#append) | | | Append to existing manifest |
|
| [`--append`](#append) | | | Append to existing manifest |
|
||||||
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
|
||||||
| [`--dry-run`](#dry-run) | | | Show final image instead of pushing |
|
| [`--dry-run`](#dry-run) | | | Show final image instead of pushing |
|
||||||
| [`-f`](#file), [`--file`](#file) | `stringArray` | | Read source descriptor from file |
|
| [`-f`](#file), [`--file`](#file) | `stringArray` | | Read source descriptor from file |
|
||||||
| `--progress` | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
|
| `--prefer-index` | `bool` | `true` | When only a single source is specified, prefer outputting an image index or manifest list instead of performing a carbon copy |
|
||||||
| [`-t`](#tag), [`--tag`](#tag) | `stringArray` | | Set reference for new image |
|
| `--progress` | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
|
||||||
|
| [`-t`](#tag), [`--tag`](#tag) | `stringArray` | | Set reference for new image |
|
||||||
|
|
||||||
|
|
||||||
<!---MARKER_GEN_END-->
|
<!---MARKER_GEN_END-->
|
||||||
|
@ -26,8 +27,13 @@ Create a new image based on source images
|
||||||
|
|
||||||
Create a new manifest list based on source manifests. The source manifests can
|
Create a new manifest list based on source manifests. The source manifests can
|
||||||
be manifest lists or single platform distribution manifests and must already
|
be manifest lists or single platform distribution manifests and must already
|
||||||
exist in the registry where the new manifest is created. If only one source is
|
exist in the registry where the new manifest is created.
|
||||||
specified, create performs a carbon copy.
|
|
||||||
|
If only one source is specified and that source is a manifest list or image index,
|
||||||
|
create performs a carbon copy. If one source is specified and that source is *not*
|
||||||
|
a list or index, the output will be a manifest list, however you can disable this
|
||||||
|
behavior with `--prefer-index=false` which attempts to preserve the source manifest
|
||||||
|
format in the output.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,19 @@ func testImagetoolsCopyManifest(t *testing.T, sb integration.Sandbox) {
|
||||||
for i := range mfst.Layers {
|
for i := range mfst.Layers {
|
||||||
require.Equal(t, mfst.Layers[i].Digest, mfst2.Layers[i].Digest)
|
require.Equal(t, mfst.Layers[i].Digest, mfst2.Layers[i].Digest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd = buildxCmd(sb, withArgs("imagetools", "create", "--prefer-index=false", "-t", target2+"-not-index", target))
|
||||||
|
dt, err = cmd.CombinedOutput()
|
||||||
|
require.NoError(t, err, string(dt))
|
||||||
|
|
||||||
|
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2+"-not-index", "--raw"))
|
||||||
|
dt, err = cmd.CombinedOutput()
|
||||||
|
require.NoError(t, err, string(dt))
|
||||||
|
|
||||||
|
var idx3 ocispecs.Manifest
|
||||||
|
err = json.Unmarshal(dt, &idx3)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, images.MediaTypeDockerSchema2Manifest, idx3.MediaType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testImagetoolsCopyIndex(t *testing.T, sb integration.Sandbox) {
|
func testImagetoolsCopyIndex(t *testing.T, sb integration.Sandbox) {
|
||||||
|
@ -127,6 +140,24 @@ func testImagetoolsCopyIndex(t *testing.T, sb integration.Sandbox) {
|
||||||
for i := range idx.Manifests {
|
for i := range idx.Manifests {
|
||||||
require.Equal(t, idx.Manifests[i].Digest, idx2.Manifests[i].Digest)
|
require.Equal(t, idx.Manifests[i].Digest, idx2.Manifests[i].Digest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd = buildxCmd(sb, withArgs("imagetools", "create", "--prefer-index=false", "-t", target2+"-still-index", target))
|
||||||
|
dt, err = cmd.CombinedOutput()
|
||||||
|
require.NoError(t, err, string(dt))
|
||||||
|
|
||||||
|
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2+"-still-index", "--raw"))
|
||||||
|
dt, err = cmd.CombinedOutput()
|
||||||
|
require.NoError(t, err, string(dt))
|
||||||
|
|
||||||
|
var idx3 ocispecs.Index
|
||||||
|
err = json.Unmarshal(dt, &idx3)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx3.MediaType)
|
||||||
|
|
||||||
|
require.Equal(t, len(idx.Manifests), len(idx3.Manifests))
|
||||||
|
for i := range idx.Manifests {
|
||||||
|
require.Equal(t, idx.Manifests[i].Digest, idx3.Manifests[i].Digest)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testImagetoolsInspectAndFilter(t *testing.T, sb integration.Sandbox) {
|
func testImagetoolsInspectAndFilter(t *testing.T, sb integration.Sandbox) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ type Source struct {
|
||||||
Ref reference.Named
|
Ref reference.Named
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann []string) ([]byte, ocispec.Descriptor, error) {
|
func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann []string, preferIndex bool) ([]byte, ocispec.Descriptor, error) {
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
dts := make([][]byte, len(srcs))
|
dts := make([][]byte, len(srcs))
|
||||||
|
@ -79,8 +79,16 @@ func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann []string) ([
|
||||||
|
|
||||||
// on single source, return original bytes
|
// on single source, return original bytes
|
||||||
if len(srcs) == 1 && len(ann) == 0 {
|
if len(srcs) == 1 && len(ann) == 0 {
|
||||||
if mt := srcs[0].Desc.MediaType; mt == images.MediaTypeDockerSchema2ManifestList || mt == ocispec.MediaTypeImageIndex {
|
switch srcs[0].Desc.MediaType {
|
||||||
|
// if the source is already an image index or manifest list, there is no need to consider the value
|
||||||
|
// of preferIndex since if set to true then the source is already in the preferred format, and if false
|
||||||
|
// it doesn't matter since we're not going to split it into separate manifests
|
||||||
|
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
|
||||||
return dts[0], srcs[0].Desc, nil
|
return dts[0], srcs[0].Desc, nil
|
||||||
|
default:
|
||||||
|
if !preferIndex {
|
||||||
|
return dts[0], srcs[0].Desc, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue