Skip to content

WebAssembly Components support #132

Description

@applejag

Heyo! I just came across this project and have only read the blog posts and skimmed over docs. So please excuse me while I make assumptions over how yoke works.

You mentioned this a little in https://yokecd.github.io/blog/posts/interfacing-with-webassembly-in-go/#hurdles where you explain how wazero doesn't support the component model (you write "yet" in the blog post, but they seem quite adamant that they'll never support it: wazero/wazero#2200). However, the way I see it, WebAssembly Component Model is the way forward and it does give some other benefits like WASM GC & a strongly-typed ABI, and hopefully soon also async support.

So this feature request kind of requires the switch to a different WASM runtime.

As for how this would be implemented: what if you exposed an ABI over WebAssembly Components that allows the yoke flight to offload some of the heavy lifting?

  • Converting a Helm tarfile into list of templated manifests
  • Converting a Yoke Flight WASM blob into list of manifests
  • Converting YAML to JSON and vice versa
  • Requiring dependencies so the Yoke Flight doesn't need to embed a bunch of other blobs inside it
  • A bunch of helper functions to for example generate a Kubernetes secret or adding a label to a manifest.
  • Expose a kustomize-like API for transforming some templates

I haven't looked too deep into how to use WIT (WASM Interface Types), but I'd imagine something like this:

world flight {
    import command;
    import yoke;
    import encodings;
    export renderer;
}

interface command {
    /// Returns the command-line arguments forwarded from yoke to this flight.
    get-args: func() list<string>;
}

interface yoke {
    render-chart-tarball: func(tarball: list<u8>) list<manifest>;
    render-yoke-flight: func(wasm: list<u8>) list<manifest>;
    lookup: func(name: string, namespace: string, kind: string, api-version: string) option<manifest>;
}

interface encodings {
    yaml-to-json: func(yaml: string) list<string>;
    json-to-yaml: func(json: string) list<string>;
    yaml-to-manifests: func(yaml: string) list<manifest>;
    json-to-manifests: func(json: string) list<manifest>;
}

interface renderer {
    render-manifests: func() list<manifest>;
}

resource object-meta {
    name: func() string;
    namespace: func() string;
}

resource manifest {
    api-version: func() string;
    kind: func() string;
    metadata: func() object-meta;

    /// Returns this manifest rendered as JSON
    json: func() string;

    /// Returns this manifest rendered as YAML
    yaml: func() string;
}

Here's a great talk that summarizes this a little: https://2024.wasm.io/sessions/webassembly-component-model-what-how-and-why-you-should-not-ignore-it/


Benefits of this:

  • Allows offloading a lot of domain-specific stuff like "render Helm chart", which helps reducing the size of the WASM blobs as they could skip including a YAML parser & Helm rendering engine.
  • Allows users to use other languages than Go when working with Helm tarballs.
  • Allows stronger typing than "just read from stdin/write to stdout"
  • With some design work, maybe the WIT could allow for chaining one Yoke Flight to another. Which in turn could allow Yoke to generate Yoke Flight WASM blobs out of a list of kustomize files in a super-optimized way.
  • The WIT could maybe also introduce a small handshake where the Yoke Flight requests some dependencies that the yoke CLI could manage. Such as "gimme bitnami/mongodb chart that fulfills version >=v1.0.0 & <v2.0.0". So that the yoke flights don't need to embed their dependencies.

Drawbacks:

Personally I'd like to try use https://www.moonbitlang.com/ to develop Yoke Flights for their famously small WASM blobs. Would be cool :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions