Merge remote-tracking branch 'origin/staging' into systemd-219

Conflicts:
	pkgs/os-specific/linux/kernel/linux-3.4.nix
	pkgs/os-specific/linux/systemd/default.nix
This commit is contained in:
Eelco Dolstra
2015-07-20 22:57:23 +02:00
2207 changed files with 83880 additions and 41719 deletions

View File

@@ -81,6 +81,8 @@ let
substituteAll ${./switch-to-configuration.pl} $out/bin/switch-to-configuration
chmod +x $out/bin/switch-to-configuration
echo -n "${toString config.system.extraDependencies}" > $out/extra-dependencies
${config.system.extraSystemBuilderCmds}
'';
@@ -99,6 +101,7 @@ let
if [] == failed then pkgs.stdenv.mkDerivation {
name = "nixos-${config.system.nixosVersion}";
preferLocalBuild = true;
allowSubstitutes = false;
buildCommand = systemBuilder;
inherit (pkgs) utillinux coreutils;
@@ -188,6 +191,16 @@ in
'';
};
system.extraDependencies = mkOption {
type = types.listOf types.package;
default = [];
description = ''
A list of packages that should be included in the system
closure but not otherwise made available to users. This is
primarily used by the installation tests.
'';
};
system.replaceRuntimeDependencies = mkOption {
default = [];
example = lib.literalExample "[ ({ original = pkgs.openssl; replacement = pkgs.callPackage /path/to/openssl { ... }; }) ]";

View File

@@ -0,0 +1,51 @@
{ config, lib, pkgs, ... }:
with lib;
{
options = {
systemd.coredump = {
enable = mkOption {
default = false;
type = types.bool;
description = ''
Enables storing core dumps in systemd.
Note that this alone is not enough to enable core dumps. The maximum
file size for core dumps must be specified in limits.conf as well. See
<option>security.pam.loginLimits</option> as well as the limits.conf(5)
man page.
'';
};
extraConfig = mkOption {
default = "";
type = types.lines;
example = "Storage=journal";
description = ''
Extra config options for systemd-coredump. See coredump.conf(5) man page
for available options.
'';
};
};
};
config = mkIf config.systemd.coredump.enable {
environment.etc."systemd/coredump.conf".text =
''
[Coredump]
${config.systemd.coredump.extraConfig}
'';
# Have the kernel pass core dumps to systemd's coredump helper binary.
# From systemd's 50-coredump.conf file. See:
# <https://github.com/systemd/systemd/blob/v218/sysctl.d/50-coredump.conf.in>
boot.kernel.sysctl."kernel.core_pattern" = "|${pkgs.systemd}/lib/systemd/systemd-coredump %p %u %g %s %t %e";
};
}

View File

@@ -159,7 +159,7 @@ in
boot.kernel.sysctl."kernel.printk" = config.boot.consoleLogLevel;
boot.kernelModules = [ "loop" "configs" ];
boot.kernelModules = [ "loop" "configs" "atkbd" ];
boot.initrd.availableKernelModules =
[ # Note: most of these (especially the SATA/PATA modules)

View File

@@ -0,0 +1,44 @@
{ config, lib, pkgs, ... }:
with lib;
let
blCfg = config.boot.loader;
cfg = blCfg.generic-extlinux-compatible;
timeoutStr = if blCfg.timeout == null then "-1" else toString blCfg.timeout;
builder = import ./extlinux-conf-builder.nix { inherit pkgs; };
in
{
options = {
boot.loader.generic-extlinux-compatible = {
enable = mkOption {
default = false;
type = types.bool;
description = ''
Whether to generate an extlinux-compatible configuration file
under <literal>/boot/extlinux.conf</literal>. For instance,
U-Boot's generic distro boot support uses this file format.
See <link xlink:href="http://git.denx.de/?p=u-boot.git;a=blob;f=doc/README.distro;hb=refs/heads/master">U-boot's documentation</link>
for more information.
'';
};
configurationLimit = mkOption {
default = 20;
example = 10;
type = types.int;
description = ''
Maximum number of configurations in the boot menu.
'';
};
};
};
config = mkIf cfg.enable {
system.build.installBootLoader = "${builder} -g ${toString cfg.configurationLimit} -t ${timeoutStr} -c";
system.boot.loader.id = "generic-extlinux-compatible";
};
}

View File

@@ -0,0 +1,8 @@
{ pkgs }:
pkgs.substituteAll {
src = ./extlinux-conf-builder.sh;
isExecutable = true;
inherit (pkgs) bash;
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
}

View File

@@ -0,0 +1,132 @@
#! @bash@/bin/sh -e
shopt -s nullglob
export PATH=/empty
for i in @path@; do PATH=$PATH:$i/bin; done
usage() {
echo "usage: $0 -t <timeout> -c <path-to-default-configuration> [-d <boot-dir>] [-g <num-generations>]" >&2
exit 1
}
timeout= # Timeout in centiseconds
default= # Default configuration
target=/boot # Target directory
numGenerations=0 # Number of other generations to include in the menu
while getopts "t:c:d:g:" opt; do
case "$opt" in
t) # U-Boot interprets '0' as infinite and negative as instant boot
if [ "$OPTARG" -lt 0 ]; then
timeout=0
elif [ "$OPTARG" = 0 ]; then
timeout=-10
else
timeout=$((OPTARG * 10))
fi
;;
c) default="$OPTARG" ;;
d) target="$OPTARG" ;;
g) numGenerations="$OPTARG" ;;
\?) usage ;;
esac
done
[ "$timeout" = "" -o "$default" = "" ] && usage
mkdir -p $target/nixos
mkdir -p $target/extlinux
# Convert a path to a file in the Nix store such as
# /nix/store/<hash>-<name>/file to <hash>-<name>-<file>.
cleanName() {
local path="$1"
echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g'
}
# Copy a file from the Nix store to $target/nixos.
declare -A filesCopied
copyToKernelsDir() {
local src=$(readlink -f "$1")
local dst="$target/nixos/$(cleanName $src)"
# Don't copy the file if $dst already exists. This means that we
# have to create $dst atomically to prevent partially copied
# kernels or initrd if this script is ever interrupted.
if ! test -e $dst; then
local dstTmp=$dst.tmp.$$
cp -r $src $dstTmp
mv $dstTmp $dst
fi
filesCopied[$dst]=1
result=$dst
}
# Copy its kernel, initrd and dtbs to $target/nixos, and echo out an
# extlinux menu entry
addEntry() {
local path=$(readlink -f "$1")
local tag="$2" # Generation number or 'default'
if ! test -e $path/kernel -a -e $path/initrd; then
return
fi
copyToKernelsDir "$path/kernel"; kernel=$result
copyToKernelsDir "$path/initrd"; initrd=$result
# XXX UGLY: maybe the system config should have a top-level "dtbs" entry?
copyToKernelsDir $(readlink -m "$path/kernel/../dtbs"); dtbs=$result
timestampEpoch=$(stat -L -c '%Z' $path)
timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch)
nixosVersion="$(cat $path/nixos-version)"
extraParams="$(cat $path/kernel-params)"
echo
echo "LABEL nixos-$tag"
if [ "$tag" = "default" ]; then
echo " MENU LABEL NixOS - Default"
else
echo " MENU LABEL NixOS - Configuration $tag ($timestamp - $nixosVersion)"
fi
echo " LINUX ../nixos/$(basename $kernel)"
echo " INITRD ../nixos/$(basename $initrd)"
echo " FDTDIR ../nixos/$(basename $dtbs)"
echo " APPEND systemConfig=$path init=$path/init $extraParams"
}
tmpFile="$target/extlinux/extlinux.conf.tmp.$$"
cat > $tmpFile <<EOF
# Generated file, all changes will be lost on nixos-rebuild!
# Change this to e.g. nixos-42 to temporarily boot to an older configuration.
DEFAULT nixos-default
TIMEOUT $timeout
$(addEntry $default default)
EOF
# Add up to $numGenerations generations of the system profile to the menu,
# in reverse (most recent to least recent) order.
for generation in $(
(cd /nix/var/nix/profiles && ls -d system-*-link) \
| sed 's/system-\([0-9]\+\)-link/\1/' \
| sort -n -r \
| head -n $numGenerations); do
link=/nix/var/nix/profiles/system-$generation-link
addEntry $link $generation
done >> $tmpFile
mv -f $tmpFile $target/extlinux/extlinux.conf
# Remove obsolete files from $target/nixos.
for fn in $target/nixos/*; do
if ! test "${filesCopied[$fn]}" = 1; then
echo "Removing no longer needed boot file: $fn"
chmod +w -- "$fn"
rm -rf -- "$fn"
fi
done

View File

@@ -10,7 +10,8 @@ let
realGrub = if cfg.version == 1 then pkgs.grub
else if cfg.zfsSupport then pkgs.grub2.override { zfsSupport = true; }
else pkgs.grub2;
else if cfg.enableTrustedboot then pkgs.trustedGrub
else pkgs.grub2;
grub =
# Don't include GRUB if we're only generating a GRUB menu (e.g.,
@@ -21,25 +22,36 @@ let
grubEfi =
# EFI version of Grub v2
if (cfg.devices != ["nodev"]) && cfg.efiSupport && (cfg.version == 2)
if cfg.efiSupport && (cfg.version == 2)
then realGrub.override { efiSupport = cfg.efiSupport; }
else null;
f = x: if x == null then "" else "" + x;
grubConfig = pkgs.writeText "grub-config.xml" (builtins.toXML
{ splashImage = f config.boot.loader.grub.splashImage;
grubConfig = args:
let
efiSysMountPoint = if args.efiSysMountPoint == null then args.path else args.efiSysMountPoint;
efiSysMountPoint' = replaceChars [ "/" ] [ "-" ] efiSysMountPoint;
in
pkgs.writeText "grub-config.xml" (builtins.toXML
{ splashImage = f cfg.splashImage;
grub = f grub;
grubTarget = f (grub.grubTarget or "");
shell = "${pkgs.stdenv.shell}";
fullName = (builtins.parseDrvName realGrub.name).name;
fullVersion = (builtins.parseDrvName realGrub.name).version;
grubEfi = f grubEfi;
grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else "";
inherit (efi) efiSysMountPoint canTouchEfiVariables;
bootPath = args.path;
storePath = config.boot.loader.grub.storePath;
bootloaderId = if args.efiBootloaderId == null then "NixOS${efiSysMountPoint'}" else args.efiBootloaderId;
inherit efiSysMountPoint;
inherit (args) devices;
inherit (efi) canTouchEfiVariables;
inherit (cfg)
version extraConfig extraPerEntryConfig extraEntries
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout
default devices fsIdentifier efiSupport;
default fsIdentifier efiSupport gfxmodeEfi gfxmodeBios;
path = (makeSearchPath "bin" ([
pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfsProgs
pkgs.utillinux ] ++ (if cfg.efiSupport && (cfg.version == 2) then [pkgs.efibootmgr ] else [])
@@ -48,6 +60,9 @@ let
]);
});
bootDeviceCounters = fold (device: attr: attr // { "${device}" = (attr."${device}" or 0) + 1; }) {}
(concatMap (args: args.devices) cfg.mirroredBoots);
in
{
@@ -101,6 +116,64 @@ in
'';
};
mirroredBoots = mkOption {
default = [ ];
example = [
{ path = "/boot1"; devices = [ "/dev/sda" ]; }
{ path = "/boot2"; devices = [ "/dev/sdb" ]; }
];
description = ''
Mirror the boot configuration to multiple partitions and install grub
to the respective devices corresponding to those partitions.
'';
type = types.listOf types.optionSet;
options = {
path = mkOption {
example = "/boot1";
type = types.str;
description = ''
The path to the boot directory where grub will be written. Generally
this boot parth should double as an efi path.
'';
};
efiSysMountPoint = mkOption {
default = null;
example = "/boot1/efi";
type = types.nullOr types.str;
description = ''
The path to the efi system mount point. Usually this is the same
partition as the above path and can be left as null.
'';
};
efiBootloaderId = mkOption {
default = null;
example = "NixOS-fsid";
type = types.nullOr types.str;
description = ''
The id of the bootloader to store in efi nvram.
The default is to name it NixOS and append the path or efiSysMountPoint.
This is only used if <literal>boot.loader.efi.canTouchEfiVariables</literal> is true.
'';
};
devices = mkOption {
default = [ ];
example = [ "/dev/sda" "/dev/sdb" ];
type = types.listOf types.str;
description = ''
The path to the devices which will have the grub mbr written.
Note these are typically device paths and not paths to partitions.
'';
};
};
};
configurationName = mkOption {
default = "";
example = "Stable 2.6.21";
@@ -110,6 +183,15 @@ in
'';
};
storePath = mkOption {
default = "/nix/store";
type = types.str;
description = ''
Path to the Nix store when looking for kernels at boot.
Only makes sense when copyKernels is false.
'';
};
extraPrepareConfig = mkOption {
default = "";
type = types.lines;
@@ -189,6 +271,24 @@ in
'';
};
gfxmodeEfi = mkOption {
default = "auto";
example = "1024x768";
type = types.str;
description = ''
The gfxmode to pass to grub when loading a graphical boot interface under efi.
'';
};
gfxmodeBios = mkOption {
default = "1024x768";
example = "auto";
type = types.str;
description = ''
The gfxmode to pass to grub when loading a graphical boot interface under bios.
'';
};
configurationLimit = mkOption {
default = 100;
example = 120;
@@ -269,6 +369,15 @@ in
'';
};
enableTrustedboot = mkOption {
default = false;
type = types.bool;
description = ''
Enable trusted boot. Grub will measure all critical components during
the boot process to offer TCG (TPM) support.
'';
};
};
};
@@ -284,20 +393,25 @@ in
sha256 = "14kqdx2lfqvh40h6fjjzqgff1mwk74dmbjvmqphi6azzra7z8d59";
}
# GRUB 1.97 doesn't support gzipped XPMs.
else ./winkler-gnu-blue-640x480.png);
else "${pkgs.nixos-artwork}/share/artwork/gnome/Gnome_Dark.png");
}
(mkIf cfg.enable {
boot.loader.grub.devices = optional (cfg.device != "") cfg.device;
system.build.installBootLoader =
if cfg.devices == [] then
throw "You must set the option boot.loader.grub.device to make the system bootable."
else
"PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ListCompare ])} " +
(if cfg.enableCryptodisk then "GRUB_ENABLE_CRYPTODISK=y " else "") +
"${pkgs.perl}/bin/perl ${./install-grub.pl} ${grubConfig}";
boot.loader.grub.mirroredBoots = optionals (cfg.devices != [ ]) [
{ path = "/boot"; inherit (cfg) devices; inherit (efi) efiSysMountPoint; }
];
system.build.installBootLoader = pkgs.writeScript "install-grub.sh" (''
#!${pkgs.stdenv.shell}
set -e
export PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ListCompare ])}
${optionalString cfg.enableCryptodisk "export GRUB_ENABLE_CRYPTODISK=y"}
'' + flip concatMapStrings cfg.mirroredBoots (args: ''
${pkgs.perl}/bin/perl ${./install-grub.pl} ${grubConfig args} $@
''));
system.build.grub = grub;
@@ -312,13 +426,53 @@ in
${pkgs.coreutils}/bin/cp -pf "${v}" "/boot/${n}"
'') config.boot.loader.grub.extraFiles);
assertions = [{ assertion = !cfg.zfsSupport || cfg.version == 2;
message = "Only grub version 2 provides zfs support";}]
++ flip map cfg.devices (dev: {
assertion = dev == "nodev" || hasPrefix "/" dev;
message = "Grub devices must be absolute paths, not ${dev}";
});
assertions = [
{
assertion = !cfg.zfsSupport || cfg.version == 2;
message = "Only grub version 2 provides zfs support";
}
{
assertion = cfg.mirroredBoots != [ ];
message = "You must set the option boot.loader.grub.devices or "
+ "'boot.loader.grub.mirroredBoots' to make the system bootable.";
}
{
assertion = all (c: c < 2) (mapAttrsToList (_: c: c) bootDeviceCounters);
message = "You cannot have duplicated devices in mirroredBoots";
}
{
assertion = !cfg.enableTrustedboot || cfg.version == 2;
message = "Trusted GRUB is only available for GRUB 2";
}
{
assertion = !cfg.efiSupport || !cfg.enableTrustedboot;
message = "Trusted GRUB does not have EFI support";
}
{
assertion = !cfg.zfsSupport || !cfg.enableTrustedboot;
message = "Trusted GRUB does not have ZFS support";
}
{
assertion = !cfg.enableTrustedboot;
message = "Trusted GRUB can break your system. Remove assertion if you want to test trustedGRUB nevertheless.";
}
] ++ flip concatMap cfg.mirroredBoots (args: [
{
assertion = args.devices != [ ];
message = "A boot path cannot have an empty devices string in ${arg.path}";
}
{
assertion = hasPrefix "/" args.path;
message = "Boot paths must be absolute, not ${args.path}";
}
{
assertion = if args.efiSysMountPoint == null then true else hasPrefix "/" args.efiSysMountPoint;
message = "Efi paths must be absolute, not ${args.efiSysMountPoint}";
}
] ++ flip map args.devices (device: {
assertion = device == "nodev" || hasPrefix "/" device;
message = "Grub devices must be absolute paths, not ${dev} in ${args.path}";
}));
})
];

View File

@@ -7,6 +7,7 @@ use File::Path;
use File::stat;
use File::Copy;
use File::Slurp;
use File::Temp;
require List::Compare;
use POSIX;
use Cwd;
@@ -54,24 +55,29 @@ my $defaultEntry = int(get("default"));
my $fsIdentifier = get("fsIdentifier");
my $grubEfi = get("grubEfi");
my $grubTargetEfi = get("grubTargetEfi");
my $bootPath = get("bootPath");
my $storePath = get("storePath");
my $canTouchEfiVariables = get("canTouchEfiVariables");
my $efiSysMountPoint = get("efiSysMountPoint");
my $gfxmodeEfi = get("gfxmodeEfi");
my $gfxmodeBios = get("gfxmodeBios");
my $bootloaderId = get("bootloaderId");
$ENV{'PATH'} = get("path");
die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2;
print STDERR "updating GRUB $grubVersion menu...\n";
mkpath("/boot/grub", 0, 0700);
mkpath("$bootPath/grub", 0, 0700);
# Discover whether /boot is on the same filesystem as / and
# Discover whether the bootPath is on the same filesystem as / and
# /nix/store. If not, then all kernels and initrds must be copied to
# /boot.
if (stat("/boot")->dev != stat("/nix/store")->dev) {
# the bootPath.
if (stat($bootPath)->dev != stat("/nix/store")->dev) {
$copyKernels = 1;
}
# Discover information about the location of /boot
# Discover information about the location of the bootPath
struct(Fs => {
device => '$',
type => '$',
@@ -180,7 +186,7 @@ sub GrubFs {
if ($status != 0) {
die "Failed to retrieve subvolume info for @{[$fs->mount]}\n";
}
my @ids = join("", @id_info) =~ m/Object ID:[ \t\n]*([^ \t\n]*)/;
my @ids = join("", @id_info) =~ m/Subvolume ID:[ \t\n]*([^ \t\n]*)/;
if ($#ids > 0) {
die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n"
} elsif ($#ids == 0) {
@@ -206,10 +212,10 @@ sub GrubFs {
}
return Grub->new(path => $path, search => $search);
}
my $grubBoot = GrubFs("/boot");
my $grubBoot = GrubFs($bootPath);
my $grubStore;
if ($copyKernels == 0) {
$grubStore = GrubFs("/nix/store");
$grubStore = GrubFs($storePath);
}
# Generate the header.
@@ -221,7 +227,7 @@ if ($grubVersion == 1) {
timeout $timeout
";
if ($splashImage) {
copy $splashImage, "/boot/background.xpm.gz" or die "cannot copy $splashImage to /boot\n";
copy $splashImage, "$bootPath/background.xpm.gz" or die "cannot copy $splashImage to $bootPath\n";
$conf .= "splashimage " . $grubBoot->path . "/background.xpm.gz\n";
}
}
@@ -253,10 +259,23 @@ else {
set timeout=$timeout
fi
if loadfont " . $grubBoot->path . "/grub/fonts/unicode.pf2; then
set gfxmode=640x480
insmod gfxterm
# Setup the graphics stack for bios and efi systems
if [ \"\${grub_platform}\" = \"efi\" ]; then
insmod efi_gop
insmod efi_uga
else
insmod vbe
fi
insmod font
if loadfont " . $grubBoot->path . "/grub/fonts/unicode.pf2; then
insmod gfxterm
if [ \"\${grub_platform}\" = \"efi\" ]; then
set gfxmode=$gfxmodeEfi
set gfxpayload=keep
else
set gfxmode=$gfxmodeBios
set gfxpayload=text
fi
terminal_output gfxterm
fi
";
@@ -264,7 +283,7 @@ else {
if ($splashImage) {
# FIXME: GRUB 1.97 doesn't resize the background image if it
# doesn't match the video resolution.
copy $splashImage, "/boot/background.png" or die "cannot copy $splashImage to /boot\n";
copy $splashImage, "$bootPath/background.png" or die "cannot copy $splashImage to $bootPath\n";
$conf .= "
insmod png
if background_image " . $grubBoot->path . "/background.png; then
@@ -285,14 +304,14 @@ $conf .= "$extraConfig\n";
$conf .= "\n";
my %copied;
mkpath("/boot/kernels", 0, 0755) if $copyKernels;
mkpath("$bootPath/kernels", 0, 0755) if $copyKernels;
sub copyToKernelsDir {
my ($path) = @_;
return $grubStore->path . substr($path, length("/nix/store")) unless $copyKernels;
$path =~ /\/nix\/store\/(.*)/ or die;
my $name = $1; $name =~ s/\//-/g;
my $dst = "/boot/kernels/$name";
my $dst = "$bootPath/kernels/$name";
# Don't copy the file if $dst already exists. This means that we
# have to create $dst atomically to prevent partially copied
# kernels or initrd if this script is ever interrupted.
@@ -396,14 +415,14 @@ if ($extraPrepareConfig ne "") {
}
# Atomically update the GRUB config.
my $confFile = $grubVersion == 1 ? "/boot/grub/menu.lst" : "/boot/grub/grub.cfg";
my $confFile = $grubVersion == 1 ? "$bootPath/grub/menu.lst" : "$bootPath/grub/grub.cfg";
my $tmpFile = $confFile . ".tmp";
writeFile($tmpFile, $conf);
rename $tmpFile, $confFile or die "cannot rename $tmpFile to $confFile\n";
# Remove obsolete files from /boot/kernels.
foreach my $fn (glob "/boot/kernels/*") {
# Remove obsolete files from $bootPath/kernels.
foreach my $fn (glob "$bootPath/kernels/*") {
next if defined $copied{$fn};
print STDERR "removing obsolete file $fn\n";
unlink $fn;
@@ -415,15 +434,18 @@ foreach my $fn (glob "/boot/kernels/*") {
#
struct(GrubState => {
name => '$',
version => '$',
efi => '$',
devices => '$',
efiMountPoint => '$',
});
sub readGrubState {
my $defaultGrubState = GrubState->new(version => "", efi => "", devices => "", efiMountPoint => "" );
open FILE, "</boot/grub/state" or return $defaultGrubState;
my $defaultGrubState = GrubState->new(name => "", version => "", efi => "", devices => "", efiMountPoint => "" );
open FILE, "<$bootPath/grub/state" or return $defaultGrubState;
local $/ = "\n";
my $name = <FILE>;
chomp($name);
my $version = <FILE>;
chomp($version);
my $efi = <FILE>;
@@ -433,7 +455,7 @@ sub readGrubState {
my $efiMountPoint = <FILE>;
chomp($efiMountPoint);
close FILE;
my $grubState = GrubState->new(version => $version, efi => $efi, devices => $devices, efiMountPoint => $efiMountPoint );
my $grubState = GrubState->new(name => $name, version => $version, efi => $efi, devices => $devices, efiMountPoint => $efiMountPoint );
return $grubState
}
@@ -478,12 +500,16 @@ my $efiTarget = getEfiTarget();
my $prevGrubState = readGrubState();
my @prevDeviceTargets = split/:/, $prevGrubState->devices;
my $devicesDiffer = scalar (List::Compare->new( '-u', '-a', \@deviceTargets, \@prevDeviceTargets)->get_symmetric_difference() );
my $versionDiffer = (get("fullVersion") eq \$prevGrubState->version);
my $efiDiffer = ($efiTarget eq \$prevGrubState->efi);
my $efiMountPointDiffer = ($efiSysMountPoint eq \$prevGrubState->efiMountPoint);
my $requireNewInstall = $devicesDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1");
my $devicesDiffer = scalar (List::Compare->new( '-u', '-a', \@deviceTargets, \@prevDeviceTargets)->get_symmetric_difference());
my $nameDiffer = get("fullName") ne $prevGrubState->name;
my $versionDiffer = get("fullVersion") ne $prevGrubState->version;
my $efiDiffer = $efiTarget ne $prevGrubState->efi;
my $efiMountPointDiffer = $efiSysMountPoint ne $prevGrubState->efiMountPoint;
my $requireNewInstall = $devicesDiffer || $nameDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1");
# install a symlink so that grub can detect the boot drive
my $tmpDir = File::Temp::tempdir(CLEANUP => 1) or die "Failed to create temporary space";
symlink "$bootPath", "$tmpDir/boot" or die "Failed to symlink $tmpDir/boot";
# install non-EFI GRUB
if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
@@ -491,10 +517,10 @@ if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
next if $dev eq "nodev";
print STDERR "installing the GRUB $grubVersion boot loader on $dev...\n";
if ($grubTarget eq "") {
system("$grub/sbin/grub-install", "--recheck", Cwd::abs_path($dev)) == 0
system("$grub/sbin/grub-install", "--recheck", "--root-directory=$tmpDir", Cwd::abs_path($dev)) == 0
or die "$0: installation of GRUB on $dev failed\n";
} else {
system("$grub/sbin/grub-install", "--recheck", "--target=$grubTarget", Cwd::abs_path($dev)) == 0
system("$grub/sbin/grub-install", "--recheck", "--root-directory=$tmpDir", "--target=$grubTarget", Cwd::abs_path($dev)) == 0
or die "$0: installation of GRUB on $dev failed\n";
}
}
@@ -505,10 +531,10 @@ if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both")) {
print STDERR "installing the GRUB $grubVersion EFI boot loader into $efiSysMountPoint...\n";
if ($canTouchEfiVariables eq "true") {
system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--efi-directory=$efiSysMountPoint") == 0
system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint", "--bootloader-id=$bootloaderId") == 0
or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n";
} else {
system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--efi-directory=$efiSysMountPoint", "--no-nvram") == 0
system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint", "--no-nvram") == 0
or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n";
}
}
@@ -516,7 +542,8 @@ if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both"))
# update GRUB state file
if ($requireNewInstall != 0) {
open FILE, ">/boot/grub/state" or die "cannot create /boot/grub/state: $!\n";
open FILE, ">$bootPath/grub/state" or die "cannot create $bootPath/grub/state: $!\n";
print FILE get("fullName"), "\n" or die;
print FILE get("fullVersion"), "\n" or die;
print FILE $efiTarget, "\n" or die;
print FILE join( ":", @deviceTargets ), "\n" or die;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@@ -1,6 +0,0 @@
This is a resized version of
http://www.gnu.org/graphics/winkler-gnu-blue.png
by Kyle Winkler and released under the Free Art License
(http://artlibre.org/licence.php/lalgb.html).

View File

@@ -5,7 +5,7 @@ with lib;
let
luks = config.boot.initrd.luks;
openCommand = { name, device, keyFile, keyFileSize, allowDiscards, yubikey, ... }: ''
openCommand = { name, device, header, keyFile, keyFileSize, allowDiscards, yubikey, ... }: ''
# Wait for luksRoot to appear, e.g. if on a usb drive.
# XXX: copied and adapted from stage-1-init.sh - should be
# available as a function.
@@ -33,6 +33,7 @@ let
open_normally() {
cryptsetup luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \
${optionalString (header != null) "--header=${header}"} \
${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"}
}
@@ -211,7 +212,7 @@ in
};
boot.initrd.luks.cryptoModules = mkOption {
type = types.listOf types.string;
type = types.listOf types.str;
default =
[ "aes" "aes_generic" "blowfish" "twofish"
"serpent" "cbc" "xts" "lrw" "sha1" "sha256" "sha512"
@@ -251,6 +252,16 @@ in
description = "Path of the underlying block device.";
};
header = mkOption {
default = null;
example = "/root/header.img";
type = types.nullOr types.string;
description = ''
The name of the file or block device that
should be used as header for the encrypted device.
'';
};
keyFile = mkOption {
default = null;
example = "/dev/sdb1";

View File

@@ -101,7 +101,7 @@ with lib;
echo ${config.system.sbin.modprobe}/sbin/modprobe > /proc/sys/kernel/modprobe
'';
environment.variables.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules";
environment.sessionVariables.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules";
};

View File

@@ -317,7 +317,7 @@ mountFS() {
# Try to find and mount the root device.
mkdir /mnt-root
mkdir -p $targetRoot
exec 3< @fsInfo@

View File

@@ -358,7 +358,7 @@ in
boot.initrd.supportedFilesystems = mkOption {
default = [ ];
example = [ "btrfs" ];
type = types.listOf types.string;
type = types.listOf types.str;
description = "Names of supported filesystem types in the initial ramdisk.";
};

View File

@@ -13,13 +13,20 @@ rec {
pathSafeName = lib.replaceChars ["@" ":" "\\"] ["-" "-" "-"] name;
in
if unit.enable then
pkgs.runCommand "unit-${pathSafeName}" { preferLocalBuild = true; inherit (unit) text; }
pkgs.runCommand "unit-${pathSafeName}"
{ preferLocalBuild = true;
allowSubstitutes = false;
inherit (unit) text;
}
''
mkdir -p $out
echo -n "$text" > $out/${shellEscape name}
''
else
pkgs.runCommand "unit-${pathSafeName}-disabled" { preferLocalBuild = true; }
pkgs.runCommand "unit-${pathSafeName}-disabled"
{ preferLocalBuild = true;
allowSubstitutes = false;
}
''
mkdir -p $out
ln -s /dev/null $out/${shellEscape name}
@@ -89,7 +96,10 @@ rec {
as));
generateUnits = type: units: upstreamUnits: upstreamWants:
pkgs.runCommand "${type}-units" { preferLocalBuild = true; } ''
pkgs.runCommand "${type}-units"
{ preferLocalBuild = true;
allowSubstitutes = false;
} ''
mkdir -p $out
# Copy the upstream systemd units we're interested in.

View File

@@ -42,13 +42,13 @@ in rec {
requiredBy = mkOption {
default = [];
type = types.listOf types.string;
type = types.listOf types.str;
description = "Units that require (i.e. depend on and need to go down with) this unit.";
};
wantedBy = mkOption {
default = [];
type = types.listOf types.string;
type = types.listOf types.str;
description = "Units that want (i.e. depend on) this unit.";
};

View File

@@ -490,7 +490,7 @@ in
services.journald.rateLimitBurst = mkOption {
default = 100;
type = types.uniq types.int;
type = types.int;
description = ''
Configures the rate limiting burst limit (number of messages per
interval) that is applied to all messages generated on the system.

View File

@@ -14,6 +14,7 @@ let
builder = ./make-etc.sh;
preferLocalBuild = true;
allowSubstitutes = false;
/* !!! Use toXML. */
sources = map (x: x.source) etc';