Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/runtime/incus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ impl IncusRuntime {
/// Detect the UID of the first non-root user in the VM.
async fn detect_vm_uid(vm: &str) -> Option<String> {
// Find first user with UID >= 1000 (standard non-system user)
// Use bash -lc to get login shell PATH (NixOS needs /run/current-system/sw/bin/)
let result = run_cmd(
"incus",
&["exec", vm, "--", "bash", "-c",
&["exec", vm, "--", "bash", "-lc",
"awk -F: '$3 >= 1000 && $3 < 65534 { print $3; exit }' /etc/passwd"],
).await.ok()?;
let uid = result.stdout.trim().to_string();
Expand All @@ -85,9 +86,10 @@ impl IncusRuntime {

/// Detect the HOME directory for a given UID in the VM.
async fn detect_vm_home(vm: &str, uid: &str) -> String {
// Use bash -lc to get login shell PATH (getent is in /run/current-system/sw/bin/ on NixOS)
let result = run_cmd(
"incus",
&["exec", vm, "--", "bash", "-c",
&["exec", vm, "--", "bash", "-lc",
&format!("getent passwd {uid} | cut -d: -f6")],
).await;
match result {
Expand Down
13 changes: 8 additions & 5 deletions src/sandbox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ impl SandboxManager {
}

// Check if Zellij is available in the VM
let zellij_check = runtime.exec_cmd(name, &["which", "zellij"], false).await;
// Use bash -lc to get login shell PATH (NixOS puts binaries in /run/current-system/sw/bin/)
let zellij_check = runtime.exec_cmd(name, &["bash", "-lc", "which zellij"], false).await;
let has_zellij = zellij_check.is_ok() && zellij_check.unwrap().exit_code == 0;

if !has_zellij {
Expand Down Expand Up @@ -293,22 +294,23 @@ impl SandboxManager {

// Always clean up dead sessions first, then check for alive ones.
// `zellij delete-all-sessions` removes only dead (EXITED) sessions.
// Use bash -lc for NixOS PATH compatibility.
let _ = runtime
.exec_cmd(name, &["zellij", "delete-all-sessions", "-y"], false)
.exec_cmd(name, &["bash", "-lc", "zellij delete-all-sessions -y"], false)
.await;

if force_new_session {
// Kill the live session so we can start fresh
let kill_cmd = format!("zellij kill-session {session_name} 2>/dev/null; true");
let _ = runtime
.exec_cmd(name, &["bash", "-c", &kill_cmd], false)
.exec_cmd(name, &["bash", "-lc", &kill_cmd], false)
.await;
}

// Check if a live session exists
let list_cmd = format!("zellij list-sessions 2>/dev/null | grep -q '{session_name}'");
let session_alive = runtime
.exec_cmd(name, &["bash", "-c", &list_cmd], false)
.exec_cmd(name, &["bash", "-lc", &list_cmd], false)
.await
.map(|r| r.exit_code == 0)
.unwrap_or(false);
Expand Down Expand Up @@ -404,7 +406,8 @@ impl SandboxManager {

/// Probe for zsh in the VM, fall back to bash.
async fn probe_shell(runtime: &dyn crate::runtime::Runtime, name: &str) -> String {
let probe = runtime.exec_cmd(name, &["which", "zsh"], false).await;
// Use bash -lc to get login shell PATH (NixOS puts binaries in /run/current-system/sw/bin/)
let probe = runtime.exec_cmd(name, &["bash", "-lc", "which zsh"], false).await;
if probe.is_ok() && probe.unwrap().exit_code == 0 {
"zsh".to_string()
} else {
Expand Down
Loading