add run-qemu --nic argument

This commit is contained in:
Niklas Gollenstede 2023-10-08 16:49:55 +02:00
parent 7bb3dc480f
commit 2bbefc97c3
5 changed files with 24 additions and 16 deletions

Binary file not shown.

View File

@ -227,7 +227,7 @@ in rec {
PS1=''${PS1/\\$/\\[\\e[93m\\](${name})\\[\\e[97m\\]\\$} PS1=''${PS1/\\$/\\[\\e[93m\\](${name})\\[\\e[97m\\]\\$}
source "'"$self"'" ; PATH=$hostPath source "'"$self"'" ; PATH=$hostPath
') -i -s ':' "$@" ') -i -s ':' "$@" # execute : (noop) as command, preserve argv
fi fi
# provide installer tools (not necessarily for system.pkgs.config.hostPlatform) # provide installer tools (not necessarily for system.pkgs.config.hostPlatform)

View File

@ -200,7 +200,7 @@ function install-system-to {( set -u # 1: mnt, 2?: topLevel
else else
( set +x ; echo "Installation done! This shell is in a chroot in the mounted system for inspection. Exiting the shell will unmount the system." 1>&2 ) ( set +x ; echo "Installation done! This shell is in a chroot in the mounted system for inspection. Exiting the shell will unmount the system." 1>&2 )
fi fi
LC_ALL=C PATH=$PATH:@{native.util-linux}/bin @{native.nixos-install-tools}/bin/nixos-enter --root $mnt -- /nix/var/nix/profiles/system/sw/bin/bash -c 'source /etc/set-environment ; CHROOT_DIR="'"$mnt"'" mnt=/ exec "'"$self"'" bash' || exit # +o monitor LC_ALL=C PATH=$PATH:@{native.util-linux}/bin @{native.nixos-install-tools}/bin/nixos-enter --root $mnt -- /nix/var/nix/profiles/system/sw/bin/bash -c 'source /etc/set-environment ; NIXOS_INSTALL_BOOTLOADER=1 CHROOT_DIR="'"$mnt"'" mnt=/ exec "'"$self"'" bash' || exit # +o monitor
fi fi
mkdir -p $mnt/var/lib/systemd/timesync && touch $mnt/var/lib/systemd/timesync/clock || true # save current time mkdir -p $mnt/var/lib/systemd/timesync && touch $mnt/var/lib/systemd/timesync/clock || true # save current time

View File

@ -58,9 +58,17 @@ declare-flag run-qemu efi-vars "path" "For »--efi« systems, path to a fil
declare-flag run-qemu graphic "" "Open a graphical window even of the target system logs to serial and not (explicitly) TTY1." declare-flag run-qemu graphic "" "Open a graphical window even of the target system logs to serial and not (explicitly) TTY1."
declare-flag run-qemu install "[1|always]" "If any of the guest system's disk images does not exist, perform the its installation before starting the VM. If set to »always«, always install before starting the VM. With this flag set, »diskImages« defaults to paths in »/tmp/." declare-flag run-qemu install "[1|always]" "If any of the guest system's disk images does not exist, perform the its installation before starting the VM. If set to »always«, always install before starting the VM. With this flag set, »diskImages« defaults to paths in »/tmp/."
declare-flag run-qemu mem "num" "VM RAM in MiB (»qemu -m«)." declare-flag run-qemu mem "num" "VM RAM in MiB (»qemu -m«)."
declare-flag run-qemu nat-fw "forwards" "Port forwards to the guest's NATed NIC. E.g: »--nat-fw=:8000-:8000,:8001-:8001,127.0.0.1:2022-:22«."
declare-flag run-qemu no-kvm "" "Do not rey to use (or complain about the unavailability of) KVM." declare-flag run-qemu no-kvm "" "Do not rey to use (or complain about the unavailability of) KVM."
declare-flag run-qemu nat-fw "forwards" "Port forwards to the guest's NATed NIC. E.g: »--nat-fw=:8000-:8000,:8001-:8001,127.0.0.1:2022-:22«."
declare-flag run-qemu no-nat "" "Do not provide a NATed NIC to the guest." declare-flag run-qemu no-nat "" "Do not provide a NATed NIC to the guest."
declare-flag run-qemu nic "type[,options]" "Create an additional network interface using the »-nic« flag. Automatically sets a decent »model« and a »mac« derived from »config.networking.hostId«.
Example 1 (connect two VMs, unprivileged):
$ ... --nic=socket,listen=:4321 # once
$ ... --nic=socket,connect=:4321 # once
Example 2 (connect many VMs, unprivileged):
$ nix shell nixpkgs#vde2 --command vde_switch -sock /tmp/vm-net
$ ... --nic=vde,sock=/tmp/vm-net # multiple times
"
declare-flag run-qemu no-serial "" "Do not connect the calling terminal to a serial adapter the guest can log to and open a terminal on the guests serial, as would be the default if the guests logs to ttyS0." declare-flag run-qemu no-serial "" "Do not connect the calling terminal to a serial adapter the guest can log to and open a terminal on the guests serial, as would be the default if the guests logs to ttyS0."
declare-flag run-qemu share "decls" "Host dirs to make available as network shares for the guest, as space separated list of »name:host-path,options. E.g. »--share='foo:/home/user/foo,readonly=on bar:/tmp/bar«. In the VM hte share can be mounted with: »$ mount -t 9p -o trans=virtio -o version=9p2000.L -o msize=4194304 -o ro foo /foo«." declare-flag run-qemu share "decls" "Host dirs to make available as network shares for the guest, as space separated list of »name:host-path,options. E.g. »--share='foo:/home/user/foo,readonly=on bar:/tmp/bar«. In the VM hte share can be mounted with: »$ mount -t 9p -o trans=virtio -o version=9p2000.L -o msize=4194304 -o ro foo /foo«."
declare-flag run-qemu smp "num" "Number of guest CPU cores." declare-flag run-qemu smp "num" "Number of guest CPU cores."
@ -94,7 +102,7 @@ function run-qemu {
qemu+=( -m ${args[mem]:-2048} ) qemu+=( -m ${args[mem]:-2048} )
if [[ ${args[smp]:-} ]] ; then qemu+=( -smp ${args[smp]} ) ; fi if [[ ${args[smp]:-} ]] ; then qemu+=( -smp ${args[smp]} ) ; fi
if [[ @{config.boot.loader.systemd-boot.enable} || ${args[efi]:-} ]] ; then # UEFI. Otherwise it boots SeaBIOS. if [[ @{config.virtualisation.useEFIBoot:-} || @{config.boot.loader.systemd-boot.enable} || ${args[efi]:-} ]] ; then # UEFI. Otherwise it boots SeaBIOS.
local ovmf ; ovmf=$( build-lazy @{pkgs.OVMF.drvPath!unsafeDiscardStringContext} fd ) || return local ovmf ; ovmf=$( build-lazy @{pkgs.OVMF.drvPath!unsafeDiscardStringContext} fd ) || return
#qemu+=( -bios ${ovmf}/FV/OVMF.fd ) # This works, but is a legacy fallback that stores the EFI vars in /NvVars on the EFI partition (which is really bad). #qemu+=( -bios ${ovmf}/FV/OVMF.fd ) # This works, but is a legacy fallback that stores the EFI vars in /NvVars on the EFI partition (which is really bad).
local fwName=OVMF ; if [[ @{pkgs.system} == aarch64-* ]] ; then fwName=AAVMF ; fi # fwName=QEMU local fwName=OVMF ; if [[ @{pkgs.system} == aarch64-* ]] ; then fwName=AAVMF ; fi # fwName=QEMU
@ -144,12 +152,12 @@ function run-qemu {
fi fi
if [[ ! ${args[no-nat]:-} ]] ; then # e.g. --nat-fw=:8000-:8000,:8001-:8001,127.0.0.1:2022-:22 if [[ ! ${args[no-nat]:-} ]] ; then # e.g. --nat-fw=:8000-:8000,:8001-:8001,127.0.0.1:2022-:22
qemu+=( -nic user,model=virtio-net-pci${args[nat-fw]:+,hostfwd=tcp:${args[nat-fw]//,/,hostfwd=tcp:}} ) # NATed, IPs: 10.0.2.15+/32, gateway: 10.0.2.2 qemu+=( -nic user,model=virtio-net-pci${args[nat-fw]:+,hostfwd=tcp:${args[nat-fw]//,/,hostfwd=tcp:}} ) # NATed, IPs: 10.0.2.15+/24, gateway/host: 10.0.2.2, DNS: 10.0.2.3
fi
if [[ ${args[nic]:-} ]] ; then
[[ @{config.networking.hostId} =~ ^(.)(.)(.)(.)(.)(.)(.)(.)$ ]] && mac=$( printf "52:54:%s%s:%s%s:%s%s:%s%s" "${BASH_REMATCH[@]:1}" ) || { echo 'Invalid hostId' &>2 ; return; }
qemu+=( -nic model=virtio-net-pci,mac=$mac,type="${args[nic]}" )
fi fi
# TODO: network bridging:
#[[ @{config.networking.hostId} =~ ^(.)(.)(.)(.)(.)(.)(.)(.)$ ]] && mac=$( printf "52:54:%s%s:%s%s:%s%s:%s%s" "${BASH_REMATCH[@]:1}" ) || { echo 'Invalid hostId' &>2 ; return; }
#qemu+=( -netdev bridge,id=enp0s3,macaddr=$mac -device virtio-net-pci,netdev=hn0,id=nic1 )
# To pass a USB device (e.g. a YubiKey for unlocking), add pass »--usb-port=${bus}-${port}«, where bus and port refer to the physical USB port »/sys/bus/usb/devices/${bus}-${port}« (see »lsusb -tvv«). E.g.: »--usb-port=3-1.1.1.4« # To pass a USB device (e.g. a YubiKey for unlocking), add pass »--usb-port=${bus}-${port}«, where bus and port refer to the physical USB port »/sys/bus/usb/devices/${bus}-${port}« (see »lsusb -tvv«). E.g.: »--usb-port=3-1.1.1.4«
if [[ ${args[usb-port]:-} ]] ; then local decl ; for decl in ${args[usb-port]//:/ } ; do if [[ ${args[usb-port]:-} ]] ; then local decl ; for decl in ${args[usb-port]//:/ } ; do

View File

@ -31,16 +31,16 @@ in {
}; }))); }; })));
apply = lib.filterAttrs (k: v: v != null); apply = lib.filterAttrs (k: v: v != null);
}; };
commands = let desc = when: mounted: '' commands = let cmdOpt = when: mounted: lib.mkOption { description = ''
Bash commands that are executed during the system installation, ${when}. Bash commands that are executed during the system installation, ${when}.
Note that these commands are executed without any further sandboxing (i.e. when not using the VM installation mode, as root on the host). Note that these commands are executed without any further sandboxing (i.e. when not using the VM installation mode, as root on the host).
Partitions may be used via `/dev/disk/by-partlabel/`.${lib.optionalString mounted '' The target system is mounted at `$mnt`.''} Partitions may be used via `/dev/disk/by-partlabel/`.${lib.optionalString mounted '' The target system is mounted at `$mnt`.''}
''; in { ''; type = lib.types.lines; default = ""; }; in {
postPartition = lib.mkOption { description = desc "after partitioning the disks" false; type = lib.types.lines; default = ""; }; postPartition = cmdOpt "after partitioning the disks" false;
postFormat = lib.mkOption { description = desc "after formatting the partitions with filesystems" false; type = lib.types.lines; default = ""; }; postFormat = cmdOpt "after formatting the partitions with filesystems" false;
postMount = lib.mkOption { description = desc "after mounting all filesystems" true; type = lib.types.lines; default = ""; }; postMount = cmdOpt "after mounting all filesystems" true;
preInstall = lib.mkOption { description = desc "before installing the bootloader" true; type = lib.types.lines; default = ""; }; preInstall = cmdOpt "before installing the bootloader" true;
postInstall = lib.mkOption { description = desc "just before unmounting the new system" true; type = lib.types.lines; default = ""; }; postInstall = cmdOpt "just before unmounting the new system" true;
}; };
outputName = lib.mkOption { outputName = lib.mkOption {
description = ''The name this system is (/ should be) exported as by its defining flake (as »nixosConfigurations.''${outputName}« and »apps.*-linux.''${outputName}«).''; description = ''The name this system is (/ should be) exported as by its defining flake (as »nixosConfigurations.''${outputName}« and »apps.*-linux.''${outputName}«).'';