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

feat(spin): conditionally load runtime config from root #179

Merged
merged 1 commit into from
Nov 11, 2023

Conversation

kate-goldenring
Copy link
Contributor

Adds support for Runtime Config in the shim by expecting it to be loaded into the root of a container. This is fairly prescriptive. We may want to support detecting/finding the runtime config in Spin runtime instead of passing it as a flag to the Spin CLI. If we come up with a Spin solution to this, we may need to update the shim to be aligned with whatever approach we choose in Spin. But this unlocks a lot of use cases with the Spin shim now.

Test it out

To test it app, you can use a runtime config to use a non-default KV store. A build example can be pulled from here (http://ghcr.io/kate-goldenring/keyvalue:latest). It is a Spin 1.x app but should still run on the 2.0 shim. I included a section with the app contents below.
The Dockerfile for the app looks like:

FROM scratch
COPY ./spin.toml ./spin.toml
COPY ./target/wasm32-wasi/release/keyvalue.wasm ./target/wasm32-wasi/release/keyvalue.wasm
COPY ./runtime-config.toml ./runtime-config.toml

And the runtime config (runtime-config.toml) defines a new store named foo. The app allows this store in the Spin.toml (key_value_stores = ["foo"]).

# This defines a new store named user_data
[key_value_store.foo]
type = "spin" 
path = "user_data.db"

Download the shim from the action of this PR (or can use a 1.0 shim with k3d:v0.9.2 with these changes here https://github.com/kate-goldenring/containerd-wasm-shims/suites/17958017983/artifacts/1032496968).

k3d cluster create wasm-cluster --image ghcr.io/deislabs/containerd-wasm-shims/examples/k3d:v0.9.3 -p "8081:80@loadbalancer" --agents 1
# Apply the wasmtime-spin runtime class
cat <<EOF | kubectl create -f -
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: "wasmtime-spin"
handler: "spin"
EOF
# Get the container ID for both the server and agent containers
docker container ls | grep deis | awk '{print $1}'
# Copy the shim into the agent and server containers
docker cp ~/Downloads/containerd-shim-spin $CONTAINER_ID_SRV:/bin/containerd-shim-spin
docker cp ~/Downloads/containerd-shim-spin $CONTAINER_ID_AGENT:/bin/containerd-shim-spin
# get the Spin app
docker pull ghcr.io/kate-goldenring/keyvalue:latest

Create a deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: keyvalue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: keyvalue
  template:
    metadata:
      labels:
        app: keyvalue
    spec:
      runtimeClassName: wasmtime-spin
      containers:
        - name: keyvalue
          image: ghcr.io/kate-goldenring/keyvalue:latest
          command: ["/"]
          imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  name: keyvalue
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: keyvalue
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: keyvalue
  annotations:
    ingress.kubernetes.io/ssl-redirect: "false"
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - http:
        paths:
          - path: /keyvalue
            pathType: Prefix
            backend:
              service:
                name: keyvalue
                port:
                  number: 80

Apply toml and ping the app:

$ curl -v http://0.0.0.0:8081/keyvalue
wow

Contents of the Spin App

Example Spin manifest (notice key_value_stores = ["foo"]). This is a 1.0 manifest. Feel free to update to use 2.0

spin_manifest_version = "1"
authors = ["Kate Goldenring <kate.goldenring@fermyon.com>"]
description = "hello"
name = "keyvalue"
trigger = { type = "http", base = "/" }
version = "0.1.0"

[[component]]
id = "keyvalue"
source = "target/wasm32-wasi/release/keyvalue.wasm"
allowed_http_hosts = []
key_value_stores = ["foo"]
[component.trigger]
route = "/..."
[component.build]
command = "cargo build --target wasm32-wasi --release"
watch = ["src/**/*.rs", "Cargo.toml"]

Example implementation which gets and sets a value to the non default store:

use anyhow::Result;
use spin_sdk::{
    http::{Request, Response},
    http_component,
    key_value::Store,
};

/// A simple Spin HTTP component.
#[http_component]
fn handle_kv(_req: Request) -> Result<Response> {
    let store = Store::open("foo")?;
    store.set("mykey", "wow")?;
    let value = store.get("mykey").unwrap_or_else(|_| "not found".into());
    Ok(http::Response::builder()
    .status(200)
    .header("foo", "bar")
    .body(Some(value.into()))?)
}

Signed-off-by: Kate Goldenring <kate.goldenring@fermyon.com>
@jsturtevant
Copy link
Contributor

This is fairly prescriptive. We may want to support detecting/finding the runtime config in Spin runtime instead of passing it as a flag to the Spin CLI.

The same goes for the Spin.toml file as it is now, so this approach makes sense to me

LGTM

@Mossaka
Copy link
Member

Mossaka commented Nov 11, 2023

This is great, thanks!

@Mossaka Mossaka merged commit d90737b into deislabs:main Nov 11, 2023
20 checks passed
Mossaka added a commit to Mossaka/shims that referenced this pull request Nov 13, 2023
This commit adds an integration test for spin-keyvalue using dynamic config file that was introduced by deislabs#179 and an integraion test for outbound redis introduced by deislabs#117

Signed-off-by: jiaxiao zhou <jiazho@microsoft.com>
Mossaka added a commit to Mossaka/shims that referenced this pull request Nov 14, 2023
This commit adds an integration test for spin-keyvalue using dynamic config file that was introduced by deislabs#179 and an integraion test for outbound redis introduced by deislabs#117

Signed-off-by: jiaxiao zhou <jiazho@microsoft.com>
Mossaka added a commit that referenced this pull request Nov 15, 2023
* test(spin): add more integration tests

This commit adds an integration test for spin-keyvalue using dynamic config file that was introduced by #179 and an integraion test for outbound redis introduced by #117

Signed-off-by: jiaxiao zhou <jiazho@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants