Add entrypoint option

This commit is contained in:
2026-04-04 10:16:57 +02:00
parent 8ecba5d6dc
commit 062ddab5f8
2 changed files with 278 additions and 24 deletions

View File

@@ -15,10 +15,28 @@ fn sandbox(extra_args: &[&str]) -> Command {
cmd
}
fn write_config(dir: &TempDir, content: &str) -> String {
let path = dir.path().join("config.toml");
fs::write(&path, content).expect("failed to write config");
path.to_str().unwrap().to_string()
struct ConfigFile {
_dir: TempDir,
path: String,
}
impl ConfigFile {
fn new(content: &str) -> Self {
let dir = TempDir::new().unwrap();
let path = dir.path().join("config.toml");
fs::write(&path, content).expect("failed to write config");
Self {
_dir: dir,
path: path.to_str().unwrap().to_string(),
}
}
}
impl std::ops::Deref for ConfigFile {
type Target = str;
fn deref(&self) -> &str {
&self.path
}
}
fn read_sid_from_stat(stat: &str) -> u32 {
@@ -582,8 +600,7 @@ fn config_missing_file_errors() {
#[test]
fn config_invalid_toml_errors() {
let dir = TempDir::new().unwrap();
let cfg = write_config(&dir, "not valid {{{{ toml");
let cfg = ConfigFile::new("not valid {{{{ toml");
let output = sandbox_withconfig(&["--config", &cfg])
.args(["--", "true"])
@@ -600,8 +617,7 @@ fn config_invalid_toml_errors() {
#[test]
fn config_unknown_key_errors() {
let dir = TempDir::new().unwrap();
let cfg = write_config(&dir, "hardened = true\nbogus = \"nope\"\n");
let cfg = ConfigFile::new("hardened = true\nbogus = \"nope\"\n");
let output = sandbox_withconfig(&["--config", &cfg])
.args(["--", "true"])
@@ -677,6 +693,109 @@ fn bwrap_arg_setenv_passes_through() {
);
}
#[test]
fn config_entrypoint_appends_passthrough_args() {
let cfg = ConfigFile::new(
r#"
[profile.test]
entrypoint = ["bash", "-c"]
"#,
);
let output = sandbox_withconfig(&["--config", &cfg, "--profile", "test"])
.args(["--", "echo entrypoint-works"])
.output()
.expect("failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert_eq!(
stdout, "entrypoint-works",
"expected passthrough args appended to entrypoint, got: {stdout}"
);
}
#[test]
fn config_entrypoint_falls_back_to_command_defaults() {
let cfg = ConfigFile::new(
r#"
[profile.test]
entrypoint = ["bash", "-c"]
command = ["echo default-args"]
"#,
);
let output = sandbox_withconfig(&["--config", &cfg, "--profile", "test"])
.output()
.expect("failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert_eq!(
stdout, "default-args",
"expected command defaults when no passthrough args, got: {stdout}"
);
}
#[test]
fn config_entrypoint_alone_without_command_or_passthrough() {
let cfg = ConfigFile::new(
r#"
[profile.test]
entrypoint = ["bash", "-c", "echo entrypoint-only"]
"#,
);
let output = sandbox_withconfig(&["--config", &cfg, "--profile", "test"])
.output()
.expect("failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert_eq!(
stdout, "entrypoint-only",
"expected entrypoint to run on its own, got: {stdout}"
);
}
#[test]
fn config_command_alone_without_passthrough() {
let cfg = ConfigFile::new(
r#"
[profile.test]
command = ["bash", "-c", "echo command-only"]
"#,
);
let output = sandbox_withconfig(&["--config", &cfg, "--profile", "test"])
.output()
.expect("failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert_eq!(
stdout, "command-only",
"expected config command to run on its own, got: {stdout}"
);
}
#[test]
fn config_command_replaced_by_passthrough() {
let cfg = ConfigFile::new(
r#"
[profile.test]
command = ["bash", "-c", "echo should-not-see-this"]
"#,
);
let output = sandbox_withconfig(&["--config", &cfg, "--profile", "test"])
.args(["--", "bash", "-c", "echo replaced"])
.output()
.expect("failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert_eq!(
stdout, "replaced",
"expected passthrough to replace config command, got: {stdout}"
);
}
#[test]
fn mask_nonexistent_path_becomes_tmpfs() {
let dir = TempDir::new().unwrap();