Skip to content

Commit 5db97a6

Browse files
committed
Add support for --init
1 parent 2a840e7 commit 5db97a6

2 files changed

Lines changed: 49 additions & 1 deletion

File tree

composefs-run/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,10 @@ pub(crate) struct Cli {
317317
#[clap(short = 'i', long, hide = true)]
318318
interactive: bool,
319319

320+
/// Run an init process (catatonit) as PID 1 to forward signals
321+
#[clap(long)]
322+
init: bool,
323+
320324
/// Add a host device to the container (HOST_PATH[:CONTAINER_PATH[:PERMISSIONS]])
321325
#[clap(long, value_parser = clap::value_parser!(DeviceSpec))]
322326
device: Vec<DeviceSpec>,

composefs-run/src/run.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,25 @@ fn setup_netns(bundle_dir: &Path) -> Result<PathBuf> {
371371
Ok(netns_path)
372372
}
373373

374+
const CATATONIT_PATHS: &[&str] = &[
375+
"/usr/libexec/catatonit/catatonit",
376+
"/usr/libexec/podman/catatonit",
377+
"/usr/local/libexec/podman/catatonit",
378+
"/usr/local/lib/podman/catatonit",
379+
"/usr/libexec/catatonit",
380+
"/usr/bin/catatonit",
381+
];
382+
383+
fn find_catatonit() -> Result<PathBuf> {
384+
for path in CATATONIT_PATHS {
385+
let p = Path::new(path);
386+
if p.exists() {
387+
return Ok(p.to_owned());
388+
}
389+
}
390+
anyhow::bail!("catatonit not found")
391+
}
392+
374393
fn setup_pasta(netns_path: &Path, pid_file: &Path, publish: &[PortSpec]) -> Result<i32> {
375394
let mut pasta_cmd = Command::new("pasta");
376395
pasta_cmd
@@ -556,7 +575,7 @@ fn build_runtime_spec(
556575

557576
// ── Resolve image + CLI into effective values ───────────────────────
558577

559-
let args = if cli.cmd.is_empty() {
578+
let mut args = if cli.cmd.is_empty() {
560579
let mut args = oci_config.entrypoint().clone().unwrap_or_default();
561580
args.extend(oci_config.cmd().clone().unwrap_or_default());
562581
ensure!(
@@ -568,6 +587,15 @@ fn build_runtime_spec(
568587
cli.cmd.clone()
569588
};
570589

590+
let init_path = if cli.init {
591+
let path = find_catatonit().context("--init requires catatonit")?;
592+
args.insert(0, "/dev/init".into());
593+
args.insert(1, "--".into());
594+
Some(path)
595+
} else {
596+
None
597+
};
598+
571599
let mut env: Vec<String> = oci_config.env().clone().unwrap_or_else(|| {
572600
vec!["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin".into()]
573601
});
@@ -932,6 +960,22 @@ fn build_runtime_spec(
932960
)?;
933961
mounts.extend(etc_mounts);
934962

963+
if let Some(ref path) = init_path {
964+
mounts.push(
965+
MountBuilder::default()
966+
.typ("bind")
967+
.source(path)
968+
.destination("/dev/init")
969+
.options(vec![
970+
"bind".into(),
971+
"ro".into(),
972+
"nosuid".into(),
973+
"nodev".into(),
974+
])
975+
.build()?,
976+
);
977+
}
978+
935979
spec.set_mounts(Some(mounts));
936980

937981
// Poststop hook: unmount bundle and clean up the container directory

0 commit comments

Comments
 (0)