uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead
https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948 this can do it nicely. Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
commit
56de2bcd43
30691 changed files with 3076956 additions and 0 deletions
22
nixos/modules/installer/tools/get-version-suffix
Normal file
22
nixos/modules/installer/tools/get-version-suffix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
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 nixpkgs=$(nix-instantiate --find-file nixpkgs "$@"); then
|
||||
getVersion $nixpkgs
|
||||
if [ -n "$rev" ]; then
|
||||
echo ".git.$rev"
|
||||
fi
|
||||
fi
|
||||
7
nixos/modules/installer/tools/nix-fallback-paths.nix
Normal file
7
nixos/modules/installer/tools/nix-fallback-paths.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
x86_64-linux = "/nix/store/6mjgljq8sm9bsz6k22as5ar3jw78644m-nix-2.8.1";
|
||||
i686-linux = "/nix/store/c4yjv4l8wncdla6ycicvsjrdf40xjkpp-nix-2.8.1";
|
||||
aarch64-linux = "/nix/store/qkgvks80mdibq7m86hqasgr5lpixbnmh-nix-2.8.1";
|
||||
x86_64-darwin = "/nix/store/riz4mzb1xhp36088ffnp40lz52bpxz01-nix-2.8.1";
|
||||
aarch64-darwin = "/nix/store/dirm8hsnmvvzjs21hrx8i84w8k453jzp-nix-2.8.1";
|
||||
}
|
||||
31
nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
Normal file
31
nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{ system ? builtins.currentSystem
|
||||
, config ? {}
|
||||
, networkExpr
|
||||
}:
|
||||
|
||||
let
|
||||
nodes = builtins.mapAttrs (vm: module: {
|
||||
_file = "${networkExpr}@node-${vm}";
|
||||
imports = [ module ];
|
||||
}) (import networkExpr);
|
||||
|
||||
pkgs = import ../../../../.. { inherit system config; };
|
||||
|
||||
testing = import ../../../../lib/testing-python.nix {
|
||||
inherit system pkgs;
|
||||
};
|
||||
|
||||
interactiveDriver = (testing.makeTest { inherit nodes; testScript = "start_all(); join_all();"; }).driverInteractive;
|
||||
in
|
||||
|
||||
|
||||
pkgs.runCommand "nixos-build-vms" { nativeBuildInputs = [ pkgs.makeWrapper ]; } ''
|
||||
mkdir -p $out/bin
|
||||
ln -s ${interactiveDriver}/bin/nixos-test-driver $out/bin/nixos-test-driver
|
||||
ln -s ${interactiveDriver}/bin/nixos-test-driver $out/bin/nixos-run-vms
|
||||
wrapProgram $out/bin/nixos-test-driver \
|
||||
--add-flags "--interactive"
|
||||
wrapProgram $out/bin/nixos-run-vms \
|
||||
--set testScript "${pkgs.writeText "start-all" "start_all(); join_all();"}" \
|
||||
--add-flags "--no-interactive"
|
||||
''
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#! @runtimeShell@ -e
|
||||
# shellcheck shell=bash
|
||||
|
||||
# Shows the usage of this command to the user
|
||||
|
||||
showUsage() {
|
||||
exec man nixos-build-vms
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse valid argument options
|
||||
|
||||
nixBuildArgs=()
|
||||
networkExpr=
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--no-out-link)
|
||||
nixBuildArgs+=("--no-out-link")
|
||||
;;
|
||||
--show-trace)
|
||||
nixBuildArgs+=("--show-trace")
|
||||
;;
|
||||
-h|--help)
|
||||
showUsage
|
||||
exit 0
|
||||
;;
|
||||
--option)
|
||||
shift
|
||||
nixBuildArgs+=("--option" "$1" "$2"); shift
|
||||
;;
|
||||
*)
|
||||
if [ -n "$networkExpr" ]; then
|
||||
echo "Network expression already set!"
|
||||
showUsage
|
||||
exit 1
|
||||
fi
|
||||
networkExpr="$(readlink -f "$1")"
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
if [ -z "$networkExpr" ]
|
||||
then
|
||||
echo "ERROR: A network expression must be specified!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build a network of VMs
|
||||
nix-build '<nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix>' \
|
||||
--argstr networkExpr "$networkExpr" "${nixBuildArgs[@]}"
|
||||
109
nixos/modules/installer/tools/nixos-enter.sh
Normal file
109
nixos/modules/installer/tools/nixos-enter.sh
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
#! @runtimeShell@
|
||||
# shellcheck shell=bash
|
||||
|
||||
set -e
|
||||
|
||||
# Re-exec ourselves in a private mount namespace so that our bind
|
||||
# mounts get cleaned up automatically.
|
||||
if [ -z "$NIXOS_ENTER_REEXEC" ]; then
|
||||
export NIXOS_ENTER_REEXEC=1
|
||||
if [ "$(id -u)" != 0 ]; then
|
||||
extraFlags="-r"
|
||||
fi
|
||||
exec unshare --fork --mount --uts --mount-proc --pid $extraFlags -- "$0" "$@"
|
||||
else
|
||||
mount --make-rprivate /
|
||||
fi
|
||||
|
||||
mountPoint=/mnt
|
||||
system=/nix/var/nix/profiles/system
|
||||
command=("$system/sw/bin/bash" "--login")
|
||||
silent=0
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
i="$1"; shift 1
|
||||
case "$i" in
|
||||
--root)
|
||||
mountPoint="$1"; shift 1
|
||||
;;
|
||||
--system)
|
||||
system="$1"; shift 1
|
||||
;;
|
||||
--help)
|
||||
exec man nixos-enter
|
||||
exit 1
|
||||
;;
|
||||
--command|-c)
|
||||
command=("$system/sw/bin/bash" "-c" "$1")
|
||||
shift 1
|
||||
;;
|
||||
--silent)
|
||||
silent=1
|
||||
;;
|
||||
--)
|
||||
command=("$@")
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "$0: unknown option \`$i'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ! -e $mountPoint/etc/NIXOS ]]; then
|
||||
echo "$0: '$mountPoint' is not a NixOS installation" >&2
|
||||
exit 126
|
||||
fi
|
||||
|
||||
mkdir -p "$mountPoint/dev" "$mountPoint/sys"
|
||||
chmod 0755 "$mountPoint/dev" "$mountPoint/sys"
|
||||
mount --rbind /dev "$mountPoint/dev"
|
||||
mount --rbind /sys "$mountPoint/sys"
|
||||
|
||||
# modified from https://github.com/archlinux/arch-install-scripts/blob/bb04ab435a5a89cd5e5ee821783477bc80db797f/arch-chroot.in#L26-L52
|
||||
chroot_add_resolv_conf() {
|
||||
local chrootDir="$1" resolvConf="$1/etc/resolv.conf"
|
||||
|
||||
[[ -e /etc/resolv.conf ]] || return 0
|
||||
|
||||
# Handle resolv.conf as a symlink to somewhere else.
|
||||
if [[ -L "$resolvConf" ]]; then
|
||||
# readlink(1) should always give us *something* since we know at this point
|
||||
# it's a symlink. For simplicity, ignore the case of nested symlinks.
|
||||
# We also ignore the possibility of `../`s escaping the root.
|
||||
resolvConf="$(readlink "$resolvConf")"
|
||||
if [[ "$resolvConf" = /* ]]; then
|
||||
resolvConf="$chrootDir$resolvConf"
|
||||
else
|
||||
resolvConf="$chrootDir/etc/$resolvConf"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ensure file exists to bind mount over
|
||||
if [[ ! -f "$resolvConf" ]]; then
|
||||
install -Dm644 /dev/null "$resolvConf" || return 1
|
||||
fi
|
||||
|
||||
mount --bind /etc/resolv.conf "$resolvConf"
|
||||
}
|
||||
|
||||
chroot_add_resolv_conf "$mountPoint" || echo "$0: failed to set up resolv.conf" >&2
|
||||
|
||||
(
|
||||
# If silent, write both stdout and stderr of activation script to /dev/null
|
||||
# otherwise, write both streams to stderr of this process
|
||||
if [ "$silent" -eq 1 ]; then
|
||||
exec 2>/dev/null
|
||||
fi
|
||||
|
||||
# Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
|
||||
LOCALE_ARCHIVE="$system/sw/lib/locale/locale-archive" IN_NIXOS_ENTER=1 chroot "$mountPoint" "$system/activate" 1>&2 || true
|
||||
|
||||
# Create /tmp
|
||||
chroot "$mountPoint" systemd-tmpfiles --create --remove --exclude-prefix=/dev 1>&2 || true
|
||||
)
|
||||
|
||||
unset TMPDIR
|
||||
|
||||
exec chroot "$mountPoint" "${command[@]}"
|
||||
684
nixos/modules/installer/tools/nixos-generate-config.pl
Normal file
684
nixos/modules/installer/tools/nixos-generate-config.pl
Normal file
|
|
@ -0,0 +1,684 @@
|
|||
#! @perl@
|
||||
|
||||
use strict;
|
||||
use Cwd 'abs_path';
|
||||
use File::Spec;
|
||||
use File::Path;
|
||||
use File::Basename;
|
||||
use File::Slurp;
|
||||
use File::stat;
|
||||
|
||||
umask(0022);
|
||||
|
||||
sub uniq {
|
||||
my %seen;
|
||||
my @res = ();
|
||||
foreach my $s (@_) {
|
||||
if (!defined $seen{$s}) {
|
||||
$seen{$s} = 1;
|
||||
push @res, $s;
|
||||
}
|
||||
}
|
||||
return @res;
|
||||
}
|
||||
|
||||
sub runCommand {
|
||||
my ($cmd) = @_;
|
||||
open FILE, "$cmd 2>&1 |" or die "Failed to execute: $cmd\n";
|
||||
my @ret = <FILE>;
|
||||
close FILE;
|
||||
return ($?, @ret);
|
||||
}
|
||||
|
||||
# Process the command line.
|
||||
my $outDir = "/etc/nixos";
|
||||
my $rootDir = ""; # = /
|
||||
my $force = 0;
|
||||
my $noFilesystems = 0;
|
||||
my $showHardwareConfig = 0;
|
||||
|
||||
for (my $n = 0; $n < scalar @ARGV; $n++) {
|
||||
my $arg = $ARGV[$n];
|
||||
if ($arg eq "--help") {
|
||||
exec "man nixos-generate-config" or die;
|
||||
}
|
||||
elsif ($arg eq "--dir") {
|
||||
$n++;
|
||||
$outDir = $ARGV[$n];
|
||||
die "$0: ‘--dir’ requires an argument\n" unless defined $outDir;
|
||||
}
|
||||
elsif ($arg eq "--root") {
|
||||
$n++;
|
||||
$rootDir = $ARGV[$n];
|
||||
die "$0: ‘--root’ requires an argument\n" unless defined $rootDir;
|
||||
die "$0: no need to specify `/` with `--root`, it is the default\n" if $rootDir eq "/";
|
||||
$rootDir =~ s/\/*$//; # remove trailing slashes
|
||||
$rootDir = File::Spec->rel2abs($rootDir); # resolve absolute path
|
||||
}
|
||||
elsif ($arg eq "--force") {
|
||||
$force = 1;
|
||||
}
|
||||
elsif ($arg eq "--no-filesystems") {
|
||||
$noFilesystems = 1;
|
||||
}
|
||||
elsif ($arg eq "--show-hardware-config") {
|
||||
$showHardwareConfig = 1;
|
||||
}
|
||||
else {
|
||||
die "$0: unrecognized argument ‘$arg’\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my @attrs = ();
|
||||
my @kernelModules = ();
|
||||
my @initrdKernelModules = ();
|
||||
my @initrdAvailableKernelModules = ();
|
||||
my @modulePackages = ();
|
||||
my @imports;
|
||||
|
||||
|
||||
sub debug {
|
||||
return unless defined $ENV{"DEBUG"};
|
||||
print STDERR @_;
|
||||
}
|
||||
|
||||
|
||||
my $cpuinfo = read_file "/proc/cpuinfo";
|
||||
|
||||
|
||||
sub hasCPUFeature {
|
||||
my $feature = shift;
|
||||
return $cpuinfo =~ /^flags\s*:.* $feature( |$)/m;
|
||||
}
|
||||
|
||||
|
||||
sub cpuManufacturer {
|
||||
my $id = shift;
|
||||
return $cpuinfo =~ /^vendor_id\s*:.* $id$/m;
|
||||
}
|
||||
|
||||
|
||||
# Determine CPU governor to use
|
||||
if (-e "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors") {
|
||||
my $governors = read_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors");
|
||||
# ondemand governor is not available on sandy bridge or later Intel CPUs
|
||||
my @desired_governors = ("ondemand", "powersave");
|
||||
my $e;
|
||||
|
||||
foreach $e (@desired_governors) {
|
||||
if (index($governors, $e) != -1) {
|
||||
last if (push @attrs, "powerManagement.cpuFreqGovernor = lib.mkDefault \"$e\";");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Virtualization support?
|
||||
push @kernelModules, "kvm-intel" if hasCPUFeature "vmx";
|
||||
push @kernelModules, "kvm-amd" if hasCPUFeature "svm";
|
||||
|
||||
push @attrs, "hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;" if cpuManufacturer "AuthenticAMD";
|
||||
push @attrs, "hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;" if cpuManufacturer "GenuineIntel";
|
||||
|
||||
|
||||
# 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 = read_file "$path/vendor"; chomp $vendor;
|
||||
my $device = read_file "$path/device"; chomp $device;
|
||||
my $class = read_file "$path/class"; chomp $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 @initrdAvailableKernelModules, $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" ||
|
||||
$device eq "0x4331" || $device eq "0x43a0" || $device eq "0x43b1"
|
||||
) )
|
||||
{
|
||||
push @modulePackages, "config.boot.kernelPackages.broadcom_sta";
|
||||
push @kernelModules, "wl";
|
||||
}
|
||||
|
||||
# broadcom FullMac driver
|
||||
# list taken from
|
||||
# https://wireless.wiki.kernel.org/en/users/Drivers/brcm80211#brcmfmac
|
||||
if ($vendor eq "0x14e4" &&
|
||||
($device eq "0x43a3" || $device eq "0x43df" || $device eq "0x43ec" ||
|
||||
$device eq "0x43d3" || $device eq "0x43d9" || $device eq "0x43e9" ||
|
||||
$device eq "0x43ba" || $device eq "0x43bb" || $device eq "0x43bc" ||
|
||||
$device eq "0xaa52" || $device eq "0x43ca" || $device eq "0x43cb" ||
|
||||
$device eq "0x43cc" || $device eq "0x43c3" || $device eq "0x43c4" ||
|
||||
$device eq "0x43c5"
|
||||
) )
|
||||
{
|
||||
# we need e.g. brcmfmac43602-pcie.bin
|
||||
push @imports, "(modulesPath + \"/hardware/network/broadcom-43xx.nix\")";
|
||||
}
|
||||
|
||||
# In case this is a virtio scsi device, we need to explicitly make this available.
|
||||
if ($vendor eq "0x1af4" && $device eq "0x1004") {
|
||||
push @initrdAvailableKernelModules, "virtio_scsi";
|
||||
}
|
||||
|
||||
# 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).
|
||||
# FIXME: do we want to enable an unfree driver here?
|
||||
#$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 = read_file "$path/bInterfaceClass"; chomp $class;
|
||||
my $subclass = read_file "$path/bInterfaceSubClass"; chomp $subclass;
|
||||
my $protocol = read_file "$path/bInterfaceProtocol"; chomp $protocol;
|
||||
|
||||
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 @initrdAvailableKernelModules, $module;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $path (glob "/sys/bus/usb/devices/*") {
|
||||
if (-e "$path/bInterfaceClass") {
|
||||
usbCheck $path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Add the modules for all block and MMC devices.
|
||||
foreach my $path (glob "/sys/class/{block,mmc_host}/*") {
|
||||
my $module;
|
||||
if (-e "$path/device/driver/module") {
|
||||
$module = basename `readlink -f $path/device/driver/module`;
|
||||
chomp $module;
|
||||
push @initrdAvailableKernelModules, $module;
|
||||
}
|
||||
}
|
||||
|
||||
# Add bcache module, if needed.
|
||||
my @bcacheDevices = glob("/dev/bcache*");
|
||||
if (scalar @bcacheDevices > 0) {
|
||||
push @initrdAvailableKernelModules, "bcache";
|
||||
}
|
||||
|
||||
# Prevent unbootable systems if LVM snapshots are present at boot time.
|
||||
if (`lsblk -o TYPE` =~ "lvm") {
|
||||
push @initrdKernelModules, "dm-snapshot";
|
||||
}
|
||||
|
||||
my $virt = `@detectvirt@`;
|
||||
chomp $virt;
|
||||
|
||||
|
||||
# Check if we're a VirtualBox guest. If so, enable the guest
|
||||
# additions.
|
||||
if ($virt eq "oracle") {
|
||||
push @attrs, "virtualisation.virtualbox.guest.enable = true;"
|
||||
}
|
||||
|
||||
|
||||
# Likewise for QEMU.
|
||||
if ($virt eq "qemu" || $virt eq "kvm" || $virt eq "bochs") {
|
||||
push @imports, "(modulesPath + \"/profiles/qemu-guest.nix\")";
|
||||
}
|
||||
|
||||
# Also for Hyper-V.
|
||||
if ($virt eq "microsoft") {
|
||||
push @attrs, "virtualisation.hypervGuest.enable = true;"
|
||||
}
|
||||
|
||||
|
||||
# Pull in NixOS configuration for containers.
|
||||
if ($virt eq "systemd-nspawn") {
|
||||
push @attrs, "boot.isContainer = true;";
|
||||
}
|
||||
|
||||
|
||||
# Provide firmware for devices that are not detected by this script,
|
||||
# unless we're in a VM/container.
|
||||
push @imports, "(modulesPath + \"/installer/scan/not-detected.nix\")"
|
||||
if $virt eq "none";
|
||||
|
||||
|
||||
# For a device name like /dev/sda1, find a more stable path like
|
||||
# /dev/disk/by-uuid/X or /dev/disk/by-label/Y.
|
||||
sub findStableDevPath {
|
||||
my ($dev) = @_;
|
||||
return $dev if substr($dev, 0, 1) ne "/";
|
||||
return $dev unless -e $dev;
|
||||
|
||||
my $st = stat($dev) or return $dev;
|
||||
|
||||
foreach my $dev2 (glob("/dev/disk/by-uuid/*"), glob("/dev/mapper/*"), glob("/dev/disk/by-label/*")) {
|
||||
my $st2 = stat($dev2) or next;
|
||||
return $dev2 if $st->rdev == $st2->rdev;
|
||||
}
|
||||
|
||||
return $dev;
|
||||
}
|
||||
|
||||
push @attrs, "services.xserver.videoDrivers = [ \"$videoDriver\" ];" if $videoDriver;
|
||||
|
||||
# Generate the swapDevices option from the currently activated swap
|
||||
# devices.
|
||||
my @swaps = read_file("/proc/swaps", err_mode => 'carp');
|
||||
my @swapDevices;
|
||||
if (@swaps) {
|
||||
shift @swaps;
|
||||
foreach my $swap (@swaps) {
|
||||
my @fields = split ' ', $swap;
|
||||
my $swapFilename = $fields[0];
|
||||
my $swapType = $fields[1];
|
||||
next unless -e $swapFilename;
|
||||
my $dev = findStableDevPath $swapFilename;
|
||||
if ($swapType =~ "partition") {
|
||||
# zram devices are more likely created by configuration.nix, so
|
||||
# ignore them here
|
||||
next if ($swapFilename =~ /^\/dev\/zram/);
|
||||
push @swapDevices, "{ device = \"$dev\"; }";
|
||||
} elsif ($swapType =~ "file") {
|
||||
# swap *files* are more likely specified in configuration.nix, so
|
||||
# ignore them here.
|
||||
} else {
|
||||
die "Unsupported swap type: $swapType\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Generate the fileSystems option from the currently mounted
|
||||
# filesystems.
|
||||
sub in {
|
||||
my ($d1, $d2) = @_;
|
||||
return $d1 eq $d2 || substr($d1, 0, length($d2) + 1) eq "$d2/";
|
||||
}
|
||||
|
||||
my $fileSystems;
|
||||
my %fsByDev;
|
||||
foreach my $fs (read_file("/proc/self/mountinfo")) {
|
||||
chomp $fs;
|
||||
my @fields = split / /, $fs;
|
||||
my $mountPoint = $fields[4];
|
||||
$mountPoint =~ s/\\040/ /g; # account for mount points with spaces in the name (\040 is the escape character)
|
||||
$mountPoint =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
|
||||
next unless -d $mountPoint;
|
||||
my @mountOptions = split /,/, $fields[5];
|
||||
|
||||
next if !in($mountPoint, $rootDir);
|
||||
$mountPoint = substr($mountPoint, length($rootDir)); # strip the root directory (e.g. /mnt)
|
||||
$mountPoint = "/" if $mountPoint eq "";
|
||||
|
||||
# Skip special filesystems.
|
||||
next if in($mountPoint, "/proc") || in($mountPoint, "/dev") || in($mountPoint, "/sys") || in($mountPoint, "/run") || $mountPoint eq "/var/lib/nfs/rpc_pipefs";
|
||||
|
||||
# Skip the optional fields.
|
||||
my $n = 6; $n++ while $fields[$n] ne "-"; $n++;
|
||||
my $fsType = $fields[$n];
|
||||
my $device = $fields[$n + 1];
|
||||
my @superOptions = split /,/, $fields[$n + 2];
|
||||
$device =~ s/\\040/ /g; # account for devices with spaces in the name (\040 is the escape character)
|
||||
$device =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
|
||||
|
||||
# Skip the read-only bind-mount on /nix/store.
|
||||
next if $mountPoint eq "/nix/store" && (grep { $_ eq "rw" } @superOptions) && (grep { $_ eq "ro" } @mountOptions);
|
||||
|
||||
# Maybe this is a bind-mount of a filesystem we saw earlier?
|
||||
if (defined $fsByDev{$fields[2]}) {
|
||||
# Make sure this isn't a btrfs subvolume.
|
||||
my $msg = `@btrfs@ subvol show $rootDir$mountPoint`;
|
||||
if ($? != 0 || $msg =~ /ERROR:/s) {
|
||||
my $path = $fields[3]; $path = "" if $path eq "/";
|
||||
my $base = $fsByDev{$fields[2]};
|
||||
$base = "" if $base eq "/";
|
||||
$fileSystems .= <<EOF;
|
||||
fileSystems.\"$mountPoint\" =
|
||||
{ device = \"$base$path\";
|
||||
fsType = \"none\";
|
||||
options = \[ \"bind\" \];
|
||||
};
|
||||
|
||||
EOF
|
||||
next;
|
||||
}
|
||||
}
|
||||
$fsByDev{$fields[2]} = $mountPoint;
|
||||
|
||||
# We don't know how to handle FUSE filesystems.
|
||||
if ($fsType eq "fuseblk" || $fsType eq "fuse") {
|
||||
print STDERR "warning: don't know how to emit ‘fileSystem’ option for FUSE filesystem ‘$mountPoint’\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Is this a mount of a loopback device?
|
||||
my @extraOptions;
|
||||
if ($device =~ /\/dev\/loop(\d+)/) {
|
||||
my $loopnr = $1;
|
||||
my $backer = read_file "/sys/block/loop$loopnr/loop/backing_file";
|
||||
if (defined $backer) {
|
||||
chomp $backer;
|
||||
$device = $backer;
|
||||
push @extraOptions, "loop";
|
||||
}
|
||||
}
|
||||
|
||||
# Is this a btrfs filesystem?
|
||||
if ($fsType eq "btrfs") {
|
||||
my ($status, @info) = runCommand("@btrfs@ subvol show $rootDir$mountPoint");
|
||||
if ($status != 0 || join("", @info) =~ /ERROR:/) {
|
||||
die "Failed to retrieve subvolume info for $mountPoint\n";
|
||||
}
|
||||
my @ids = join("\n", @info) =~ m/^(?!\/\n).*Subvolume ID:[ \t\n]*([0-9]+)/s;
|
||||
if ($#ids > 0) {
|
||||
die "Btrfs subvol name for $mountPoint listed multiple times in mount\n"
|
||||
} elsif ($#ids == 0) {
|
||||
my @paths = join("", @info) =~ m/^([^\n]*)/;
|
||||
if ($#paths > 0) {
|
||||
die "Btrfs returned multiple paths for a single subvolume id, mountpoint $mountPoint\n";
|
||||
} elsif ($#paths != 0) {
|
||||
die "Btrfs did not return a path for the subvolume at $mountPoint\n";
|
||||
}
|
||||
push @extraOptions, "subvol=$paths[0]";
|
||||
}
|
||||
}
|
||||
|
||||
# Don't emit tmpfs entry for /tmp, because it most likely comes from the
|
||||
# boot.tmpOnTmpfs option in configuration.nix (managed declaratively).
|
||||
next if ($mountPoint eq "/tmp" && $fsType eq "tmpfs");
|
||||
|
||||
# Emit the filesystem.
|
||||
$fileSystems .= <<EOF;
|
||||
fileSystems.\"$mountPoint\" =
|
||||
{ device = \"${\(findStableDevPath $device)}\";
|
||||
fsType = \"$fsType\";
|
||||
EOF
|
||||
|
||||
if (scalar @extraOptions > 0) {
|
||||
$fileSystems .= <<EOF;
|
||||
options = \[ ${\join " ", map { "\"" . $_ . "\"" } uniq(@extraOptions)} \];
|
||||
EOF
|
||||
}
|
||||
|
||||
$fileSystems .= <<EOF;
|
||||
};
|
||||
|
||||
EOF
|
||||
|
||||
# If this filesystem is on a LUKS device, then add a
|
||||
# boot.initrd.luks.devices entry.
|
||||
if (-e $device) {
|
||||
my $deviceName = basename(abs_path($device));
|
||||
if (-e "/sys/class/block/$deviceName"
|
||||
&& read_file("/sys/class/block/$deviceName/dm/uuid", err_mode => 'quiet') =~ /^CRYPT-LUKS/)
|
||||
{
|
||||
my @slaves = glob("/sys/class/block/$deviceName/slaves/*");
|
||||
if (scalar @slaves == 1) {
|
||||
my $slave = "/dev/" . basename($slaves[0]);
|
||||
if (-e $slave) {
|
||||
my $dmName = read_file("/sys/class/block/$deviceName/dm/name");
|
||||
chomp $dmName;
|
||||
# Ensure to add an entry only once
|
||||
my $luksDevice = " boot.initrd.luks.devices.\"$dmName\".device";
|
||||
if ($fileSystems !~ /^\Q$luksDevice\E/m) {
|
||||
$fileSystems .= "$luksDevice = \"${\(findStableDevPath $slave)}\";\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# For lack of a better way to determine it, guess whether we should use a
|
||||
# bigger font for the console from the display mode on the first
|
||||
# framebuffer. A way based on the physical size/actual DPI reported by
|
||||
# the monitor would be nice, but I don't know how to do this without X :)
|
||||
my $fb_modes_file = "/sys/class/graphics/fb0/modes";
|
||||
if (-f $fb_modes_file && -r $fb_modes_file) {
|
||||
my $modes = read_file($fb_modes_file);
|
||||
$modes =~ m/([0-9]+)x([0-9]+)/;
|
||||
my $console_width = $1, my $console_height = $2;
|
||||
if ($console_width > 1920) {
|
||||
push @attrs, "# high-resolution display";
|
||||
push @attrs, 'hardware.video.hidpi.enable = lib.mkDefault true;';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Generate the hardware configuration file.
|
||||
|
||||
sub toNixStringList {
|
||||
my $res = "";
|
||||
foreach my $s (@_) {
|
||||
$res .= " \"$s\"";
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
sub toNixList {
|
||||
my $res = "";
|
||||
foreach my $s (@_) {
|
||||
$res .= " $s";
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub multiLineList {
|
||||
my $indent = shift;
|
||||
return " [ ]" if !@_;
|
||||
my $res = "\n${indent}[ ";
|
||||
my $first = 1;
|
||||
foreach my $s (@_) {
|
||||
$res .= "$indent " if !$first;
|
||||
$first = 0;
|
||||
$res .= "$s\n";
|
||||
}
|
||||
$res .= "$indent]";
|
||||
return $res;
|
||||
}
|
||||
|
||||
my $initrdAvailableKernelModules = toNixStringList(uniq @initrdAvailableKernelModules);
|
||||
my $initrdKernelModules = toNixStringList(uniq @initrdKernelModules);
|
||||
my $kernelModules = toNixStringList(uniq @kernelModules);
|
||||
my $modulePackages = toNixList(uniq @modulePackages);
|
||||
|
||||
my $fsAndSwap = "";
|
||||
if (!$noFilesystems) {
|
||||
$fsAndSwap = "\n$fileSystems ";
|
||||
$fsAndSwap .= "swapDevices =" . multiLineList(" ", @swapDevices) . ";\n";
|
||||
}
|
||||
|
||||
my $networkingDhcpConfig = generateNetworkingDhcpConfig();
|
||||
|
||||
my $hwConfig = <<EOF;
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =${\multiLineList(" ", @imports)};
|
||||
|
||||
boot.initrd.availableKernelModules = [$initrdAvailableKernelModules ];
|
||||
boot.initrd.kernelModules = [$initrdKernelModules ];
|
||||
boot.kernelModules = [$kernelModules ];
|
||||
boot.extraModulePackages = [$modulePackages ];
|
||||
$fsAndSwap
|
||||
$networkingDhcpConfig
|
||||
${\join "", (map { " $_\n" } (uniq @attrs))}}
|
||||
EOF
|
||||
|
||||
sub generateNetworkingDhcpConfig {
|
||||
# FIXME disable networking.useDHCP by default when switching to networkd.
|
||||
my $config = <<EOF;
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
# still possible to use this option, but it's recommended to use it in conjunction
|
||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
EOF
|
||||
|
||||
foreach my $path (glob "/sys/class/net/*") {
|
||||
my $dev = basename($path);
|
||||
if ($dev ne "lo") {
|
||||
$config .= " # networking.interfaces.$dev.useDHCP = lib.mkDefault true;\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
sub generateXserverConfig {
|
||||
my $xserverEnabled = "@xserverEnabled@";
|
||||
|
||||
my $config = "";
|
||||
if ($xserverEnabled eq "1") {
|
||||
$config = <<EOF;
|
||||
# Enable the X11 windowing system.
|
||||
services.xserver.enable = true;
|
||||
EOF
|
||||
} else {
|
||||
$config = <<EOF;
|
||||
# Enable the X11 windowing system.
|
||||
# services.xserver.enable = true;
|
||||
EOF
|
||||
}
|
||||
}
|
||||
|
||||
if ($showHardwareConfig) {
|
||||
print STDOUT $hwConfig;
|
||||
} else {
|
||||
if ($outDir eq "/etc/nixos") {
|
||||
$outDir = "$rootDir$outDir";
|
||||
} else {
|
||||
$outDir = File::Spec->rel2abs($outDir);
|
||||
$outDir =~ s/\/*$//; # remove trailing slashes
|
||||
}
|
||||
|
||||
my $fn = "$outDir/hardware-configuration.nix";
|
||||
print STDERR "writing $fn...\n";
|
||||
mkpath($outDir, 0, 0755);
|
||||
write_file($fn, $hwConfig);
|
||||
|
||||
# Generate a basic configuration.nix, unless one already exists.
|
||||
$fn = "$outDir/configuration.nix";
|
||||
if ($force || ! -e $fn) {
|
||||
print STDERR "writing $fn...\n";
|
||||
|
||||
my $bootLoaderConfig = "";
|
||||
if (-e "/sys/firmware/efi/efivars") {
|
||||
$bootLoaderConfig = <<EOF;
|
||||
# Use the systemd-boot EFI boot loader.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
EOF
|
||||
} elsif (-e "/boot/extlinux") {
|
||||
$bootLoaderConfig = <<EOF;
|
||||
# Use the extlinux boot loader. (NixOS wants to enable GRUB by default)
|
||||
boot.loader.grub.enable = false;
|
||||
# Enables the generation of /boot/extlinux/extlinux.conf
|
||||
boot.loader.generic-extlinux-compatible.enable = true;
|
||||
EOF
|
||||
} elsif ($virt ne "systemd-nspawn") {
|
||||
$bootLoaderConfig = <<EOF;
|
||||
# Use the GRUB 2 boot loader.
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.version = 2;
|
||||
# boot.loader.grub.efiSupport = true;
|
||||
# boot.loader.grub.efiInstallAsRemovable = true;
|
||||
# boot.loader.efi.efiSysMountPoint = "/boot/efi";
|
||||
# Define on which hard drive you want to install Grub.
|
||||
# boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
|
||||
EOF
|
||||
}
|
||||
|
||||
my $networkingDhcpConfig = generateNetworkingDhcpConfig();
|
||||
|
||||
my $xserverConfig = generateXserverConfig();
|
||||
|
||||
(my $desktopConfiguration = <<EOF)=~s/^/ /gm;
|
||||
@desktopConfiguration@
|
||||
EOF
|
||||
|
||||
write_file($fn, <<EOF);
|
||||
@configuration@
|
||||
EOF
|
||||
print STDERR "For more hardware-specific settings, see https://github.com/NixOS/nixos-hardware.\n"
|
||||
} else {
|
||||
print STDERR "warning: not overwriting existing $fn\n";
|
||||
}
|
||||
}
|
||||
|
||||
# workaround for a bug in substituteAll
|
||||
218
nixos/modules/installer/tools/nixos-install.sh
Normal file
218
nixos/modules/installer/tools/nixos-install.sh
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
#! @runtimeShell@
|
||||
# shellcheck shell=bash
|
||||
|
||||
set -e
|
||||
shopt -s nullglob
|
||||
|
||||
export PATH=@path@:$PATH
|
||||
|
||||
# Ensure a consistent umask.
|
||||
umask 0022
|
||||
|
||||
# Parse the command line for the -I flag
|
||||
extraBuildFlags=()
|
||||
flakeFlags=()
|
||||
|
||||
mountPoint=/mnt
|
||||
channelPath=
|
||||
system=
|
||||
verbosity=()
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
i="$1"; shift 1
|
||||
case "$i" in
|
||||
--max-jobs|-j|--cores|-I|--substituters)
|
||||
j="$1"; shift 1
|
||||
extraBuildFlags+=("$i" "$j")
|
||||
;;
|
||||
--option)
|
||||
j="$1"; shift 1
|
||||
k="$1"; shift 1
|
||||
extraBuildFlags+=("$i" "$j" "$k")
|
||||
;;
|
||||
--root)
|
||||
mountPoint="$1"; shift 1
|
||||
;;
|
||||
--system|--closure)
|
||||
system="$1"; shift 1
|
||||
;;
|
||||
--flake)
|
||||
flake="$1"
|
||||
flakeFlags=(--experimental-features 'nix-command flakes')
|
||||
shift 1
|
||||
;;
|
||||
--recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
|
||||
lockFlags+=("$i")
|
||||
;;
|
||||
--update-input)
|
||||
j="$1"; shift 1
|
||||
lockFlags+=("$i" "$j")
|
||||
;;
|
||||
--override-input)
|
||||
j="$1"; shift 1
|
||||
k="$1"; shift 1
|
||||
lockFlags+=("$i" "$j" "$k")
|
||||
;;
|
||||
--channel)
|
||||
channelPath="$1"; shift 1
|
||||
;;
|
||||
--no-channel-copy)
|
||||
noChannelCopy=1
|
||||
;;
|
||||
--no-root-password|--no-root-passwd)
|
||||
noRootPasswd=1
|
||||
;;
|
||||
--no-bootloader)
|
||||
noBootLoader=1
|
||||
;;
|
||||
--show-trace|--impure|--keep-going)
|
||||
extraBuildFlags+=("$i")
|
||||
;;
|
||||
--help)
|
||||
exec man nixos-install
|
||||
exit 1
|
||||
;;
|
||||
--debug)
|
||||
set -x
|
||||
;;
|
||||
-v*|--verbose)
|
||||
verbosity+=("$i")
|
||||
;;
|
||||
*)
|
||||
echo "$0: unknown option \`$i'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! test -e "$mountPoint"; then
|
||||
echo "mount point $mountPoint doesn't exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify permissions are okay-enough
|
||||
checkPath="$(realpath "$mountPoint")"
|
||||
while [[ "$checkPath" != "/" ]]; do
|
||||
mode="$(stat -c '%a' "$checkPath")"
|
||||
if [[ "${mode: -1}" -lt "5" ]]; then
|
||||
echo "path $checkPath should have permissions 755, but had permissions $mode. Consider running 'chmod o+rx $checkPath'."
|
||||
exit 1
|
||||
fi
|
||||
checkPath="$(dirname "$checkPath")"
|
||||
done
|
||||
|
||||
# Get the path of the NixOS configuration file.
|
||||
if [[ -z $NIXOS_CONFIG ]]; then
|
||||
NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix
|
||||
fi
|
||||
|
||||
if [[ ${NIXOS_CONFIG:0:1} != / ]]; then
|
||||
echo "$0: \$NIXOS_CONFIG is not an absolute path"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n $flake ]]; then
|
||||
if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
|
||||
flake="${BASH_REMATCH[1]}"
|
||||
flakeAttr="${BASH_REMATCH[2]}"
|
||||
fi
|
||||
if [[ -z "$flakeAttr" ]]; then
|
||||
echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri."
|
||||
echo "For example, to use the output nixosConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri."
|
||||
exit 1
|
||||
fi
|
||||
flakeAttr="nixosConfigurations.\"$flakeAttr\""
|
||||
fi
|
||||
|
||||
# Resolve the flake.
|
||||
if [[ -n $flake ]]; then
|
||||
flake=$(nix "${flakeFlags[@]}" flake metadata --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url)
|
||||
fi
|
||||
|
||||
if [[ ! -e $NIXOS_CONFIG && -z $system && -z $flake ]]; then
|
||||
echo "configuration file $NIXOS_CONFIG doesn't exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# A place to drop temporary stuff.
|
||||
tmpdir="$(mktemp -d -p "$mountPoint")"
|
||||
trap 'rm -rf $tmpdir' EXIT
|
||||
|
||||
# store temporary files on target filesystem by default
|
||||
export TMPDIR=${TMPDIR:-$tmpdir}
|
||||
|
||||
sub="auto?trusted=1"
|
||||
|
||||
# Copy the NixOS/Nixpkgs sources to the target as the initial contents
|
||||
# of the NixOS channel.
|
||||
if [[ -z $noChannelCopy ]]; then
|
||||
if [[ -z $channelPath ]]; then
|
||||
channelPath="$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")"
|
||||
fi
|
||||
if [[ -n $channelPath ]]; then
|
||||
echo "copying channel..."
|
||||
mkdir -p "$mountPoint"/nix/var/nix/profiles/per-user/root
|
||||
nix-env --store "$mountPoint" "${extraBuildFlags[@]}" --extra-substituters "$sub" \
|
||||
-p "$mountPoint"/nix/var/nix/profiles/per-user/root/channels --set "$channelPath" --quiet \
|
||||
"${verbosity[@]}"
|
||||
install -m 0700 -d "$mountPoint"/root/.nix-defexpr
|
||||
ln -sfn /nix/var/nix/profiles/per-user/root/channels "$mountPoint"/root/.nix-defexpr/channels
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build the system configuration in the target filesystem.
|
||||
if [[ -z $system ]]; then
|
||||
outLink="$tmpdir/system"
|
||||
if [[ -z $flake ]]; then
|
||||
echo "building the configuration in $NIXOS_CONFIG..."
|
||||
nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \
|
||||
--extra-substituters "$sub" \
|
||||
'<nixpkgs/nixos>' -A system -I "nixos-config=$NIXOS_CONFIG" "${verbosity[@]}"
|
||||
else
|
||||
echo "building the flake in $flake..."
|
||||
nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" \
|
||||
--store "$mountPoint" --extra-substituters "$sub" "${verbosity[@]}" \
|
||||
"${extraBuildFlags[@]}" "${lockFlags[@]}" --out-link "$outLink"
|
||||
fi
|
||||
system=$(readlink -f "$outLink")
|
||||
fi
|
||||
|
||||
# Set the system profile to point to the configuration. TODO: combine
|
||||
# this with the previous step once we have a nix-env replacement with
|
||||
# a progress bar.
|
||||
nix-env --store "$mountPoint" "${extraBuildFlags[@]}" \
|
||||
--extra-substituters "$sub" \
|
||||
-p "$mountPoint"/nix/var/nix/profiles/system --set "$system" "${verbosity[@]}"
|
||||
|
||||
# Mark the target as a NixOS installation, otherwise switch-to-configuration will chicken out.
|
||||
mkdir -m 0755 -p "$mountPoint/etc"
|
||||
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.
|
||||
if [[ -z $noBootLoader ]]; then
|
||||
echo "installing the boot loader..."
|
||||
# Grub needs an mtab.
|
||||
ln -sfn /proc/mounts "$mountPoint"/etc/mtab
|
||||
NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root "$mountPoint" -- /run/current-system/bin/switch-to-configuration boot
|
||||
fi
|
||||
|
||||
# Ask the user to set a root password, but only if the passwd command
|
||||
# exists (i.e. when mutable user accounts are enabled).
|
||||
if [[ -z $noRootPasswd ]] && [ -t 0 ]; then
|
||||
if nixos-enter --root "$mountPoint" -c 'test -e /nix/var/nix/profiles/system/sw/bin/passwd'; then
|
||||
set +e
|
||||
nixos-enter --root "$mountPoint" -c 'echo "setting root password..." && /nix/var/nix/profiles/system/sw/bin/passwd'
|
||||
exit_code=$?
|
||||
set -e
|
||||
|
||||
if [[ $exit_code != 0 ]]; then
|
||||
echo "Setting a root password failed with the above printed error."
|
||||
echo "You can set the root password manually by executing \`nixos-enter --root ${mountPoint@Q}\` and then running \`passwd\` in the shell of the new system."
|
||||
exit $exit_code
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "installation finished!"
|
||||
1
nixos/modules/installer/tools/nixos-option/default.nix
Normal file
1
nixos/modules/installer/tools/nixos-option/default.nix
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ pkgs, ... }: pkgs.nixos-option
|
||||
24
nixos/modules/installer/tools/nixos-version.sh
Normal file
24
nixos/modules/installer/tools/nixos-version.sh
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#! @runtimeShell@
|
||||
# shellcheck shell=bash
|
||||
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
exec man nixos-version
|
||||
exit 1
|
||||
;;
|
||||
--hash|--revision)
|
||||
if ! [[ @revision@ =~ ^[0-9a-f]+$ ]]; then
|
||||
echo "$0: Nixpkgs commit hash is unknown"
|
||||
exit 1
|
||||
fi
|
||||
echo "@revision@"
|
||||
;;
|
||||
--json)
|
||||
cat <<EOF
|
||||
@json@
|
||||
EOF
|
||||
;;
|
||||
*)
|
||||
echo "@version@ (@codeName@)"
|
||||
;;
|
||||
esac
|
||||
243
nixos/modules/installer/tools/tools.nix
Normal file
243
nixos/modules/installer/tools/tools.nix
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
# This module generates nixos-install, nixos-rebuild,
|
||||
# nixos-generate-config, etc.
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
makeProg = args: pkgs.substituteAll (args // {
|
||||
dir = "bin";
|
||||
isExecutable = true;
|
||||
});
|
||||
|
||||
nixos-build-vms = makeProg {
|
||||
name = "nixos-build-vms";
|
||||
src = ./nixos-build-vms/nixos-build-vms.sh;
|
||||
inherit (pkgs) runtimeShell;
|
||||
};
|
||||
|
||||
nixos-install = makeProg {
|
||||
name = "nixos-install";
|
||||
src = ./nixos-install.sh;
|
||||
inherit (pkgs) runtimeShell;
|
||||
nix = config.nix.package.out;
|
||||
path = makeBinPath [
|
||||
pkgs.jq
|
||||
nixos-enter
|
||||
];
|
||||
};
|
||||
|
||||
nixos-rebuild = pkgs.nixos-rebuild.override { nix = config.nix.package.out; };
|
||||
|
||||
nixos-generate-config = makeProg {
|
||||
name = "nixos-generate-config";
|
||||
src = ./nixos-generate-config.pl;
|
||||
perl = "${pkgs.perl.withPackages (p: [ p.FileSlurp ])}/bin/perl";
|
||||
detectvirt = "${config.systemd.package}/bin/systemd-detect-virt";
|
||||
btrfs = "${pkgs.btrfs-progs}/bin/btrfs";
|
||||
inherit (config.system.nixos-generate-config) configuration desktopConfiguration;
|
||||
xserverEnabled = config.services.xserver.enable;
|
||||
};
|
||||
|
||||
nixos-option =
|
||||
if lib.versionAtLeast (lib.getVersion config.nix.package) "2.4pre"
|
||||
then null
|
||||
else pkgs.nixos-option;
|
||||
|
||||
nixos-version = makeProg {
|
||||
name = "nixos-version";
|
||||
src = ./nixos-version.sh;
|
||||
inherit (pkgs) runtimeShell;
|
||||
inherit (config.system.nixos) version codeName revision;
|
||||
inherit (config.system) configurationRevision;
|
||||
json = builtins.toJSON ({
|
||||
nixosVersion = config.system.nixos.version;
|
||||
} // optionalAttrs (config.system.nixos.revision != null) {
|
||||
nixpkgsRevision = config.system.nixos.revision;
|
||||
} // optionalAttrs (config.system.configurationRevision != null) {
|
||||
configurationRevision = config.system.configurationRevision;
|
||||
});
|
||||
};
|
||||
|
||||
nixos-enter = makeProg {
|
||||
name = "nixos-enter";
|
||||
src = ./nixos-enter.sh;
|
||||
inherit (pkgs) runtimeShell;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
options.system.nixos-generate-config = {
|
||||
configuration = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
description = ''
|
||||
The NixOS module that <literal>nixos-generate-config</literal>
|
||||
saves to <literal>/etc/nixos/configuration.nix</literal>.
|
||||
|
||||
This is an internal option. No backward compatibility is guaranteed.
|
||||
Use at your own risk!
|
||||
|
||||
Note that this string gets spliced into a Perl script. The perl
|
||||
variable <literal>$bootLoaderConfig</literal> can be used to
|
||||
splice in the boot loader configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
desktopConfiguration = mkOption {
|
||||
internal = true;
|
||||
type = types.listOf types.lines;
|
||||
default = [];
|
||||
description = ''
|
||||
Text to preseed the desktop configuration that <literal>nixos-generate-config</literal>
|
||||
saves to <literal>/etc/nixos/configuration.nix</literal>.
|
||||
|
||||
This is an internal option. No backward compatibility is guaranteed.
|
||||
Use at your own risk!
|
||||
|
||||
Note that this string gets spliced into a Perl script. The perl
|
||||
variable <literal>$bootLoaderConfig</literal> can be used to
|
||||
splice in the boot loader configuration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
options.system.disableInstallerTools = mkOption {
|
||||
internal = true;
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Disable nixos-rebuild, nixos-generate-config, nixos-installer
|
||||
and other NixOS tools. This is useful to shrink embedded,
|
||||
read-only systems which are not expected to be rebuild or
|
||||
reconfigure themselves. Use at your own risk!
|
||||
'';
|
||||
};
|
||||
|
||||
config = lib.mkIf (config.nix.enable && !config.system.disableInstallerTools) {
|
||||
|
||||
system.nixos-generate-config.configuration = mkDefault ''
|
||||
# Edit this configuration file to define what should be installed on
|
||||
# your system. Help is available in the configuration.nix(5) man page
|
||||
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ # Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
$bootLoaderConfig
|
||||
# networking.hostName = "nixos"; # Define your hostname.
|
||||
# Pick only one of the below networking options.
|
||||
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
|
||||
# networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
|
||||
|
||||
# Set your time zone.
|
||||
# time.timeZone = "Europe/Amsterdam";
|
||||
|
||||
# Configure network proxy if necessary
|
||||
# networking.proxy.default = "http://user:password\@proxy:port/";
|
||||
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||
|
||||
# Select internationalisation properties.
|
||||
# i18n.defaultLocale = "en_US.UTF-8";
|
||||
# console = {
|
||||
# font = "Lat2-Terminus16";
|
||||
# keyMap = "us";
|
||||
# useXkbConfig = true; # use xkbOptions in tty.
|
||||
# };
|
||||
|
||||
$xserverConfig
|
||||
|
||||
$desktopConfiguration
|
||||
# Configure keymap in X11
|
||||
# services.xserver.layout = "us";
|
||||
# services.xserver.xkbOptions = {
|
||||
# "eurosign:e";
|
||||
# "caps:escape" # map caps to escape.
|
||||
# };
|
||||
|
||||
# Enable CUPS to print documents.
|
||||
# services.printing.enable = true;
|
||||
|
||||
# Enable sound.
|
||||
# sound.enable = true;
|
||||
# hardware.pulseaudio.enable = true;
|
||||
|
||||
# Enable touchpad support (enabled default in most desktopManager).
|
||||
# services.xserver.libinput.enable = true;
|
||||
|
||||
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||
# users.users.jane = {
|
||||
# isNormalUser = true;
|
||||
# extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
|
||||
# packages = with pkgs; [
|
||||
# firefox
|
||||
# thunderbird
|
||||
# ];
|
||||
# };
|
||||
|
||||
# List packages installed in system profile. To search, run:
|
||||
# \$ nix search wget
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
|
||||
# wget
|
||||
# ];
|
||||
|
||||
# Some programs need SUID wrappers, can be configured further or are
|
||||
# started in user sessions.
|
||||
# programs.mtr.enable = true;
|
||||
# programs.gnupg.agent = {
|
||||
# enable = true;
|
||||
# enableSSHSupport = true;
|
||||
# };
|
||||
|
||||
# List services that you want to enable:
|
||||
|
||||
# Enable the OpenSSH daemon.
|
||||
# services.openssh.enable = true;
|
||||
|
||||
# Open ports in the firewall.
|
||||
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||
# Or disable the firewall altogether.
|
||||
# networking.firewall.enable = false;
|
||||
|
||||
# Copy the NixOS configuration file and link it from the resulting system
|
||||
# (/run/current-system/configuration.nix). This is useful in case you
|
||||
# accidentally delete configuration.nix.
|
||||
# system.copySystemConfiguration = true;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "${config.system.nixos.release}"; # Did you read the comment?
|
||||
|
||||
}
|
||||
'';
|
||||
|
||||
environment.systemPackages =
|
||||
[ nixos-build-vms
|
||||
nixos-install
|
||||
nixos-rebuild
|
||||
nixos-generate-config
|
||||
nixos-version
|
||||
nixos-enter
|
||||
] ++ lib.optional (nixos-option != null) nixos-option;
|
||||
|
||||
system.build = {
|
||||
inherit nixos-install nixos-generate-config nixos-option nixos-rebuild nixos-enter;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue