fix(#702): give hive-priv a PATH; route forge/matrix list through priv
hive-priv had no PATH, so the nixos-container it runs for every container op (incl. lifecycle::list) failed ENOENT. build_all swallows that into an empty list — the 'no managed containers' symptom. Give the helper the minimal set nixos-container shells out to (nixos-container, nix, util-linux, e2fsprogs) on top of the systemd/coreutils/findutils already in the unit PATH, rather than the whole system profile. Also route forge/matrix is_present() through priv_client::list_containers instead of spawning nixos-container directly from unprivileged hive-c0re.
This commit is contained in:
parent
1e4066b9cb
commit
e7b6896e4c
3 changed files with 23 additions and 17 deletions
|
|
@ -70,17 +70,14 @@ fn token_path(name: &str) -> PathBuf {
|
|||
}
|
||||
|
||||
/// Probe whether `hive-forge` exists as a nixos-container. Cheap —
|
||||
/// `nixos-container list` is just a directory scan in /etc.
|
||||
/// `nixos-container list` is just a directory scan in /etc. Routed
|
||||
/// through hive-priv: `nixos-container` needs root, and hive-c0re runs
|
||||
/// unprivileged (privsep).
|
||||
pub async fn is_present() -> bool {
|
||||
let Ok(out) = Command::new("nixos-container").arg("list").output().await else {
|
||||
let Ok(stdout) = crate::priv_client::list_containers().await else {
|
||||
return false;
|
||||
};
|
||||
if !out.status.success() {
|
||||
return false;
|
||||
}
|
||||
String::from_utf8_lossy(&out.stdout)
|
||||
.lines()
|
||||
.any(|l| l.trim() == FORGE_CONTAINER)
|
||||
stdout.lines().any(|l| l.trim() == FORGE_CONTAINER)
|
||||
}
|
||||
|
||||
/// Run `forgejo admin <args>` inside the hive-forge container as the
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
use reqwest::StatusCode;
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::coordinator::Coordinator;
|
||||
|
||||
|
|
@ -55,17 +54,13 @@ fn password_path(name: &str) -> PathBuf {
|
|||
|
||||
/// Probe whether `hive-matrix` exists as a nixos-container. Cheap —
|
||||
/// `nixos-container list` is just a directory scan in /etc. Same shape
|
||||
/// as `forge::is_present`.
|
||||
/// as `forge::is_present` — routed through hive-priv since
|
||||
/// `nixos-container` needs root and hive-c0re runs unprivileged.
|
||||
pub async fn is_present() -> bool {
|
||||
let Ok(out) = Command::new("nixos-container").arg("list").output().await else {
|
||||
let Ok(stdout) = crate::priv_client::list_containers().await else {
|
||||
return false;
|
||||
};
|
||||
if !out.status.success() {
|
||||
return false;
|
||||
}
|
||||
String::from_utf8_lossy(&out.stdout)
|
||||
.lines()
|
||||
.any(|l| l.trim() == MATRIX_CONTAINER)
|
||||
stdout.lines().any(|l| l.trim() == MATRIX_CONTAINER)
|
||||
}
|
||||
|
||||
/// Read `n` cryptographic-quality bytes from `/dev/urandom` and return
|
||||
|
|
|
|||
|
|
@ -507,6 +507,20 @@ in
|
|||
# entry point; systemd starts this service on first connect.
|
||||
after = [ "hive-priv.socket" ];
|
||||
requires = [ "hive-priv.socket" ];
|
||||
# `nixos-container` is a perl script that shells out by bare name to
|
||||
# nix / nix-env / nix-instantiate (create + update), machinectl +
|
||||
# systemctl (start/stop), and find / rm / umount / chattr (destroy);
|
||||
# only nsenter + su are hardcoded. Give the helper exactly those —
|
||||
# not the whole system profile — on top of the systemd/coreutils/
|
||||
# findutils already in the default unit PATH. Without `nixos-container`
|
||||
# on PATH every container op fails ENOENT, which `build_all` silently
|
||||
# swallows into an empty list ("no managed containers").
|
||||
path = [
|
||||
pkgs.nixos-container
|
||||
pkgs.nix # nix, nix-env, nix-instantiate — create + update
|
||||
pkgs.util-linux # umount (nsenter is hardcoded in the script)
|
||||
pkgs.e2fsprogs # chattr
|
||||
];
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/hive-priv";
|
||||
Type = "simple";
|
||||
|
|
|
|||
Loading…
Reference in a new issue