Initial networking VM

Also general improvements around VMs
This commit is contained in:
2022-05-16 00:05:02 +01:00
parent 5563d1be46
commit 009dec03cf
18 changed files with 487 additions and 111 deletions

View File

@@ -46,7 +46,13 @@ in
name = "qemu-genmac";
category = "utilities";
help = "Generate MAC address suitable for QEMU";
command = ''printf "52:54:00:ab:%02x:%02x\n" $((RANDOM%256)) $((RANDOM%256))'';
command = ''printf "52:54:00:%02x:%02x:%02x\n" $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256))'';
}
{
name = "ssh-get-ed25519";
category = "utilities";
help = "Print the ed25519 pubkey for a host";
command = "${pkgs.openssh}/bin/ssh-keyscan -t ed25519 \"$1\" 2> /dev/null | awk '{ print $2 \" \" $3 }'";
}
{

View File

@@ -3,7 +3,7 @@ let
inherit (lib.my) attrsToNVList;
in
{
imports = [ ./commands.nix ./install.nix ];
imports = [ ./commands.nix ./install.nix ./vm-tasks.nix ];
env = attrsToNVList {
# starship will show this
@@ -13,6 +13,8 @@ in
''
experimental-features = nix-command flakes ca-derivations
'');
INSTALLER_SSH_OPTS = "-i .keys/deploy.key";
};
packages = with pkgs; [

View File

@@ -1,7 +1,7 @@
{ lib, pkgs, config, ... }:
let
inherit (lib) mapAttrsToList concatMapStringsSep;
inherit (lib.my) mkOpt' attrsToNVList;
inherit (lib) mapAttrsToList;
inherit (lib.my) mkOpt';
parseArgs = opts:
''
@@ -45,10 +45,10 @@ let
log "[\e[36;1minfo\e[0m]: \e[36m$*\e[0m"
}
warn() {
log "[\e[33;1minfo\e[0m]: \e[33m$*\e[0m"
log "[\e[33;1mwarn\e[0m]: \e[33m$*\e[0m"
}
error() {
log "[\e[31;1minfo\e[0m]: \e[31m$*\e[0m"
log "[\e[31;1merror\e[0m]: \e[31m$*\e[0m"
}
die() {
error "$@"

128
devshell/vm-tasks.nix Normal file
View File

@@ -0,0 +1,128 @@
{ lib, pkgs, config, ... }:
let
inherit (lib) mapAttrsToList;
inherit (lib.my) mkOpt;
parseArgs = opts:
''
POSITIONAL_ARGS=()
while [ $# -gt 0 ]; do
# shellcheck disable=SC2221,SC2222
case $1 in
${opts}
-*|--*)
die "Unknown option $1"
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
set -- "''${POSITIONAL_ARGS[@]}" # restore positional parameters
'';
common = pkgs.writeShellApplication {
name = "vm-tasks-common.sh";
runtimeInputs = with pkgs; [
openssh
];
text =
''
: "''${VM_SSH_OPTS:=}"
IFS=" " read -ra SSH_OPTS <<< "$VM_SSH_OPTS"
SSH_OPTS+=(-N)
HOST="''${1:-}"
VM="''${2:-}"
if [ -z "$HOST" ] || [ -z "$VM" ]; then
echo "usage: $0 <host> <vm> ..." >&2
exit 1
fi
SOCKS_DIR="$(mktemp -d --tmpdir vm-socks.XXXXXX)"
cleanup() {
rm -rf "$SOCKS_DIR"
}
trap cleanup EXIT
SOCKS=()
closeSocks() {
for p in "''${SOCK_PIDS[@]}"; do
kill "$p"
done
}
openSock() {
local s="$SOCKS_DIR"/"$1".sock
ssh "''${SSH_OPTS[@]}" -L "$s":/run/vms/"$VM"/"$1".sock "$HOST" &
SOCKS+=($!)
echo "$s"
}
'';
};
vmTaskOpts = with lib.types; {
options = {
help = mkOpt str null;
script = mkOpt lines "";
packages = mkOpt (listOf package) [ ];
};
};
in
{
options.my.vmTasks = with lib.types;
mkOpt (attrsOf (submodule vmTaskOpts)) { };
config = {
my.vmTasks = {
vm-tty = {
help = "Access remote VM's TTY";
packages = with pkgs; [ minicom ];
script =
''
sock="$(openSock tty)"
minicom -D unix#"$sock"
closeSocks
'';
};
vm-monitor = {
help = "Access remote VM's QEMU monitor";
packages = with pkgs; [ minicom ];
script =
''
sock="$(openSock monitor)"
minicom -D unix#"$sock"
closeSocks
'';
};
vm-viewer = {
help = "Access remote VM's display with virt-viewer";
packages = with pkgs; [ virt-viewer ];
script =
''
sock=$(openSock spice)
remote-viewer spice+unix://"$sock"
closeSocks
'';
};
};
commands = mapAttrsToList (name: cmd: {
inherit name;
inherit (cmd) help;
category = "vm-tasks";
package = pkgs.writeShellApplication {
inherit name;
runtimeInputs = cmd.packages;
text =
''
# shellcheck disable=SC1091
source "${common}/bin/vm-tasks-common.sh"
${cmd.script}
'';
};
}) config.my.vmTasks;
};
}