Skip to content

Conversation

@ChengyuZhu6
Copy link
Member

@ChengyuZhu6 ChengyuZhu6 commented Jun 23, 2025

Fixes: #4351

Reorganize `ImageConvertOptions` by extracting format-specific options
into dedicated structs (EstargzOptions, ZstdOptions, ZstdChunkedOptions,
NydusOptions, OverlaybdOptions) and embedding them for better code
organization and maintainability.

Signed-off-by: ChengyuZhu6 <hudson@cyzhu.com>
@ChengyuZhu6
Copy link
Member Author

Just rebased to main. No code change.

cmd.Flags().Bool("estargz", false, "Convert the committed layer to eStargz for lazy pulling")
cmd.Flags().Int("estargz-compression-level", 9, "eStargz compression level (1-9)")
cmd.Flags().Int("estargz-chunk-size", 0, "eStargz chunk size")
cmd.Flags().Int("estargz-min-chunk-size", 0, "The minimal number of bytes of data must be written in one gzip stream")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this should cover all the convert flags, but I guess it can be fixed later

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this should cover all the convert flags, but I guess it can be fixed later

@AkihiroSuda Only these fields are retained because EstargzExternalToc and EstargzKeepDiffID are specifically used for the estargz-externaltoc feature. However, since externaltoc cannot be detected or updated during the commit phase—even if the writable layers are correctly converted to stargz blobs—I have not included these two fields.

@ChengyuZhu6 ChengyuZhu6 force-pushed the estargz branch 2 times, most recently from 60d047a to 932aca1 Compare June 24, 2025 03:43
@ChengyuZhu6
Copy link
Member Author

Example:

# Step 1: Inspect an existing eStargz image to see its structure
$ skopeo inspect --raw docker://registry.domain.local/library/app:estargz | jq .
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:8262dc955932ff4fea464fbd47c4765558d36ef04e0f70626bd1cd83afb740fc",
    "size": 7608
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:9a8ece1256563321005c05a5e56e74f9b6b5033fd3b278156d5af768f2343b72",
      "size": 31413787,
      "annotations": {
        "containerd.io/snapshot/stargz/toc.digest": "sha256:e127ce321dc5c5bc6d719142ceba4f0fc3e5c802014bd849eaea6c04d3615cf8",
        "io.containers.estargz.uncompressed-size": "79133696"
      }
    },
    // ... more OCI layers from base image
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:71d29537527e51c8b7c3037a9aacdaab5fd09ec7a5b5f88efb75fe03900eda2e",
      "size": 808812211,
      "annotations": {
        "containerd.io/snapshot/stargz/toc.digest": "sha256:a2d7960cd75fdd2a41d758170bdf67307ab04cf8ae3d02e89c7758ca464b4b53",
        "io.containers.estargz.uncompressed-size": "1073745920"
      }
    }
  ]
}

# Step 2: Run the eStargz image with stargz snapshotter for lazy pulling
$ nerdctl --snapshotter stargz run -it --rm --entrypoint sh registry.domain.local/library/app:estargz -c "/bin/bash"
registry.domain.local/library/app:estargz:                                  resolved       |++++++++++++++++++++++++++++++++++++++| 
manifest-sha256:61f6acd3b02c475b53474051193bc1fc227149acd8854cbc40ff77e4efc2e334: done           |++++++++++++++++++++++++++++++++++++++| 
config-sha256:8262dc955932ff4fea464fbd47c4765558d36ef04e0f70626bd1cd83afb740fc:   done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 0.7 s                                                                    total:  7.4 Ki (10.6 KiB/s)                                      
root@e6e28616e508:/# 

# Step 3: Make changes inside the container
root@e6e28616e508:/# echo "1" > file.txt

# Step 4: Commit the container with eStargz optimization
$ nerdctl commit e6e28616e508 --format oci --estargz registry.domain.local/library/app:estargz-after-commit
INFO[0011] Converting diff layer to eStargz format      
sha256:a371379f86039e253fbe94ca8c335fef915a43e970b722900cc53840a0590cce

# Step 5: Push the new eStargz image
$ nerdctl push registry.domain.local/library/app:estargz-after-commit

# Step 6: Verify the new image has eStargz layers
$ skopeo inspect --raw docker://registry.domain.local/library/app:estargz-after-commit | jq .
{
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "schemaVersion": 2,
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:a371379f86039e253fbe94ca8c335fef915a43e970b722900cc53840a0590cce",
    "size": 7763
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:9a8ece1256563321005c05a5e56e74f9b6b5033fd3b278156d5af768f2343b72",
      "size": 31413787,
      "annotations": {
        "containerd.io/snapshot/stargz/toc.digest": "sha256:e127ce321dc5c5bc6d719142ceba4f0fc3e5c802014bd849eaea6c04d3615cf8",
        "io.containers.estargz.uncompressed-size": "79133696"
      }
    },
   // ... more OCI layers from base image
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:71d29537527e51c8b7c3037a9aacdaab5fd09ec7a5b5f88efb75fe03900eda2e",
      "size": 808812211,
      "annotations": {
        "containerd.io/snapshot/stargz/toc.digest": "sha256:a2d7960cd75fdd2a41d758170bdf67307ab04cf8ae3d02e89c7758ca464b4b53",
        "io.containers.estargz.uncompressed-size": "1073745920"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:d9874efb6f5b65e5a52cfb7b87843888d1f2c956172a9f1fad8c2df4c96823dc",
      "size": 908,
      "annotations": {
        "containerd.io/snapshot/stargz/toc.digest": "sha256:d90c6a5a2484100662035073b2098be8cb2f01da1828bef61d4c0c19cb6cc6fd",
        "io.containers.estargz.uncompressed-size": "5632"
      }
    }
  ]
}

@ChengyuZhu6
Copy link
Member Author

cc @ktock

Copy link
Member

@ktock ktock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes: #4325

Maybe #4351 ?

@ChengyuZhu6
Copy link
Member Author

Fixes: #4325

Maybe #4351 ?

Fixed.

…ommit

support estargz conversion with writable layer in container commit

Fixes: containerd#4351

Signed-off-by: ChengyuZhu6 <hudson@cyzhu.com>
Copy link
Member

@ktock ktock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@ChengyuZhu6
Copy link
Member Author

@AkihiroSuda Could this PR be added to the v2.1.3 planning?

@AkihiroSuda AkihiroSuda added this to the v2.1.3 milestone Jun 25, 2025
Copy link
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@AkihiroSuda AkihiroSuda merged commit 0a5cb1d into containerd:main Jun 25, 2025
38 checks passed
@ChengyuZhu6 ChengyuZhu6 deleted the estargz branch June 25, 2025 02:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

container_commit: Add support for converting writable layers to eStargz blobs

3 participants