Use SCRIPT_DIR, add sshpass and auto-mount workspaces, update flakes
This commit is contained in:
parent
8534f7efb9
commit
9aa72fade7
8 changed files with 292 additions and 413 deletions
7
bin/qvm
7
bin/qvm
|
|
@ -8,8 +8,11 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
# Determine script directory for locating sibling scripts
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# Source common library (use QVM_LIB_DIR from wrapper or relative path for dev)
|
||||
source "${QVM_LIB_DIR:-$(dirname "$0")/../lib}/common.sh"
|
||||
source "${QVM_LIB_DIR:-${SCRIPT_DIR}/../lib}/common.sh"
|
||||
|
||||
readonly VERSION="0.1.0"
|
||||
|
||||
|
|
@ -72,7 +75,7 @@ main() {
|
|||
start|stop|run|ssh|status|rebuild|reset)
|
||||
# Route to the appropriate qvm-* script
|
||||
# Use exec to replace this process with the subcommand
|
||||
exec "qvm-${subcommand}" "$@"
|
||||
exec "${SCRIPT_DIR}/qvm-${subcommand}" "$@"
|
||||
;;
|
||||
help|--help|-h)
|
||||
show_help
|
||||
|
|
|
|||
|
|
@ -28,9 +28,17 @@ ensure_user_flake() {
|
|||
log_info "User flake not found, copying default template..."
|
||||
|
||||
# Determine default flake location
|
||||
# In installed version: $QVM_LIB_DIR/../flake/default-vm/
|
||||
# In installed version: $QVM_LIB_DIR/../share/qvm/default-vm/
|
||||
# In development: $(dirname "$0")/../flake/default-vm/
|
||||
local default_flake_dir="$QVM_LIB_DIR/../flake/default-vm"
|
||||
local default_flake_dir
|
||||
|
||||
# Try installed location first
|
||||
if [[ -d "$QVM_LIB_DIR/../share/qvm/default-vm" ]]; then
|
||||
default_flake_dir="$QVM_LIB_DIR/../share/qvm/default-vm"
|
||||
else
|
||||
# Fall back to development location
|
||||
default_flake_dir="$(dirname "$(readlink -f "$0")")/../flake/default-vm"
|
||||
fi
|
||||
|
||||
if [[ ! -d "$default_flake_dir" ]]; then
|
||||
die "Default flake template not found at: $default_flake_dir"
|
||||
|
|
|
|||
54
bin/qvm-run
54
bin/qvm-run
|
|
@ -95,6 +95,34 @@ register_workspace() {
|
|||
return 1 # Indicate new workspace added
|
||||
}
|
||||
|
||||
#
|
||||
# ensure_workspace_mounted - Mount workspace in VM if not already mounted
|
||||
# Args: $1 - SSH port
|
||||
# $2 - mount tag (e.g., ws_abc123)
|
||||
# $3 - guest path (e.g., /workspace/abc123)
|
||||
# Returns: 0 on success
|
||||
#
|
||||
ensure_workspace_mounted() {
|
||||
local ssh_port="$1"
|
||||
local mount_tag="$2"
|
||||
local guest_path="$3"
|
||||
|
||||
# SSH into VM and mount the workspace
|
||||
# - mkdir creates the mount point if missing
|
||||
# - mount attempts to mount the 9p virtfs
|
||||
# - || true ensures we don't fail if already mounted
|
||||
sshpass -p root ssh -o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o LogLevel=ERROR \
|
||||
-o PubkeyAuthentication=no \
|
||||
-o PasswordAuthentication=yes \
|
||||
-p "$ssh_port" \
|
||||
root@localhost \
|
||||
"mkdir -p '$guest_path' && mount -t 9p -o trans=virtio,version=9p2000.L,msize=104857600 '$mount_tag' '$guest_path' 2>/dev/null || true" >/dev/null 2>&1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# is_workspace_mounted - Check if workspace is actually mounted in VM
|
||||
# Args: $1 - SSH port
|
||||
|
|
@ -106,9 +134,11 @@ is_workspace_mounted() {
|
|||
local guest_path="$2"
|
||||
|
||||
# SSH into VM and check if guest path exists and is a directory
|
||||
if ssh -o StrictHostKeyChecking=no \
|
||||
if sshpass -p root ssh -o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o LogLevel=ERROR \
|
||||
-o PubkeyAuthentication=no \
|
||||
-o PasswordAuthentication=yes \
|
||||
-p "$ssh_port" \
|
||||
root@localhost \
|
||||
"test -d '$guest_path'" 2>/dev/null; then
|
||||
|
|
@ -169,14 +199,22 @@ main() {
|
|||
local ssh_port
|
||||
ssh_port=$(get_ssh_port)
|
||||
|
||||
# Check if workspace is actually mounted in VM
|
||||
# Get mount tag from workspaces.json
|
||||
local mount_tag
|
||||
mount_tag=$(jq -r --arg path "$workspace_path" '.[] | select(.host_path == $path) | .mount_tag' "$QVM_WORKSPACES_FILE")
|
||||
|
||||
# Ensure workspace is mounted (auto-mount if not)
|
||||
log_info "Ensuring workspace is mounted..."
|
||||
ensure_workspace_mounted "$ssh_port" "$mount_tag" "$guest_path"
|
||||
|
||||
# Verify workspace is actually mounted
|
||||
if ! is_workspace_mounted "$ssh_port" "$guest_path"; then
|
||||
log_error "Workspace not mounted in VM"
|
||||
log_error "Failed to mount workspace in VM"
|
||||
echo ""
|
||||
echo "This workspace was just registered but is not mounted in the VM."
|
||||
echo "Workspaces must be mounted at VM start time."
|
||||
echo "The workspace could not be mounted automatically."
|
||||
echo "This may indicate the VM was started before this workspace was registered."
|
||||
echo ""
|
||||
echo "Please restart the VM to mount this workspace:"
|
||||
echo "Please restart the VM to properly configure the workspace:"
|
||||
echo " qvm stop"
|
||||
echo " qvm start"
|
||||
echo ""
|
||||
|
|
@ -185,14 +223,18 @@ main() {
|
|||
fi
|
||||
|
||||
# Build SSH command
|
||||
# - Use sshpass for automated password auth (password: root)
|
||||
# - Use -t if stdin is a TTY (for interactive commands)
|
||||
# - Suppress SSH warnings (ephemeral VM, host keys change)
|
||||
# - cd to guest path and execute command
|
||||
local ssh_cmd=(
|
||||
sshpass -p root
|
||||
ssh
|
||||
-o StrictHostKeyChecking=no
|
||||
-o UserKnownHostsFile=/dev/null
|
||||
-o LogLevel=ERROR
|
||||
-o PubkeyAuthentication=no
|
||||
-o PasswordAuthentication=yes
|
||||
-p "$ssh_port"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -85,12 +85,15 @@ main() {
|
|||
local port
|
||||
port=$(get_ssh_port)
|
||||
|
||||
# Build SSH command
|
||||
# Build SSH command with sshpass for automated password auth
|
||||
local ssh_cmd=(
|
||||
sshpass -p root
|
||||
ssh
|
||||
-o StrictHostKeyChecking=no
|
||||
-o UserKnownHostsFile=/dev/null
|
||||
-o LogLevel=ERROR # Suppress host key warnings
|
||||
-o PubkeyAuthentication=no # Use password auth (password: root)
|
||||
-o PasswordAuthentication=yes
|
||||
-p "$port"
|
||||
root@localhost
|
||||
)
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ mount_workspaces() {
|
|||
local i=0
|
||||
while (( i < workspace_count )); do
|
||||
local path mount_tag
|
||||
path=$(jq -r ".[$i].path" "$QVM_WORKSPACES_FILE")
|
||||
path=$(jq -r ".[$i].host_path" "$QVM_WORKSPACES_FILE")
|
||||
mount_tag=$(jq -r ".[$i].mount_tag" "$QVM_WORKSPACES_FILE")
|
||||
|
||||
if [[ -z "$path" || -z "$mount_tag" || "$path" == "null" || "$mount_tag" == "null" ]]; then
|
||||
|
|
@ -93,9 +93,9 @@ mount_workspaces() {
|
|||
fi
|
||||
|
||||
log_info " - $path -> $mount_tag"
|
||||
cmd_array+=(-virtfs "local,path=$path,mount_tag=$mount_tag,security_model=mapped-xattr,trans=virtio,version=9p2000.L,msize=104857600")
|
||||
cmd_array+=(-virtfs "local,path=$path,mount_tag=$mount_tag,security_model=mapped-xattr")
|
||||
|
||||
(( i++ ))
|
||||
(( i++ )) || true # Prevent set -e from exiting when i was 0
|
||||
done
|
||||
}
|
||||
|
||||
|
|
@ -173,10 +173,11 @@ main() {
|
|||
-device "virtio-net-pci,netdev=net0"
|
||||
|
||||
# 9p mounts for shared caches (security_model=mapped-xattr for proper permissions)
|
||||
-virtfs "local,path=$QVM_CARGO_HOME,mount_tag=cargo_home,security_model=mapped-xattr,trans=virtio,version=9p2000.L,msize=104857600"
|
||||
-virtfs "local,path=$QVM_CARGO_TARGET,mount_tag=cargo_target,security_model=mapped-xattr,trans=virtio,version=9p2000.L,msize=104857600"
|
||||
-virtfs "local,path=$QVM_PNPM_STORE,mount_tag=pnpm_store,security_model=mapped-xattr,trans=virtio,version=9p2000.L,msize=104857600"
|
||||
-virtfs "local,path=$QVM_SCCACHE,mount_tag=sccache,security_model=mapped-xattr,trans=virtio,version=9p2000.L,msize=104857600"
|
||||
# Note: trans, version, msize are kernel-side mount options (in NixOS flake), not QEMU options
|
||||
-virtfs "local,path=$QVM_CARGO_HOME,mount_tag=cargo_home,security_model=mapped-xattr"
|
||||
-virtfs "local,path=$QVM_CARGO_TARGET,mount_tag=cargo_target,security_model=mapped-xattr"
|
||||
-virtfs "local,path=$QVM_PNPM_STORE,mount_tag=pnpm_store,security_model=mapped-xattr"
|
||||
-virtfs "local,path=$QVM_SCCACHE,mount_tag=sccache,security_model=mapped-xattr"
|
||||
)
|
||||
|
||||
# Add workspace mounts from registry
|
||||
|
|
@ -187,8 +188,8 @@ main() {
|
|||
# Serial console to log file
|
||||
-serial "file:$QVM_SERIAL_LOG"
|
||||
|
||||
# No graphics
|
||||
-nographic
|
||||
# No graphics (use -display none for daemonized mode)
|
||||
-display none
|
||||
|
||||
# Daemonize with PID file
|
||||
-daemonize
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue