Skip to content

Question on usage of preopens in WASM component #194

@shihanng

Description

@shihanng

I have a Go code that writes to a temporary directory like the following. I want to compile the code into a WebAssembly component and call it from a Python code.

package main

import (
	"os"

	gen "github.com/shihanng/play-wasm/wit/gen"
)

func init() {
	a := HostImpl{}
	gen.SetConvert(a)
}

type HostImpl struct{}

func (e HostImpl) Exec(input []uint8) []uint8 {
	res := []byte(input)
	res = append(res, "hello from exec"...)

	gen.ConvertPrint(string(res))

	tmpFile, err := os.CreateTemp("", "test_")
	if err != nil {
		// Print for debug
		return []byte(err.Error() + ": create temp")
	}

	defer tmpFile.Close()
	defer os.Remove(tmpFile.Name())

	if _, err := tmpFile.Write(res); err != nil {
		// Print for debug
		return []byte(err.Error() + ": write")
	}

	return []byte(res)
}

//go:generate wit-bindgen tiny-go . --out-dir=gen
func main() {}

I can compile the code and use python -m wasmtime.bindgen to generate the Python code. The following is my entry point to call the WebAssembly code:

import json

import wasmtime.bindgen
from pyconvert import Root, RootImports, imports
from wasmtime import Store


class Host(imports.Host):
    def print(self, s: str):
        print(s + "test")


class HostEnvironment:
    def get_environment(self):
        return [("TMPDIR", "/tmp2/")]


class HostPreopens:
    def get_directories(self):
        return []


def main():
    store = Store()
    demo = Root(
        store,
        RootImports(
            Host(),
            None,
            None,
            None,
            None,
            HostPreopens(),
            HostEnvironment(),
            None,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
        ),
    )
    data = {"key": "value"}
    json_str = json.dumps(data)
    json_bytes = json_str.encode("utf-8")
    res = demo.exec(store, json_bytes)
    print(res.decode("utf-8"))


if __name__ == "__main__":
    main()

When trying to execute the main.py, I get an error indicating that I don't have access to the temporary directory. I am guessing that I need to implement the HostPreopens; however, I could not find documentation showing how to do so.

python main.py
{"key": "value"}hello from exectest
open /tmp2/test_0: errno 76: create temp

Is Preopens the right approach to solve the issue above? Where can I find documentation or example code regarding providing WASM component access to the file system?

Note: I put all the codes above, including the WIT-file, in this repo https://github.com/shihanng/play-wasm/tree/fs/wit for reproducibility.

Thank you.

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