Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tempfile): allow usage of custom tempdir locations #856

Merged
merged 1 commit into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/bin/uhyve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ struct Args {
#[clap(long)]
file_mapping: Vec<String>,

/// The path that should be used for temporary directories storing unmapped files.
///
/// This is useful for manually created tmpfs filesystems and for selecting
/// directories not managed by a temporary file cleaner, which can remove open files
/// manually. In most cases, mapping the guest path /root/ instead should be sufficient.
///
/// Defaults to /tmp.
#[clap(long)]
tempdir: Option<String>,

#[clap(flatten, next_help_heading = "Memory OPTIONS")]
memory_args: MemoryArgs,

Expand Down Expand Up @@ -257,6 +267,7 @@ impl From<Args> for Params {
#[cfg(target_os = "linux")]
gdb_port,
file_mapping,
tempdir,
kernel: _,
kernel_args,
output,
Expand All @@ -277,6 +288,7 @@ impl From<Args> for Params {
#[cfg(target_os = "macos")]
gdb_port: None,
kernel_args,
tempdir,
// TODO
output: if let Some(outp) = output {
Output::from_str(&outp).unwrap()
Expand Down
13 changes: 7 additions & 6 deletions src/isolation/filemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ impl UhyveFileMap {
/// Creates a UhyveFileMap.
///
/// * `mappings` - A list of host->guest path mappings with the format "./host_path.txt:guest.txt"
pub fn new(mappings: &[String]) -> UhyveFileMap {
/// * `tempdir` - Path to create temporary directory on
pub fn new(mappings: &[String], tempdir: &Option<String>) -> UhyveFileMap {
UhyveFileMap {
files: mappings
.iter()
.map(String::as_str)
.map(Self::split_guest_and_host_path)
.map(Result::unwrap)
.collect(),
tempdir: create_temp_dir(),
tempdir: create_temp_dir(tempdir),
}
}

Expand Down Expand Up @@ -193,7 +194,7 @@ mod tests {
path_prefix.clone() + "/this_symlink_leads_to_a_file" + ":guest_file_symlink",
];

let mut map = UhyveFileMap::new(&map_parameters);
let mut map = UhyveFileMap::new(&map_parameters, &None);

assert_eq!(
map.get_host_path("readme_file.md").unwrap(),
Expand Down Expand Up @@ -245,7 +246,7 @@ mod tests {
host_path_map.to_str().unwrap(),
guest_path_map.to_str().unwrap()
)];
let mut map = UhyveFileMap::new(&uhyvefilemap_params);
let mut map = UhyveFileMap::new(&uhyvefilemap_params, &None);

let mut found_host_path = map.get_host_path(target_guest_path.clone().to_str().unwrap());

Expand Down Expand Up @@ -276,7 +277,7 @@ mod tests {
guest_path_map.to_str().unwrap()
)];

map = UhyveFileMap::new(&uhyvefilemap_params);
map = UhyveFileMap::new(&uhyvefilemap_params, &None);

target_guest_path = PathBuf::from("/root/this_symlink_leads_to_a_file");
target_host_path = fixture_path.clone();
Expand All @@ -289,7 +290,7 @@ mod tests {

// Tests directory traversal with no maps
let empty_array: [String; 0] = [];
map = UhyveFileMap::new(&empty_array);
map = UhyveFileMap::new(&empty_array, &None);
found_host_path = map.get_host_path(target_guest_path.to_str().unwrap());
assert!(found_host_path.is_none());
}
Expand Down
29 changes: 22 additions & 7 deletions src/isolation/tempdir.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
use std::{fs::Permissions, os::unix::fs::PermissionsExt};

use tempfile::{Builder, TempDir};
use uuid::Uuid;

/// Creates a temporary directory.
pub fn create_temp_dir() -> TempDir {
let dir = Builder::new()
.permissions(Permissions::from_mode(0o700))
.prefix("uhyve-")
.tempdir()
.ok()
.unwrap_or_else(|| panic!("The temporary directory could not be created."));
///
/// * `dir_path` - The location in which the temporary directory should be created.
pub fn create_temp_dir(dir_path: &Option<String>) -> TempDir {
let dir: TempDir;
if let Some(dir_path) = dir_path {
dir = Builder::new()
.permissions(Permissions::from_mode(0o700))
.prefix("uhyve-")
.suffix(&Uuid::new_v4().to_string())
n0toose marked this conversation as resolved.
Show resolved Hide resolved
.tempdir_in(dir_path)
.ok()
.unwrap_or_else(|| panic!("The temporary directory could not be created."));
} else {
dir = Builder::new()
.permissions(Permissions::from_mode(0o700))
.prefix("uhyve-")
.suffix(&Uuid::new_v4().to_string())
.tempdir()
.ok()
.unwrap_or_else(|| panic!("The temporary directory could not be created."));
}

let dir_permissions = dir.path().metadata().unwrap().permissions();
assert!(!dir_permissions.readonly());
Expand Down
4 changes: 4 additions & 0 deletions src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ pub struct Params {
/// Mapped paths between the guest and host OS
pub file_mapping: Vec<String>,

/// Path to create temporary directory on
pub tempdir: Option<String>,

/// Kernel output handling
pub output: Output,

Expand All @@ -59,6 +62,7 @@ impl Default for Params {
cpu_count: Default::default(),
gdb_port: Default::default(),
file_mapping: Default::default(),
tempdir: Default::default(),
kernel_args: Default::default(),
output: Default::default(),
stats: false,
Expand Down
2 changes: 1 addition & 1 deletion src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ impl<VirtBackend: VirtualizationBackend> UhyveVm<VirtBackend> {
"gdbstub is only supported with one CPU"
);

let file_mapping = Mutex::new(UhyveFileMap::new(&params.file_mapping));
let file_mapping = Mutex::new(UhyveFileMap::new(&params.file_mapping, &params.tempdir));

let output = match params.output {
params::Output::None => Output::None,
Expand Down
Loading