Skip to content

Commit

Permalink
Containerd: use correct platform for building
Browse files Browse the repository at this point in the history
Signed-off-by: James Sturtevant <[email protected]>
  • Loading branch information
jsturtevant committed Oct 24, 2023
1 parent 03a3214 commit 7976bfd
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 29 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,11 @@ dist/img-oci.tar: target/wasm32-wasi/$(OPT_PROFILE)/img-oci.tar
load: dist/img.tar
sudo ctr -n $(CONTAINERD_NAMESPACE) image import --all-platforms $<

CTR_VERSION := $(shell sudo ctr version | sed -n -e '/Version/ {s/.*: *//p;q;}')
load/oci: dist/img-oci.tar
sudo ../containerd/bin/ctr -n $(CONTAINERD_NAMESPACE) image import --all-platforms $<
@echo $(CTR_VERSION)\\nv1.7.7 | sort -crV || (echo "containerd version must be 1.7.7+ was $(CTR_VERSION)" && exit 1)
@echo using containerd $(CTR_VERSION)
sudo ctr -n $(CONTAINERD_NAMESPACE) image import --all-platforms $<

.PHONY:
target/wasm32-wasi/$(OPT_PROFILE)/img-oci.tar: target/wasm32-wasi/$(OPT_PROFILE)/wasi-demo-app.wasm
Expand Down
14 changes: 14 additions & 0 deletions crates/containerd-shim-wasm/src/container/context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::path::{Path, PathBuf};

use oci_spec::image::Platform;
use oci_spec::runtime::Spec;

use crate::sandbox::oci::WasmLayer;
Expand All @@ -24,6 +25,8 @@ pub trait RuntimeContext {
fn wasi_entrypoint(&self) -> WasiEntrypoint;

fn wasm_layers(&self) -> &[WasmLayer];

fn platform(&self) -> &Platform;
}

pub struct WasiEntrypoint {
Expand All @@ -34,6 +37,7 @@ pub struct WasiEntrypoint {
pub(crate) struct WasiContext<'a> {
pub spec: &'a Spec,
pub wasm_layers: &'a [WasmLayer],
pub platform: &'a Platform,
}

impl RuntimeContext for WasiContext<'_> {
Expand Down Expand Up @@ -62,6 +66,10 @@ impl RuntimeContext for WasiContext<'_> {
fn wasm_layers(&self) -> &[WasmLayer] {
self.wasm_layers
}

fn platform(&self) -> &Platform {
self.platform
}
}

