container-pid 1.0.0

Resolve container names to their PIDs
Documentation
use anyhow::{bail, Context};
use libc::pid_t;
use std::process::Command;

use crate::cmd;
use crate::result::Result;
use crate::Container;

#[derive(Clone, Debug)]
pub(crate) struct Nspawn {}

impl Container for Nspawn {
    fn lookup(&self, container_id: &str) -> Result<pid_t> {
        let output = Command::new("machinectl")
            .args(&["show", "--property=Leader", container_id])
            .output()
            .context("failed to execute 'machinectl show'")?;

        if !output.status.success() {
            let stderr = String::from_utf8_lossy(&output.stderr);
            bail!(
                "machinectl show command failed (exit status {}): {}",
                output.status,
                stderr.trim_end()
            );
        }

        let fields: Vec<&[u8]> = output.stdout.splitn(2, |c| *c == b'=').collect();
        if fields.len() != 2 {
            bail!(
                "unexpected output format from machinectl show for container '{}'",
                container_id
            );
        }

        let pid = String::from_utf8_lossy(fields[1]);

        pid.trim_end().parse::<pid_t>().with_context(|| {
            format!(
                "invalid PID '{}' from machinectl for container '{}'",
                pid.trim(),
                container_id
            )
        })
    }
    fn check_required_tools(&self) -> Result<()> {
        if cmd::which("machinectl").is_some() {
            Ok(())
        } else {
            bail!("systemd-nspawn runtime not found: 'machinectl' command is not available")
        }
    }
}