Skip to content

Conversation

@rodneyosodo
Copy link

Description

This PR adds comprehensive support for WebAssembly (WASM) OCI images to the container-libs image package, enabling WASM container images to be stored, distributed, and managed through the OCI registry ecosystem.

Changes

  • Add WASM media type constants (application/vnd.wasm.content.layer.v1 and application/vnd.wasm.config.v1+json)
  • Support WASM layer compression with gzip and zstd algorithms
  • Enable WASM layer encryption with all encryption variants
  • Update OCI manifest validation to recognise WASM media types
  • Extend image inspection, ID computation, and compression handling for WASM images

Use Case

This change enables users to work with WASM container images using Podman, Buildah, Skopeo, and other tools in the containers ecosystem. WASM images can now be pulled, pushed, inspected, and managed just like traditional container images, integrating seamlessly with the existing crun-wasm runtime support for wasi/wasm platforms.

Add comprehensive support for WebAssembly OCI images, including WASM
content layers, configuration blobs, compression, and encryption.

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
@github-actions github-actions bot added the image Related to "image" package label Jan 18, 2026
podmanbot pushed a commit to podmanbot/buildah that referenced this pull request Jan 18, 2026
@podmanbot
Copy link

✅ A new PR has been created in buildah to vendor these changes: containers/buildah#6644

@packit-as-a-service
Copy link

Packit jobs failed. @containers/packit-build please check.

rodneyosodo added a commit to rodneyosodo/skopeo that referenced this pull request Jan 18, 2026
This updates skopeo dependency of `go.podman.io/image/v5` based on the new changes as of containers/container-libs#596

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Copy link
Contributor

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

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

Thanks, but I can’t see how this could possibly work.

AFAICS the WASM OCI specification doesn’t support compressing layers, so by default I don’t know why we should do so. Is that, at least, a current design discussion in that project?

I feel somewhat similarly about the encryption part, although in there it might be more plausible to just do things without specification… except that the image’s config is not encrypted in the current c/image implementation. Is that really an encryption mechanism to commit to, in this entirely new format?!

As a starting hypothesis, continuing to treat these objects as non-image artifacts should mostly work — sure, without some of the extra features.

// old image manifests work (docker v2s1 especially).
func (m *manifestOCI1) OCIConfig(ctx context.Context) (*imgspecv1.Image, error) {
if m.m.Config.MediaType != imgspecv1.MediaTypeImageConfig {
if m.m.Config.MediaType != imgspecv1.MediaTypeImageConfig && m.m.Config.MediaType != internalManifest.WasmConfigMediaType {
Copy link
Contributor

Choose a reason for hiding this comment

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

AFAICS the two objects are not interchangeable and it makes no sense to parse the WASM one as an OCI one.

// This does not change the state of the original manifestOCI1 object.
func (m *manifestOCI1) convertToManifestSchema2(_ context.Context, options *types.ManifestUpdateOptions) (*manifestSchema2, error) {
if m.m.Config.MediaType != imgspecv1.MediaTypeImageConfig {
if m.m.Config.MediaType != imgspecv1.MediaTypeImageConfig && m.m.Config.MediaType != internalManifest.WasmConfigMediaType {
Copy link
Contributor

Choose a reason for hiding this comment

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

How would that work??!

// This does not change the state of the original manifestOCI1 object.
func (m *manifestOCI1) convertToManifestSchema1(ctx context.Context, options *types.ManifestUpdateOptions) (genericManifest, error) {
if m.m.Config.MediaType != imgspecv1.MediaTypeImageConfig {
if m.m.Config.MediaType != imgspecv1.MediaTypeImageConfig && m.m.Config.MediaType != internalManifest.WasmConfigMediaType {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

func (m *OCI1) Inspect(configGetter func(types.BlobInfo) ([]byte, error)) (*types.ImageInspectInfo, error) {
if m.Config.MediaType != imgspecv1.MediaTypeImageConfig {
// We could return at least the layers, but thats already available in a better format via types.Image.LayerInfos.
if m.Config.MediaType != imgspecv1.MediaTypeImageConfig && m.Config.MediaType != manifest.WasmConfigMediaType {
Copy link
Contributor

Choose a reason for hiding this comment

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

And again

imgspecv1.MediaTypeImageManifest,
imgspecv1.MediaTypeLayoutHeader,
ociencspec.MediaTypeLayerEnc, ociencspec.MediaTypeLayerGzipEnc:
ociencspec.MediaTypeLayerEnc, ociencspec.MediaTypeLayerGzipEnc,
Copy link
Contributor

Choose a reason for hiding this comment

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

This function is deprecated and has no known users, so I don’t see much point in extending it.

@mtrmac
Copy link
Contributor

mtrmac commented Jan 19, 2026

Also, for {internal/,}{image,manifest} we’d generally want to have realistic unit tests covering as much as possible — especially for formats that might not be used daily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

image Related to "image" package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants