Initial networking VM
Also general improvements around VMs
This commit is contained in:
@@ -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 }'";
|
||||
}
|
||||
|
||||
{
|
||||
|
@@ -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; [
|
||||
|
@@ -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
128
devshell/vm-tasks.nix
Normal 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;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user