summary refs log tree commit diff
path: root/nixos/modules/installer/tools
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/installer/tools')
-rw-r--r--nixos/modules/installer/tools/get-version-suffix29
-rw-r--r--nixos/modules/installer/tools/nixos-build-vms/build-vms.nix9
-rw-r--r--nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh62
-rw-r--r--nixos/modules/installer/tools/nixos-checkout.nix55
-rw-r--r--nixos/modules/installer/tools/nixos-gen-seccure-keys.sh13
-rw-r--r--nixos/modules/installer/tools/nixos-hardware-scan.pl248
-rw-r--r--nixos/modules/installer/tools/nixos-install.sh238
-rw-r--r--nixos/modules/installer/tools/nixos-option.sh395
-rw-r--r--nixos/modules/installer/tools/nixos-rebuild.sh222
-rw-r--r--nixos/modules/installer/tools/nixos-version.sh2
-rw-r--r--nixos/modules/installer/tools/tools.nix112
11 files changed, 1385 insertions, 0 deletions
diff --git a/nixos/modules/installer/tools/get-version-suffix b/nixos/modules/installer/tools/get-version-suffix
new file mode 100644
index 00000000000..76cec8d5dae
--- /dev/null
+++ b/nixos/modules/installer/tools/get-version-suffix
@@ -0,0 +1,29 @@
+getVersion() {
+    local dir="$1"
+    rev=
+    if [ -e "$dir/.git" ]; then
+        if [ -z "$(type -P git)" ]; then
+            echo "warning: Git not found; cannot figure out revision of $dir" >&2
+            return
+        fi
+        cd "$dir"
+        rev=$(git rev-parse --short HEAD)
+        if git describe --always --dirty | grep -q dirty; then
+            rev+=M
+        fi
+    fi
+}
+
+if nixos=$(nix-instantiate --find-file nixos "$@"); then
+    getVersion $nixos
+    if [ -n "$rev" ]; then
+        suffix="pre-$rev"
+        if nixpkgs=$(nix-instantiate --find-file nixpkgs "$@"); then
+            getVersion $nixpkgs
+            if [ -n "$rev" ]; then
+                suffix+="-$rev"
+            fi
+        fi
+        echo $suffix
+    fi
+fi
diff --git a/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix b/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
new file mode 100644
index 00000000000..5e77b701ff5
--- /dev/null
+++ b/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
@@ -0,0 +1,9 @@
+{ system ? builtins.currentSystem
+, networkExpr
+}:
+
+let nodes = import networkExpr; in
+
+with import ../../../../lib/testing.nix { inherit system; };
+
+(complete { inherit nodes; testScript = ""; }).driver
diff --git a/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh b/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
new file mode 100644
index 00000000000..0a6e8b920a1
--- /dev/null
+++ b/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
@@ -0,0 +1,62 @@
+#! @shell@ -e
+
+# Shows the usage of this command to the user
+
+showUsage()
+{
+    echo "Usage: $0 network_expr"
+    echo "Options:"
+    echo
+    echo "--no-out-link   Do not create a 'result' symlink"
+    echo "--show-trace    Shows the output trace"
+    echo "-h,--help       Shows the usage of this command"
+}
+
+# Parse valid argument options
+
+PARAMS=`getopt -n $0 -o h -l no-out-link,show-trace,help -- "$@"`
+
+if [ $? != 0 ]
+then
+    showUsage
+    exit 1
+fi
+
+eval set -- "$PARAMS"
+
+# Evaluate valid options
+
+while [ "$1" != "--" ]
+do
+    case "$1" in
+	--no-out-link)
+	    noOutLinkArg="--no-out-link"
+	    ;;
+	--show-trace)
+	    showTraceArg="--show-trace"
+	    ;;
+	-h|--help)
+	    showUsage
+	    exit 0
+	    ;;
+    esac
+    
+    shift
+done
+
+shift
+
+# Validate the given options
+
+if [ "$1" = "" ]
+then
+    echo "ERROR: A network expression must be specified!" >&2
+    exit 1
+else
+    networkExpr=$(readlink -f $1)
+fi
+
+# Build a network of VMs
+
+nix-build '<nixos/modules/installer/tools/nixos-build-vms/build-vms.nix>' \
+    --argstr networkExpr $networkExpr $noOutLinkArg $showTraceArg
diff --git a/nixos/modules/installer/tools/nixos-checkout.nix b/nixos/modules/installer/tools/nixos-checkout.nix
new file mode 100644
index 00000000000..1a734ca5eeb
--- /dev/null
+++ b/nixos/modules/installer/tools/nixos-checkout.nix
@@ -0,0 +1,55 @@
+# This module generates the nixos-checkout script, which replaces the
+# NixOS and Nixpkgs source trees in /etc/nixos/{nixos,nixpkgs} with
+# Git checkouts.
+
+{config, pkgs, ...}:
+
+with pkgs.lib;
+
+let
+
+  nixosCheckout = pkgs.substituteAll {
+    name = "nixos-checkout";
+    dir = "bin";
+    isExecutable = true;
+    src = pkgs.writeScript "nixos-checkout"
+      ''
+        #! ${pkgs.stdenv.shell} -e
+
+        if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
+          echo "Usage: `basename $0` [PREFIX]. See NixOS Manual for more info."
+          exit 0
+        fi        
+
+        prefix="$1"
+        if [ -z "$prefix" ]; then prefix=/etc/nixos; fi
+        mkdir -p "$prefix"
+        cd "$prefix"
+
+        if [ -z "$(type -P git)" ]; then
+            echo "installing Git..."
+            nix-env -iA nixos.pkgs.git || nix-env -i git
+        fi
+
+        # Move any old nixos or nixpkgs directories out of the way.
+        backupTimestamp=$(date "+%Y%m%d%H%M%S")
+
+        if [ -e nixos -a ! -e nixos/.git ]; then
+            mv nixos nixos-$backupTimestamp
+        fi
+
+        if [ -e nixpkgs -a ! -e nixpkgs/.git ]; then
+            mv nixpkgs nixpkgs-$backupTimestamp
+        fi
+
+        # Check out the NixOS and Nixpkgs sources.
+        git clone git://github.com/NixOS/nixos.git nixos
+        git clone git://github.com/NixOS/nixpkgs.git nixpkgs
+      '';
+   };
+
+in
+
+{
+  environment.systemPackages = [ nixosCheckout ];
+}
diff --git a/nixos/modules/installer/tools/nixos-gen-seccure-keys.sh b/nixos/modules/installer/tools/nixos-gen-seccure-keys.sh
new file mode 100644
index 00000000000..a97eef672f7
--- /dev/null
+++ b/nixos/modules/installer/tools/nixos-gen-seccure-keys.sh
@@ -0,0 +1,13 @@
+#! @shell@ -e
+
+mkdir -p /var/elliptic-keys
+chmod 0755 /var/elliptic-keys
+cd /var/elliptic-keys
+touch private
+chmod 0700 private
+dd if=/dev/urandom bs=128 count=1 of=private
+chmod 0500 private
+public=$(seccure-key -F private 2>&1)
+echo ${public#*The public key is: } > public
+chmod 0555 public
+
diff --git a/nixos/modules/installer/tools/nixos-hardware-scan.pl b/nixos/modules/installer/tools/nixos-hardware-scan.pl
new file mode 100644
index 00000000000..3204f3d4051
--- /dev/null
+++ b/nixos/modules/installer/tools/nixos-hardware-scan.pl
@@ -0,0 +1,248 @@
+#! @perl@/bin/perl -w
+
+use File::Spec;
+use File::Basename;
+
+
+my @attrs = ();
+my @kernelModules = ();
+my @initrdKernelModules = ();
+my @modulePackages = ();
+my @imports = ("<nixos/modules/installer/scan/not-detected.nix>");
+
+
+sub debug {
+    return unless defined $ENV{"DEBUG"};
+    print STDERR @_;
+}
+
+
+# Read a file, returning undef if the file cannot be opened.
+sub readFile {
+    my $filename = shift;
+    my $res;
+    if (open FILE, "<$filename") {
+        my $prev = $/;
+        undef $/;
+        $res = <FILE>;
+        $/ = $prev;
+        close FILE;
+        chomp $res;
+    }
+    return $res;
+}
+
+
+my $cpuinfo = readFile "/proc/cpuinfo";
+
+
+sub hasCPUFeature {
+    my $feature = shift;
+    return $cpuinfo =~ /^flags\s*:.* $feature( |$)/m;
+}
+
+
+# Detect the number of CPU cores.
+my $cpus = scalar (grep {/^processor\s*:/} (split '\n', $cpuinfo));
+
+
+# Virtualization support?
+push @kernelModules, "kvm-intel" if hasCPUFeature "vmx";
+push @kernelModules, "kvm-amd" if hasCPUFeature "svm";
+
+
+# Look at the PCI devices and add necessary modules.  Note that most
+# modules are auto-detected so we don't need to list them here.
+# However, some are needed in the initrd to boot the system.
+
+my $videoDriver;
+
+sub pciCheck {
+    my $path = shift;
+    my $vendor = readFile "$path/vendor";
+    my $device = readFile "$path/device";
+    my $class = readFile "$path/class";
+    
+    my $module;
+    if (-e "$path/driver/module") {
+        $module = basename `readlink -f $path/driver/module`;
+        chomp $module;
+    }
+    
+    debug "$path: $vendor $device $class";
+    debug " $module" if defined $module;
+    debug "\n";
+
+    if (defined $module) {
+        # See the bottom of http://pciids.sourceforge.net/pci.ids for
+        # device classes.
+        if (# Mass-storage controller.  Definitely important.
+            $class =~ /^0x01/ ||
+
+            # Firewire controller.  A disk might be attached.
+            $class =~ /^0x0c00/ ||
+
+            # USB controller.  Needed if we want to use the
+            # keyboard when things go wrong in the initrd.
+            $class =~ /^0x0c03/
+            )
+        {
+            push @initrdKernelModules, $module;
+        }
+    }
+
+    # broadcom STA driver (wl.ko)
+    # list taken from http://www.broadcom.com/docs/linux_sta/README.txt
+    if ($vendor eq "0x14e4" &&
+        ($device eq "0x4311" || $device eq "0x4312" || $device eq "0x4313" ||
+         $device eq "0x4315" || $device eq "0x4327" || $device eq "0x4328" ||
+         $device eq "0x4329" || $device eq "0x432a" || $device eq "0x432b" ||
+         $device eq "0x432c" || $device eq "0x432d" || $device eq "0x4353" ||
+         $device eq "0x4357" || $device eq "0x4358" || $device eq "0x4359" ) )
+     {
+        push @modulePackages, "config.boot.kernelPackages.broadcom_sta";
+        push @kernelModules, "wl";
+     }
+
+    # Can't rely on $module here, since the module may not be loaded
+    # due to missing firmware.  Ideally we would check modules.pcimap
+    # here.
+    push @attrs, "networking.enableIntel2200BGFirmware = true;" if
+        $vendor eq "0x8086" &&
+        ($device eq "0x1043" || $device eq "0x104f" || $device eq "0x4220" ||
+         $device eq "0x4221" || $device eq "0x4223" || $device eq "0x4224");
+
+    push @attrs, "networking.enableIntel3945ABGFirmware = true;" if
+        $vendor eq "0x8086" &&
+        ($device eq "0x4229" || $device eq "0x4230" ||
+         $device eq "0x4222" || $device eq "0x4227");
+
+    # Assume that all NVIDIA cards are supported by the NVIDIA driver.
+    # There may be exceptions (e.g. old cards).
+    $videoDriver = "nvidia" if $vendor eq "0x10de" && $class =~ /^0x03/;
+}
+
+foreach my $path (glob "/sys/bus/pci/devices/*") {
+    pciCheck $path;
+}
+
+
+# Idem for USB devices.
+
+sub usbCheck {
+    my $path = shift;
+    my $class = readFile "$path/bInterfaceClass";
+    my $subclass = readFile "$path/bInterfaceSubClass";
+    my $protocol = readFile "$path/bInterfaceProtocol";
+
+    my $module;
+    if (-e "$path/driver/module") {
+        $module = basename `readlink -f $path/driver/module`;
+        chomp $module;
+    }
+    
+    debug "$path: $class $subclass $protocol";
+    debug " $module" if defined $module;
+    debug "\n";
+ 
+    if (defined $module) {
+        if (# Mass-storage controller.  Definitely important.
+            $class eq "08" ||
+
+            # Keyboard.  Needed if we want to use the
+            # keyboard when things go wrong in the initrd.
+            ($class eq "03" && $protocol eq "01")
+            )
+        {
+            push @initrdKernelModules, $module;
+        }
+    }
+}
+
+foreach my $path (glob "/sys/bus/usb/devices/*") {
+    if (-e "$path/bInterfaceClass") {
+        usbCheck $path;
+    }
+}
+
+
+# Add the modules for all block devices.
+
+foreach my $path (glob "/sys/class/block/*") {
+    my $module;
+    if (-e "$path/device/driver/module") {
+        $module = basename `readlink -f $path/device/driver/module`;
+        chomp $module;
+        push @initrdKernelModules, $module;
+    }
+}
+
+
+if ($videoDriver) {
+    push @attrs, "services.xserver.videoDrivers = [ \"$videoDriver\" ];";
+}
+
+
+# Check if we're a VirtualBox guest.  If so, enable the guest
+# additions.
+my $dmi = `@dmidecode@/sbin/dmidecode`;
+if ($dmi =~ /Manufacturer: innotek/) {
+    push @attrs, "services.virtualbox.enable = true;"
+}
+
+
+# Generate the configuration file.
+
+sub removeDups {
+    my %seen;
+    my @res = ();
+    foreach my $s (@_) {
+        if (!defined $seen{$s}) {
+            $seen{$s} = "";
+            push @res, $s;
+        }
+    }
+    return @res;
+}
+
+sub toNixExpr {
+    my $res = "";
+    foreach my $s (@_) {
+        $res .= " \"$s\"";
+    }
+    return $res;
+}
+
+sub multiLineList {
+    my $indent = shift;
+    my $res = "";
+    $res = "\n" if scalar @_ > 0;
+    foreach my $s (@_) {
+        $res .= "$indent$s\n";
+    }
+    return $res;
+}
+
+my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules);
+my $kernelModules = toNixExpr(removeDups @kernelModules);
+my $modulePackages = toNixExpr(removeDups @modulePackages);
+my $attrs = multiLineList("  ", removeDups @attrs);
+my $imports = multiLineList("    ", removeDups @imports);
+
+
+print <<EOF ;
+# This is a generated file.  Do not modify!
+# Make changes to /etc/nixos/configuration.nix instead.
+{ config, pkgs, ... }:
+
+{
+  imports = [$imports  ];
+
+  boot.initrd.kernelModules = [$initrdKernelModules ];
+  boot.kernelModules = [$kernelModules ];
+  boot.extraModulePackages = [$modulePackages ];
+
+  nix.maxJobs = $cpus;
+$attrs}
+EOF
+# workaround for a bug in substituteAll
diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh
new file mode 100644
index 00000000000..a4ac5b68dd7
--- /dev/null
+++ b/nixos/modules/installer/tools/nixos-install.sh
@@ -0,0 +1,238 @@
+#! @shell@
+
+# - [mount target device] <- currently disabled
+# - make Nix store etc.
+# - copy closure of Nix to target device
+# - register validity
+# - with a chroot to the target device:
+#   * nix-env -p /nix/var/nix/profiles/system -i <nix-expr for the configuration>
+#   * run the activation script of the configuration (also installs Grub)
+
+# Parse the command line for the -I flag
+extraBuildFlags=()
+
+while [ "$#" -gt 0 ]; do
+    i="$1"; shift 1
+    case "$i" in
+      -I)
+        given_path="$1"; shift 1
+        absolute_path=$(readlink -m $given_path)
+        extraBuildFlags+=("$i" "/mnt$absolute_path")
+        ;;
+      *)
+        echo "$0: unknown option \`$i'"
+        exit 1
+        ;;
+    esac
+done
+
+set -e
+shopt -s nullglob
+
+if test -z "$mountPoint"; then
+    mountPoint=/mnt
+fi
+
+if test -z "$NIXOS_CONFIG"; then
+    NIXOS_CONFIG=/etc/nixos/configuration.nix
+fi
+
+if ! test -e "$mountPoint"; then
+    echo "mount point $mountPoint doesn't exist"
+    exit 1
+fi
+
+if ! grep -F -q " $mountPoint " /proc/mounts; then
+    echo "$mountPoint doesn't appear to be a mount point"
+    exit 1
+fi
+
+if ! test -e "$mountPoint/$NIXOS_CONFIG"; then
+    echo "configuration file $mountPoint/$NIXOS_CONFIG doesn't exist"
+    exit 1
+fi
+
+
+
+# Mount some stuff in the target root directory.  We bind-mount /etc
+# into the chroot because we need networking and the nixbld user
+# accounts in /etc/passwd.  But we do need the target's /etc/nixos.
+mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/mnt $mountPoint/mnt2 $mountPoint/mnt-nixos $mountPoint/mnt-nixpkgs $mountPoint/etc /etc/nixos
+mount --make-private / # systemd makes / shared, which is annoying
+mount --bind / $mountPoint/mnt
+mount --bind /nix $mountPoint/mnt/nix
+mount --bind /nix/store $mountPoint/mnt/nix/store
+mount --bind /dev $mountPoint/dev
+mount --bind /dev/shm $mountPoint/dev/shm
+mount --bind /proc $mountPoint/proc
+mount --bind /sys $mountPoint/sys
+mount --bind /sys/firmware/efi/efivars $mountPoint/sys/firmware/efi/efivars &>/dev/null || true
+mount --bind $mountPoint/etc/nixos $mountPoint/mnt2
+mount --bind /etc $mountPoint/etc
+mount --bind $mountPoint/mnt2 $mountPoint/etc/nixos
+
+cleanup() {
+    set +e
+    mountpoint -q $mountPoint/etc/nixos && umount $mountPoint/etc/nixos
+    mountpoint -q $mountPoint/etc && umount $mountPoint/etc
+    umount $mountPoint/mnt2
+    umount $mountPoint/mnt-nixos
+    umount $mountPoint/mnt-nixpkgs
+    umount $mountPoint/sys/firmware/efi/efivars &>/dev/null || true
+    umount $mountPoint/sys
+    umount $mountPoint/proc
+    umount $mountPoint/dev/shm
+    umount $mountPoint/dev
+    umount $mountPoint/mnt/nix/store
+    umount $mountPoint/mnt/nix
+    umount $mountPoint/mnt
+    rmdir $mountPoint/mnt $mountPoint/mnt2 $mountPoint/mnt-nixos $mountPoint/mnt-nixpkgs
+}
+
+trap "cleanup" EXIT
+
+mkdir -m 01777 -p $mountPoint/tmp
+mkdir -m 0755 -p $mountPoint/var
+
+
+# Create the necessary Nix directories on the target device, if they
+# don't already exist.
+mkdir -m 0755 -p \
+    $mountPoint/nix/var/nix/gcroots \
+    $mountPoint/nix/var/nix/temproots \
+    $mountPoint/nix/var/nix/manifests \
+    $mountPoint/nix/var/nix/userpool \
+    $mountPoint/nix/var/nix/profiles \
+    $mountPoint/nix/var/nix/db \
+    $mountPoint/nix/var/log/nix/drvs
+
+mkdir -m 1775 -p $mountPoint/nix/store
+build_users_group=$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"build-users-group"};')
+if test -n "$build_users_group"; then
+    chown root:"$build_users_group" $mountPoint/nix/store
+else
+    chown root $mountPoint/nix/store
+fi
+
+
+# Get the store paths to copy from the references graph.
+storePaths=$(@perl@/bin/perl @pathsFromGraph@ @nixClosure@)
+
+
+# Copy Nix to the Nix store on the target device.
+echo "copying Nix to $mountPoint...."
+for i in $storePaths; do
+    echo "  $i"
+    chattr -R -i $mountPoint/$i 2> /dev/null || true # clear immutable bit
+    rsync -a $i $mountPoint/nix/store/
+done
+
+
+# We don't have locale-archive in the chroot, so clear $LANG.
+export LANG=
+export LC_ALL=
+export LC_TIME=
+
+
+# There is no daemon in the chroot
+unset NIX_REMOTE
+
+
+# Create a temporary Nix config file that causes the nixbld users to
+# be used.
+if test -n "$build_users_group"; then
+    echo "build-users-group = $build_users_group" > $mountPoint/tmp/nix.conf
+fi
+binary_caches=$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};')
+if test -n "$binary_caches"; then
+    echo "binary-caches = $binary_caches" >> $mountPoint/tmp/nix.conf
+fi
+export NIX_CONF_DIR=/tmp
+
+
+# Register the paths in the Nix closure as valid.  This is necessary
+# to prevent them from being deleted the first time we install
+# something.  (I.e., Nix will see that, e.g., the glibc path is not
+# valid, delete it to get it out of the way, but as a result nothing
+# will work anymore.)
+chroot $mountPoint @nix@/bin/nix-store --register-validity < @nixClosure@
+
+
+# Create the required /bin/sh symlink; otherwise lots of things
+# (notably the system() function) won't work.
+mkdir -m 0755 -p $mountPoint/bin
+# !!! assuming that @shell@ is in the closure
+ln -sf @shell@ $mountPoint/bin/sh
+
+
+if test -n "$NIXOS_PREPARE_CHROOT_ONLY"; then
+    echo "User requested only to prepare chroot. Exiting."
+    exit 0
+fi
+
+
+# Make the build below copy paths from the CD if possible.  Note that
+# /mnt in the chroot is the root of the CD.
+export NIX_OTHER_STORES=/mnt/nix:$NIX_OTHER_STORES
+
+p=@nix@/libexec/nix/substituters
+export NIX_SUBSTITUTERS=$p/copy-from-other-stores.pl:$p/download-from-binary-cache.pl
+
+
+# Make manifests available in the chroot.
+rm -f $mountPoint/nix/var/nix/manifests/*
+for i in /nix/var/nix/manifests/*.nixmanifest; do
+    chroot $mountPoint @nix@/bin/nix-store -r "$(readlink -f "$i")" > /dev/null
+    cp -pd "$i" $mountPoint/nix/var/nix/manifests/
+done
+
+
+# Get the absolute path to the NixOS/Nixpkgs sources.
+mount --bind $(readlink -f $(nix-instantiate --find-file nixpkgs)) $mountPoint/mnt-nixpkgs
+mount --bind $(readlink -f $(nix-instantiate --find-file nixos)) $mountPoint/mnt-nixos
+
+
+# Build the specified Nix expression in the target store and install
+# it into the system configuration profile.
+echo "building the system configuration..."
+NIX_PATH="nixpkgs=/mnt-nixpkgs:nixos=/mnt-nixos:nixos-config=$NIXOS_CONFIG" NIXOS_CONFIG= \
+    chroot $mountPoint @nix@/bin/nix-env \
+    "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/system -f '<nixos>' --set -A system --show-trace
+
+
+# Copy the NixOS/Nixpkgs sources to the target as the initial contents
+# of the NixOS channel.
+mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles
+mkdir -m 1777 -p $mountPoint/nix/var/nix/profiles/per-user
+mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles/per-user/root
+srcs=$(nix-env "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")
+if test -n "$srcs"; then
+    echo "copying NixOS/Nixpkgs sources..."
+    chroot $mountPoint @nix@/bin/nix-env \
+        "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/per-user/root/channels -i "$srcs" --quiet
+fi
+mkdir -m 0700 -p $mountPoint/root/.nix-defexpr
+ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels
+
+
+# We're done building/downloading, so we don't need the /etc bind
+# mount anymore.  In fact, below we want to modify the target's /etc.
+umount $mountPoint/etc/nixos
+umount $mountPoint/etc
+
+
+# Grub needs an mtab.
+ln -sfn /proc/mounts $mountPoint/etc/mtab
+
+
+# Mark the target as a NixOS installation, otherwise
+# switch-to-configuration will chicken out.
+touch $mountPoint/etc/NIXOS
+
+
+# Switch to the new system configuration.  This will install Grub with
+# a menu default pointing at the kernel/initrd/etc of the new
+# configuration.
+echo "finalising the installation..."
+NIXOS_INSTALL_GRUB=1 chroot $mountPoint \
+    /nix/var/nix/profiles/system/bin/switch-to-configuration boot
diff --git a/nixos/modules/installer/tools/nixos-option.sh b/nixos/modules/installer/tools/nixos-option.sh
new file mode 100644
index 00000000000..7f008d62c24
--- /dev/null
+++ b/nixos/modules/installer/tools/nixos-option.sh
@@ -0,0 +1,395 @@
+#! @shell@ -e
+
+# Allow the location of NixOS sources and the system configuration
+# file to be overridden.
+
+: ${mountPoint=/mnt}
+: ${NIXOS_CONFIG=/etc/nixos/configuration.nix}
+export NIXOS_CONFIG
+
+usage () {
+  echo 1>&2 "
+Usage: $0 [-v] [-d] [-l] [--xml] OPTION_NAME
+       $0 --install
+
+This program allows you to inspect the current value of NixOS
+configuration options.  It can also generate a basic NixOS
+configuration file.
+
+Options:
+
+  -i | --install        Write a template NixOS configuration file to
+                        ${mountPoint:+$mountPoint/}$NIXOS_CONFIG.
+  -v | --value          Display the current value, based on your
+                        configuration.
+  -d | --description    Display the default value, the example and the
+                        description.
+  -l | --lookup         Display where the option is defined and where it
+                        is declared.
+  --xml                 Print an XML representation of the result.
+                        Implies -vdl options.
+  --help                Show this message.
+
+Environment variables affecting $0:
+
+  \$mountPoint          Path to the target file system.
+  \$NIXOS_CONFIG        Path to your configuration file.
+
+"
+
+  exit 1;
+}
+
+#####################
+# Process Arguments #
+#####################
+
+desc=false
+defs=false
+value=false
+xml=false
+install=false
+verbose=false
+
+option=""
+
+argfun=""
+for arg; do
+  if test -z "$argfun"; then
+    case $arg in
+      -*)
+        longarg=""
+        sarg="$arg"
+        while test "$sarg" != "-"; do
+          case $sarg in
+            --*) longarg=$arg; sarg="--";;
+            -d*) longarg="$longarg --description";;
+            -v*) longarg="$longarg --value";;
+            -l*) longarg="$longarg --lookup";;
+            -i*) longarg="$longarg --install";;
+            -*) usage;;
+          esac
+          # remove the first letter option
+          sarg="-${sarg#??}"
+        done
+        ;;
+      *) longarg=$arg;;
+    esac
+    for larg in $longarg; do
+      case $larg in
+        --description) desc=true;;
+        --value) value=true;;
+        --lookup) defs=true;;
+        --xml) xml=true;;
+        --install) install=true;;
+        --verbose) verbose=true;;
+        --help) usage;;
+        -*) usage;;
+        *) if test -z "$option"; then
+             option="$larg"
+           else
+             usage
+           fi;;
+      esac
+    done
+  else
+    case $argfun in
+      set_*)
+        var=$(echo $argfun | sed 's,^set_,,')
+        eval $var=$arg
+        ;;
+    esac
+    argfun=""
+  fi
+done
+
+if $xml; then
+  value=true
+  desc=true
+  defs=true
+fi
+
+# --install cannot be used with -d -v -l without option name.
+if $value || $desc || $defs && $install && test -z "$option"; then
+  usage
+fi
+
+generate=false
+if ! $defs && ! $desc && ! $value && $install && test -z "$option"; then
+  generate=true
+fi
+
+if ! $defs && ! $desc; then
+  value=true
+fi
+
+if $verbose; then
+  set -x
+else
+  set +x
+fi
+
+#############################
+# Process the configuration #
+#############################
+
+evalNix(){
+  nix-instantiate - --eval-only "$@"
+}
+
+evalAttr(){
+  local prefix=$1
+  local suffix=$2
+  local strict=$3
+  echo "(import <nixos> {}).$prefix${option:+.$option}${suffix:+.$suffix}" |
+    evalNix ${strict:+--strict}
+}
+
+evalOpt(){
+  evalAttr "eval.options" "$@"
+}
+
+evalCfg(){
+  evalAttr "config" "$@"
+}
+
+findSources(){
+  local suffix=$1
+  echo "builtins.map (f: f.source) (import <nixos> {}).eval.options${option:+.$option}.$suffix" |
+    evalNix --strict
+}
+
+# Given a result from nix-instantiate, recover the list of attributes it
+# contains.
+attrNames() {
+  local attributeset=$1
+  # sed is used to replace un-printable subset by 0s, and to remove most of
+  # the inner-attribute set, which reduce the likelyhood to encounter badly
+  # pre-processed input.
+  echo "builtins.attrNames $attributeset" | \
+    sed 's,<[A-Z]*>,0,g; :inner; s/{[^\{\}]*};/0;/g; t inner;' | \
+    evalNix --strict
+}
+
+# map a simple list which contains strings or paths.
+nixMap() {
+  local fun="$1"
+  local list="$2"
+  local elem
+  for elem in $list; do
+    test $elem = '[' -o $elem = ']' && continue;
+    $fun $elem
+  done
+}
+
+if $install; then
+  NIXOS_CONFIG="$mountPoint$NIXOS_CONFIG"
+fi
+
+if $generate; then
+  mkdir -p $(dirname "$NIXOS_CONFIG")
+
+  # Scan the hardware and add the result to /etc/nixos/hardware-scan.nix.
+  hardware_config="${NIXOS_CONFIG%/configuration.nix}/hardware-configuration.nix"
+  if test -e "$hardware_config"; then
+    echo "A hardware configuration file exists, generation skipped."
+  else
+    echo "Generating a hardware configuration file in $hardware_config..."
+    nixos-hardware-scan > "$hardware_config"
+  fi
+
+  if test -e "$NIXOS_CONFIG"; then
+    echo 1>&2 "error: Cannot generate a template configuration because a configuration file exists."
+    exit 1
+  fi
+
+  nl="
+"
+  if test -e /sys/firmware/efi/efivars; then
+    l1="  # Use the gummiboot efi boot loader."
+    l2="  boot.loader.grub.enable = false;"
+    l3="  boot.loader.gummiboot.enable = true;"
+    l4="  boot.loader.efi.canTouchEfiVariables = true;"
+    # !!! Remove me when nixos is on 3.10 or greater by default
+    l5="  # EFI booting requires kernel >= 3.10"
+    l6="  boot.kernelPackages = pkgs.linuxPackages_3_10;"
+    bootloader_config="$l1$nl$l2$nl$l3$nl$l4$nl$nl$l5$nl$l6"
+  else
+    l1="  # Use the Grub2 boot loader."
+    l2="  boot.loader.grub.enable = true;"
+    l3="  boot.loader.grub.version = 2;"
+    l4="  # Define on which hard drive you want to install Grub."
+    l5='  # boot.loader.grub.device = "/dev/sda";'
+    bootloader_config="$l1$nl$l2$nl$l3$nl$nl$l4$nl$l5"
+  fi
+
+  echo "Generating a basic configuration file in $NIXOS_CONFIG..."
+
+  # Generate a template configuration file where the user has to
+  # fill the gaps.
+  cat <<EOF > "$NIXOS_CONFIG"
+# Edit this configuration file to define what should be installed on
+# the system.  Help is available in the configuration.nix(5) man page
+# or the NixOS manual available on virtual console 8 (Alt+F8).
+
+{ config, pkgs, ... }:
+
+{
+  imports =
+    [ # Include the results of the hardware scan.
+      ./hardware-configuration.nix
+    ];
+
+  boot.initrd.kernelModules =
+    [ # Specify all kernel modules that are necessary for mounting the root
+      # filesystem.
+      # "xfs" "ata_piix"
+      # fbcon # Uncomment this when EFI booting to see the console before the root partition is mounted
+    ];
+    
+$bootloader_config
+
+  # networking.hostName = "nixos"; # Define your hostname.
+  # networking.wireless.enable = true;  # Enables Wireless.
+
+  # Add filesystem entries for each partition that you want to see
+  # mounted at boot time.  This should include at least the root
+  # filesystem.
+
+  # fileSystems."/".device = "/dev/disk/by-label/nixos";
+
+  # fileSystems."/data" =     # where you want to mount the device
+  #   { device = "/dev/sdb";  # the device
+  #     fsType = "ext3";      # the type of the partition
+  #     options = "data=journal";
+  #   };
+
+  # List swap partitions activated at boot time.
+  swapDevices =
+    [ # { device = "/dev/disk/by-label/swap"; }
+    ];
+
+  # Select internationalisation properties.
+  # i18n = {
+  #   consoleFont = "lat9w-16";
+  #   consoleKeyMap = "us";
+  #   defaultLocale = "en_US.UTF-8";
+  # };
+
+  # List services that you want to enable:
+
+  # Enable the OpenSSH daemon.
+  # services.openssh.enable = true;
+
+  # Enable CUPS to print documents.
+  # services.printing.enable = true;
+
+  # Enable the X11 windowing system.
+  # services.xserver.enable = true;
+  # services.xserver.layout = "us";
+  # services.xserver.xkbOptions = "eurosign:e";
+
+  # Enable the KDE Desktop Environment.
+  # services.xserver.displayManager.kdm.enable = true;
+  # services.xserver.desktopManager.kde4.enable = true;
+}
+EOF
+
+  exit 0
+fi;
+
+# This duplicates the work made below, but it is useful for processing
+# the output of nixos-option with other tools such as nixos-gui.
+if $xml; then
+  evalNix --xml --no-location <<EOF
+let
+  reach = attrs: attrs${option:+.$option};
+  nixos = import <nixos> {};
+  nixpkgs = import <nixpkgs> {};
+  sources = builtins.map (f: f.source);
+  opt = reach nixos.eval.options;
+  cfg = reach nixos.config;
+in
+
+with nixpkgs.lib;
+
+let
+  optStrict = v:
+    let
+      traverse = x :
+        if isAttrs x then
+          if x ? outPath then true
+          else all id (mapAttrsFlatten (n: traverseNoAttrs) x)
+        else traverseNoAttrs x;
+      traverseNoAttrs = x:
+        # do not continue in attribute sets
+        if isAttrs x then true
+        else if isList x then all id (map traverse x)
+        else true;
+    in assert traverse v; v;
+in
+
+if isOption opt then
+  optStrict ({}
+  // optionalAttrs (opt ? default) { inherit (opt) default; }
+  // optionalAttrs (opt ? example) { inherit (opt) example; }
+  // optionalAttrs (opt ? description) { inherit (opt) description; }
+  // optionalAttrs (opt ? type) { typename = opt.type.name; }
+  // optionalAttrs (opt ? options) { inherit (opt) options; }
+  // {
+    # to disambiguate the xml output.
+    _isOption = true;
+    declarations = sources opt.declarations;
+    definitions = sources opt.definitions;
+    value = cfg;
+  })
+else
+  opt
+EOF
+  exit $?
+fi
+
+if test "$(evalOpt "_type" 2> /dev/null)" = '"option"'; then
+  $value && evalCfg;
+
+  if $desc; then
+    $value && echo;
+
+    if default=$(evalOpt "default" - 2> /dev/null); then
+      echo "Default: $default"
+    else
+      echo "Default: <None>"
+    fi
+    if example=$(evalOpt "example" - 2> /dev/null); then
+      echo "Example: $example"
+    fi
+    echo "Description:"
+    eval printf $(evalOpt "description")
+  fi
+
+  if $defs; then
+    $desc || $value && echo;
+
+    printPath () { echo "  $1"; }
+
+    echo "Declared by:"
+    nixMap printPath "$(findSources "declarations")"
+    echo ""
+    echo "Defined by:"
+    nixMap printPath "$(findSources "definitions")"
+    echo ""
+  fi
+
+else
+  # echo 1>&2 "Warning: This value is not an option."
+
+  result=$(evalCfg)
+  if names=$(attrNames "$result" 2> /dev/null); then
+    echo 1>&2 "This attribute set contains:"
+    escapeQuotes () { eval echo "$1"; }
+    nixMap escapeQuotes "$names"
+  else
+    echo 1>&2 "An error occured while looking for attribute names."
+    echo $result
+  fi
+fi
diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh
new file mode 100644
index 00000000000..8734cb273d4
--- /dev/null
+++ b/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -0,0 +1,222 @@
+#! @shell@ -e
+
+showSyntax() {
+    # !!! more or less cut&paste from
+    # system/switch-to-configuration.sh (which we call, of course).
+    cat <<EOF
+Usage: $0 [OPTIONS...] OPERATION
+
+The operation is one of the following:
+
+  switch:   make the configuration the boot default and activate now
+  boot:     make the configuration the boot default
+  test:     activate the configuration, but don't make it the boot default
+  build:    build the configuration, but don't make it the default or
+            activate it
+  build-vm: build a virtual machine containing the configuration
+            (useful for testing)
+  build-vm-with-bootloader:
+            like build-vm, but include a boot loader in the VM
+  dry-run:  just show what store paths would be built/downloaded
+
+Options:
+
+  --upgrade              fetch the latest version of NixOS before rebuilding
+  --install-grub         (re-)install the Grub bootloader
+  --no-build-nix         don't build the latest Nix from Nixpkgs before
+                           building NixOS
+  --rollback             restore the previous NixOS configuration (only
+                           with switch, boot, test, build)
+  --profile-name / -p    install in the specified system profile
+  --fast                 same as --no-build-nix --show-trace
+
+Various nix-build options are also accepted, in particular:
+
+  --show-trace           show a detailed stack trace for evaluation errors
+
+Environment variables affecting nixos-rebuild:
+
+  \$NIX_PATH              Nix expression search path
+  \$NIXOS_CONFIG          path to the NixOS system configuration specification
+EOF
+    exit 1
+}
+
+
+# Parse the command line.
+extraBuildFlags=()
+action=
+buildNix=1
+rollback=
+upgrade=
+repair=
+profile=/nix/var/nix/profiles/system
+
+while [ "$#" -gt 0 ]; do
+    i="$1"; shift 1
+    case "$i" in
+      --help)
+        showSyntax
+        ;;
+      switch|boot|test|build|dry-run|build-vm|build-vm-with-bootloader)
+        action="$i"
+        ;;
+      --install-grub)
+        export NIXOS_INSTALL_GRUB=1
+        ;;
+      --no-build-nix)
+        buildNix=
+        ;;
+      --rollback)
+        rollback=1
+        ;;
+      --upgrade)
+        upgrade=1
+        ;;
+      --repair)
+        repair=1
+        extraBuildFlags+=("$i")
+        ;;
+      --show-trace|--no-build-hook|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair)
+        extraBuildFlags+=("$i")
+        ;;
+      --max-jobs|-j|--cores|-I)
+        j="$1"; shift 1
+        extraBuildFlags+=("$i" "$j")
+        ;;
+      --option)
+        j="$1"; shift 1
+        k="$1"; shift 1
+        extraBuildFlags+=("$i" "$j" "$k")
+        ;;
+      --fast)
+        buildNix=
+        extraBuildFlags+=(--show-trace)
+        ;;
+      --profile-name|-p)
+        if [ -z "$1" ]; then
+            echo "$0: ‘--profile-name’ requires an argument"
+            exit 1
+        fi
+        if [ "$1" != system ]; then
+            profile="/nix/var/nix/profiles/system-profiles/$1"
+            mkdir -p -m 0755 "$(dirname "$profile")"
+        fi
+        shift 1
+        ;;
+      *)
+        echo "$0: unknown option \`$i'"
+        exit 1
+        ;;
+    esac
+done
+
+if [ -z "$action" ]; then showSyntax; fi
+
+if [ -n "$rollback" ]; then
+    buildNix=
+fi
+
+
+tmpDir=$(mktemp -t -d nixos-rebuild.XXXXXX)
+trap 'rm -rf "$tmpDir"' EXIT
+
+
+# If the Nix daemon is running, then use it.  This allows us to use
+# the latest Nix from Nixpkgs (below) for expression evaluation, while
+# still using the old Nix (via the daemon) for actual store access.
+# This matters if the new Nix in Nixpkgs has a schema change.  It
+# would upgrade the schema, which should only happen once we actually
+# switch to the new configuration.
+# If --repair is given, don't try to use the Nix daemon, because the
+# flag can only be used directly.
+if [ -z "$repair" ] && systemctl show nix-daemon.socket nix-daemon.service | grep -q ActiveState=active; then
+    export NIX_REMOTE=${NIX_REMOTE:-daemon}
+fi
+
+
+# If ‘--upgrade’ is given, run ‘nix-channel --update nixos’.
+if [ -n "$upgrade" ]; then
+    nix-channel --update nixos
+fi
+
+
+# First build Nix, since NixOS may require a newer version than the
+# current one.  Of course, the same goes for Nixpkgs, but Nixpkgs is
+# more conservative.
+if [ "$action" != dry-run -a -n "$buildNix" ]; then
+    echo "building Nix..." >&2
+    if ! nix-build '<nixos>' -A config.environment.nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
+        if ! nix-build '<nixos>' -A nixFallback -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
+            nix-build '<nixpkgs>' -A nixUnstable -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null
+        fi
+    fi
+    PATH=$tmpDir/nix/bin:$PATH
+fi
+
+
+# Update the version suffix if we're building from Git (so that
+# nixos-version shows something useful).
+if nixos=$(nix-instantiate --find-file nixos "${extraBuildFlags[@]}"); then
+    suffix=$(@shell@ $nixos/modules/installer/tools/get-version-suffix "${extraBuildFlags[@]}")
+    if [ -n "$suffix" ]; then
+        echo -n "$suffix" > "$nixos/.version-suffix" || true
+    fi
+fi
+
+
+if [ "$action" = dry-run ]; then
+    extraBuildFlags+=(--dry-run)
+fi
+
+
+# Either upgrade the configuration in the system profile (for "switch"
+# or "boot"), or just build it and create a symlink "result" in the
+# current directory (for "build" and "test").
+if [ -z "$rollback" ]; then
+    echo "building the system configuration..." >&2
+    if [ "$action" = switch -o "$action" = boot ]; then
+        nix-env "${extraBuildFlags[@]}" -p "$profile" -f '<nixos>' --set -A system
+        pathToConfig="$profile"
+    elif [ "$action" = test -o "$action" = build -o "$action" = dry-run ]; then
+        nix-build '<nixos>' -A system -K -k "${extraBuildFlags[@]}" > /dev/null
+        pathToConfig=./result
+    elif [ "$action" = build-vm ]; then
+        nix-build '<nixos>' -A vm -K -k "${extraBuildFlags[@]}" > /dev/null
+        pathToConfig=./result
+    elif [ "$action" = build-vm-with-bootloader ]; then
+        nix-build '<nixos>' -A vmWithBootLoader -K -k "${extraBuildFlags[@]}" > /dev/null
+        pathToConfig=./result
+    else
+        showSyntax
+    fi
+else # [ -n "$rollback" ]
+    if [ "$action" = switch -o "$action" = boot ]; then
+        nix-env --rollback -p "$profile"
+        pathToConfig="$profile"
+    elif [ "$action" = test -o "$action" = build ]; then
+        systemNumber=$(
+            nix-env -p "$profile" --list-generations |
+            sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h'
+        )
+        ln -sT "$profile"-${systemNumber}-link ./result
+        pathToConfig=./result
+    else
+        showSyntax
+    fi
+fi
+
+
+# If we're not just building, then make the new configuration the boot
+# default and/or activate it now.
+if [ "$action" = switch -o "$action" = boot -o "$action" = test ]; then
+    $pathToConfig/bin/switch-to-configuration "$action"
+fi
+
+
+if [ "$action" = build-vm ]; then
+    cat >&2 <<EOF
+
+Done.  The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm).
+EOF
+fi
diff --git a/nixos/modules/installer/tools/nixos-version.sh b/nixos/modules/installer/tools/nixos-version.sh
new file mode 100644
index 00000000000..5dbf277fe4c
--- /dev/null
+++ b/nixos/modules/installer/tools/nixos-version.sh
@@ -0,0 +1,2 @@
+#! @shell@
+echo "@nixosVersion@ (@nixosCodeName@)"
diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix
new file mode 100644
index 00000000000..c761d74a890
--- /dev/null
+++ b/nixos/modules/installer/tools/tools.nix
@@ -0,0 +1,112 @@
+# This module generates nixos-install, nixos-rebuild,
+# nixos-hardware-scan, etc.
+
+{ config, pkgs, modulesPath, ... }:
+
+let
+  ### implementation
+  cfg = config.installer;
+
+  makeProg = args: pkgs.substituteAll (args // {
+    dir = "bin";
+    isExecutable = true;
+  });
+
+  nixosBuildVMS = makeProg {
+    name = "nixos-build-vms";
+    src = ./nixos-build-vms/nixos-build-vms.sh;
+  };
+
+  nixosInstall = makeProg {
+    name = "nixos-install";
+    src = ./nixos-install.sh;
+
+    inherit (pkgs) perl pathsFromGraph;
+    nix = config.environment.nix;
+
+    nixClosure = pkgs.runCommand "closure"
+      { exportReferencesGraph = ["refs" config.environment.nix]; }
+      "cp refs $out";
+  };
+
+  nixosRebuild = makeProg {
+    name = "nixos-rebuild";
+    src = ./nixos-rebuild.sh;
+  };
+
+  /*
+  nixosGenSeccureKeys = makeProg {
+    name = "nixos-gen-seccure-keys";
+    src = ./nixos-gen-seccure-keys.sh;
+  };
+  */
+
+  nixosHardwareScan = makeProg {
+    name = "nixos-hardware-scan";
+    src = ./nixos-hardware-scan.pl;
+    inherit (pkgs) perl dmidecode;
+  };
+
+  nixosOption = makeProg {
+    name = "nixos-option";
+    src = ./nixos-option.sh;
+  };
+
+  nixosVersion = makeProg {
+    name = "nixos-version";
+    src = ./nixos-version.sh;
+    inherit (config.system) nixosVersion nixosCodeName;
+  };
+
+  nixosGui = pkgs.xulrunnerWrapper {
+    launcher = "nixos-gui";
+    application = pkgs.stdenv.mkDerivation {
+      name = "nixos-gui";
+      buildCommand = ''
+        cp -r "$gui" "$out"
+
+        # Do not force the copy if the file exists in the sources (this
+        # happens for developpers)
+        test -e "$out/chrome/content/jquery-1.5.2.js" ||
+          cp -f "$jquery" "$out/chrome/content/jquery-1.5.2.js"
+      '';
+      gui = pkgs.lib.cleanSource "${modulesPath}/../gui";
+      jquery = pkgs.fetchurl {
+        url = http://code.jquery.com/jquery-1.5.2.min.js;
+        sha256 = "8f0a19ee8c606b35a10904951e0a27da1896eafe33c6e88cb7bcbe455f05a24a";
+      };
+    };
+  };
+
+in
+
+{
+  options = {
+
+    installer.enableGraphicalTools = pkgs.lib.mkOption {
+      default = false;
+      type = with pkgs.lib.types; bool;
+      example = true;
+      description = ''
+        Enable the installation of graphical tools.
+      '';
+    };
+
+  };
+
+  config = {
+    environment.systemPackages =
+      [ nixosBuildVMS
+        nixosInstall
+        nixosRebuild
+        nixosHardwareScan
+        #nixosGenSeccureKeys
+        nixosOption
+        nixosVersion
+      ] ++ pkgs.lib.optional cfg.enableGraphicalTools nixosGui;
+
+    system.build = {
+      inherit nixosInstall nixosHardwareScan nixosOption;
+    };
+  };
+}