Compare commits

...

7 commits

2 changed files with 39 additions and 31 deletions

View file

@ -39,18 +39,23 @@ on disk
- **Process detachment**: you can log out and have your virtual machines
still running, control them via Unix sockets
## Is it better than `libvirt` ?
No. `qemush` and `libvirt` are for different use cases. `qemush` will allow you to spin up virtual machines really fast and with as little setup as possible, and aims to be nothing more than a QEMU wrapper, while `libvirt` will offer better out-of-the-box experience, with already existing pre-configurations, associated tools like the `virt-manager` GUI and a friendlier process supervision. You should use `qemush` if you care about controlling every aspect of your virtual machines, and are already used to using bare QEMU without an abstraction layer.
## Dependencies
From version 0.9.0, `qemush` is written in pure POSIX shell! The previous dependency on `bash` was removed in consequence.
All dependencies are common packages for a distribution, you'll be able to
grab them from your favorite packages sources.
- `qemu` - this is literally a QEMU wrapper so there's a chance you'll
need it
- `bash` - the `qemush` interpreter
- A POSIX compliant shell - `bash` (POSIX mode), `*ash`, `*ksh` are POSIX shells
- `coreutils` - used for basic OS operations
- `sudo` - execute commands as `qemu`
- `socat` - monitor machines via Unix sockets
- `pathof` - see [Installation instructions](#installation-instructions)
- any text editor - used for builtin function to edit launching scripts
## Installation instructions

View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash
# version=0.8.0
#!/usr/bin/env sh
# version=0.10.0
# Re-exec the script as qemu via sudo (only if needed)
[ "$(whoami)" != qemu ] && exec sudo -E -H -u qemu -- "$0" "$@"
@ -10,7 +10,6 @@ PATH="${HOME}/launchers:${HOME}/bin:${PATH}"
# Aliases
alias ls='ls --color=auto'
alias exec='exec '
shopt -s expand_aliases
# Set a restrictive umask to make sure qemu user files are private
umask 7027
@ -27,19 +26,19 @@ public_help() {
exec cat << EOF
${name}: usage:
${name} running - (default behaviour) list running VMs
${name} ls - list available VMs
${name} add <path to script> [<VM name>] - add a launching script
${name} edit <VM name> - edit VM launching script
${name} start <VM name> - start a VM
${name} attach <VM name> - attach to the VM monitor socket
${name} ls - list available VMs
${name} edit <VM name> - edit VM launching script
${name} rm <VM name> - delete launch script
${name} diskls - list available disk images
${name} diskadd <disk name> <size> - create a disk image
${name} diskrm <disk name> - delete disk image
${name} shell - start a shell as user qemu
${name} help - show this help
${name} add <path to script> [<VM name>] - add a launching script
${name} do <command> - run shell input as user qemu
${name} do <shell code> - run shell input as user qemu
${name} spice <running VM> [<TCP port>] - expose a SPICE socket to TCP
${name} help - show this help
EOF
}
@ -69,9 +68,19 @@ public_start() {
# Attach to a running virtual machine output, the latest opened if no
# argument is provided
public_attach() {
export QEMUSH_NAME="$1"
export QEMUSH_NAME
exec socat -,rawer,escape=15 "UNIX-CONNECT:$(pathof socket)"
if [ -n "$1" ]; then
QEMUSH_NAME=$1
socket_path=$(pathof socket)
else
socket_path=$(find ~/sockets/monitors -type s -printf '%T@ %p\n' | sort -r -n | head -1 | cut -d \ -f 2-)
QEMUSH_NAME=$(basename "$socket_path")
fi
printf 'Attaching to \033[1m%s\033[0m, escape with C-d (EOF)\n' "$QEMUSH_NAME"
socat -,rawer,escape=4 "UNIX-CONNECT:${socket_path}"
echo
}
# List running virtual machines
@ -193,23 +202,17 @@ public_spice() {
socat TCP-LISTEN:"${port},reuseaddr,fork" UNIX-CLIENT:"$(pathof spice)"
}
function_exists() {
declare -F \
| cut -d \ -f 3- \
| grep '^public_' \
| sed 's/^public_//' \
| grep -q "^${1}\$"
}
case "$1" in
"")
public_running
;;
running|ls|add|edit|start|attach|rm|diskls|diskadd|diskrm|shell|do|spice|help)
function=$1
shift
# Defauts to `active` if no function is supplied; else checks for a public
# function named after the argument; else fails
if [ -z "$1" ]; then
public_running
elif function_exists "$1"; then
function=$1
shift
"public_${function}" "$@"
else
error_usage
fi
"public_${function}" "$@"
;;
*)
error_usage
;;
esac