priv: WriteNspawnFlags takes Vec<BindMount> instead of raw flag strings
This commit is contained in:
parent
a922376778
commit
c9eb520e7c
3 changed files with 38 additions and 24 deletions
|
|
@ -20,7 +20,7 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{Context as _, Result, bail};
|
||||
use hive_sh4re::priv_proto::{AGENT_PREFIX, MANAGER_NAME, META_DIR, PRIV_SOCK, SIBLING_CONTAINERS, PrivRequest, PrivResponse};
|
||||
use hive_sh4re::priv_proto::{AGENT_PREFIX, MANAGER_NAME, META_DIR, PRIV_SOCK, SIBLING_CONTAINERS, BindMount, PrivRequest, PrivResponse};
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||
use tokio::net::{UnixListener, UnixStream};
|
||||
use tokio::process::Command;
|
||||
|
|
@ -173,12 +173,13 @@ async fn exec(req: PrivRequest) -> Result<(String, String)> {
|
|||
|
||||
PrivRequest::ListContainers => container_run(&["list"]).await,
|
||||
|
||||
PrivRequest::WriteNspawnFlags { ref container, ref extra_nspawn_flags } => {
|
||||
PrivRequest::WriteNspawnFlags { ref container, ref binds } => {
|
||||
validate_container_system_name(container)?;
|
||||
for flag in extra_nspawn_flags {
|
||||
validate_nspawn_flag(flag)?;
|
||||
for bind in binds {
|
||||
validate_bind_path(&bind.host_path)?;
|
||||
validate_bind_path(&bind.container_path)?;
|
||||
}
|
||||
write_nspawn_flags(container, extra_nspawn_flags)?;
|
||||
write_nspawn_flags(container, binds)?;
|
||||
Ok((String::new(), String::new()))
|
||||
}
|
||||
|
||||
|
|
@ -352,17 +353,15 @@ fn agent_flake_ref(name: &str) -> String {
|
|||
format!("{META_DIR}#{name}")
|
||||
}
|
||||
|
||||
/// Validate one nspawn flag entry. Must be non-empty and contain no
|
||||
/// ASCII whitespace (would split the entry when the start script
|
||||
/// expands `$EXTRA_NSPAWN_FLAGS` unquoted), double-quotes (would
|
||||
/// break the `EXTRA_NSPAWN_FLAGS="..."` conf line), or null bytes.
|
||||
fn validate_nspawn_flag(flag: &str) -> Result<()> {
|
||||
if flag.is_empty()
|
||||
|| flag.bytes().any(|b| b == 0 || b == b'"' || b.is_ascii_whitespace())
|
||||
/// Validate a bind-mount path: must be absolute, non-empty, and contain
|
||||
/// no newlines, null bytes, or double-quotes (which would break the
|
||||
/// `EXTRA_NSPAWN_FLAGS="..."` conf line format).
|
||||
fn validate_bind_path(path: &str) -> Result<()> {
|
||||
if path.is_empty()
|
||||
|| !path.starts_with('/')
|
||||
|| path.bytes().any(|b| b == 0 || b == b'\n' || b == b'"')
|
||||
{
|
||||
bail!(
|
||||
"invalid nspawn flag {flag:?}: must be non-empty and contain no whitespace, double-quotes, or null bytes"
|
||||
);
|
||||
bail!("invalid bind path {path:?}: must be an absolute path with no newlines, null bytes, or double-quotes");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -371,7 +370,7 @@ fn validate_nspawn_flag(flag: &str) -> Result<()> {
|
|||
/// vars (`PRIVATE_NETWORK`, `HOST_ADDRESS*`, `LOCAL_ADDRESS*`, `HOST_BRIDGE`,
|
||||
/// `EXTRA_NSPAWN_FLAGS`), forces `PRIVATE_NETWORK=0` and blank network vars,
|
||||
/// then appends `EXTRA_NSPAWN_FLAGS="<flags>"`.
|
||||
fn write_nspawn_flags(container: &str, extra_nspawn_flags: &[String]) -> Result<()> {
|
||||
fn write_nspawn_flags(container: &str, binds: &[BindMount]) -> Result<()> {
|
||||
let path = format!("/etc/nixos-containers/{container}.conf");
|
||||
let original = std::fs::read_to_string(&path)
|
||||
.with_context(|| format!("read {path}"))?;
|
||||
|
|
@ -398,7 +397,11 @@ fn write_nspawn_flags(container: &str, extra_nspawn_flags: &[String]) -> Result<
|
|||
out.push_str("HOST_ADDRESS6=\n");
|
||||
out.push_str("LOCAL_ADDRESS6=\n");
|
||||
out.push_str("HOST_BRIDGE=\n");
|
||||
let flags_joined = extra_nspawn_flags.join(" ");
|
||||
let flags: Vec<String> = binds.iter().map(|b| {
|
||||
let flag = if b.read_only { "--bind-ro" } else { "--bind" };
|
||||
format!("{flag}={}:{}", b.host_path, b.container_path)
|
||||
}).collect();
|
||||
let flags_joined = flags.join(" ");
|
||||
out.push_str(&format!("EXTRA_NSPAWN_FLAGS=\"{flags_joined}\"\n"));
|
||||
std::fs::write(&path, out).with_context(|| format!("write {path}"))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue