diff --git a/src/runtime-rs/crates/resource/src/manager_inner.rs b/src/runtime-rs/crates/resource/src/manager_inner.rs index 16f55a36a6..18e74dacf4 100644 --- a/src/runtime-rs/crates/resource/src/manager_inner.rs +++ b/src/runtime-rs/crates/resource/src/manager_inner.rs @@ -10,6 +10,7 @@ use crate::{network::NetworkConfig, resource_persist::ResourceState}; use agent::{types::Device, Agent, Storage}; use anyhow::{anyhow, Context, Ok, Result}; use async_trait::async_trait; + use hypervisor::{ device::{device_manager::DeviceManager, DeviceConfig}, BlockConfig, Hypervisor, @@ -255,6 +256,7 @@ impl ResourceManagerInner { spec, self.device_manager.as_ref(), &self.sid, + self.agent.clone(), ) .await } diff --git a/src/runtime-rs/crates/resource/src/volume/mod.rs b/src/runtime-rs/crates/resource/src/volume/mod.rs index ea7d4f5d60..52b826b2db 100644 --- a/src/runtime-rs/crates/resource/src/volume/mod.rs +++ b/src/runtime-rs/crates/resource/src/volume/mod.rs @@ -11,13 +11,13 @@ mod share_fs_volume; mod shm_volume; use async_trait::async_trait; +use crate::{share_fs::ShareFs, volume::block_volume::is_block_volume}; +use agent::Agent; use anyhow::{Context, Result}; use hypervisor::device::device_manager::DeviceManager; use std::{sync::Arc, vec::Vec}; use tokio::sync::RwLock; -use crate::{share_fs::ShareFs, volume::block_volume::is_block_volume}; - use self::hugepage::{get_huge_page_limits_map, get_huge_page_option}; const BIND: &str = "bind"; @@ -52,6 +52,7 @@ impl VolumeResource { spec: &oci::Spec, d: &RwLock, sid: &str, + agent: Arc, ) -> Result>> { let mut volumes: Vec> = vec![]; let oci_mounts = &spec.mounts; @@ -85,7 +86,7 @@ impl VolumeResource { ) } else if share_fs_volume::is_share_fs_volume(m) { Arc::new( - share_fs_volume::ShareFsVolume::new(share_fs, m, cid, read_only) + share_fs_volume::ShareFsVolume::new(share_fs, m, cid, read_only, agent.clone()) .await .with_context(|| format!("new share fs volume {:?}", m))?, ) diff --git a/src/runtime-rs/crates/resource/src/volume/share_fs_volume.rs b/src/runtime-rs/crates/resource/src/volume/share_fs_volume.rs index 0748e374d1..098dc399f7 100644 --- a/src/runtime-rs/crates/resource/src/volume/share_fs_volume.rs +++ b/src/runtime-rs/crates/resource/src/volume/share_fs_volume.rs @@ -5,11 +5,15 @@ // use std::{ + fs::File, + io::Read, + os::unix::fs::MetadataExt, path::{Path, PathBuf}, str::FromStr, sync::Arc, }; +use agent::Agent; use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; use hypervisor::device::device_manager::DeviceManager; @@ -19,6 +23,9 @@ use super::Volume; use crate::share_fs::{MountedInfo, ShareFs, ShareFsVolumeConfig}; use kata_types::mount; +use crate::share_fs::DEFAULT_KATA_GUEST_SANDBOX_DIR; +use crate::share_fs::PASSTHROUGH_FS_DIR; + const SYS_MOUNT_PREFIX: [&str; 2] = ["/proc", "/sys"]; // copy file to container's rootfs if filesystem sharing is not supported, otherwise @@ -39,6 +46,7 @@ impl ShareFsVolume { m: &oci::Mount, cid: &str, readonly: bool, + agent: Arc, ) -> Result { // The file_name is in the format of "sandbox-{uuid}-{file_name}" let file_name = Path::new(&m.source).file_name().unwrap().to_str().unwrap(); @@ -61,11 +69,67 @@ impl ShareFsVolume { Ok(src) => src, }; + // If the mount source is a file, we can copy it to the sandbox if src.is_file() { - // TODO: copy file - debug!(sl!(), "FIXME: copy file {}", &m.source); - } else { + // This is where we set the value for the guest path + let dest = [ + DEFAULT_KATA_GUEST_SANDBOX_DIR, + PASSTHROUGH_FS_DIR, + file_name.clone().as_str(), + ] + .join("/"); + debug!( + sl!(), + "copy local file {:?} to guest {:?}", + &m.source, + dest.clone() + ); + + // Read file metadata + let file_metadata = std::fs::metadata(src.clone()) + .with_context(|| format!("Failed to read metadata from file: {:?}", src))?; + + // Open file + let mut file = File::open(&src) + .with_context(|| format!("Failed to open file: {:?}", src))?; + + // Open read file contents to buffer + let mut buffer = Vec::new(); + file.read_to_end(&mut buffer) + .with_context(|| format!("Failed to read file: {:?}", src))?; + + // Create gRPC request + let r = agent::CopyFileRequest { + path: dest.clone(), + file_size: file_metadata.len() as i64, + uid: file_metadata.uid() as i32, + gid: file_metadata.gid() as i32, + file_mode: file_metadata.mode(), + data: buffer, + ..Default::default() + }; + + debug!(sl!(), "copy_file: {:?} to sandbox {:?}", &src, dest.clone()); + + // Issue gRPC request to agent + agent.copy_file(r).await.with_context(|| { + format!( + "copy file request failed: src: {:?}, dest: {:?}", + file_name, dest + ) + })?; + + // append oci::Mount structure to volume mounts + volume.mounts.push(oci::Mount { + destination: m.destination.clone(), + r#type: "bind".to_string(), + source: dest.clone(), + options: m.options.clone(), + }) + } else { + // If not, we can ignore it. Let's issue a warning so that the user knows. + warn!( sl!(), "Ignoring non-regular file as FS sharing not supported. mount: {:?}", m );