From 9f043e4bbecea199128111e2e4ac1cd48741f23f Mon Sep 17 00:00:00 2001 From: jay <38236622+JayJamieson@users.noreply.github.com> Date: Mon, 15 Jan 2024 22:39:36 +1300 Subject: [PATCH 1/2] added filesystem access example --- README.md | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/README.md b/README.md index 379caa4..cda57fd 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,105 @@ config := PluginConfig{ _, err := NewPlugin(ctx, manifest, config, []HostFunction{}) ``` +### Enable filesystem access + +WASM plugins can read/write files outside the runtime. To do this we add allowed path mapping of "HOST:PLUGIN" to the `extism.Manifest` of our plugin. + +```go +package main + +import ( + "context" + "fmt" + "os" + + extism "github.com/extism/go-sdk" +) + +func main() { + manifest := extism.Manifest{ + AllowedPaths: map[string]string{ + + // Here we specifify a host directory data to be linked + // to the /mnt directory inside the wasm runtime + "data": "/mnt", + }, + Wasm: []extism.Wasm{ + extism.WasmFile{ + Path: "plugin.wasm", + }, + }, + } + + ctx := context.Background() + config := extism.PluginConfig{ + EnableWasi: true, + } + plugin, err := extism.NewPlugin(ctx, manifest, config, []extism.HostFunction{}) + + if err != nil { + fmt.Printf("Failed to initialize plugin: %v\n", err) + os.Exit(1) + } + + data := []byte("Hello world, this is written from within our wasm plugin.") + exit, _, err := plugin.Call("write_file", data) + if err != nil { + fmt.Println(err) + os.Exit(int(exit)) + } +} +``` + +Next we need to setup the runtime to make filesystem APIs available, we do this by calling `__wasm_call_ctors()` exported method in a WASM `_initialize` hook. + +```go +package main + +import ( + "os" + + "github.com/extism/go-pdk" +) + +//export __wasm_call_ctors +func __wasm_call_ctors() + +//export _initialize +func _initialize() { + __wasm_call_ctors() +} + +//export write_file +func writeFile() int32 { + input := pdk.Input() + + err := pluginMain("/mnt/wasm.txt", input) + + if err != nil { + pdk.Log(pdk.LogTrace, err.Error()) + return 1 + } + + return 0 +} + +func pluginMain(filename string, data []byte) error { + pdk.Log(pdk.LogInfo, "Writing following data to disk: "+string(data)) + + // Write to the file, will be created if it doesn't exist + err := os.WriteFile(filename, data, 0644) + if err != nil { + return err + } + + return nil +} + +func main() {} + +``` + ## Build example plugins Since our [example plugins](./plugins/) are also written in Go, for compiling them we use [TinyGo](https://tinygo.org/): From 67af788a90d556e9af13b9c9ab7fe6409b656b2b Mon Sep 17 00:00:00 2001 From: jay <38236622+JayJamieson@users.noreply.github.com> Date: Tue, 16 Jan 2024 23:58:39 +1300 Subject: [PATCH 2/2] removed pdk code and added reference to pdk repository --- README.md | 54 +++--------------------------------------------------- 1 file changed, 3 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index cda57fd..e811b30 100644 --- a/README.md +++ b/README.md @@ -267,7 +267,7 @@ _, err := NewPlugin(ctx, manifest, config, []HostFunction{}) ### Enable filesystem access -WASM plugins can read/write files outside the runtime. To do this we add allowed path mapping of "HOST:PLUGIN" to the `extism.Manifest` of our plugin. +WASM plugins can read/write files outside the runtime. To do this we add `AllowedPaths` mapping of "HOST:PLUGIN" to the `extism.Manifest` of our plugin. ```go package main @@ -283,14 +283,13 @@ import ( func main() { manifest := extism.Manifest{ AllowedPaths: map[string]string{ - // Here we specifify a host directory data to be linked // to the /mnt directory inside the wasm runtime "data": "/mnt", }, Wasm: []extism.Wasm{ extism.WasmFile{ - Path: "plugin.wasm", + Path: "fs_plugin.wasm", }, }, } @@ -315,54 +314,7 @@ func main() { } ``` -Next we need to setup the runtime to make filesystem APIs available, we do this by calling `__wasm_call_ctors()` exported method in a WASM `_initialize` hook. - -```go -package main - -import ( - "os" - - "github.com/extism/go-pdk" -) - -//export __wasm_call_ctors -func __wasm_call_ctors() - -//export _initialize -func _initialize() { - __wasm_call_ctors() -} - -//export write_file -func writeFile() int32 { - input := pdk.Input() - - err := pluginMain("/mnt/wasm.txt", input) - - if err != nil { - pdk.Log(pdk.LogTrace, err.Error()) - return 1 - } - - return 0 -} - -func pluginMain(filename string, data []byte) error { - pdk.Log(pdk.LogInfo, "Writing following data to disk: "+string(data)) - - // Write to the file, will be created if it doesn't exist - err := os.WriteFile(filename, data, 0644) - if err != nil { - return err - } - - return nil -} - -func main() {} - -``` +> *Note*: In order for filesystem APIs to work the plugin needs to be compiled with WASI target. Source code for the plugin can be found [here](https://github.com/extism/go-pdk/blob/main/example/fs/main.go) and is written in Go, but it could be written in any of our PDK languages. ## Build example plugins