Skip to content

Commit f36bdef

Browse files
committed
Add support for catatonin, and add --no-init
1 parent 2a840e7 commit f36bdef

3 files changed

Lines changed: 55 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ tracking.
2222
- No detached mode, always assumes `-i`.
2323
- By default, writable overlays are transient, stored in /var/tmp.
2424
This can be overridden with `--overlay-dir`
25+
- By default runs catatonit in the container to forward signals
2526

2627
### Quick start
2728

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+
/// Disable the default init process (catatonit) as PID 1
321+
#[clap(long)]
322+
no_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: 50 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!(
@@ -610,6 +629,20 @@ fn build_runtime_spec(
610629
SystemdMode::Auto => is_systemd_command(&args),
611630
};
612631

632+
let use_init = !cli.no_init && !systemd_mode;
633+
let init_path = if use_init {
634+
match find_catatonit() {
635+
Ok(path) => {
636+
args.insert(0, "/dev/init".into());
637+
args.insert(1, "--".into());
638+
Some(path)
639+
}
640+
Err(_) => None,
641+
}
642+
} else {
643+
None
644+
};
645+
613646
let host_network = netns_path.is_none();
614647

615648
// Capabilities: start from podman's default set (containers.conf),
@@ -932,6 +965,22 @@ fn build_runtime_spec(
932965
)?;
933966
mounts.extend(etc_mounts);
934967

968+
if let Some(ref path) = init_path {
969+
mounts.push(
970+
MountBuilder::default()
971+
.typ("bind")
972+
.source(path)
973+
.destination("/dev/init")
974+
.options(vec![
975+
"bind".into(),
976+
"ro".into(),
977+
"nosuid".into(),
978+
"nodev".into(),
979+
])
980+
.build()?,
981+
);
982+
}
983+
935984
spec.set_mounts(Some(mounts));
936985

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

0 commit comments

Comments
 (0)