Merge branch 'nix-2.0'

This commit is contained in:
Vladimír Čunát 2018-03-03 18:10:45 +01:00
commit d586f5d97e
No known key found for this signature in database
GPG key ID: E747DF1F9575A3AA
31 changed files with 393 additions and 417 deletions

View file

@ -11,15 +11,17 @@ tedious, so here is a quick way to see if the installer works
properly:
<screen>
$ nix-build -A config.system.build.nixos-install
# mount -t tmpfs none /mnt
# nixos-generate-config --root /mnt
$ nix-build '&lt;nixpkgs/nixos>' -A config.system.build.nixos-install
# ./result/bin/nixos-install</screen>
To start a login shell in the new NixOS installation in
<filename>/mnt</filename>:
<screen>
# ./result/bin/nixos-install --chroot
$ nix-build '&lt;nixpkgs/nixos>' -A config.system.build.nixos-enter
# ./result/bin/nixos-enter
</screen>
</para>

View file

@ -0,0 +1,119 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><command>nixos-enter</command></refentrytitle>
<manvolnum>8</manvolnum>
<refmiscinfo class="source">NixOS</refmiscinfo>
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
</refmeta>
<refnamediv>
<refname><command>nixos-enter</command></refname>
<refpurpose>run a command in a NixOS chroot environment</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nixos-enter</command>
<arg>
<arg choice='plain'><option>--root</option></arg>
<replaceable>root</replaceable>
</arg>
<arg>
<arg choice='plain'><option>--system</option></arg>
<replaceable>system</replaceable>
</arg>
<arg>
<arg choice='plain'><option>-c</option></arg>
<replaceable>shell-command</replaceable>
</arg>
<arg>
<arg choice='plain'><option>--help</option></arg>
</arg>
<arg>
<arg choice='plain'><option>--</option></arg>
<replaceable>arguments</replaceable>
</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>This command runs a command in a NixOS chroot environment, that
is, in a filesystem hierarchy previously prepared using
<command>nixos-install</command>.</para>
</refsection>
<refsection><title>Options</title>
<para>This command accepts the following options:</para>
<variablelist>
<varlistentry>
<term><option>--root</option></term>
<listitem>
<para>The path to the NixOS system you want to enter. It defaults to <filename>/mnt</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--system</option></term>
<listitem>
<para>The NixOS system configuration to use. It defaults to
<filename>/nix/var/nix/profiles/system</filename>. You can enter
a previous NixOS configuration by specifying a path such as
<filename>/nix/var/nix/profiles/system-106-link</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--command</option></term>
<term><option>-c</option></term>
<listitem>
<para>The bash command to execute.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--</option></term>
<listitem><para>Interpret the remaining arguments as the program
name and arguments to be invoked. The program is not executed in a
shell.</para></listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Examples</title>
<para>Start an interactive shell in the NixOS installation in
<filename>/mnt</filename>:</para>
<screen>
# nixos-enter /mnt
</screen>
<para>Run a shell command:</para>
<screen>
# nixos-enter -c 'ls -l /; cat /proc/mounts'
</screen>
<para>Run a non-shell command:</para>
<screen>
# nixos-enter -- cat /proc/mounts
</screen>
</refsection>
</refentry>

View file

@ -26,8 +26,8 @@
<replaceable>root</replaceable>
</arg>
<arg>
<arg choice='plain'><option>--closure</option></arg>
<replaceable>closure</replaceable>
<arg choice='plain'><option>--system</option></arg>
<replaceable>path</replaceable>
</arg>
<arg>
<arg choice='plain'><option>--no-channel-copy</option></arg>
@ -118,7 +118,7 @@ it.</para>
</varlistentry>
<varlistentry>
<term><option>--closure</option></term>
<term><option>--system</option></term>
<listitem>
<para>If this option is provided, <command>nixos-install</command> will install the specified closure
rather than attempt to build one from <filename>/mnt/etc/nixos/configuration.nix</filename>.</para>

View file

@ -15,7 +15,7 @@
</author>
<copyright>
<year>2007-2015</year>
<year>2007-2018</year>
<holder>Eelco Dolstra</holder>
</copyright>
@ -25,6 +25,7 @@
<xi:include href="man-nixos-build-vms.xml" />
<xi:include href="man-nixos-generate-config.xml" />
<xi:include href="man-nixos-install.xml" />
<xi:include href="man-nixos-enter.xml" />
<xi:include href="man-nixos-option.xml" />
<xi:include href="man-nixos-rebuild.xml" />
<xi:include href="man-nixos-version.xml" />

View file

@ -18,6 +18,13 @@
has the following highlights: </para>
<itemizedlist>
<listitem>
<para>
Nix now defaults to 2.0; see its
<link xlink:href="https://nixos.org/nix/manual/#ssec-relnotes-2.0">release notes</link>.
</para>
</listitem>
<listitem>
<para>
Linux kernel defaults to the 4.14 branch (it was 4.9).

View file

@ -51,7 +51,7 @@ with lib;
let format' = format; in let
format = if (format' == "qcow2-compressed") then "qcow2" else format';
format = if format' == "qcow2-compressed" then "qcow2" else format';
compress = optionalString (format' == "qcow2-compressed") "-c";
@ -84,6 +84,7 @@ let format' = format; in let
nixpkgs = cleanSource pkgs.path;
# FIXME: merge with channel.nix / make-channel.nix.
channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}" {} ''
mkdir -p $out
cp -prd ${nixpkgs} $out/nixos
@ -95,13 +96,16 @@ let format' = format; in let
echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
'';
metaClosure = pkgs.writeText "meta" ''
${config.system.build.toplevel}
${config.nix.package.out}
${channelSources}
'';
prepareImageInputs = with pkgs; [ rsync utillinux parted e2fsprogs lkl fakeroot config.system.build.nixos-prepare-root ] ++ stdenv.initialPath;
binPath = with pkgs; makeBinPath (
[ rsync
utillinux
parted
e2fsprogs
lkl
config.system.build.nixos-install
config.system.build.nixos-enter
nix
] ++ stdenv.initialPath);
# I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate
# image building logic. The comment right below this now appears in 4 different places in nixpkgs :)
@ -109,8 +113,10 @@ let format' = format; in let
sources = map (x: x.source) contents;
targets = map (x: x.target) contents;
closureInfo = pkgs.closureInfo { rootPaths = [ config.system.build.toplevel channelSources ]; };
prepareImage = ''
export PATH=${makeBinPath prepareImageInputs}
export PATH=${binPath}
# Yes, mkfs.ext4 takes different units in different contexts. Fun.
sectorsToKilobytes() {
@ -168,11 +174,15 @@ let format' = format; in let
fi
done
# TODO: Nix really likes to chown things it creates to its current user...
fakeroot nixos-prepare-root $root ${channelSources} ${config.system.build.toplevel} closure
export HOME=$TMPDIR
# fakeroot seems to always give the owner write permissions, which we do not want
find $root/nix/store -mindepth 1 -maxdepth 1 -type f -o -type d | xargs chmod -R a-w
# Provide a Nix database so that nixos-install can copy closures.
export NIX_STATE_DIR=$TMPDIR/state
nix-store --load-db < ${closureInfo}/registration
echo "running nixos-install..."
nixos-install --root $root --no-bootloader --no-root-passwd \
--system ${config.system.build.toplevel} --channel ${channelSources} --substituters ""
echo "copying staging root to image..."
cptofs -p ${optionalString (partitionTableType != "none") "-P ${rootPartition}"} -t ${fsType} -i $diskImage $root/* /
@ -181,7 +191,6 @@ in pkgs.vmTools.runInLinuxVM (
pkgs.runCommand name
{ preVM = prepareImage;
buildInputs = with pkgs; [ utillinux e2fsprogs dosfstools ];
exportReferencesGraph = [ "closure" metaClosure ];
postVM = ''
${if format == "raw" then ''
mv $diskImage $out/${filename}
@ -194,6 +203,8 @@ in pkgs.vmTools.runInLinuxVM (
memSize = 1024;
}
''
export PATH=${binPath}:$PATH
rootDisk=${if partitionTableType != "none" then "/dev/vda${rootPartition}" else "/dev/vda"}
# Some tools assume these exist
@ -218,15 +229,8 @@ in pkgs.vmTools.runInLinuxVM (
cp ${configFile} /mnt/etc/nixos/configuration.nix
''}
mount --rbind /dev $mountPoint/dev
mount --rbind /proc $mountPoint/proc
mount --rbind /sys $mountPoint/sys
# Set up core system link, GRUB, etc.
NIXOS_INSTALL_BOOTLOADER=1 chroot $mountPoint /nix/var/nix/profiles/system/bin/switch-to-configuration boot
# TODO: figure out if I should activate, but for now I won't
# chroot $mountPoint /nix/var/nix/profiles/system/activate
NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root $mountPoint -- /nix/var/nix/profiles/system/bin/switch-to-configuration boot
# The above scripts will generate a random machine-id and we don't want to bake a single ID into all our images
rm -f $mountPoint/etc/machine-id

View file

@ -1,4 +1,4 @@
{ stdenv, perl, pathsFromGraph, xorriso, syslinux
{ stdenv, perl, closureInfo, xorriso, syslinux
, # The file name of the resulting ISO image.
isoName ? "cd.iso"
@ -48,9 +48,9 @@ assert usbBootable -> isohybridMbrImage != "";
stdenv.mkDerivation {
name = isoName;
builder = ./make-iso9660-image.sh;
buildInputs = [perl xorriso syslinux];
buildInputs = [ xorriso syslinux ];
inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable isohybridMbrImage usbBootable;
inherit isoName bootable bootImage compressImage volumeID efiBootImage efiBootable isohybridMbrImage usbBootable;
# !!! should use XML.
sources = map (x: x.source) contents;
@ -61,6 +61,5 @@ stdenv.mkDerivation {
symlinks = map (x: x.symlink) storeContents;
# For obtaining the closure of `storeContents'.
exportReferencesGraph =
map (x: [("closure-" + baseNameOf x.object) x.object]) storeContents;
closureInfo = closureInfo { rootPaths = map (x: x.object) storeContents; };
}

View file

@ -72,16 +72,15 @@ done
# Add the closures of the top-level store objects.
storePaths=$(perl $pathsFromGraph closure-*)
for i in $storePaths; do
for i in $(< $closureInfo/store-paths); do
addPath "${i:1}" "$i"
done
# Also include a manifest of the closures in a format suitable for
# nix-store --load-db.
if [ -n "$object" ]; then
printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration
if [[ ${#objects[*]} != 0 ]]; then
cp $closureInfo/registration nix-path-registration
addPath "nix-path-registration" "nix-path-registration"
fi

View file

@ -1,4 +1,4 @@
{ stdenv, squashfsTools, perl, pathsFromGraph
{ stdenv, squashfsTools, closureInfo
, # The root directory of the squashfs filesystem is filled with the
# closures of the Nix store paths listed here.
@ -8,50 +8,18 @@
stdenv.mkDerivation {
name = "squashfs.img";
nativeBuildInputs = [perl squashfsTools];
# For obtaining the closure of `storeContents'.
exportReferencesGraph =
map (x: [("closure-" + baseNameOf x) x]) storeContents;
nativeBuildInputs = [ squashfsTools ];
buildCommand =
''
# Add the closures of the top-level store objects.
storePaths=$(perl ${pathsFromGraph} closure-*)
# If a Hydra slave happens to have store paths with bad permissions/mtime,
# abort now so that they don't end up in ISO images in the channel.
# https://github.com/NixOS/nixpkgs/issues/32242
hasBadPaths=""
for path in $storePaths; do
if [ -h "$path" ]; then
continue
fi
mtime=$(stat -c %Y "$path")
mode=$(stat -c %a "$path")
if [ "$mtime" != 1 ]; then
echo "Store path '$path' has an invalid mtime."
hasBadPaths=1
fi
if [ "$mode" != 444 ] && [ "$mode" != 555 ]; then
echo "Store path '$path' has invalid permissions ($mode)."
hasBadPaths=1
fi
done
if [ -n "$hasBadPaths" ]; then
echo "You have bad paths in your store, please fix them."
exit 1
fi
closureInfo=${closureInfo { rootPaths = storeContents; }}
# Also include a manifest of the closures in a format suitable
# for nix-store --load-db.
printRegistration=1 perl ${pathsFromGraph} closure-* > nix-path-registration
cp $closureInfo/registration nix-path-registration
# Generate the squashfs image.
mksquashfs nix-path-registration $storePaths $out \
mksquashfs nix-path-registration $(cat $closureInfo/store-paths) $out \
-keep-as-directory -all-root -b 1048576 -comp xz -Xdict-size 100%
'';
}

View file

@ -529,6 +529,9 @@ in {
system.activationScripts.users = stringAfter [ "stdio" ]
''
install -m 0700 -d /root
install -m 0755 -d /home
${pkgs.perl}/bin/perl -w \
-I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl \
-I${pkgs.perlPackages.JSON}/lib/perl5/site_perl \

View file

@ -331,8 +331,7 @@ in
config.system.build.toplevel.drvPath;
# Create the squashfs image that contains the Nix store.
system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
inherit (pkgs) stdenv squashfsTools perl pathsFromGraph;
system.build.squashfsStore = pkgs.callPackage ../../../lib/make-squashfs.nix {
storeContents = config.isoImage.storeContents;
};
@ -383,11 +382,8 @@ in
boot.loader.timeout = 10;
# Create the ISO image.
system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({
inherit (pkgs) stdenv perl pathsFromGraph xorriso syslinux;
system.build.isoImage = pkgs.callPackage ../../../lib/make-iso9660-image.nix ({
inherit (config.isoImage) isoName compressImage volumeID contents;
bootable = true;
bootImage = "/isolinux/isolinux.bin";
} // optionalAttrs config.isoImage.makeUsbBootable {

View file

@ -1,6 +1,6 @@
{
x86_64-linux = "/nix/store/gy4yv67gv3j6in0lalw37j353zdmfcwm-nix-1.11.16";
i686-linux = "/nix/store/ifmyq5ryfxhhrzh62hiq65xyz1fwffga-nix-1.11.16";
aarch64-linux = "/nix/store/y9mfv3sx75mbfibf1zna1kq9v98fk2nb-nix-1.11.16";
x86_64-darwin = "/nix/store/hwpp7kia2f0in5ns2hiw41q38k30jpj2-nix-1.11.16";
x86_64-linux = "/nix/store/6p2gambjac7xdkd2a7w1dsxdk1q5cq4d-nix-2.0";
i686-linux = "/nix/store/zznnaijjk3nwx0cmpczxsvngmqzhl7r4-nix-2.0";
aarch64-linux = "/nix/store/ci96w9kxfkmlc7x2vwqiz4da0r6abxnq-nix-2.0";
x86_64-darwin = "/nix/store/xmi4fylvx4qc79ji9v5q3zfy9vfdy4sv-nix-2.0";
}

View file

@ -0,0 +1,60 @@
#! @shell@
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
command=("bash" "--login")
system=/nix/var/nix/profiles/system
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=("bash" "-c" "$1")
shift 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 -m 0755 -p "$mountPoint/dev"
mount --rbind /dev "$mountPoint/dev"
# Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
LOCALE_ARCHIVE=$system/sw/lib/locale/locale-archive chroot "$mountPoint" "$system/activate" >&2 || true
exec chroot "$mountPoint" "${command[@]}"

View file

@ -1,35 +1,23 @@
#! @shell@
# - 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>
# * install the boot loader
set -e
shopt -s nullglob
export PATH=@path@:$PATH
# Ensure a consistent umask.
umask 0022
# Re-exec ourselves in a private mount namespace so that our bind
# mounts get cleaned up automatically.
if [ "$(id -u)" = 0 ]; then
if [ -z "$NIXOS_INSTALL_REEXEC" ]; then
export NIXOS_INSTALL_REEXEC=1
exec unshare --mount --uts -- "$0" "$@"
else
mount --make-rprivate /
fi
fi
# Parse the command line for the -I flag
extraBuildFlags=()
chrootCommand=(/run/current-system/sw/bin/bash)
buildUsersGroup="nixbld"
mountPoint=/mnt
channelPath=
while [ "$#" -gt 0 ]; do
i="$1"; shift 1
case "$i" in
--max-jobs|-j|--cores|-I)
--max-jobs|-j|--cores|-I|--substituters)
j="$1"; shift 1
extraBuildFlags+=("$i" "$j")
;;
@ -41,9 +29,11 @@ while [ "$#" -gt 0 ]; do
--root)
mountPoint="$1"; shift 1
;;
--closure)
closure="$1"; shift 1
buildUsersGroup=""
--system|--closure)
system="$1"; shift 1
;;
--channel)
channelPath="$1"; shift 1
;;
--no-channel-copy)
noChannelCopy=1
@ -57,17 +47,13 @@ while [ "$#" -gt 0 ]; do
--show-trace)
extraBuildFlags+=("$i")
;;
--chroot)
runChroot=1
if [[ "$@" != "" ]]; then
chrootCommand=("$@")
fi
break
;;
--help)
exec man nixos-install
exit 1
;;
--debug)
set -x
;;
*)
echo "$0: unknown option \`$i'"
exit 1
@ -75,132 +61,83 @@ while [ "$#" -gt 0 ]; do
esac
done
set -e
shopt -s nullglob
if test -z "$mountPoint"; then
mountPoint=/mnt
fi
if ! test -e "$mountPoint"; then
echo "mount point $mountPoint doesn't exist"
exit 1
fi
# Get the path of the NixOS configuration file.
if test -z "$NIXOS_CONFIG"; then
NIXOS_CONFIG=/etc/nixos/configuration.nix
if [[ -z $NIXOS_CONFIG ]]; then
NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix
fi
if [ ! -e "$mountPoint/$NIXOS_CONFIG" ] && [ -z "$closure" ]; then
echo "configuration file $mountPoint/$NIXOS_CONFIG doesn't exist"
if [[ ${NIXOS_CONFIG:0:1} != / ]]; then
echo "$0: \$NIXOS_CONFIG is not an absolute path"
exit 1
fi
# Builds will use users that are members of this group
extraBuildFlags+=(--option "build-users-group" "$buildUsersGroup")
# Inherit binary caches from the host
# TODO: will this still work with Nix 1.12 now that it has no perl? Probably not...
binary_caches="$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};')"
extraBuildFlags+=(--option "binary-caches" "$binary_caches")
# We only need nixpkgs in the path if we don't already have a system closure to install
if [[ -z "$closure" ]]; then
nixpkgs="$(readlink -f "$(nix-instantiate --find-file nixpkgs)")"
export NIX_PATH="nixpkgs=$nixpkgs:nixos-config=$mountPoint/$NIXOS_CONFIG"
fi
unset NIXOS_CONFIG
# These get created in nixos-prepare-root as well, but we want to make sure they're here in case we're
# running with --chroot. TODO: --chroot should just be split into a separate tool.
mkdir -m 0755 -p "$mountPoint/dev" "$mountPoint/proc" "$mountPoint/sys"
# Set up some bind mounts we'll want regardless of chroot or not
mount --rbind /dev "$mountPoint/dev"
mount --rbind /proc "$mountPoint/proc"
mount --rbind /sys "$mountPoint/sys"
# If we asked for a chroot, that means we're not actually installing anything (yeah I was confused too)
# and we just want to run a command in the context of a $mountPoint that we're assuming has already been
# set up by a previous nixos-install invocation. In that case we set up some remaining bind mounts and
# exec the requested command, skipping the rest of the installation procedure.
if [ -n "$runChroot" ]; then
mount -t tmpfs -o "mode=0755" none $mountPoint/run
rm -rf $mountPoint/var/run
ln -s /run $mountPoint/var/run
for f in /etc/resolv.conf /etc/hosts; do rm -f $mountPoint/$f; [ -f "$f" ] && cp -Lf $f $mountPoint/etc/; done
for f in /etc/passwd /etc/group; do touch $mountPoint/$f; [ -f "$f" ] && mount --rbind -o ro $f $mountPoint/$f; done
if ! [ -L $mountPoint/nix/var/nix/profiles/system ]; then
echo "$0: installation not finished; cannot chroot into installation directory"
exit 1
fi
ln -s /nix/var/nix/profiles/system $mountPoint/run/current-system
exec chroot $mountPoint "${chrootCommand[@]}"
if [[ ! -e $NIXOS_CONFIG && -z $system ]]; then
echo "configuration file $NIXOS_CONFIG doesn't exist"
exit 1
fi
# A place to drop temporary closures
# A place to drop temporary stuff.
trap "rm -rf $tmpdir" EXIT
tmpdir="$(mktemp -d)"
# Build a closure (on the host; we then copy it into the guest)
function closure() {
nix-build "${extraBuildFlags[@]}" --no-out-link -E "with import <nixpkgs> {}; runCommand \"closure\" { exportReferencesGraph = [ \"x\" (buildEnv { name = \"env\"; paths = [ ($1) stdenv ]; }) ]; } \"cp x \$out\""
}
sub="auto?trusted=1"
system_closure="$tmpdir/system.closure"
# Use a FIFO for piping nix-store --export into nix-store --import, saving disk
# I/O and space. nix-store --import is run by nixos-prepare-root.
mkfifo $system_closure
if [ -z "$closure" ]; then
expr="(import <nixpkgs/nixos> {}).system"
system_root="$(nix-build -E "$expr")"
system_closure="$(closure "$expr")"
else
system_root=$closure
# Create a temporary file ending in .closure (so nixos-prepare-root knows to --import it) to transport the store closure
# to the filesytem we're preparing. Also delete it on exit!
# Run in background to avoid blocking while trying to write to the FIFO
# $system_closure refers to
nix-store --export $(nix-store -qR $closure) > $system_closure &
# Build the system configuration in the target filesystem.
if [[ -z $system ]]; then
echo "building the configuration in $NIXOS_CONFIG..."
outLink="$tmpdir/system"
nix build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \
--extra-substituters "$sub" \
-f '<nixpkgs/nixos>' system -I "nixos-config=$NIXOS_CONFIG"
system=$(readlink -f $outLink)
fi
channel_root="$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")"
channel_closure="$tmpdir/channel.closure"
nix-store --export $channel_root > $channel_closure
# 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"
# Populate the target root directory with the basics
@prepare_root@/bin/nixos-prepare-root "$mountPoint" "$channel_root" "$system_root" @nixClosure@ "$system_closure" "$channel_closure"
# 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
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
# nixos-prepare-root doesn't currently do anything with file ownership, so we set it up here instead
chown @root_uid@:@nixbld_gid@ $mountPoint/nix/store
# 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.
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.
echo "finalising the installation..."
if [ -z "$noBootLoader" ]; then
NIXOS_INSTALL_BOOTLOADER=1 chroot $mountPoint \
/nix/var/nix/profiles/system/bin/switch-to-configuration boot
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
# Run the activation script.
chroot $mountPoint /nix/var/nix/profiles/system/activate
# Ask the user to set a root password.
if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /run/wrappers/bin/passwd ] && [ -t 0 ]; then
echo "setting root password..."
chroot $mountPoint /run/wrappers/bin/passwd
# 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
nixos-enter --root "$mountPoint" -c '[[ -e /nix/var/nix/profiles/system/sw/bin/passwd ]] && echo "setting root password..." && /nix/var/nix/profiles/system/sw/bin/passwd'
fi
echo "installation finished!"

View file

@ -1,104 +0,0 @@
#! @shell@
# This script's goal is to perform all "static" setup of a filesystem structure from pre-built store paths. Everything
# in here should run in a non-root context and inside a Nix builder. It's designed primarily to be called from image-
# building scripts and from nixos-install, but because it makes very few assumptions about the context in which it runs,
# it could be useful in other contexts as well.
#
# Current behavior:
# - set up basic filesystem structure
# - make Nix store etc.
# - copy Nix, system, channel, and misceallaneous closures to target Nix store
# - register validity of all paths in the target store
# - set up channel and system profiles
# Ensure a consistent umask.
umask 0022
set -e
mountPoint="$1"
channel="$2"
system="$3"
shift 3
closures="$@"
PATH="@coreutils@/bin:@nix@/bin:@perl@/bin:@utillinux@/bin:@rsync@/bin"
if ! test -e "$mountPoint"; then
echo "mount point $mountPoint doesn't exist"
exit 1
fi
# Create a few of the standard directories in the target root directory.
install -m 0755 -d $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/etc $mountPoint/run $mountPoint/home
install -m 01777 -d $mountPoint/tmp
install -m 0755 -d $mountPoint/tmp/root
install -m 0755 -d $mountPoint/var
install -m 0700 -d $mountPoint/root
ln -sf /run $mountPoint/var/run
# Create the necessary Nix directories on the target device
install -m 0755 -d \
$mountPoint/nix/var/nix/gcroots \
$mountPoint/nix/var/nix/temproots \
$mountPoint/nix/var/nix/userpool \
$mountPoint/nix/var/nix/profiles \
$mountPoint/nix/var/nix/db \
$mountPoint/nix/var/log/nix/drvs
install -m 1775 -d $mountPoint/nix/store
# All Nix operations below should operate on our target store, not /nix/store.
# N.B: this relies on Nix 1.12 or higher
export NIX_REMOTE=local?root=$mountPoint
# Copy our closures to the Nix store on the target mount point, unless they're already there.
for i in $closures; do
# We support closures both in the format produced by `nix-store --export` and by `exportReferencesGraph`,
# mostly because there doesn't seem to be a single format that can be produced outside of a nix build and
# inside one. See https://github.com/NixOS/nix/issues/1242 for more discussion.
if [[ "$i" =~ \.closure$ ]]; then
echo "importing serialized closure $i to $mountPoint..."
nix-store --import < $i
else
# There has to be a better way to do this, right?
echo "copying closure $i to $mountPoint..."
for j in $(perl @pathsFromGraph@ $i); do
echo " $j... "
rsync -a $j $mountPoint/nix/store/
done
nix-store --option build-users-group root --register-validity < $i
fi
done
# Create the required /bin/sh symlink; otherwise lots of things
# (notably the system() function) won't work.
if [ ! -x $mountPoint/@shell@ ]; then
echo "Error: @shell@ wasn't included in the closure" >&2
exit 1
fi
install -m 0755 -d $mountPoint/bin
ln -sf @shell@ $mountPoint/bin/sh
echo "setting the system closure to '$system'..."
nix-env "${extraBuildFlags[@]}" -p $mountPoint/nix/var/nix/profiles/system --set "$system"
ln -sfn /nix/var/nix/profiles/system $mountPoint/run/current-system
# Copy the NixOS/Nixpkgs sources to the target as the initial contents of the NixOS channel.
install -m 0755 -d $mountPoint/nix/var/nix/profiles
install -m 1777 -d $mountPoint/nix/var/nix/profiles/per-user
install -m 0755 -d $mountPoint/nix/var/nix/profiles/per-user/root
if [ -z "$noChannelCopy" ] && [ -n "$channel" ]; then
echo "copying channel..."
nix-env --option build-use-substitutes false "${extraBuildFlags[@]}" -p $mountPoint/nix/var/nix/profiles/per-user/root/channels --set "$channel" --quiet
fi
install -m 0700 -d $mountPoint/root/.nix-defexpr
ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels
# Mark the target as a NixOS installation, otherwise switch-to-configuration will chicken out.
touch $mountPoint/etc/NIXOS

View file

@ -1,7 +1,9 @@
# This module generates nixos-install, nixos-rebuild,
# nixos-generate-config, etc.
{ config, pkgs, modulesPath, ... }:
{ config, lib, pkgs, modulesPath, ... }:
with lib;
let
cfg = config.installer;
@ -16,28 +18,11 @@ let
src = ./nixos-build-vms/nixos-build-vms.sh;
};
nixos-prepare-root = makeProg {
name = "nixos-prepare-root";
src = ./nixos-prepare-root.sh;
nix = pkgs.nixUnstable;
inherit (pkgs) perl pathsFromGraph rsync utillinux coreutils;
};
nixos-install = makeProg {
name = "nixos-install";
src = ./nixos-install.sh;
inherit (pkgs) perl pathsFromGraph rsync;
nix = config.nix.package.out;
cacert = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
root_uid = config.ids.uids.root;
nixbld_gid = config.ids.gids.nixbld;
prepare_root = nixos-prepare-root;
nixClosure = pkgs.runCommand "closure"
{ exportReferencesGraph = ["refs" config.nix.package.out]; }
"cp refs $out";
path = makeBinPath [ nixos-enter ];
};
nixos-rebuild =
@ -69,6 +54,11 @@ let
inherit (config.system.nixos) version codeName revision;
};
nixos-enter = makeProg {
name = "nixos-enter";
src = ./nixos-enter.sh;
};
in
{
@ -77,16 +67,16 @@ in
environment.systemPackages =
[ nixos-build-vms
nixos-prepare-root
nixos-install
nixos-rebuild
nixos-generate-config
nixos-option
nixos-version
nixos-enter
];
system.build = {
inherit nixos-install nixos-prepare-root nixos-generate-config nixos-option nixos-rebuild;
inherit nixos-install nixos-prepare-root nixos-generate-config nixos-option nixos-rebuild nixos-enter;
};
};

View file

@ -72,7 +72,13 @@ with lib;
# To speed up installation a little bit, include the complete
# stdenv in the Nix store on the CD.
system.extraDependencies = with pkgs; [ stdenv stdenvNoCC busybox ];
system.extraDependencies = with pkgs;
[
stdenv
stdenvNoCC # for runCommand
busybox
jq # for closureInfo
];
# Show all debug messages from the kernel but don't log refused packets
# because we have the firewall enabled. This makes installs from the

View file

@ -33,9 +33,9 @@ let
sh = pkgs.stdenv.shell;
binshDeps = pkgs.writeReferencesToFile sh;
in
pkgs.runCommand "nix.conf" { extraOptions = cfg.extraOptions; inherit binshDeps; } ''
pkgs.runCommand "nix.conf" { extraOptions = cfg.extraOptions; } ''
${optionalString (!isNix20) ''
extraPaths=$(for i in $(cat binshDeps); do if test -d $i; then echo $i; fi; done)
extraPaths=$(for i in $(cat ${binshDeps}); do if test -d $i; then echo $i; fi; done)
''}
cat > $out <<END
# WARNING: this file is generated from the nix.* options in

View file

@ -117,14 +117,7 @@ in
config = {
system.activationScripts.stdio =
''
# Needed by some programs.
ln -sfn /proc/self/fd /dev/fd
ln -sfn /proc/self/fd/0 /dev/stdin
ln -sfn /proc/self/fd/1 /dev/stdout
ln -sfn /proc/self/fd/2 /dev/stderr
'';
system.activationScripts.stdio = ""; # obsolete
system.activationScripts.var =
''

View file

@ -54,7 +54,7 @@ with lib;
environment.systemPackages = [ pkgs.kmod ];
system.activationScripts.modprobe =
system.activationScripts.modprobe = stringAfter ["specialfs"]
''
# Allow the kernel to find our wrapped modprobe (which searches
# in the right location in the Nix store for kernel modules).

View file

@ -82,7 +82,6 @@ ln -s /proc/mounts /etc/mtab
mkdir -m 01777 -p /tmp
mkdir -m 0755 -p /var/{log,lib,db} /nix/var /etc/nixos/ \
/run/lock /home /bin # for the /bin/sh symlink
install -m 0700 -d /root
# Miscellaneous boot time cleanup.

View file

@ -50,6 +50,10 @@ in rec {
separateBoot
simple;
};
boot = {
inherit (nixos'.tests.boot)
biosCdrom;
};
};
};

View file

@ -24,6 +24,12 @@ let
my $machine = createMachine({ ${machineConfig}, qemuFlags => '-m 768' });
$machine->start;
$machine->waitForUnit("multi-user.target");
$machine->succeed("nix verify -r --no-trust /run/current-system");
# Test whether the channel got installed correctly.
$machine->succeed("nix-instantiate --dry-run '<nixpkgs>' -A hello");
$machine->succeed("nix-env --dry-run -iA nixos.procps");
$machine->shutdown;
'';
};

View file

@ -145,7 +145,7 @@ let
# Check that the daemon works, and that non-root users can run builds (this will build a new profile generation through the daemon)
$machine->succeed("su alice -l -c 'nix-env -iA nixos.procps' >&2");
# We need to a writable nix-store on next boot.
# We need a writable Nix store on next boot.
$machine->copyFileFromHost(
"${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; forceGrubReinstallCount = 1; } }",
"/etc/nixos/configuration.nix");
@ -195,8 +195,7 @@ let
};
nodes = {
# The configuration of the machine used to run "nixos-install". It
# also has a web server that simulates cache.nixos.org.
# The configuration of the machine used to run "nixos-install".
machine =
{ config, lib, pkgs, ... }:
@ -208,7 +207,6 @@ let
virtualisation.diskSize = 8 * 1024;
virtualisation.memorySize = 1024;
virtualisation.writableStore = true;
# Use a small /dev/vdb as the root disk for the
# installer. This ensures the target disk (/dev/vda) is
@ -245,6 +243,11 @@ let
++ optionals (bootLoader == "grub" && grubVersion == 2) [ pkgs.grub2 pkgs.grub2_efi ];
nix.binaryCaches = mkForce [ ];
nix.extraOptions =
''
hashed-mirrors =
connect-timeout = 1
'';
};
};

View file

@ -1,11 +1,13 @@
# Miscellaneous small tests that don't warrant their own VM run.
import ./make-test.nix ({ pkgs, ...} : {
import ./make-test.nix ({ pkgs, ...} : rec {
name = "misc";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ eelco chaoflow ];
};
foo = pkgs.writeText "foo" "Hello World";
machine =
{ config, lib, pkgs, ... }:
with lib;
@ -27,10 +29,17 @@ import ./make-test.nix ({ pkgs, ...} : {
security.sudo = { enable = true; wheelNeedsPassword = false; };
boot.kernel.sysctl."vm.swappiness" = 1;
boot.kernelParams = [ "vsyscall=emulate" ];
system.extraDependencies = [ foo ];
};
testScript =
''
subtest "nix-db", sub {
my $json = $machine->succeed("nix path-info --json ${foo}");
$json =~ /"narHash":"sha256:0afw0d9j1hvwiz066z93jiddc33nxg6i6qyp26vnqyglpyfivlq5"/ or die "narHash not set";
$json =~ /"narSize":128/ or die "narSize not set";
};
subtest "nixos-version", sub {
$machine->succeed("[ `nixos-version | wc -w` = 2 ]");
};

View file

@ -4,55 +4,31 @@
# "nix-store --load-db" and "nix-store --register-validity
# --hash-given".
{ stdenv, coreutils, jq, perl, pathsFromGraph }:
{ stdenv, coreutils, jq }:
{ rootPaths }:
#if builtins.langVersion >= 5 then
# FIXME: it doesn't work on Hydra, failing to find mkdir;
# perhaps .attrs.sh clobbers PATH with new nix?
if false then
assert builtins.langVersion >= 5;
# Nix >= 1.12: Include NAR hash / size info.
stdenv.mkDerivation {
name = "closure-info";
stdenv.mkDerivation {
name = "closure-info";
__structuredAttrs = true;
__structuredAttrs = true;
exportReferencesGraph.closure = rootPaths;
exportReferencesGraph.closure = rootPaths;
PATH = "${coreutils}/bin:${jq}/bin";
PATH = "${coreutils}/bin:${jq}/bin";
builder = builtins.toFile "builder"
''
. .attrs.sh
builder = builtins.toFile "builder"
''
if [ -e .attrs.sh ]; then . .attrs.sh; fi
out=''${outputs[out]}
out=''${outputs[out]}
mkdir $out
mkdir $out
jq -r '.closure | map([.path, .narHash, .narSize, "", (.references | length)] + .references) | add | map("\(.)\n") | add' < .attrs.json | head -n -1 > $out/registration
jq -r .closure[].path < .attrs.json > $out/store-paths
'';
}
else
# Nix < 1.12
stdenv.mkDerivation {
name = "closure-info";
exportReferencesGraph =
map (x: [("closure-" + baseNameOf x) x]) rootPaths;
buildInputs = [ perl ];
buildCommand =
''
mkdir $out
printRegistration=1 perl ${pathsFromGraph} closure-* > $out/registration
perl ${pathsFromGraph} closure-* > $out/store-paths
'';
}
jq -r ".closure | map(.narSize) | add" < .attrs.json > $out/total-nar-size
jq -r '.closure | map([.path, .narHash, .narSize, "", (.references | length)] + .references) | add | map("\(.)\n") | add' < .attrs.json | head -n -1 > $out/registration
jq -r .closure[].path < .attrs.json > $out/store-paths
'';
}

View file

@ -12,7 +12,7 @@
# `contents = {object = ...; symlink = /init;}' is a typical
# argument.
{ stdenv, perl, cpio, contents, compressor, prepend, ubootTools
{ stdenv, closureInfo, cpio, contents, compressor, prepend, ubootTools
, hostPlatform
}:
@ -22,7 +22,7 @@ stdenv.mkDerivation rec {
makeUInitrd = hostPlatform.platform.kernelTarget == "uImage";
nativeBuildInputs = [ perl cpio ]
nativeBuildInputs = [ cpio ]
++ stdenv.lib.optional makeUInitrd ubootTools;
# !!! should use XML.
@ -30,10 +30,7 @@ stdenv.mkDerivation rec {
symlinks = map (x: x.symlink) contents;
suffices = map (x: if x ? suffix then x.suffix else "none") contents;
# For obtaining the closure of `contents'.
exportReferencesGraph =
map (x: [("closure-" + baseNameOf x.symlink) x.object]) contents;
pathsFromGraph = ./paths-from-graph.pl;
closure = closureInfo { rootPaths = (map (x: x.object) contents); };
inherit compressor prepend;
}

View file

@ -25,13 +25,9 @@ for ((n = 0; n < ${#objects[*]}; n++)); do
done
# Get the paths in the closure of `object'.
storePaths=$(perl $pathsFromGraph closure-*)
# Paths in cpio archives *must* be relative, otherwise the kernel
# won't unpack 'em.
(cd root && cp -prd --parents $storePaths .)
(cd root && cp -prd --parents $(cat $closure/store-paths) .)
# Put the closure in a gzipped cpio archive.

View file

@ -1,3 +1,5 @@
# NOTE: this script is deprecated. Use closureInfo instead.
# Parses a /nix/store/*-closure file and prints
# various information.
# By default, the nodes in the graph are printed to stdout.

View file

@ -116,7 +116,7 @@ in rec {
nix = nixStable;
nixStable = (common rec {
nix1 = (common rec {
name = "nix-1.11.16";
src = fetchurl {
url = "http://nixos.org/releases/nix/${name}/${name}.tar.xz";
@ -124,6 +124,14 @@ in rec {
};
}) // { perl-bindings = nixStable; };
nixStable = (common rec {
name = "nix-2.0";
src = fetchurl {
url = "http://nixos.org/releases/nix/${name}/${name}.tar.xz";
sha256 = "7024d327314bf92c1d3e6cccd944929828a44b24093954036bfb0115a92f5a14";
};
}) // { perl-bindings = perl-bindings { nix = nixStable; }; };
nixUnstable = (lib.lowPrio (common rec {
name = "nix-2.0${suffix}";
suffix = "pre5968_a6c0b773";

View file

@ -4047,9 +4047,7 @@ with pkgs;
p7zip = callPackage ../tools/archivers/p7zip { };
packagekit = callPackage ../tools/package-management/packagekit {
nix = nixUnstable;
};
packagekit = callPackage ../tools/package-management/packagekit { };
packagekit-qt = libsForQt5.callPackage ../tools/package-management/packagekit/qt.nix { };
@ -6978,8 +6976,6 @@ with pkgs;
mujs = callPackage ../development/interpreters/mujs { };
nix-exec = callPackage ../development/interpreters/nix-exec {
nix = nixUnstable;
git = gitMinimal;
};
@ -10573,8 +10569,7 @@ with pkgs;
};
libnghttp2 = nghttp2.lib;
nix-plugins = callPackage ../development/libraries/nix-plugins
{ nix = nixUnstable; };
nix-plugins = callPackage ../development/libraries/nix-plugins { };
nlohmann_json = callPackage ../development/libraries/nlohmann_json { };
@ -20231,6 +20226,7 @@ with pkgs;
stateDir = config.nix.stateDir or "/nix/var";
})
nix
nix1
nixStable
nixUnstable;
@ -20242,7 +20238,7 @@ with pkgs;
nixui = callPackage ../tools/package-management/nixui { node_webkit = nwjs_0_12; };
nix-bundle = callPackage ../tools/package-management/nix-bundle { nix = nixUnstable; };
nix-bundle = callPackage ../tools/package-management/nix-bundle { };
nix-delegate = haskell.lib.justStaticExecutables haskellPackages.nix-delegate;
nix-deploy = haskell.lib.justStaticExecutables haskellPackages.nix-deploy;