Skip to content

Add soci convert dirty #18

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions cmd/nerdctl/image/image_convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ func convertCommand() *cobra.Command {
cmd.Flags().String("overlaybd-dbstr", "", "Database config string for overlaybd")
// #endregion

// #region soci flags
cmd.Flags().Bool("soci", false, "Convert image to SOCI Index V2 format.")
cmd.Flags().Int64("soci-min-layer-size", -1, "The minimum size of layers that will be converted to SOCI Index V2 format")
cmd.Flags().Int64("soci-span-size", -1, "The size of SOCI spans")
// #endregion

// #region generic flags
cmd.Flags().Bool("uncompress", false, "Convert tar.gz layers to uncompressed tar layers")
cmd.Flags().Bool("oci", false, "Convert Docker media types to OCI media types")
Expand Down Expand Up @@ -213,6 +219,21 @@ func convertOptions(cmd *cobra.Command) (types.ImageConvertOptions, error) {
}
// #endregion

// #region soci flags
soci, err := cmd.Flags().GetBool("soci")
if err != nil {
return types.ImageConvertOptions{}, err
}
sociMinLayerSize, err := cmd.Flags().GetInt64("soci-min-layer-size")
if err != nil {
return types.ImageConvertOptions{}, err
}
sociSpanSize, err := cmd.Flags().GetInt64("soci-span-size")
if err != nil {
return types.ImageConvertOptions{}, err
}
// #endregion

// #region generic flags
uncompress, err := cmd.Flags().GetBool("uncompress")
if err != nil {
Expand Down Expand Up @@ -268,6 +289,13 @@ func convertOptions(cmd *cobra.Command) (types.ImageConvertOptions, error) {
OverlayFsType: overlaybdFsType,
OverlaydbDBStr: overlaybdDbstr,
// #endregion
// #region soci flags
Soci: soci,
SociOptions: types.SociOptions{
SpanSize: sociSpanSize,
MinLayerSize: sociMinLayerSize,
},
// #endregion
// #region generic flags
Uncompress: uncompress,
Oci: oci,
Expand Down
18 changes: 18 additions & 0 deletions cmd/nerdctl/image/image_convert_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,24 @@ func TestImageConvert(t *testing.T) {
},
Expected: test.Expects(0, nil, nil),
},
{
Description: "soci",
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",
"--soci-span-size", "2097152",
"--soci-min-layer-size", "20971520",
testutil.CommonImage, data.Identifier("converted-image"))
},
Expected: test.Expects(0, nil, nil),
},
},
}

Expand Down
4 changes: 4 additions & 0 deletions docs/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,10 @@ Flags:
- `--oci` : convert Docker media types to OCI media types
- `--platform=<PLATFORM>` : convert content for a specific platform
- `--all-platforms` : convert content for all platforms (default: false)
- `--soci`: generate SOCI v2 Indices to oci images. *[**Note**: content is converted for all platforms by default when using this flag, use the `--platorm` flag to limit this behavior]*
- `--soci-min-layer-size` : Span size in bytes that soci index uses to segment layer data. Default is 4 MiB.
- `--soci-min-layer-size`: Minimum layer size in bytes to build zTOC for. Smaller layers won't have zTOC and not lazy pulled. Default is 10 MiB.


### :nerd_face: nerdctl image encrypt

