diff --git a/cmd/nerdctl/image/image_convert.go b/cmd/nerdctl/image/image_convert.go index 49496f09ee7..48a8bed42f9 100644 --- a/cmd/nerdctl/image/image_convert.go +++ b/cmd/nerdctl/image/image_convert.go @@ -303,6 +303,8 @@ func convertOptions(cmd *cobra.Command) (types.ImageConvertOptions, error) { SociOptions: types.SociOptions{ SpanSize: sociSpanSize, MinLayerSize: sociMinLayerSize, + Platforms: platforms, + AllPlatforms: allPlatforms, }, }, Stdout: cmd.OutOrStdout(), diff --git a/cmd/nerdctl/image/image_convert_linux_test.go b/cmd/nerdctl/image/image_convert_linux_test.go index be24918fb31..07cd2a7003d 100644 --- a/cmd/nerdctl/image/image_convert_linux_test.go +++ b/cmd/nerdctl/image/image_convert_linux_test.go @@ -39,7 +39,7 @@ func TestImageConvert(t *testing.T) { require.Not(nerdtest.Docker), ), Setup: func(data test.Data, helpers test.Helpers) { - helpers.Ensure("pull", "--quiet", testutil.CommonImage) + helpers.Ensure("pull", "--quiet", "--all-platforms", testutil.CommonImage) }, SubTests: []*test.Case{ { @@ -107,6 +107,24 @@ func TestImageConvert(t *testing.T) { }, Expected: test.Expects(0, nil, nil), }, + { + Description: "soci with all-platforms", + Require: require.All( + require.Not(nerdtest.Docker), + nerdtest.Soci, + nerdtest.SociVersion("0.10.0"), + ), + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("rmi", "-f", data.Identifier("converted-image")) + }, + Command: func(data test.Data, helpers test.Helpers) test.TestableCommand { + return helpers.Command("image", "convert", "--soci", "--all-platforms", + "--soci-span-size", "2097152", + "--soci-min-layer-size", "0", + testutil.CommonImage, data.Identifier("converted-image")) + }, + Expected: test.Expects(0, nil, nil), + }, }, } diff --git a/pkg/api/types/image_types.go b/pkg/api/types/image_types.go index 5ff507ccc7c..0ceb3148896 100644 --- a/pkg/api/types/image_types.go +++ b/pkg/api/types/image_types.go @@ -310,4 +310,8 @@ type SociOptions struct { SpanSize int64 // Minimum layer size to build zTOC for. Smaller layers won't have zTOC and not lazy pulled. Default is 10 MiB. MinLayerSize int64 + // Platforms convert content for a specific platform + Platforms []string + // AllPlatforms convert content for all platforms + AllPlatforms bool } diff --git a/pkg/cmd/image/convert.go b/pkg/cmd/image/convert.go index 12a2040d598..c197755b3a5 100644 --- a/pkg/cmd/image/convert.go +++ b/pkg/cmd/image/convert.go @@ -171,7 +171,7 @@ func Convert(ctx context.Context, client *containerd.Client, srcRawRef, targetRa convertType = "nydus" case soci: // Convert image to SOCI format - convertedRef, err := snapshotterutil.ConvertSociIndexV2(ctx, client, srcRef, targetRef, options.GOptions, options.Platforms, options.SociOptions) + convertedRef, err := snapshotterutil.ConvertSociIndexV2(ctx, client, srcRef, targetRef, options.GOptions, options.SociOptions) if err != nil { return fmt.Errorf("failed to convert image to SOCI format: %w", err) } diff --git a/pkg/snapshotterutil/sociutil.go b/pkg/snapshotterutil/sociutil.go index 240ef54737e..82e8773ce66 100644 --- a/pkg/snapshotterutil/sociutil.go +++ b/pkg/snapshotterutil/sociutil.go @@ -104,7 +104,7 @@ func CheckSociVersion(requiredVersion string) error { } // ConvertSociIndexV2 converts an image to SOCI format and returns the converted image reference with digest -func ConvertSociIndexV2(ctx context.Context, client *client.Client, srcRef string, destRef string, gOpts types.GlobalCommandOptions, platforms []string, sOpts types.SociOptions) (string, error) { +func ConvertSociIndexV2(ctx context.Context, client *client.Client, srcRef string, destRef string, gOpts types.GlobalCommandOptions, sOpts types.SociOptions) (string, error) { // Check if SOCI version is at least 0.10.0 which is required for the convert operation if err := CheckSociVersion("0.10.0"); err != nil { return "", err @@ -117,10 +117,12 @@ func ConvertSociIndexV2(ctx context.Context, client *client.Client, srcRef strin sociCmd.Args = append(sociCmd.Args, "convert") - if len(platforms) > 0 { + if sOpts.AllPlatforms { + sociCmd.Args = append(sociCmd.Args, "--all-platforms") + } else if len(sOpts.Platforms) > 0 { // multiple values need to be passed as separate, repeating flags in soci as it uses urfave // https://github.com/urfave/cli/blob/main/docs/v2/examples/flags.md#multiple-values-per-single-flag - for _, p := range platforms { + for _, p := range sOpts.Platforms { sociCmd.Args = append(sociCmd.Args, "--platform", p) } }