mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-17 22:34:25 +01:00
Merge pull request #5220 from liubin/fix/5184-rs-inotify
runtime-rs: support watchable mount
This commit is contained in:
@@ -25,7 +25,10 @@ const VIRTIO_FS: &str = "virtio-fs";
|
||||
const INLINE_VIRTIO_FS: &str = "inline-virtio-fs";
|
||||
|
||||
const KATA_HOST_SHARED_DIR: &str = "/run/kata-containers/shared/sandboxes/";
|
||||
|
||||
/// share fs (for example virtio-fs) mount path in the guest
|
||||
const KATA_GUEST_SHARE_DIR: &str = "/run/kata-containers/shared/containers/";
|
||||
|
||||
pub(crate) const DEFAULT_KATA_GUEST_SANDBOX_DIR: &str = "/run/kata-containers/sandbox/";
|
||||
|
||||
const PASSTHROUGH_FS_DIR: &str = "passthrough";
|
||||
@@ -51,10 +54,12 @@ pub struct ShareFsVolumeConfig {
|
||||
pub source: String,
|
||||
pub target: String,
|
||||
pub readonly: bool,
|
||||
pub mount_options: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct ShareFsMountResult {
|
||||
pub guest_path: String,
|
||||
pub storages: Vec<agent::Storage>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@@ -42,12 +42,12 @@ pub(crate) fn share_to_guest(
|
||||
Ok(do_get_guest_path(target, cid, is_volume))
|
||||
}
|
||||
|
||||
pub(crate) fn get_host_ro_shared_path(id: &str) -> PathBuf {
|
||||
Path::new(KATA_HOST_SHARED_DIR).join(id).join("ro")
|
||||
pub(crate) fn get_host_ro_shared_path(sid: &str) -> PathBuf {
|
||||
Path::new(KATA_HOST_SHARED_DIR).join(sid).join("ro")
|
||||
}
|
||||
|
||||
pub(crate) fn get_host_rw_shared_path(id: &str) -> PathBuf {
|
||||
Path::new(KATA_HOST_SHARED_DIR).join(id).join("rw")
|
||||
pub(crate) fn get_host_rw_shared_path(sid: &str) -> PathBuf {
|
||||
Path::new(KATA_HOST_SHARED_DIR).join(sid).join("rw")
|
||||
}
|
||||
|
||||
fn do_get_guest_any_path(target: &str, cid: &str, is_volume: bool, is_virtiofs: bool) -> String {
|
||||
@@ -66,11 +66,11 @@ fn do_get_guest_any_path(target: &str, cid: &str, is_volume: bool, is_virtiofs:
|
||||
path.to_str().unwrap().to_string()
|
||||
}
|
||||
|
||||
fn do_get_guest_path(target: &str, cid: &str, is_volume: bool) -> String {
|
||||
pub(crate) fn do_get_guest_path(target: &str, cid: &str, is_volume: bool) -> String {
|
||||
do_get_guest_any_path(target, cid, is_volume, false)
|
||||
}
|
||||
|
||||
fn do_get_host_path(
|
||||
pub(crate) fn do_get_host_path(
|
||||
target: &str,
|
||||
sid: &str,
|
||||
cid: &str,
|
||||
|
||||
@@ -4,10 +4,21 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use agent::Storage;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_trait::async_trait;
|
||||
use kata_types::k8s::is_watchable_mount;
|
||||
use std::fs;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::path::Path;
|
||||
|
||||
use super::{utils, ShareFsMount, ShareFsMountResult, ShareFsRootfsConfig, ShareFsVolumeConfig};
|
||||
const WATCHABLE_PATH_NAME: &str = "watchable";
|
||||
const WATCHABLE_BIND_DEV_TYPE: &str = "watchable-bind";
|
||||
|
||||
use super::{
|
||||
utils, ShareFsMount, ShareFsMountResult, ShareFsRootfsConfig, ShareFsVolumeConfig,
|
||||
KATA_GUEST_SHARE_DIR, PASSTHROUGH_FS_DIR,
|
||||
};
|
||||
|
||||
pub struct VirtiofsShareMount {
|
||||
id: String,
|
||||
@@ -32,11 +43,14 @@ impl ShareFsMount for VirtiofsShareMount {
|
||||
false,
|
||||
)
|
||||
.context("share to guest")?;
|
||||
Ok(ShareFsMountResult { guest_path })
|
||||
Ok(ShareFsMountResult {
|
||||
guest_path,
|
||||
storages: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
async fn share_volume(&self, config: ShareFsVolumeConfig) -> Result<ShareFsMountResult> {
|
||||
let guest_path = utils::share_to_guest(
|
||||
let mut guest_path = utils::share_to_guest(
|
||||
&config.source,
|
||||
&config.target,
|
||||
&self.id,
|
||||
@@ -45,6 +59,61 @@ impl ShareFsMount for VirtiofsShareMount {
|
||||
true,
|
||||
)
|
||||
.context("share to guest")?;
|
||||
Ok(ShareFsMountResult { guest_path })
|
||||
|
||||
// watchable mounts
|
||||
if is_watchable_mount(&config.source) {
|
||||
// Create path in shared directory for creating watchable mount:
|
||||
let host_rw_path = utils::get_host_rw_shared_path(&self.id);
|
||||
|
||||
// "/run/kata-containers/shared/sandboxes/$sid/rw/passthrough/watchable"
|
||||
let watchable_host_path = Path::new(&host_rw_path)
|
||||
.join(PASSTHROUGH_FS_DIR)
|
||||
.join(WATCHABLE_PATH_NAME);
|
||||
|
||||
fs::create_dir_all(&watchable_host_path).context(format!(
|
||||
"unable to create watchable path: {:?}",
|
||||
&watchable_host_path,
|
||||
))?;
|
||||
|
||||
fs::set_permissions(watchable_host_path, fs::Permissions::from_mode(0o750))?;
|
||||
|
||||
// path: /run/kata-containers/shared/containers/passthrough/watchable/config-map-name
|
||||
let file_name = Path::new(&guest_path)
|
||||
.file_name()
|
||||
.context("get file name from guest path")?;
|
||||
let watchable_guest_mount = Path::new(KATA_GUEST_SHARE_DIR)
|
||||
.join(PASSTHROUGH_FS_DIR)
|
||||
.join(WATCHABLE_PATH_NAME)
|
||||
.join(file_name)
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.map_err(|e| anyhow!("failed to get watchable guest mount path {:?}", e))?;
|
||||
|
||||
let watchable_storage: Storage = Storage {
|
||||
driver: String::from(WATCHABLE_BIND_DEV_TYPE),
|
||||
driver_options: Vec::new(),
|
||||
source: guest_path,
|
||||
fs_type: String::from("bind"),
|
||||
fs_group: None,
|
||||
options: config.mount_options,
|
||||
mount_point: watchable_guest_mount.clone(),
|
||||
};
|
||||
|
||||
// Update the guest_path, in order to identify what will
|
||||
// change in the OCI spec.
|
||||
guest_path = watchable_guest_mount;
|
||||
|
||||
let storages = vec![watchable_storage];
|
||||
|
||||
return Ok(ShareFsMountResult {
|
||||
guest_path,
|
||||
storages,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(ShareFsMountResult {
|
||||
guest_path,
|
||||
storages: vec![],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ use crate::share_fs::{ShareFs, ShareFsVolumeConfig};
|
||||
// skip the volumes whose source had already set to guest share dir.
|
||||
pub(crate) struct ShareFsVolume {
|
||||
mounts: Vec<oci::Mount>,
|
||||
storages: Vec<agent::Storage>,
|
||||
}
|
||||
|
||||
impl ShareFsVolume {
|
||||
@@ -30,7 +31,10 @@ impl ShareFsVolume {
|
||||
let file_name = Path::new(&m.source).file_name().unwrap().to_str().unwrap();
|
||||
let file_name = generate_mount_path(cid, file_name);
|
||||
|
||||
let mut volume = Self { mounts: vec![] };
|
||||
let mut volume = Self {
|
||||
mounts: vec![],
|
||||
storages: vec![],
|
||||
};
|
||||
match share_fs {
|
||||
None => {
|
||||
let src = match std::fs::canonicalize(&m.source) {
|
||||
@@ -61,10 +65,15 @@ impl ShareFsVolume {
|
||||
source: m.source.clone(),
|
||||
target: file_name,
|
||||
readonly: false,
|
||||
mount_options: m.options.clone(),
|
||||
})
|
||||
.await
|
||||
.context("share fs volume")?;
|
||||
|
||||
// set storages for the volume
|
||||
volume.storages = mount_result.storages;
|
||||
|
||||
// set mount for the volume
|
||||
volume.mounts.push(oci::Mount {
|
||||
destination: m.destination.clone(),
|
||||
r#type: "bind".to_string(),
|
||||
@@ -83,7 +92,7 @@ impl Volume for ShareFsVolume {
|
||||
}
|
||||
|
||||
fn get_storage(&self) -> Result<Vec<agent::Storage>> {
|
||||
Ok(vec![])
|
||||
Ok(self.storages.clone())
|
||||
}
|
||||
|
||||
fn cleanup(&self) -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user