mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-30 20:54:26 +00:00
runtime-rs: handle copy files when share_fs is not available
In hypervisors that do not support virtiofs we have to copy files in the VM sandbox to properly setup the network (resolv.conf, hosts, and hostname). To do that, we construct the volume as before, with the addition of an extra variable that designates the path where the file will reside in the sandbox. In this case, we issue a `copy_file` agent request *and* we patch the spec to account for this change. Fixes: #6978 Signed-off-by: Anastassios Nanos <ananos@nubificus.co.uk> Signed-off-by: George Pyrros <gpyrros@nubificus.co.uk>
This commit is contained in:
parent
18b1a019d4
commit
ed37715e05
@ -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
|
||||
}
|
||||
|
@ -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<DeviceManager>,
|
||||
sid: &str,
|
||||
agent: Arc<dyn Agent>,
|
||||
) -> Result<Vec<Arc<dyn Volume>>> {
|
||||
let mut volumes: Vec<Arc<dyn Volume>> = 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))?,
|
||||
)
|
||||
|
@ -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<dyn Agent>,
|
||||
) -> Result<Self> {
|
||||
// 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
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user