Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update plugin section - user guide #146

Merged
merged 4 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/embed/use-case/plugin/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Plugin-User Guide",
"position": 7,
"link": {
"type": "generated-index",
"description": "We will learn how to use WasmEdge Plugin System."
}
}
147 changes: 147 additions & 0 deletions docs/embed/use-case/plugin/c_sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
sidebar_position: 1
---

## Using Plug-ins to Extend the Runtime in C

The WasmEdge plug-ins are the shared libraries to provide the WasmEdge runtime to load and create host module instances. With the plug-ins, the WasmEdge runtime can be extended more easily.

## Loading Plug-ins from Paths

Developers can start using WasmEdge plug-ins by loading them from specific paths. To load plug-ins from the default paths, the following API can be used:

```c
WasmEdge_PluginLoadWithDefaultPaths();
```

Once this API is called, plug-ins from the default paths will be loaded. The default paths include:

- The path specified in the `WASMEDGE_PLUGIN_PATH` environment variable.
- The `../plugin/` directory relative to the WasmEdge installation path.
- The `./wasmedge/` directory under the library path if WasmEdge is installed in a system directory (e.g., `/usr` and `/usr/local`).

Developers can also load plug-ins from specific paths using this API:

```c
WasmEdge_PluginLoadFromPath("PATH_TO_PLUGIN/plugin.so");
```

## Listing Loaded Plug-ins

Once plug-ins are loaded, developers can list the loaded plug-in names using the following approach:

```c
WasmEdge_PluginLoadWithDefaultPaths();
printf("Number of loaded plug-ins: %d\n", WasmEdge_PluginListPluginsLength());

WasmEdge_String Names[20];
uint32_t NumPlugins = WasmEdge_PluginListPlugins(Names, 20);
for (int I = 0; I < NumPlugins; I++) {
printf("Plug-in %d name: %s\n", I, Names[I].Buf);
}
```

## Getting Plug-in Context by Name

Developers can obtain the plug-in context by its name using the following method:

```c
/* Assume that wasi_crypto plug-in is installed in the default plug-in path. */
WasmEdge_PluginLoadWithDefaultPaths();

const char PluginName[] = "wasi_crypto";
WasmEdge_String NameString =
WasmEdge_StringWrap(PluginName, strlen(PluginName));
const WasmEdge_PluginContext *PluginCxt = WasmEdge_PluginFind(NameString);
```

## Creating Module Instances from Plug-ins

With the plug-in context, developers can create module instances by providing the module name:

```c
/* Assume that the `PluginCxt` is the context to the wasi_crypto plug-in. */

/* List the available host modules in the plug-in. */
WasmEdge_String Names[20];
uint32_t ModuleLen = WasmEdge_PluginListModule(PluginCxt, Names, 20);
for (uint32_t I = 0; I < ModuleLen; I++) {
/* Will print the available host module names in the plug-in. */
printf("%s\n", Names[I].Buf);
}
/*
* Will print here for the WASI-Crypto plug-in here:
* wasi_ephemeral_crypto_asymmetric_common
* wasi_ephemeral_crypto_common
* wasi_ephemeral_crypto_kx
* wasi_ephemeral_crypto_signatures
* wasi_ephemeral_crypto_symmetric
*/

/* Create a module instance from the plug-in by the module name. */
const char ModuleName[] = "wasi_ephemeral_crypto_common";
WasmEdge_String NameString =
WasmEdge_StringWrap(ModuleName, strlen(ModuleName));
WasmEdge_ModuleInstance *ModCxt =
WasmEdge_PluginCreateModule(PluginCxt, NameString);

WasmEdge_ModuleInstanceDelete(ModCxt);
```

