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 :)

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions