Skip to content
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
67 changes: 32 additions & 35 deletions crates/integration-tests/src/tests/mount_feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,57 +20,48 @@ use tempfile::TempDir;

use crate::{get_test_image, run_bcvk, INTEGRATION_TEST_LABEL};

/// Create a systemd unit that verifies a mount exists and contains expected content
/// Create a systemd unit that verifies a mount exists and tests writability
fn create_mount_verify_unit(
unit_dir: &Utf8Path,
mount_name: &str,
expected_file: &str,
expected_content: &str,
expected_content: Option<&str>,
readonly: bool,
) -> std::io::Result<()> {
let unit_content = format!(
r#"[Unit]
Description=Verify mount {mount_name} and poweroff
RequiresMountsFor=/run/virtiofs-mnt-{mount_name}
let (description, content_check, write_check, unit_prefix) = if readonly {
(
format!("Verify read-only mount {mount_name} and poweroff"),
format!("ExecStart=test -f /run/virtiofs-mnt-{mount_name}/{expected_file}"),
format!("ExecStart=/bin/sh -c '! echo test-write > /run/virtiofs-mnt-{mount_name}/write-test.txt 2>/dev/null'"),
"verify-ro-mount",
)
} else {
let content = expected_content.expect("expected_content required for writable mounts");
(
format!("Verify mount {mount_name} and poweroff"),
format!("ExecStart=grep -qF \"{content}\" /run/virtiofs-mnt-{mount_name}/{expected_file}"),
format!("ExecStart=/bin/sh -c 'echo test-write > /run/virtiofs-mnt-{mount_name}/write-test.txt'"),
"verify-mount",
)
Comment thread
cgwalters marked this conversation as resolved.
};

[Service]
Type=oneshot
ExecStart=grep -qF "{expected_content}" /run/virtiofs-mnt-{mount_name}/{expected_file}
ExecStart=test -w /run/virtiofs-mnt-{mount_name}/{expected_file}
ExecStart=echo ok mount verify {mount_name}
ExecStart=systemctl poweroff
StandardOutput=journal+console
StandardError=journal+console
"#
);

let unit_path = unit_dir.join(format!("verify-mount-{}.service", mount_name));
fs::write(&unit_path, unit_content)?;
Ok(())
}

/// Create a systemd unit that tries to write to a mount to verify read-only status
fn create_ro_mount_verify_unit(
unit_dir: &Utf8Path,
mount_name: &str,
expected_file: &str,
) -> std::io::Result<()> {
let unit_content = format!(
r#"[Unit]
Description=Verify read-only mount {mount_name} and poweroff
Description={description}
RequiresMountsFor=/run/virtiofs-mnt-{mount_name}

[Service]
Type=oneshot
ExecStart=test -f /run/virtiofs-mnt-{mount_name}/{expected_file}
ExecStart=test '!' -w /run/virtiofs-mnt-{mount_name}/{expected_file}
{content_check}
{write_check}
ExecStart=echo ok mount verify {mount_name}
ExecStart=systemctl poweroff
StandardOutput=journal+console
StandardError=journal+console
"#
);

let unit_path = unit_dir.join(format!("verify-ro-mount-{}.service", mount_name));
let unit_path = unit_dir.join(format!("{unit_prefix}-{mount_name}.service"));
fs::write(&unit_path, unit_content)?;
Ok(())
}
Expand All @@ -90,8 +81,14 @@ pub fn test_mount_feature_bind() {
fs::create_dir(&system_dir).expect("Failed to create system directory");

// Create verification unit
create_mount_verify_unit(&system_dir, "testmount", "test.txt", test_content)
.expect("Failed to create verify unit");
create_mount_verify_unit(
&system_dir,
"testmount",
"test.txt",
Some(test_content),
false,
)
.expect("Failed to create verify unit");

println!("Testing bind mount with temp directory: {}", temp_dir_path);

Expand Down Expand Up @@ -135,7 +132,7 @@ pub fn test_mount_feature_ro_bind() {
fs::create_dir(&system_dir).expect("Failed to create system directory");

// Create verification unit for read-only mount
create_ro_mount_verify_unit(&system_dir, "romount", "readonly.txt")
create_mount_verify_unit(&system_dir, "romount", "readonly.txt", None, true)
.expect("Failed to create verify unit");

println!(
Expand Down
8 changes: 6 additions & 2 deletions crates/kit/src/qemu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,8 @@ pub struct VirtiofsConfig {
/// Host directory to share
pub shared_dir: Utf8PathBuf,
pub debug: bool,
/// Mount as read-only
pub readonly: bool,
}

impl Default for VirtiofsConfig {
Expand All @@ -906,6 +908,8 @@ impl Default for VirtiofsConfig {
socket_path: "/run/inner-shared/virtiofs.sock".into(),
shared_dir: "/run/source-image".into(),
debug: false,
// We don't need to write to this, there's a transient overlay
readonly: true,
}
}
}
Expand Down Expand Up @@ -977,8 +981,8 @@ pub async fn spawn_virtiofsd_async(config: &VirtiofsConfig) -> Result<tokio::pro
"--sandbox=none",
]);

// Only add --readonly if supported
if supports_readonly {
// Only add --readonly if requested and supported
if config.readonly && supports_readonly {
cmd.arg("--readonly");
}

Expand Down
1 change: 1 addition & 0 deletions crates/kit/src/run_ephemeral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,7 @@ pub(crate) async fn run_impl(opts: RunEphemeralOpts) -> Result<()> {
socket_path: socket_path.clone().into(),
shared_dir: source_path,
debug: false,
readonly: is_readonly,
};
additional_mounts.push((virtiofsd_config, tag.clone()));

Expand Down