From 637b170cc5f85269f93bbe9bcd900eee4e54b2fc Mon Sep 17 00:00:00 2001 From: damocles Date: Tue, 2 Jun 2026 00:52:56 +0200 Subject: [PATCH 1/2] fix(#1052): use full nginx path in systemd-run reload (exit 203 = EXEC) --- hive-c0re/src/gateway_nginx.rs | 16 +++++++++++----- nix/modules/hive-gateway.nix | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/hive-c0re/src/gateway_nginx.rs b/hive-c0re/src/gateway_nginx.rs index 5dc4320f..a5bd79af 100644 --- a/hive-c0re/src/gateway_nginx.rs +++ b/hive-c0re/src/gateway_nginx.rs @@ -291,17 +291,23 @@ fn reload_gateway_nginx() { let success = match state.as_str() { "active" => { // nginx master is running — SIGHUP is the zero-downtime path. - // `systemd-run --machine=hive-gateway --quiet --wait -- nginx - // -s reload` runs the signal inside the container and exits - // with the nginx exit code. `--` separates systemd-run flags - // from the command. + // `systemd-run --machine=hive-gateway --quiet --wait -- + // /run/current-system/sw/bin/nginx -s reload` runs the + // signal inside the container and exits with the nginx exit + // code. Full binary path required — systemd-run's limited + // PATH misses /run/current-system/sw/bin/. `--` separates + // systemd-run flags from the command. let status = std::process::Command::new("systemd-run") .args([ "--machine=hive-gateway", "--quiet", "--wait", "--", - "nginx", + // Full path required: systemd-run executes with a + // limited PATH that doesn't include NixOS's + // /run/current-system/sw/bin/ — plain "nginx" yields + // exit 203 (EXEC failure). + "/run/current-system/sw/bin/nginx", "-s", "reload", ]) diff --git a/nix/modules/hive-gateway.nix b/nix/modules/hive-gateway.nix index 851e8538..0f69b675 100644 --- a/nix/modules/hive-gateway.nix +++ b/nix/modules/hive-gateway.nix @@ -421,7 +421,8 @@ in }; # nginx reload is triggered from the HOST side by hive-c0re - # via `systemd-run --machine=hive-gateway nginx -s reload` + # via `systemd-run --machine=hive-gateway /run/current-system/sw/bin/nginx -s reload` + # (full path required — systemd-run's limited PATH misses /run/current-system/sw/bin/) # after each agents.conf write. A path unit watching the # bind-mounted file inside the container was tried first # (A path unit inside the container was tried but IN_MOVED_TO from an atomic rename on the host From 9d11e5b6d6dcc5b3580eb8ec0d5dbfa2c0296daf Mon Sep 17 00:00:00 2001 From: damocles Date: Tue, 2 Jun 2026 01:00:48 +0200 Subject: [PATCH 2/2] fix(#1052): use systemctl reload nginx instead of systemd-run --- hive-c0re/src/gateway_nginx.rs | 51 +++++++--------------------------- nix/modules/hive-gateway.nix | 4 +-- 2 files changed, 12 insertions(+), 43 deletions(-) diff --git a/hive-c0re/src/gateway_nginx.rs b/hive-c0re/src/gateway_nginx.rs index a5bd79af..4e6937e3 100644 --- a/hive-c0re/src/gateway_nginx.rs +++ b/hive-c0re/src/gateway_nginx.rs @@ -290,48 +290,17 @@ fn reload_gateway_nginx() { let state = nginx_active_state(); let success = match state.as_str() { "active" => { - // nginx master is running — SIGHUP is the zero-downtime path. - // `systemd-run --machine=hive-gateway --quiet --wait -- - // /run/current-system/sw/bin/nginx -s reload` runs the - // signal inside the container and exits with the nginx exit - // code. Full binary path required — systemd-run's limited - // PATH misses /run/current-system/sw/bin/. `--` separates - // systemd-run flags from the command. - let status = std::process::Command::new("systemd-run") - .args([ - "--machine=hive-gateway", - "--quiet", - "--wait", - "--", - // Full path required: systemd-run executes with a - // limited PATH that doesn't include NixOS's - // /run/current-system/sw/bin/ — plain "nginx" yields - // exit 203 (EXEC failure). - "/run/current-system/sw/bin/nginx", - "-s", - "reload", - ]) - .status(); - match status { - Ok(s) if s.success() => { - tracing::debug!("gateway nginx reload signal sent"); - true - } - Ok(s) => { - tracing::warn!( - exit_code = ?s.code(), - "gateway nginx reload exited non-zero — will retry next poll tick" - ); - false - } - Err(e) => { - tracing::warn!( - error = %e, - "failed to invoke systemd-run for gateway nginx reload — will retry" - ); - false - } + // nginx master is running — ask systemd to reload the unit + // (SIGHUP to master, zero-downtime worker replacement). + // `systemctl -M hive-gateway reload nginx` lets systemd + // resolve the binary path; avoids the exit-203 (EXEC) + // failure that `systemd-run -- nginx` hit on NixOS where + // the limited transient-unit PATH misses /run/current-system/sw/bin/. + let ok = gateway_systemctl(&["reload", "nginx"]); + if ok { + tracing::debug!("gateway nginx reload signal sent"); } + ok } "failed" => { // Unit hit start-limit (e.g. repeated nginx -t failures from diff --git a/nix/modules/hive-gateway.nix b/nix/modules/hive-gateway.nix index 0f69b675..036b569b 100644 --- a/nix/modules/hive-gateway.nix +++ b/nix/modules/hive-gateway.nix @@ -421,8 +421,8 @@ in }; # nginx reload is triggered from the HOST side by hive-c0re - # via `systemd-run --machine=hive-gateway /run/current-system/sw/bin/nginx -s reload` - # (full path required — systemd-run's limited PATH misses /run/current-system/sw/bin/) + # via `systemctl -M hive-gateway reload nginx` — lets systemd + # resolve the nginx binary path, avoiding exit-203 EXEC failures. # after each agents.conf write. A path unit watching the # bind-mounted file inside the container was tried first # (A path unit inside the container was tried but IN_MOVED_TO from an atomic rename on the host