There may be several plug-ins in the default plug-in paths if users [installed WasmEdge plug-ins by the installer](/contribute/installer.md#plugins).

Before using the plug-ins, developers should [Loading Plug-ins from Paths](#loading-plug-ins-from-paths).

## Automatic Module Creation and Mocking

Upon creating a `VM` context, the WasmEdge runtime will automatically create and register the modules of loaded plug-ins. In cases where specific plug-ins are not loaded, WasmEdge will provide mock implementations for certain host modules. These mocked modules include:

- `wasi_ephemeral_crypto_asymmetric_common` (for the `WASI-Crypto`)
- `wasi_ephemeral_crypto_common` (for the `WASI-Crypto`)
- `wasi_ephemeral_crypto_kx` (for the `WASI-Crypto`)
- `wasi_ephemeral_crypto_signatures` (for the `WASI-Crypto`)
- `wasi_ephemeral_crypto_symmetric` (for the `WASI-Crypto`)
- `wasi_ephemeral_nn`
- `wasi_snapshot_preview1`
- `wasmedge_httpsreq`
- `wasmedge_process`

## Handling Missing Plug-ins and Error Messages

When the WASM want to invoke these host functions but the corresponding plug-in is not installed, WasmEdge will print the error message and return an error.

```c
/* Load the plug-ins in the default paths first. */
WasmEdge_PluginLoadWithDefaultPaths();
/* Create the configure context and add the WASI configuration. */
WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
WasmEdge_ConfigureAddHostRegistration(ConfCxt,
WasmEdge_HostRegistration_Wasi);
WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(ConfCxt, NULL);
WasmEdge_ConfigureDelete(ConfCxt);
/*
* The following API can retrieve the registered modules in the VM context,
mhmohona marked this conversation as resolved.
Show resolved Hide resolved
* includes the built-in WASI and the plug-ins.
*/
/*
* This API will return `NULL` if the module instance is not found.
*/
WasmEdge_String WasiName =
WasmEdge_StringCreateByCString("wasi_snapshot_preview1");
/* The `WasiModule` will not be `NULL` because the configuration was set. */
const WasmEdge_ModuleInstanceContext *WasiModule =
WasmEdge_VMGetRegisteredModule(VMCxt, WasiName);
WasmEdge_StringDelete(WasiName);
WasmEdge_String WasiNNName =
WasmEdge_StringCreateByCString("wasi_ephemeral_nn");
/*
* The `WasiNNModule` will not be `NULL` even if the wasi_nn plug-in is not
* installed, because the VM context will mock and register the host
* modules.
*/
const WasmEdge_ModuleInstanceContext *WasiNNModule =
WasmEdge_VMGetRegisteredModule(VMCxt, WasiNNName);
WasmEdge_StringDelete(WasiNNName);

WasmEdge_VMDelete(VMCxt);
```
118 changes: 118 additions & 0 deletions docs/embed/use-case/plugin/go_sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
sidebar_position: 3
---

## Using Plug-ins to Extend the Runtime in Go

The WasmEdge plug-ins are the shared libraries to provide the WasmEdge runtime to load and create host module instances. With the plug-ins, the WasmEdge runtime can be extended more easily.

## Loading Plug-ins from Paths

Developers can start using WasmEdge plug-ins by loading them from specific paths. To load plug-ins from the default paths, the following API can be used:

```go
wasmedge.LoadPluginDefaultPaths()
```

Once this API is called, plug-ins from the default paths will be loaded. The default paths include:

- The path specified in the `WASMEDGE_PLUGIN_PATH` environment variable.
- The `../plugin/` directory relative to the WasmEdge installation path.
- The `./wasmedge/` directory under the library path if WasmEdge is installed in a system directory (e.g., `/usr` and `/usr/local`).

Developers can also load plug-ins from specific paths using this API:

```go
wasmedge.LoadPluginFromPath("PATH_TO_PLUGIN/plugin.so")
```

## Listing Loaded Plug-ins

Once plug-ins are loaded, developers can list the loaded plug-in names using the following approach:

```go
wasmedge.LoadPluginDefaultPaths()
pluginnames := wasmedge.ListPlugins()
for _, name := range pluginnames {
fmt.Println("Loaded plug-in name: ", name)
}
```

## Getting Plug-in Context by Name

Developers can obtain the plug-in context by its name using the following method:

```go
// Assume that wasi_crypto plug-in is installed in the default plug-in path.
wasmedge.LoadPluginDefaultPaths()
plugincrypto := wasmedge.FindPlugin("wasi_crypto")
```

## Creating Module Instances from Plug-ins

With the plug-in context, developers can create module instances by providing the module name:

```go
// Assume that the `plugincrypto` is the object to the wasi_crypto plug-in.

// List the available host modules in the plug-in.
modules := plugincrypto.ListModule()
for _, name := range modules {
fmt.Println("Available module: ", name)
}
// Will print here for the WASI-Crypto plug-in here:
// wasi_ephemeral_crypto_asymmetric_common
// wasi_ephemeral_crypto_common
// wasi_ephemeral_crypto_kx
// wasi_ephemeral_crypto_signatures
// wasi_ephemeral_crypto_symmetric

// Create a module instance from the plug-in by the module name.
modinst := plugincrypto.CreateModule("wasi_ephemeral_crypto_common")

modinst.Release()
```

There may be several plug-ins in the default plug-in paths if users [installed WasmEdge plug-ins by the installer](/contribute/installer.md#plugins).

Before using the plug-ins, developers should [Loading Plug-ins from Paths](#loading-plug-ins-from-paths).

## Automatic Module Creation and Mocking

Upon creating a `VM` context, the WasmEdge runtime will automatically create and register the modules of loaded plug-ins. In cases where specific plug-ins are not loaded, WasmEdge will provide mock implementations for certain host modules. These mocked modules include:

- `wasi_ephemeral_crypto_asymmetric_common` (for the `WASI-Crypto`)
- `wasi_ephemeral_crypto_common` (for the `WASI-Crypto`)
- `wasi_ephemeral_crypto_kx` (for the `WASI-Crypto`)
- `wasi_ephemeral_crypto_signatures` (for the `WASI-Crypto`)
- `wasi_ephemeral_crypto_symmetric` (for the `WASI-Crypto`)
- `wasi_ephemeral_nn`
- `wasi_snapshot_preview1`
- `wasmedge_httpsreq`
- `wasmedge_process`
- `wasi:logging/logging` (for the `WASI-Logging`)

## Handling Missing Plug-ins and Error Messages

When the WASM want to invoke these host functions but the corresponding plug-in not installed, WasmEdge will print the error message and return an error.

```go
// Load the plug-ins in the default paths first.
wasmedge.LoadPluginDefaultPaths()

// Create the VM object with the WASI configuration.
conf := wasmedge.NewConfigure(wasmedge.WASI)
vm := wasmedge.NewVMWithConfig(conf)
conf.Release()

// The following API can retrieve the registered modules in the VM objects, includes the built-in WASI and the plug-ins.
// This API will return `NULL` if the module instance not found.

// The `wasimodule` will not be `nil` because the configuration was set.
wasimodule := vm.GetRegisteredModule("wasi_snapshot_preview1")

// The `wasinnmodule` will not be `nil` even if the wasi_nn plug-in is not installed, because the VM context will mock and register the host modules.
wasinnmodule := vm.GetRegisteredModule("wasi_ephemeral_nn")

vm.Release()
```
78 changes: 78 additions & 0 deletions docs/embed/use-case/plugin/rust_sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
sidebar_position: 2
---

## Using Plug-ins to Extend the Runtime in Rust

The WasmEdge plug-ins are the shared libraries to provide the WasmEdge runtime to load and create host module instances. With the plug-ins, the WasmEdge runtime can be extended more easily.

## Loading Plug-ins from Paths

Developers can start using WasmEdge plug-ins by loading them from specific paths. To load plug-ins from the default paths, the following API can be used:

```rust
impl PluginManager
pub fn load(path: Option<&Path>) -> WasmEdgeResult<()>
```

- The default plug-in paths will be used if the path is not given.

- The path specified in the `WASMEDGE_PLUGIN_PATH` environment variable.
- The `../plugin/` directory relative to the WasmEdge installation path.
- The `./wasmedge/` directory under the library path if WasmEdge is installed in the `/usr` directory.

- If the path is given, then

- If the path is pointing at a file, then it indicates that a single plug-in will be loaded from the file.
- If the path is pointing at a directory, then the method will load plug-ins from the files.

To get the names of all loaded plug-ins as returns -

```rust
pub fn names() -> Vec<String>
```

<!-- prettier-ignore -->
:::note
`path` - A path to a plug-in file or a directory holding plug-in files. If `None`, then the default plug-in path will be used.
:::

## Listing Loaded Plug-ins

Once plug-ins are loaded, developers can list the loaded plug-in names using the following approach:

```rust
pub fn names() -> Vec<String>
```

## Getting Plug-in Context by Name

Developers can get the plug-in context by its name using the following method:

```rust
pub fn find(name: impl AsRef<str>) -> Option<Plugin>
```

Here `name` is the name of the target plug-in.

## Getting Module Instances from Plug-ins

With the plug-in context, developers can get module instances by providing the module name:

```rust
pub fn mod_names(&self) -> Vec<String>
```

There may be several plug-ins in the default plug-in paths if users [installed WasmEdge plug-ins by the installer](/contribute/installer.md#plugins).

Before using the plug-ins, developers should [Loading Plug-ins from Paths](#loading-plug-ins-from-paths).

## Plug-in Module Instance

To initialize the `wasmedge_process` plug-in module instance with the parameters -

```rust
pub fn init_wasmedge_process(allowed_cmds: Option<Vec<&str>>, allowed: bool)
```

Here, `allowed_cmds` is A white list of commands and `allowed` determines if wasmedge_process is allowed to execute all commands on the white list.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Plugin-User Guide",
"position": 7,
"link": {
"type": "generated-index",
"description": "We will learn how to use WasmEdge Plugin System."
}
}
Loading