#[cfg(test)]
Expand All @@ -86,6 +94,7 @@ mod tests {
let ctx = WasiContext {
spec: &spec,
wasm_layers: &[],
platform: &Platform::default(),
};

let args = ctx.args();
Expand All @@ -105,6 +114,7 @@ mod tests {
let ctx = WasiContext {
spec: &spec,
wasm_layers: &[],
platform: &Platform::default(),
};

let args = ctx.args();
Expand Down Expand Up @@ -132,6 +142,7 @@ mod tests {
let ctx = WasiContext {
spec: &spec,
wasm_layers: &[],
platform: &Platform::default(),
};

let args = ctx.args();
Expand All @@ -153,6 +164,7 @@ mod tests {
let ctx = WasiContext {
spec: &spec,
wasm_layers: &[],
platform: &Platform::default(),
};

let path = ctx.wasi_entrypoint().path;
Expand Down Expand Up @@ -180,6 +192,7 @@ mod tests {
let ctx = WasiContext {
spec: &spec,
wasm_layers: &[],
platform: &Platform::default(),
};

let WasiEntrypoint { path, func } = ctx.wasi_entrypoint();
Expand Down Expand Up @@ -208,6 +221,7 @@ mod tests {
let ctx = WasiContext {
spec: &spec,
wasm_layers: &[],
platform: &Platform::default(),
};

let WasiEntrypoint { path, func } = ctx.wasi_entrypoint();
Expand Down
56 changes: 37 additions & 19 deletions crates/containerd-shim-wasm/src/sandbox/containerd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use containerd_client::services::v1::{GetContainerRequest, GetImageRequest, Read
use containerd_client::tonic::transport::Channel;
use containerd_client::{tonic, with_namespace};
use futures::TryStreamExt;
use oci_spec::image::{Arch, ImageManifest};
use oci_spec::image::{Arch, ImageManifest, MediaType, Platform};
use tokio::runtime::Runtime;
use tonic::Request;

Expand Down Expand Up @@ -116,39 +116,57 @@ impl Client {
// load module will query the containerd store to find an image that has an OS of type 'wasm'
// If found it continues to parse the manifest and return the layers that contains the WASM modules
// and possibly other configuration layers.
pub fn load_modules(&self, containerd_id: impl ToString) -> Result<Vec<oci::WasmLayer>> {
pub fn load_modules(
&self,
containerd_id: impl ToString,
) -> Result<(Vec<oci::WasmLayer>, Platform)> {
let image_name = self.get_image(containerd_id.to_string())?;
let digest = self.get_image_content_sha(image_name)?;
let manifest = self.read_content(digest)?;
let manifest = manifest.as_slice();
let manifest = ImageManifest::from_reader(manifest)?;

let arch = manifest
.config()
.platform()
.as_ref()
.ok_or_else(|| ShimError::Containerd("failed to extract platform".to_string()))?
.architecture();
let image_config_descriptor = manifest.config();
let image_config = self.read_content(image_config_descriptor.digest())?;
let image_config = image_config.as_slice();

match arch {
Arch::Wasm => {
log::info!("found manifest with WASM OCI image format.");
}
_ => {
log::info!("manifest is not in WASM OCI image format");
return Ok([].to_vec());
}
}
// the only part we care about here is the platform values
let platform: Platform = serde_json::from_slice(image_config)?;
let Arch::Wasm = platform.architecture() else {
log::info!("manifest is not in WASM OCI image format");
return Ok((vec![], platform));
};
log::info!("found manifest with WASM OCI image format.");

manifest
let layers = manifest
.layers()
.iter()
.filter(|x| !is_image_layer_type(x.media_type()))
.map(|config| {
self.read_content(config.digest()).map(|module| WasmLayer {
config: config.clone(),
layer: module,
})
})
.collect::<Result<Vec<_>>>()
.collect::<Result<Vec<_>>>()?;
Ok((layers, platform))
}
}

fn is_image_layer_type(media_type: &MediaType) -> bool {
match media_type {
MediaType::ImageLayer
| MediaType::ImageLayerGzip
| MediaType::ImageLayerNonDistributable
| MediaType::ImageLayerNonDistributableGzip
| MediaType::ImageLayerNonDistributableZstd
| MediaType::ImageLayerZstd => true,
MediaType::Other(s)
if s.as_str()
.starts_with("application/vnd.docker.image.rootfs.") =>
{
true
}
_ => false,
}
}
2 changes: 1 addition & 1 deletion crates/containerd-shim-wasm/src/sandbox/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub enum Error {
#[error("{0}")]
Libcontainer(#[from] libcontainer::error::LibcontainerError),
#[error("{0}")]
Containerd(String)
Containerd(String),
}

pub type Result<T> = ::std::result::Result<T, Error>;
Expand Down
12 changes: 10 additions & 2 deletions crates/containerd-shim-wasm/src/sys/unix/container/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use libcontainer::workload::{
Executor as LibcontainerExecutor, ExecutorError as LibcontainerExecutorError,
ExecutorValidationError,
};
use oci_spec::image::Platform;
use oci_spec::runtime::Spec;

use crate::container::{Engine, PathResolve, RuntimeContext, Stdio, WasiContext};
Expand All @@ -28,6 +29,7 @@ pub(crate) struct Executor<E: Engine> {
stdio: Stdio,
inner: OnceCell<InnerExecutor>,
wasm_layers: Vec<WasmLayer>,
platform: Platform,
}

impl<E: Engine> LibcontainerExecutor for Executor<E> {
Expand Down Expand Up @@ -64,18 +66,24 @@ impl<E: Engine> LibcontainerExecutor for Executor<E> {
}

impl<E: Engine> Executor<E> {
pub fn new(engine: E, stdio: Stdio, wasm_layers: Vec<WasmLayer>) -> Self {
pub fn new(engine: E, stdio: Stdio, wasm_layers: Vec<WasmLayer>, platform: Platform) -> Self {
Self {
engine,
stdio,
inner: Default::default(),
wasm_layers,
platform,
}
}

fn ctx<'a>(&'a self, spec: &'a Spec) -> WasiContext<'a> {
let wasm_layers = &self.wasm_layers;
WasiContext { spec, wasm_layers }
let platform = &self.platform;
WasiContext {
spec,
wasm_layers,
platform,
}
}

fn inner(&self, spec: &Spec) -> &InnerExecutor {
Expand Down
11 changes: 7 additions & 4 deletions crates/containerd-shim-wasm/src/sys/unix/container/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ use libcontainer::syscall::syscall::SyscallType;
use nix::errno::Errno;
use nix::sys::wait::{waitid, Id as WaitID, WaitPidFlag, WaitStatus};
use nix::unistd::Pid;
use oci_spec::image::Platform;

use crate::container::Engine;
use crate::sandbox::instance_utils::{determine_rootdir, get_instance_root, instance_exists};
use crate::sandbox::sync::WaitableCell;
use crate::sandbox::{containerd, Error as SandboxError, Instance as SandboxInstance, InstanceConfig, Stdio};
use crate::sandbox::{
containerd, Error as SandboxError, Instance as SandboxInstance, InstanceConfig, Stdio,
};
use crate::sys::container::executor::Executor;

static DEFAULT_CONTAINER_ROOT_DIR: &str = "/run/containerd";
Expand All @@ -41,15 +44,15 @@ impl<E: Engine> SandboxInstance for Instance<E> {
let stdio = Stdio::init_from_cfg(cfg)?;

// check if container is OCI image with wasm layers and attempt to read the module
let modules = containerd::Client::connect(cfg.get_containerd_address(), &namespace)?
let (modules, platform) = containerd::Client::connect(cfg.get_containerd_address(), &namespace)?
.load_modules(&id)
.unwrap_or_else(|e| {
log::warn!("Error obtaining wasm layers for container {id}. Will attempt to use files inside container image. Error: {e}");
vec![]
(vec![], Platform::default())
});

ContainerBuilder::new(id.clone(), SyscallType::Linux)
.with_executor(Executor::new(engine, stdio, modules))
.with_executor(Executor::new(engine, stdio, modules, platform))
.with_root_path(rootdir.clone())?
.as_init(&bundle)
.with_systemd(false)
Expand Down
4 changes: 2 additions & 2 deletions test/k8s/Dockerfile.oci
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

ARG KIND_NODE_VERSION=v1.27.3@sha256:3966ac761ae0136263ffdb6cfd4db23ef8a83cba8a463690e98317add2c9ba72
ARG RUNTIME=wasmtime
ARG GO_VERSION="1.21.1"
ARG GO_VERSION="1.21.3-bullseye"

# modified from https://github.com/kubernetes-sigs/kind/blob/main/images/base/Dockerfile
# stage for building containerd
FROM golang:${GO_VERSION} as build-containerd
ARG CONTAINERD_VERSION="main"
ARG CONTAINERD_VERSION="v1.7.7"
ARG CONTAINERD_CLONE_URL="https://github.com/containerd/containerd"
# we don't build with optional snapshotters, we never select any of these
# they're not ideal inside kind anyhow, and we save some disk space
Expand Down

0 comments on commit 7976bfd

Please sign in to comment.