Expand Down
15 changes: 15 additions & 0 deletions docs/soci.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,18 @@ For images that already have SOCI indices, see https://gallery.ecr.aws/soci-work
nerdctl push --snapshotter=soci --soci-span-size=2097152 --soci-min-layer-size=20971520 public.ecr.aws/my-registry/my-repo:latest
```
--soci-span-size and --soci-min-layer-size are two properties to customize the SOCI index. See [Command Reference](https://github.com/containerd/nerdctl/blob/377b2077bb616194a8ef1e19ccde32aa1ffd6c84/docs/command-reference.md?plain=1#L773) for further details.


## Enable SOCI for `nerdctl image convert`

| :zap: Requirement | nerdctl >= 2.2.0 |
| ----------------- | ---------------- |

| :zap: Requirement | soci-snapshotter >= 0.10.0 |
| ----------------- | ---------------- |

- Convert an image to generate SOCI Index artifacts v2. Running the `nerdctl image convert` with the `--soci` flag and a `srcImg` and `dstImg`, `nerdctl` will create the SOCI v2 indices and the new image will be present in the `dstImg` address.
```console
nerdctl image convert --soci --soci-span-size=2097152 --soci-min-layer-size=20971520 public.ecr.aws/my-registry/my-repo:latest public.ecr.aws/my-registry/my-repo:soci
```
--soci-span-size and --soci-min-layer-size are two properties to customize the SOCI index. See [Command Reference](https://github.com/containerd/nerdctl/blob/377b2077bb616194a8ef1e19ccde32aa1ffd6c84/docs/command-reference.md?plain=1#L773) for further details.
10 changes: 8 additions & 2 deletions pkg/api/types/image_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package types
import (
"io"

"github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

// ImageListOptions specifies options for `nerdctl image list`.
Expand Down Expand Up @@ -124,6 +124,12 @@ type ImageConvertOptions struct {
OverlaydbDBStr string
// #endregion

// #region soci flags
// Soci convert image to SOCI format.eiifc
Soci bool
// SociOptions contains SOCI-specific options
SociOptions SociOptions
// #endregion
}

// ImageCryptOptions specifies options for `nerdctl image encrypt` and `nerdctl image decrypt`.
Expand Down Expand Up @@ -200,7 +206,7 @@ type ImagePullOptions struct {
// If nil, it will unpack automatically if only 1 platform is specified.
Unpack *bool
// Content for specific platforms. Empty if `--all-platforms` is true
OCISpecPlatform []v1.Platform
OCISpecPlatform []ocispec.Platform
// Pull mode
Mode string
// Suppress verbose output
Expand Down
19 changes: 17 additions & 2 deletions pkg/cmd/image/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import (
converterutil "github.com/containerd/nerdctl/v2/pkg/imgutil/converter"
"github.com/containerd/nerdctl/v2/pkg/platformutil"
"github.com/containerd/nerdctl/v2/pkg/referenceutil"
"github.com/containerd/nerdctl/v2/pkg/snapshotterutil"
)

func Convert(ctx context.Context, client *containerd.Client, srcRawRef, targetRawRef string, options types.ImageConvertOptions) error {
Expand Down Expand Up @@ -86,8 +87,9 @@ func Convert(ctx context.Context, client *containerd.Client, srcRawRef, targetRa
zstdchunked := options.ZstdChunked
overlaybd := options.Overlaybd
nydus := options.Nydus
soci := options.Soci
var finalize func(ctx context.Context, cs content.Store, ref string, desc *ocispec.Descriptor) (*images.Image, error)
if estargz || zstd || zstdchunked || overlaybd || nydus {
if estargz || zstd || zstdchunked || overlaybd || nydus || soci {
convertCount := 0
if estargz {
convertCount++
Expand All @@ -104,9 +106,12 @@ func Convert(ctx context.Context, client *containerd.Client, srcRawRef, targetRa
if nydus {
convertCount++
}
if soci {
convertCount++
}

if convertCount > 1 {
return errors.New("options --estargz, --zstdchunked, --overlaybd and --nydus lead to conflict, only one of them can be used")
return errors.New("options --estargz, --zstdchunked, --overlaybd, --nydus and --soci lead to conflict, only one of them can be used")
}

var convertFunc converter.ConvertFunc
Expand Down Expand Up @@ -164,6 +169,16 @@ 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)
if err != nil {
return fmt.Errorf("failed to convert image to SOCI format: %w", err)
}
res := converterutil.ConvertedImageInfo{
Image: convertedRef,
}
return printConvertedImage(options.Stdout, options, res)
}

if convertType != "overlaybd" {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/image/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func Push(ctx context.Context, client *containerd.Client, rawRef string, options
return err
}
if options.GOptions.Snapshotter == "soci" {
if err = snapshotterutil.CreateSoci(ref, options.GOptions, options.AllPlatforms, options.Platforms, options.SociOptions); err != nil {
if err = snapshotterutil.CreateSociIndexV1(ref, options.GOptions, options.AllPlatforms, options.Platforms, options.SociOptions); err != nil {
return err
}
if err = snapshotterutil.PushSoci(ref, options.GOptions, options.AllPlatforms, options.Platforms); err != nil {
Expand Down
Loading
Loading