runtime-rs: enable start container from bundle

enable start container from bundle in this way

$ ls ./bundle
config.json  rootfs
$ sudo ctr run -d --runtime io.containerd.kata.v2 --config bundle/config.json test_kata

Fixes:#5872
Signed-off-by: Zhongtao Hu <zhongtaohu.tim@linux.alibaba.com>
This commit is contained in:
Zhongtao Hu 2022-12-11 00:11:13 +08:00
parent 67e82804c5
commit ca39a07a14
5 changed files with 57 additions and 19 deletions

View File

@ -68,11 +68,14 @@ impl ResourceManager {
pub async fn handler_rootfs( pub async fn handler_rootfs(
&self, &self,
cid: &str, cid: &str,
root: &oci::Root,
bundle_path: &str, bundle_path: &str,
rootfs_mounts: &[Mount], rootfs_mounts: &[Mount],
) -> Result<Arc<dyn Rootfs>> { ) -> Result<Arc<dyn Rootfs>> {
let inner = self.inner.read().await; let inner = self.inner.read().await;
inner.handler_rootfs(cid, bundle_path, rootfs_mounts).await inner
.handler_rootfs(cid, root, bundle_path, rootfs_mounts)
.await
} }
pub async fn handler_volumes( pub async fn handler_volumes(

View File

@ -196,6 +196,7 @@ impl ResourceManagerInner {
pub async fn handler_rootfs( pub async fn handler_rootfs(
&self, &self,
cid: &str, cid: &str,
root: &oci::Root,
bundle_path: &str, bundle_path: &str,
rootfs_mounts: &[Mount], rootfs_mounts: &[Mount],
) -> Result<Arc<dyn Rootfs>> { ) -> Result<Arc<dyn Rootfs>> {
@ -205,6 +206,7 @@ impl ResourceManagerInner {
self.hypervisor.as_ref(), self.hypervisor.as_ref(),
&self.sid, &self.sid,
cid, cid,
root,
bundle_path, bundle_path,
rootfs_mounts, rootfs_mounts,
) )

View File

@ -51,16 +51,37 @@ impl RootFsResource {
} }
} }
#[allow(clippy::too_many_arguments)]
pub async fn handler_rootfs( pub async fn handler_rootfs(
&self, &self,
share_fs: &Option<Arc<dyn ShareFs>>, share_fs: &Option<Arc<dyn ShareFs>>,
hypervisor: &dyn Hypervisor, hypervisor: &dyn Hypervisor,
sid: &str, sid: &str,
cid: &str, cid: &str,
root: &oci::Root,
bundle_path: &str, bundle_path: &str,
rootfs_mounts: &[Mount], rootfs_mounts: &[Mount],
) -> Result<Arc<dyn Rootfs>> { ) -> Result<Arc<dyn Rootfs>> {
match rootfs_mounts { match rootfs_mounts {
// if rootfs_mounts is empty
mounts_vec if mounts_vec.is_empty() => {
if let Some(share_fs) = share_fs {
let share_fs_mount = share_fs.get_share_fs_mount();
// share fs rootfs
Ok(Arc::new(
share_fs_rootfs::ShareFsRootfs::new(
&share_fs_mount,
cid,
root.path.as_str(),
None,
)
.await
.context("new share fs rootfs")?,
))
} else {
return Err(anyhow!("share fs is unavailable"));
}
}
mounts_vec if is_single_layer_rootfs(mounts_vec) => { mounts_vec if is_single_layer_rootfs(mounts_vec) => {
// Safe as single_layer_rootfs must have one layer // Safe as single_layer_rootfs must have one layer
let layer = &mounts_vec[0]; let layer = &mounts_vec[0];
@ -86,7 +107,7 @@ impl RootFsResource {
&share_fs_mount, &share_fs_mount,
cid, cid,
bundle_path, bundle_path,
layer, Some(layer),
) )
.await .await
.context("new share fs rootfs")?, .context("new share fs rootfs")?,

View File

@ -23,14 +23,18 @@ impl ShareFsRootfs {
share_fs_mount: &Arc<dyn ShareFsMount>, share_fs_mount: &Arc<dyn ShareFsMount>,
cid: &str, cid: &str,
bundle_path: &str, bundle_path: &str,
rootfs: &Mount, rootfs: Option<&Mount>,
) -> Result<Self> { ) -> Result<Self> {
let bundle_rootfs = format!("{}/{}", bundle_path, ROOTFS); let bundle_rootfs = if let Some(rootfs) = rootfs {
rootfs.mount(&bundle_rootfs).context(format!( let bundle_rootfs = format!("{}/{}", bundle_path, ROOTFS);
"mount rootfs from {:?} to {}", rootfs.mount(&bundle_rootfs).context(format!(
&rootfs, &bundle_rootfs "mount rootfs from {:?} to {}",
))?; &rootfs, &bundle_rootfs
))?;
bundle_rootfs
} else {
bundle_path.to_string()
};
let mount_result = share_fs_mount let mount_result = share_fs_mount
.share_rootfs(ShareFsRootfsConfig { .share_rootfs(ShareFsRootfsConfig {
cid: cid.to_string(), cid: cid.to_string(),

View File

@ -16,6 +16,7 @@ use common::{
}, },
}; };
use kata_sys_util::k8s::update_ephemeral_storage_type; use kata_sys_util::k8s::update_ephemeral_storage_type;
use oci::{LinuxResources, Process as OCIProcess}; use oci::{LinuxResources, Process as OCIProcess};
use resource::ResourceManager; use resource::ResourceManager;
use tokio::sync::RwLock; use tokio::sync::RwLock;
@ -84,23 +85,30 @@ impl Container {
amend_spec(&mut spec, toml_config.runtime.disable_guest_seccomp).context("amend spec")?; amend_spec(&mut spec, toml_config.runtime.disable_guest_seccomp).context("amend spec")?;
let sandbox_pidns = is_pid_namespace_enabled(&spec); let sandbox_pidns = is_pid_namespace_enabled(&spec);
// get mutable root from oci spec
let mut root = match spec.root.as_mut() {
Some(root) => root,
None => return Err(anyhow!("spec miss root field")),
};
// handler rootfs // handler rootfs
let rootfs = self let rootfs = self
.resource_manager .resource_manager
.handler_rootfs(&config.container_id, &config.bundle, &config.rootfs_mounts) .handler_rootfs(
&config.container_id,
root,
&config.bundle,
&config.rootfs_mounts,
)
.await .await
.context("handler rootfs")?; .context("handler rootfs")?;
// update rootfs // update rootfs
match spec.root.as_mut() { root.path = rootfs
Some(root) => { .get_guest_rootfs_path()
root.path = rootfs .await
.get_guest_rootfs_path() .context("get guest rootfs path")?;
.await
.context("get guest rootfs path")?
}
None => return Err(anyhow!("spec miss root field")),
};
let mut storages = vec![]; let mut storages = vec![];
if let Some(storage) = rootfs.get_storage().await { if let Some(storage) = rootfs.get_storage().await {
storages.push(storage); storages.push(storage);