qvm/bin/qvm-ssh

121 lines
3 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# qvm-ssh - Direct SSH access to the VM
#
# This script provides SSH access to the running VM:
# - Auto-starts VM if not running
# - Interactive shell by default (detects TTY)
# - Single command execution with -c flag
# - Passes through additional SSH arguments
# - Uses StrictHostKeyChecking=no for host key management
#
set -euo pipefail
# Source common library
QVM_LIB_DIR="${QVM_LIB_DIR:-$(dirname "$(readlink -f "$0")")/../lib}"
# shellcheck source=lib/common.sh
source "$QVM_LIB_DIR/common.sh"
#
# show_usage - Display help text
#
show_usage() {
cat <<EOF
Usage: qvm ssh [OPTIONS] [SSH_ARGS...]
Open an SSH session to the VM or run a single command.
OPTIONS:
-c COMMAND Run a single command instead of interactive shell
-h, --help Show this help message
EXAMPLES:
qvm ssh # Open interactive shell
qvm ssh -c "ls -la" # Run single command
qvm ssh -c "pwd" -v # Run command with SSH verbose flag
NOTES:
- VM will auto-start if not running
- SSH connects as root@localhost
- Host key checking is disabled (VM overlay is ephemeral)
- Additional SSH arguments are passed through
EOF
}
#
# main - Main execution flow
#
main() {
local command_mode=false
local command=""
local ssh_args=()
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
show_usage
exit 0
;;
-c)
if [[ $# -lt 2 ]]; then
die "Option -c requires a command argument"
fi
command_mode=true
command="$2"
shift 2
;;
*)
# Collect remaining arguments for SSH
ssh_args+=("$1")
shift
;;
esac
done
# Ensure VM is running (auto-start if needed)
if ! is_vm_running; then
log_info "VM is not running, starting it..."
"$QVM_LIB_DIR/../bin/qvm-start"
fi
# Get SSH port
local port
port=$(get_ssh_port)
# 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
)
# Add TTY flag for interactive sessions (not in command mode)
if [[ "$command_mode" = false ]] && [[ -t 0 ]]; then
ssh_cmd+=(-t)
fi
# Add any pass-through SSH arguments
if [[ ${#ssh_args[@]} -gt 0 ]]; then
ssh_cmd+=("${ssh_args[@]}")
fi
# Add command if in command mode
if [[ "$command_mode" = true ]]; then
ssh_cmd+=("$command")
fi
# Execute SSH (replace shell process)
exec "${ssh_cmd[@]}"
}
# Run main function
main "$@"