fix(#2284): replace nixos-container kill with machinectl kill SIGKILL
nixos-container has no kill verb. The KillContainer priv request was calling nixos-container kill which always fails. Replace with: machinectl kill <name> --signal=SIGKILL which sends SIGKILL to all processes in the container — the correct semantics for a forced shutdown (called after graceful stop has been attempted). Add a machinectl_run helper alongside container_run so callers stay consistent.
This commit is contained in:
parent
c7c156e57b
commit
fa944d1213
2 changed files with 35 additions and 2 deletions
|
|
@ -172,7 +172,11 @@ async fn exec(req: PrivRequest, writer: &mut OwnedWriteHalf) -> Result<(String,
|
|||
|
||||
PrivRequest::KillContainer { ref name } => {
|
||||
validate_container_name(name)?;
|
||||
container_run(&["kill", &container_system_name(name)]).await
|
||||
// nixos-container has no kill verb. Use machinectl to send SIGKILL
|
||||
// to all processes in the container — the right semantics for a
|
||||
// forced shutdown after a graceful stop has already been attempted.
|
||||
let machine = container_system_name(name);
|
||||
machinectl_run(&["kill", &machine, "--signal=SIGKILL"]).await
|
||||
}
|
||||
|
||||
PrivRequest::UpdateContainer { ref name, stream } => {
|
||||
|
|
@ -1026,6 +1030,34 @@ async fn container_run(args: &[&str]) -> Result<(String, String)> {
|
|||
Ok((stdout, stderr))
|
||||
}
|
||||
|
||||
/// Invoke `machinectl` with the given args, log output to journald.
|
||||
/// Used for operations that nixos-container doesn't expose (e.g. sending
|
||||
/// signals to running containers).
|
||||
async fn machinectl_run(args: &[&str]) -> Result<(String, String)> {
|
||||
let out = Command::new("machinectl")
|
||||
.args(args)
|
||||
.output()
|
||||
.await
|
||||
.context("invoke machinectl")?;
|
||||
let stdout = String::from_utf8_lossy(&out.stdout).into_owned();
|
||||
let stderr = String::from_utf8_lossy(&out.stderr).into_owned();
|
||||
for line in stdout.lines() {
|
||||
tracing::info!(target: "machinectl", "{line}");
|
||||
}
|
||||
for line in stderr.lines() {
|
||||
tracing::warn!(target: "machinectl", "{line}");
|
||||
}
|
||||
if !out.status.success() {
|
||||
bail!(
|
||||
"machinectl {} failed ({}): {}",
|
||||
args.join(" "),
|
||||
out.status,
|
||||
stderr.trim()
|
||||
);
|
||||
}
|
||||
Ok((stdout, stderr))
|
||||
}
|
||||
|
||||
/// Invoke `nixos-container` with the given args and forward output lines
|
||||
/// to the caller as `PrivEvent::Line` messages in real time, logging each
|
||||
/// line to journald as it arrives. Returns `(String::new(), String::new())`
|
||||
|
|
|
|||
|
|
@ -230,7 +230,8 @@ pub enum PrivRequest {
|
|||
/// `nixos-container stop <name>`
|
||||
StopContainer { name: String },
|
||||
|
||||
/// `nixos-container kill <name>`
|
||||
/// `machinectl kill <name> --signal=SIGKILL` — force-kills all processes
|
||||
/// in the container. nixos-container has no kill verb.
|
||||
KillContainer { name: String },
|
||||
|
||||
/// `nixos-container update <name> --flake <flake_ref>`
|
||||
|
|
|
|||
Loading…
Reference in a new issue