Skip to content

Commit

Permalink
Update plugin section - user guide (#146)
Browse files Browse the repository at this point in the history
* add plugin user-guide

Signed-off-by: Mahfuza <[email protected]>

* added guide for Rust

Signed-off-by: Mahfuza <[email protected]>

* small fix

Signed-off-by: Mahfuza <[email protected]>

* small fix

Signed-off-by: Mahfuza <[email protected]>

---------

Signed-off-by: Mahfuza <[email protected]>
  • Loading branch information
mhmohona authored Nov 20, 2023
1 parent 80f56b8 commit a34fc38
Show file tree
Hide file tree
Showing 8 changed files with 696 additions and 0 deletions.
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."
}
}
144 changes: 144 additions & 0 deletions docs/embed/use-case/plugin/c_sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
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,
* 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

0 comments on commit a34fc38

Please sign in to comment.