diff --git a/crates/orchestrator/Cargo.toml b/crates/orchestrator/Cargo.toml index 57af83b..bec6f5c 100644 --- a/crates/orchestrator/Cargo.toml +++ b/crates/orchestrator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "orchestrator" -version = "0.1.6" +version = "0.1.7" edition = "2024" build = "build.rs" diff --git a/crates/orchestrator/packaging/debian/postinst b/crates/orchestrator/packaging/debian/postinst index fd18478..6352d94 100644 --- a/crates/orchestrator/packaging/debian/postinst +++ b/crates/orchestrator/packaging/debian/postinst @@ -11,6 +11,12 @@ mkdir -p /etc/solstice chown root:root /etc/solstice chmod 755 /etc/solstice +# Create writable state/cache directories for the service user (for virsh/libvirt client caches) +mkdir -p /var/lib/solstice-ci/.cache/libvirt +chown -R solstice:solstice /var/lib/solstice-ci +chmod 755 /var/lib/solstice-ci +chmod -R 755 /var/lib/solstice-ci/.cache + # Reload systemd units and enable service if command -v systemctl >/dev/null 2>&1; then systemctl daemon-reload || true diff --git a/crates/orchestrator/packaging/solstice-orchestrator.service b/crates/orchestrator/packaging/solstice-orchestrator.service index 1ce42a6..83f1ce3 100644 --- a/crates/orchestrator/packaging/solstice-orchestrator.service +++ b/crates/orchestrator/packaging/solstice-orchestrator.service @@ -7,6 +7,10 @@ Wants=network-online.target Type=simple EnvironmentFile=-/etc/default/solstice-orchestrator EnvironmentFile=-/etc/solstice/orchestrator.env +# Provide sane defaults for libvirt client tools when running as system user +Environment=HOME=/var/lib/solstice-ci +Environment=XDG_CACHE_HOME=/var/lib/solstice-ci/.cache +Environment=LIBVIRT_DEFAULT_URI=qemu:///system ExecStart=/usr/bin/solstice-orchestrator Restart=on-failure RestartSec=3s diff --git a/crates/orchestrator/src/scheduler.rs b/crates/orchestrator/src/scheduler.rs index ce70da6..9fe0289 100644 --- a/crates/orchestrator/src/scheduler.rs +++ b/crates/orchestrator/src/scheduler.rs @@ -382,10 +382,31 @@ async fn discover_guest_ip_virsh(domain: &str, timeout: Duration) -> Option Attempt { - let args_vec = args.iter().map(|s| s.to_string()).collect::>(); + // Determine libvirt URI and cache/home dirs (best effort) + let uri = std::env::var("LIBVIRT_URI") + .ok() + .or_else(|| std::env::var("LIBVIRT_DEFAULT_URI").ok()) + .unwrap_or_else(|| "qemu:///system".to_string()); + let cache_base = std::env::var("XDG_CACHE_HOME").unwrap_or_else(|_| "/var/lib/solstice-ci/.cache".to_string()); + let home_dir = std::env::var("HOME").unwrap_or_else(|_| "/var/lib/solstice-ci".to_string()); + + let args_vec = { + let mut v = Vec::with_capacity(args.len() + 2); + v.push("-c".to_string()); + v.push(uri.clone()); + v.extend(args.iter().map(|s| s.to_string())); + v + }; let cmd_desc = format!("virsh {}", args_vec.join(" ")); match task::spawn_blocking(move || { - Command::new("virsh").args(&args_vec).output() + // Ensure cache dir exists to avoid virsh trying to write under /nonexistent + let _ = std::fs::create_dir_all(format!("{}/libvirt", cache_base)); + let mut cmd = Command::new("virsh"); + cmd.args(&args_vec) + .env("LIBVIRT_DEFAULT_URI", &uri) + .env("XDG_CACHE_HOME", &cache_base) + .env("HOME", &home_dir); + cmd.output() }).await { Ok(Ok(out)) => { let ok = out.status.success();