lazaret/crates/lazaret-ignored-workspace/src/daemon.rs

189 lines
5.6 KiB
Rust
Raw Normal View History

use std::ffi::{OsStr, OsString};
use std::fs::File;
use std::io::{self, Write};
use std::path::PathBuf;
use rustix::fs::{FileType, Mode, OFlags, ResolveFlags, fstat, openat2};
use crate::IgnoredWorkspace;
use crate::filesystem::RouterConfiguration;
pub const PRIVATE_ROUTER_ROLE: &str = "--lazaret-private-ignored-workspace-router-v1";
#[must_use]
pub fn dispatch_private_router(arguments: &[OsString]) -> Option<io::Result<()>> {
if arguments
.first()
.is_none_or(|argument| argument != PRIVATE_ROUTER_ROLE)
{
return None;
}
Some(parse(arguments).and_then(run))
}
struct Arguments {
workspace_fd: i32,
workspace_label: PathBuf,
isolated_fd: i32,
mountpoint: PathBuf,
global_excludes: Option<PathBuf>,
isolate_ignored: bool,
threads: usize,
}
fn parse(arguments: &[OsString]) -> io::Result<Arguments> {
let mut arguments = arguments.iter().skip(1);
let workspace_fd = number(named(&mut arguments, "--workspace-fd")?)?;
let workspace_label = PathBuf::from(named(&mut arguments, "--workspace-label")?);
let isolated_fd = number(named(&mut arguments, "--isolated-fd")?)?;
let mountpoint = PathBuf::from(named(&mut arguments, "--mountpoint")?);
let global_excludes = match named(&mut arguments, "--global-excludes")? {
value if value.is_empty() => None,
value => Some(PathBuf::from(value)),
};
let isolate_ignored = match named(&mut arguments, "--isolate-ignored")?.to_str() {
Some("true") => true,
Some("false") => false,
_ => return Err(io::Error::other("router isolation mode is invalid")),
};
let threads = number(named(&mut arguments, "--threads")?)?;
if arguments.next().is_some() || threads == 0 {
return Err(io::Error::other("router arguments are invalid"));
}
Ok(Arguments {
workspace_fd,
workspace_label,
isolated_fd,
mountpoint,
global_excludes,
isolate_ignored,
threads,
})
}
fn run(arguments: Arguments) -> io::Result<()> {
let workspace = inherited_exact_directory(arguments.workspace_fd, &arguments.workspace_label)?;
let isolated = inherited(arguments.isolated_fd)?;
IgnoredWorkspace::serve_from_authorities(
RouterConfiguration {
workspace_label: arguments.workspace_label,
workspace,
isolated_state: isolated,
mountpoint: arguments.mountpoint,
global_excludes: arguments.global_excludes,
isolate_ignored: arguments.isolate_ignored,
threads: arguments.threads,
},
|| {
let mut output = io::stdout().lock();
output.write_all(b"ready\n")?;
output.flush()
},
)
}
fn inherited_exact_directory(descriptor: i32, label: &std::path::Path) -> io::Result<File> {
let inherited = inherited(descriptor)?;
let expected = fstat(&inherited)?;
let reopened = File::from(openat2(
rustix::fs::CWD,
label,
OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC | OFlags::NOFOLLOW,
Mode::empty(),
ResolveFlags::NO_MAGICLINKS | ResolveFlags::NO_SYMLINKS,
)?);
let observed = fstat(&reopened)?;
if expected.st_dev != observed.st_dev
|| expected.st_ino != observed.st_ino
|| !FileType::from_raw_mode(observed.st_mode).is_dir()
{
return Err(io::Error::other(
"namespace-local workspace differs from inherited authority",
));
}
Ok(reopened)
}
fn inherited(descriptor: i32) -> io::Result<File> {
if descriptor < 0 {
return Err(io::Error::other("router descriptor is invalid"));
}
File::open(format!("/proc/self/fd/{descriptor}"))
}
fn named<'a>(
arguments: &mut impl Iterator<Item = &'a OsString>,
name: &str,
) -> io::Result<&'a OsString> {
if arguments.next().is_none_or(|argument| argument != name) {
return Err(io::Error::other(format!(
"router argument {name} is missing"
)));
}
arguments
.next()
.ok_or_else(|| io::Error::other(format!("router argument {name} has no value")))
}
fn number<T>(value: &OsStr) -> io::Result<T>
where
T: std::str::FromStr,
{
value
.to_str()
.and_then(|value| value.parse().ok())
.ok_or_else(|| io::Error::other("router numeric argument is invalid"))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn exact_private_arguments_parse() {
let arguments = valid_arguments();
let parsed = parse(&arguments).unwrap();
assert_eq!(parsed.workspace_fd, 3);
assert_eq!(parsed.isolated_fd, 4);
assert_eq!(parsed.threads, 2);
assert!(parsed.isolate_ignored);
}
#[test]
fn malformed_private_arguments_are_refused() {
let mut extra = valid_arguments();
extra.push("unexpected".into());
assert!(parse(&extra).is_err());
let mut zero_threads = valid_arguments();
*zero_threads.last_mut().unwrap() = "0".into();
assert!(parse(&zero_threads).is_err());
let mut missing = valid_arguments();
missing.remove(2);
assert!(parse(&missing).is_err());
}
fn valid_arguments() -> Vec<OsString> {
[
PRIVATE_ROUTER_ROLE,
"--workspace-fd",
"3",
"--workspace-label",
"/workspace",
"--isolated-fd",
"4",
"--mountpoint",
"/runtime/workspace",
"--global-excludes",
"",
"--isolate-ignored",
"true",
"--threads",
"2",
]
.into_iter()
.map(OsString::from)
.collect()
}
}