Configure
Components can be passed a map of configuration at runtime to use when executing. This configuration should first be defined using wash or as a part of your wadm manifest, and then fetched using the wasi:config/runtime
interface.
Define Configuration
- wadm
- wash
If you're using wadm to declaratively define applications, you can use the config
field to define configuration for your component. Wadm will automatically manage creating the configuration for you and supplying it to the component at runtime.
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: hello-world
annotations:
version: v0.0.1
description: 'Component that uses wasi:http and wasi:config/runtime'
spec:
components:
- name: http-component
type: component
properties:
image: file://./build/http_hello_world_s.wasm
config:
- name: custom-config
properties:
foo: bar
log-level: debug
traits:
# Govern the spread/scheduling of the component
- type: spreadscaler
properties:
instances: 1
If you're using wash to imperatively start your component, you can first define configuration using the wash config
subcommand, and then supply it alongside your component.
# wash config put <config-name> <values...>
wash config put custom-config foo=bar log-level=debug
Then, when starting your component with wash
, you can supply the configuration using the --config
flag:
# wash start component <component_ref> <component_id> --config <config-name>
wash start component ghcr.io/wasmcloud/components/http-hello-world-rust:0.1.0 hello --config custom-config
Using Configuration
Components access configuration at runtime by using the wasi-runtime-config interface. To use this interface, you'll need to import the wasi:config/runtime
interface inside of your wit/world.wit
file. This may be named differently depending on your component, but the interface should be imported in the same way.
package wasmcloud:hello;
world hello {
import wasi:config/runtime@0.2.0-draft;
}
Now, you can fetch the configuration inside of your component using the runtime configuration interface.
- Rust
- TinyGo
- TypeScript
- Python
- My Language Isn't Listed
let log_level = wasi::config::runtime::get("log-level")
.expect("Unable to fetch value")
.unwrap_or_else(|| "config value not set".to_string());
assert_eq!(log_level, "debug");
import (
"fmt"
gen "github.com/wasmcloud/wasmcloud/examples/golang/components/http-hello-world/gen"
)
// ...elided
logLevel := gen.WasiConfig0_2_0_draft_RuntimeGet("log-level").Unwrap().Unwrap()
// Prints "debug"
fmt.Println("%s", logLevel);
//@ts-expect-error -- these types aren't currently generated by JCO
import { Get } from 'wasi:config/runtime@0.2.0-draft';
// ...
const logLevel = Get('log-level');
// Prints "Log level is: debug"
console.log(`Log level is: ${logLevel}`);
# Replace `hello` with the name of your WIT world
from hello.imports.runtime import (get)
# ...
logLevel = get("log-level")
# Prints "Log level: debug"
print("Log level: {logLevel}")
If your language supports bindings generation (either via wit-bindgen or other tool) you can use the wasi:config/runtime
interface to get configuration. Follow the bindings generation documentation in order to call the wasi:config/runtime.get
function, and supply the name of the configuration property to fetch, e.g. log-level
to retrieve debug
in the above example.
Supplying multiple configurations
In both the above wadm
and wash
methods of defining configuration, you can actually supply multiple named configurations to components, providers, and links. This is useful both to reuse common pieces of configuration and provide overrides for specific instances.
Let's a case where we have a set of reasonable defaults for connections to a database that we want multiple components to use, but we also want to be able to override the connection string for specific instances. This can be accomplished by defining the default configuration and then overriding it for specific instances.
We'll use the wasmCloud HTTP Server settings as an example. We'll link the HTTP server to a component, supplying a default configuration with reasonable values and an additional configuration to change the address for that specific component. To create the default configuration, we can use the wash config put
command:
wash config put default-http max_content_len=5M readonly_mode=true address=0.0.0.0:80
By default, we'll limit the max content length to 5MB and ensure that components are only accepting GET and HEAD requests using the readonly_mode
configuration. We'll also supply a default listen address of 0.0.0.0:80
.
For our component, we can use the default configuration by supplying the default-http
configuration name, and then override the address
configuration for this specific instance:
- wadm
- wash
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: hello-world
annotations:
version: v0.0.1
description: 'Component that uses wasi:http'
spec:
components:
- name: http-component
type: component
properties:
image: file://./build/http_hello_world_s.wasm
traits:
# Govern the spread/scheduling of the component
- type: spreadscaler
properties:
instances: 1
# Add a capability provider that enables HTTP access
- name: httpserver
type: capability
properties:
image: ghcr.io/wasmcloud/http-server:0.22.0
traits:
- type: link
properties:
target: http-component
namespace: wasi
package: http
interfaces: [incoming-handler]
source_config:
- name: default-http
- name: custom-config
properties:
address: 0.0.0.0:4000
wash config put custom-config address=0.0.0.0:4000
Then, when linking the HTTP server with your component with wash
, you can supply the configuration using the --source-config
flag:
# wash link put <source_id> <target> <namespace> <package> ...
wash link put http-server http-component wasi http --interface incoming-handler --source-config default-http --source-config custom-config
Configuration is merged together in a left-folding manner, meaning that the last configuration supplied will override any previous configurations. In the above example, the address
configuration will be overridden to 0.0.0.0:4000
, but the max_content_len
and readonly_mode
configurations will remain the same as the default configuration. Put another way, the configuration this provider will receive with the link is:
{
"max_content_len": "5M",
"readonly_mode": true,
"address": "0.0.0:4000"
}