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

Pre-compile each layer individually #492

Merged
merged 13 commits into from
Mar 6, 2024
35 changes: 19 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ test/k8s/deploy-workload-oci-%: test/k8s/clean test/k8s/cluster-% dist/img-oci.t
kubectl --context=kind-$(KIND_CLUSTER_NAME) wait deployment wasi-demo --for condition=Available=True --timeout=5s
@if [ "$*" = "wasmtime" ]; then \
set -e; \
echo "checking for pre-compiled label and ensuring can scale"; \
docker exec $(KIND_CLUSTER_NAME)-control-plane ctr -n k8s.io i ls | grep "runwasi.io/precompiled"; \
echo "checking for pre-compiled labels and ensuring can scale after pre-compile"; \
docker exec $(KIND_CLUSTER_NAME)-control-plane ctr -n k8s.io content ls | grep "runwasi.io/precompiled"; \
kubectl --context=kind-$(KIND_CLUSTER_NAME) scale deployment wasi-demo --replicas=4; \
kubectl --context=kind-$(KIND_CLUSTER_NAME) wait deployment wasi-demo --for condition=Available=True --timeout=5s; \
fi
Expand Down Expand Up @@ -297,8 +297,8 @@ test/k3s-oci-%: dist/img-oci.tar bin/k3s dist-%
sudo bin/k3s kubectl get pods -o wide
@if [ "$*" = "wasmtime" ]; then \
set -e; \
echo "checking for pre-compiled label and ensuring can scale"; \
sudo bin/k3s ctr -n k8s.io i ls | grep "runwasi.io/precompiled"; \
echo "checking for pre-compiled labels and ensuring can scale"; \
sudo bin/k3s ctr -n k8s.io content ls | grep "runwasi.io/precompiled"; \
sudo bin/k3s kubectl scale deployment wasi-demo --replicas=4; \
sudo bin/k3s kubectl wait deployment wasi-demo --for condition=Available=True --timeout=5s; \
fi
Expand Down
3 changes: 2 additions & 1 deletion crates/containerd-shim-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ futures = { version = "0.3.30" }
wasmparser = "0.200.0"
tokio-stream = { version = "0.1" }
prost-types = "0.11" # should match version in containerd-shim
sha256 = "1.4.0"
sha256 = { workspace = true }

[target.'cfg(unix)'.dependencies]
caps = "0.5"
Expand All @@ -56,6 +56,7 @@ containerd-shim-wasm-test-modules = { workspace = true }
env_logger = { workspace = true }
tempfile = { workspace = true }
oci-tar-builder = { workspace = true}
rand= "0.8"

[features]
testing = ["dep:containerd-shim-wasm-test-modules", "dep:env_logger", "dep:tempfile", "dep:oci-tar-builder"]
13 changes: 8 additions & 5 deletions crates/containerd-shim-wasm/src/container/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use anyhow::{bail, Context, Result};

use super::Source;
use crate::container::{PathResolve, RuntimeContext};
use crate::sandbox::oci::WasmLayer;
use crate::sandbox::Stdio;

pub trait Engine: Clone + Send + Sync + 'static {
Expand Down Expand Up @@ -53,12 +54,14 @@ pub trait Engine: Clone + Send + Sync + 'static {
&["application/vnd.bytecodealliance.wasm.component.layer.v0+wasm"]
}

/// Precompiles a module that is in the WASM OCI layer format
/// This is used to precompile a module before it is run and will be called if can_precompile returns true.
/// Precompile passes supported OCI layers to engine for compilation
/// This is used to precompile the layers before they are run and will be called if `can_precompile` returns `true`.
/// It is called only the first time a module is run and the resulting bytes will be cached in the containerd content store.
/// The cached, precompiled module will be reloaded on subsequent runs.
fn precompile(&self, _layers: &[Vec<u8>]) -> Result<Vec<u8>> {
bail!("precompilation not supported for this runtime")
/// The cached, precompiled layers will be reloaded on subsequent runs.
/// The runtime is expected to return the same number of layers passed in, if the layer cannot be precompiled it should return `None` for that layer.
/// In some edge cases it is possible that the layers may already be precompiled and None should be returned in this case.
fn precompile(&self, _layers: &[WasmLayer]) -> Result<Vec<Option<Vec<u8>>>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: type alias for Vec<Option<Vec<u8>>>>, perhaps PrecompiledWasmLayers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One nit to counter the nit with: not everything returned is a precompiled layer, which is why there is an option wrapping, so it feels like a confusing name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe Vec<Option<WasmLayer>>?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WasmLayer is already a structure. The API was that at one point but was changed to just return the layer content rather than the content and config because the original config is used as the source of truth. I think we should maybe leave it as is or PrecompiledLayer could work, though i prefer not using types to alias something as small as Vec<u8>

bail!("precompile not supported");
}

/// Can_precompile lets the shim know if the runtime supports precompilation.
Expand Down
Loading
Loading