Merge pull request #6980 from nubificus/feat_sharefs_files

runtime-rs: handle copy files when share_fs is not available
This commit is contained in:
Fabiano Fidêncio 2023-06-06 12:26:55 +02:00 committed by GitHub
commit eb1bfa922b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 8 deletions

View File

@ -10,6 +10,7 @@ use crate::{network::NetworkConfig, resource_persist::ResourceState};
use agent::{types::Device, Agent, Storage}; use agent::{types::Device, Agent, Storage};
use anyhow::{anyhow, Context, Ok, Result}; use anyhow::{anyhow, Context, Ok, Result};
use async_trait::async_trait; use async_trait::async_trait;
use hypervisor::{ use hypervisor::{
device::{device_manager::DeviceManager, DeviceConfig}, device::{device_manager::DeviceManager, DeviceConfig},
BlockConfig, Hypervisor, BlockConfig, Hypervisor,
@ -255,6 +256,7 @@ impl ResourceManagerInner {
spec, spec,
self.device_manager.as_ref(), self.device_manager.as_ref(),
&self.sid, &self.sid,
self.agent.clone(),
) )
.await .await
} }

View File

@ -11,13 +11,13 @@ mod share_fs_volume;
mod shm_volume; mod shm_volume;
use async_trait::async_trait; use async_trait::async_trait;
use crate::{share_fs::ShareFs, volume::block_volume::is_block_volume};
use agent::Agent;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use hypervisor::device::device_manager::DeviceManager; use hypervisor::device::device_manager::DeviceManager;
use std::{sync::Arc, vec::Vec}; use std::{sync::Arc, vec::Vec};
use tokio::sync::RwLock; 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}; use self::hugepage::{get_huge_page_limits_map, get_huge_page_option};
const BIND: &str = "bind"; const BIND: &str = "bind";
@ -52,6 +52,7 @@ impl VolumeResource {
spec: &oci::Spec, spec: &oci::Spec,
d: &RwLock<DeviceManager>, d: &RwLock<DeviceManager>,
sid: &str, sid: &str,
agent: Arc<dyn Agent>,
) -> Result<Vec<Arc<dyn Volume>>> { ) -> Result<Vec<Arc<dyn Volume>>> {
let mut volumes: Vec<Arc<dyn Volume>> = vec![]; let mut volumes: Vec<Arc<dyn Volume>> = vec![];
let oci_mounts = &spec.mounts; let oci_mounts = &spec.mounts;
@ -85,7 +86,7 @@ impl VolumeResource {
) )
} else if share_fs_volume::is_share_fs_volume(m) { } else if share_fs_volume::is_share_fs_volume(m) {
Arc::new( 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 .await
.with_context(|| format!("new share fs volume {:?}", m))?, .with_context(|| format!("new share fs volume {:?}", m))?,
) )

View File

@ -5,11 +5,15 @@
// //
use std::{ use std::{
fs::File,
io::Read,
os::unix::fs::MetadataExt,
path::{Path, PathBuf}, path::{Path, PathBuf},
str::FromStr, str::FromStr,
sync::Arc, sync::Arc,
}; };
use agent::Agent;
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use async_trait::async_trait; use async_trait::async_trait;
use hypervisor::device::device_manager::DeviceManager; use hypervisor::device::device_manager::DeviceManager;
@ -19,6 +23,9 @@ use super::Volume;
use crate::share_fs::{MountedInfo, ShareFs, ShareFsVolumeConfig}; use crate::share_fs::{MountedInfo, ShareFs, ShareFsVolumeConfig};
use kata_types::mount; 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"]; const SYS_MOUNT_PREFIX: [&str; 2] = ["/proc", "/sys"];
// copy file to container's rootfs if filesystem sharing is not supported, otherwise // copy file to container's rootfs if filesystem sharing is not supported, otherwise
@ -39,6 +46,7 @@ impl ShareFsVolume {
m: &oci::Mount, m: &oci::Mount,
cid: &str, cid: &str,
readonly: bool, readonly: bool,
agent: Arc<dyn Agent>,
) -> Result<Self> { ) -> Result<Self> {
// The file_name is in the format of "sandbox-{uuid}-{file_name}" // 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(); let file_name = Path::new(&m.source).file_name().unwrap().to_str().unwrap();
@ -61,11 +69,67 @@ impl ShareFsVolume {
Ok(src) => src, Ok(src) => src,
}; };
// If the mount source is a file, we can copy it to the sandbox
if src.is_file() { if src.is_file() {
// TODO: copy file // This is where we set the value for the guest path
debug!(sl!(), "FIXME: copy file {}", &m.source); let dest = [
} else { DEFAULT_KATA_GUEST_SANDBOX_DIR,
PASSTHROUGH_FS_DIR,
file_name.clone().as_str(),
]
.join("/");
debug!( 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!(), sl!(),
"Ignoring non-regular file as FS sharing not supported. mount: {:?}", m "Ignoring non-regular file as FS sharing not supported. mount: {:?}", m
); );

View File

@ -324,12 +324,12 @@ languages:
rust: rust:
description: "Rust language" description: "Rust language"
notes: "'version' is the default minimum version used by this project." notes: "'version' is the default minimum version used by this project."
version: "1.68.0" version: "1.69.0"
meta: meta:
description: | description: |
'newest-version' is the latest version known to work when 'newest-version' is the latest version known to work when
building Kata building Kata
newest-version: "1.68.0" newest-version: "1.69.0"
golangci-lint: golangci-lint:
description: "golangci-lint" description: "golangci-lint"