Skip to content

−−help Output

Niklas Gollenstede edited this page Jun 27, 2023 · 1 revision

For reference, the output of nix run .#example -- --help | fmt -cstw100.
Note that the functionality of the setup scripts can be adjusted or amended per-host, so other host's --help may look different.

Call per-host setup and maintenance commands. Most importantly, »install-system«.

Usage:
    nix run REPO#example -- [sudo] [bash] [--FLAG[=value]]... [--] [COMMAND [ARG]...]

    Where »REPO« is the path to the flake repo exporting this system (»example«) using
    »mkSystemsFlake«.
    If the first argument (after the first »--«) is »sudo«, then the program will re-execute
    itself as root using sudo (minus that »sudo« argument).
    If the (then) first argument is »bash«, or if there are no (more) arguments, it will
    execute an interactive shell with the »COMMAND«s (bash functions and exported Nix values
    used by them) sourced.
    If a »FLAG« »--command« is supplied, then the first positional argument (»COMMAND«)
    is »eval«ed as bash instructions, otherwise the first argument should be one of the
    »COMMAND«s below, which will be called with the positional CLI »ARG«s as arguments.
    »FLAG«s may be set to customize the behavior of »COMMAND« or any sub-commands it calls.

»COMMAND« should be one of:

    add-bootkey-to-keydev blockDev
        Creates a random static key on a new key partition on the GPT partitioned
        »$blockDev«. The drive can then be used as headless but removable disk unlock method.
        To create/clear the GPT beforehand, run: $ sgdisk --zap-all "$blockDev"

    create-zpool mnt poolName
        Creates a single of the system's ZFS pools, and its datasets. Can be called manually
        to create pools that were added to the configuration, or to create those declared with
        »createDuringInstallation = false«. Expects the backing device(-partition)s to exist
        as declared for the pool.

    ensure-datasets mnt filterExp?
        Ensures that the system's datasets exist and have the defined properties (but not that
        they don't have properties that aren't defined).
        The pool(s) must exist, be imported with root prefix »$mnt«, and (if datasets are
        to be created or encryption roots to be inherited) the system's keystore must be open
        (see »mount-keystore-luks«) or the keys must be loaded.
        »keystatus« and »mounted« of existing datasets should remain unchanged by this
        function, newly crated datasets will not be mounted but have their keys loaded.

    install-system diskPaths
        This command installs a NixOS system to local disks or image files.
        It gets all the information it needs from the system's NixOS configuration -- except
        for the path(s) of the target disk(s) / image file(s).

        If »diskPaths« points to something in »/dev/«, then it is directly formatted and
        written to as block device, otherwise »diskPaths« is (re-)created as raw image and
        then used as loop device.
        For hosts that install to multiple disks, pass a :-separated list of »<disk-name>=<path>«
        pairs (the name may be omitted only for the "default" disk).

        Since the installation needs to format and mount (image files as) disks, it needs some
        way of elevating permissions. It can:
        * be run as »root«, requiring Nix to be installed system-wide / for root,
        * be run with the »sudo« argument (see »--help« output; this runs »nix« commands
        as the original user, and the rest as root),
        * or automatically perform the installation in a qemu VM (see »--vm« flag).

        Installing inside the VM is safer (will definitely only write to the supplied
        »diskPaths«), more secure (executes everything inside the VM), and does not require
        privilege elevation, is significantly slower (painfully slow without KVM), and may
        break custom »*Commands« hooks (esp. those passing in secrets). Across ISAs, the VM
        installation is even slower, taking many hours for even a simple system.
        Without VM, installations across different ISAs (e.g. from an x64 desktop to a Raspberry
        Pi microSD) works (even relatively fast) if the installing host is NixOS and sets
        »boot.binfmt.emulatedSystems« for the target systems ISA, or on other Linux with a
        matching »binfmt_misc« registration with the preload (F) flag.

        Once done, the disk(s) can be transferred -- or the image(s) be copied -- to the final
        system, and should boot there.
        If the target host's hardware target allows, a resulting image can also be passed to the
        »register-vbox« command to create a bootable VirtualBox instance for the current user,
        or to »run-qemu« to start it in a qemu VM.

        What the installation does is defined solely by the target host's NixOS configuration.
        The "Installation" section of each host's documentation should contain host specific
        details, if any.
        Various »FLAG«s below affect how the installation is performed (in VM, verbosity,
        debugging, ...).

    mount-keystore-luks cryptsetupOptions...
        Tries to open and mount the systems keystore from its LUKS partition. If successful,
        this also adds the traps to close the keystore when the parent shell exits (so this is
        not useful as a standalone »COMMAND«, use the »bash« or »--command« options).
        For the exit traps to trigger on exit from the calling script / shell, this can't run
        in a sub shell (and therefore can't be called from a pipeline).
        See »open-system«'s implementation for some example calls to this function.

    open-system diskImages
        Performs any steps necessary to mount the target system at
        »/tmp/nixos-install-${config_networking_hostName}« on the current host.
        For any steps taken, it also adds the steps to undo them on exit from the calling shell
        (so this is not useful as a standalone »COMMAND«, use the »bash« or »--command«
        options, and don't call this from a sub-shell that exits too early).
        »diskImages« may be passed in the same format as to the installer. Any image files
        passed are ensured to be loop-mounted. »root« may also pass device paths.

        Perfect to inspect/update/amend/repair a system's installation afterwards, e.g.:
        $ install-system-to $mnt
        $ nixos-install --system ${config_system_build_toplevel} --no-root-passwd --no-channel-copy
        --root $mnt
        $ nixos-enter --root $mnt

    register-vbox diskImages bridgeTo?
        On the host and for the user it is called by, creates/registers a VirtualBox VM meant
        to run the shells target host. Requires the path to the target host's »diskImage« as
        the result of running the install script. The image file may not be deleted or moved. If
        »bridgeTo« is set (to a host interface name, e.g. as »eth0«), it is added as bridged
        network "Adapter 2" (which some hosts need).

    run-qemu diskImages qemuArgs...
        Runs a host in a QEMU VM, directly from its bootable disks, without requiring any change
        in it's configuration.
        This function infers many qemu options from the target system's configuration and the
        current host system.
        »diskImages« may be passed in the same format as to the installer. Any image files
        passed are ensured to be loop-mounted. »root« may also pass device paths.

»FLAG«s may be any of:
    --command
        (global) Interpret the first positional argument as bash script (instead of the name of
        a single command) and »eval« it (with access to all commands and internal functions
        and variables).
    --debug
        (global) Hook into any »|| exit« / »|| return« statements and open a shell if they
        are triggered by an error. Implies »--trace«.
    --dry-run
        (run-qemu) Instead of running the (main) qemu (and install) command, only print it.
    --efi
        (run-qemu) Treat the target system as EFI system, even if not recognized as such
        automatically.
    --efi-vars=path
        (run-qemu) For »--efi« systems, path to a file storing the EFI variables. The default
        is in »XDG_RUNTIME_DIR«, i.e. it does not persist across host reboots.
    --graphic
        (run-qemu) Open a graphical window even of the target system logs to serial and not
        (explicitly) TTY1.
    --image-owner
        (install-system) When using image files, »chown« them to this »owner[:group]« before
        the installation.
    --inspect-cmd=script
        (install-system) Instead of opening an interactive shell for the post-installation
        inspection, »eval« this script.
    --inspectScripts
        (install-system) When running installation hooks (»...*Commands« composed as Nix
        strings) print out and pause before each command. This works ... semi-well.
    --install=[1|always]
        (run-qemu) 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/.
    --mem=num
        (run-qemu) VM RAM in MiB (»qemu -m«).
    --nat-fw=forwards
        (run-qemu) Port forwards to the guest's NATed NIC. E.g:
        »--nat-fw=:8000-:8000,:8001-:8001,127.0.0.1:2022-:22«.
    --no-inspect
        (install-system) Do not inspect the (successfully) installed system before unmounting
        its filesystems.
    --no-kvm
        (run-qemu) Do not rey to use (or complain about the unavailability of) KVM.
    --no-nat
        (run-qemu) Do not provide a NATed NIC to the guest.
    --no-serial
        (run-qemu) 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.
    --no-vm
        (install-system) Never perform the installation in a VM. Fail if not executed as »root«.
    --quiet
        (global) Try to suppress all non-error output. May also swallow some error related output.
    --share=decls
        (run-qemu) 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«.
    --smp=num
        (run-qemu) Number of guest CPU cores.
    --toplevel
        (install-system) Optional replacement for the actual »config.system.build.toplevel«.
    --trace
        (global) Turn on bash's »errtrace« option before running »COMMAND«.
    --usb-port=path
        (run-qemu) A physical USB port (or hub) to pass to the guest (e.g. a YubiKey
        for unlocking). Specified as »<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«.
    --virtio-blk
        (run-qemu) Pass the system's disks/images as virtio disks, instead of using
        AHCI+IDE. Default iff »boot.initrd.availableKernelModules« includes »virtio_blk«
        (because it requires that driver).
    --vm
        (install-system) Perform the system installation in a qemu VM instead of on the host
        itself. This is implied when not running as »root« (or with the »sudo« option).
        The VM boots the target system's kernel (or a slight modification of it, if the system
        kernel is not bootable in qemu) and performs the installation at the end of the first
        boot stage (instead of mounting the root filesystem and starting systemd).
        The target disks or images are passed into the VM as block devices (and are the only
        devices available there). The host's »/nix/« folder is passed as a read-only network
        share. This makes the installation safe and secure, but also slower (network share),
        and may cause problems with custom install commands.
        The calling user should have access to KVM, or the installation will be very very slow.
        See also the »--no-vm« and »--vm-shared=« flags.
    --vm-shared
        (install-system) When installing inside the VM, specifies a host path that is read-write
        mounted at »/tmp/shared« inside the VM.
    --zpool-force
        (install-system) (create-zpool) When creating ZFS storage pools, pass the »-f« (force)
        option. This may be required when installing to disks that are currently part of a pool,
        or ZFS refuses do reuse them.
    --help
        Do nothing but print this message and exit with success.

Examples:

    Install the system »$host« to the image file »/tmp/system-$host.img«:
        $ nix run .#$host -- install-system /tmp/system-$host.img

    Test a fresh installation of »$host« in a qemu VM:
        $ nix run .#$host -- run-qemu --install=always

    Run an interactive bash session with the setup functions in the context of the current host:
        $ nix run /etc/nixos/#$(hostname)
    Now run any of the »COMMAND«s above, or inspect/use the exported Nix variables (»declare
    -p config_<TAB><TAB>«).

    Run a root session in the context of a different host (useful if Nix is not installed for
    root on the current host):
        $ nix run .#other-host -- sudo
Clone this wiki locally