···87 exit 1
88fi
8990-91-# Mount some stuff in the target root directory.
92-mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/etc $mountPoint/run $mountPoint/home
93-mkdir -m 01777 -p $mountPoint/tmp
94-mkdir -m 0755 -p $mountPoint/tmp/root
95-mkdir -m 0755 -p $mountPoint/var
96-mkdir -m 0700 -p $mountPoint/root
97-mount --rbind /dev $mountPoint/dev
98-mount --rbind /proc $mountPoint/proc
99-mount --rbind /sys $mountPoint/sys
100-mount --rbind / $mountPoint/tmp/root
101-mount -t tmpfs -o "mode=0755" none $mountPoint/run
102-rm -rf $mountPoint/var/run
103-ln -s /run $mountPoint/var/run
104-for f in /etc/resolv.conf /etc/hosts; do rm -f $mountPoint/$f; [ -f "$f" ] && cp -Lf $f $mountPoint/etc/; done
105-for f in /etc/passwd /etc/group; do touch $mountPoint/$f; [ -f "$f" ] && mount --rbind -o ro $f $mountPoint/$f; done
106-107-cp -Lf "@cacert@" "$mountPoint/tmp/ca-cert.crt"
108-export SSL_CERT_FILE=/tmp/ca-cert.crt
109-# For Nix 1.7
110-export CURL_CA_BUNDLE=/tmp/ca-cert.crt
111-112-if [ -n "$runChroot" ]; then
113- if ! [ -L $mountPoint/nix/var/nix/profiles/system ]; then
114- echo "$0: installation not finished; cannot chroot into installation directory"
115- exit 1
116- fi
117- ln -s /nix/var/nix/profiles/system $mountPoint/run/current-system
118- exec chroot $mountPoint "${chrootCommand[@]}"
119-fi
120-121-122# Get the path of the NixOS configuration file.
123if test -z "$NIXOS_CONFIG"; then
124 NIXOS_CONFIG=/etc/nixos/configuration.nix
···130fi
131132133-# Create the necessary Nix directories on the target device, if they
134-# don't already exist.
135-mkdir -m 0755 -p \
136- $mountPoint/nix/var/nix/gcroots \
137- $mountPoint/nix/var/nix/temproots \
138- $mountPoint/nix/var/nix/userpool \
139- $mountPoint/nix/var/nix/profiles \
140- $mountPoint/nix/var/nix/db \
141- $mountPoint/nix/var/log/nix/drvs
142-143-mkdir -m 1775 -p $mountPoint/nix/store
144-chown @root_uid@:@nixbld_gid@ $mountPoint/nix/store
145-146-147-# There is no daemon in the chroot.
148-unset NIX_REMOTE
149-150-151-# We don't have locale-archive in the chroot, so clear $LANG.
152-export LANG=
153-export LC_ALL=
154-export LC_TIME=
155-156-157# Builds will use users that are members of this group
158extraBuildFlags+=(--option "build-users-group" "$buildUsersGroup")
159160-161# Inherit binary caches from the host
0162binary_caches="$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};')"
163extraBuildFlags+=(--option "binary-caches" "$binary_caches")
164000165166-# Copy Nix to the Nix store on the target device, unless it's already there.
167-if ! NIX_DB_DIR=$mountPoint/nix/var/nix/db nix-store --check-validity @nix@ 2> /dev/null; then
168- echo "copying Nix to $mountPoint...."
169- for i in $(@perl@/bin/perl @pathsFromGraph@ @nixClosure@); do
170- echo " $i"
171- chattr -R -i $mountPoint/$i 2> /dev/null || true # clear immutable bit
172- @rsync@/bin/rsync -a $i $mountPoint/nix/store/
173- done
174175- # Register the paths in the Nix closure as valid. This is necessary
176- # to prevent them from being deleted the first time we install
177- # something. (I.e., Nix will see that, e.g., the glibc path is not
178- # valid, delete it to get it out of the way, but as a result nothing
179- # will work anymore.)
180- chroot $mountPoint @nix@/bin/nix-store --register-validity < @nixClosure@
181-fi
182183-184-# Create the required /bin/sh symlink; otherwise lots of things
185-# (notably the system() function) won't work.
186-mkdir -m 0755 -p $mountPoint/bin
187-# !!! assuming that @shell@ is in the closure
188-ln -sf @shell@ $mountPoint/bin/sh
189-190191-# Build hooks likely won't function correctly in the minimal chroot; just disable them.
192-unset NIX_BUILD_HOOK
193-194-# Make the build below copy paths from the CD if possible. Note that
195-# /tmp/root in the chroot is the root of the CD.
196-export NIX_OTHER_STORES=/tmp/root/nix:$NIX_OTHER_STORES
197-198-p=@nix@/libexec/nix/substituters
199-export NIX_SUBSTITUTERS=$p/copy-from-other-stores.pl:$p/download-from-binary-cache.pl
2000201202if [ -z "$closure" ]; then
203- # Get the absolute path to the NixOS/Nixpkgs sources.
204- nixpkgs="$(readlink -f $(nix-instantiate --find-file nixpkgs))"
205-206- nixEnvAction="-f <nixpkgs/nixos> --set -A system"
207else
208- nixpkgs=""
209- nixEnvAction="--set $closure"
00210fi
211212-# Build the specified Nix expression in the target store and install
213-# it into the system configuration profile.
214-echo "building the system configuration..."
215-NIX_PATH="nixpkgs=/tmp/root/$nixpkgs:nixos-config=$NIXOS_CONFIG" NIXOS_CONFIG= \
216- chroot $mountPoint @nix@/bin/nix-env \
217- "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/system $nixEnvAction
218-219-220-# Copy the NixOS/Nixpkgs sources to the target as the initial contents
221-# of the NixOS channel.
222-mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles
223-mkdir -m 1777 -p $mountPoint/nix/var/nix/profiles/per-user
224-mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles/per-user/root
225-srcs=$(nix-env "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")
226-if [ -z "$noChannelCopy" ] && [ -n "$srcs" ]; then
227- echo "copying NixOS/Nixpkgs sources..."
228- chroot $mountPoint @nix@/bin/nix-env \
229- "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/per-user/root/channels -i "$srcs" --quiet
230-fi
231-mkdir -m 0700 -p $mountPoint/root/.nix-defexpr
232-ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels
23300234235-# Get rid of the /etc bind mounts.
236-for f in /etc/passwd /etc/group; do [ -f "$f" ] && umount $mountPoint/$f; done
237000238239# Grub needs an mtab.
240ln -sfn /proc/mounts $mountPoint/etc/mtab
241-242-243-# Mark the target as a NixOS installation, otherwise
244-# switch-to-configuration will chicken out.
245-touch $mountPoint/etc/NIXOS
246-247248# Switch to the new system configuration. This will install Grub with
249# a menu default pointing at the kernel/initrd/etc of the new
···87 exit 1
88fi
890000000000000000000000000000000090# Get the path of the NixOS configuration file.
91if test -z "$NIXOS_CONFIG"; then
92 NIXOS_CONFIG=/etc/nixos/configuration.nix
···98fi
99100000000000000000000000000101# Builds will use users that are members of this group
102extraBuildFlags+=(--option "build-users-group" "$buildUsersGroup")
1030104# Inherit binary caches from the host
105+# TODO: will this still work with Nix 1.12 now that it has no perl? Probably not...
106binary_caches="$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};')"
107extraBuildFlags+=(--option "binary-caches" "$binary_caches")
108109+nixpkgs="$(readlink -f "$(nix-instantiate --find-file nixpkgs)")"
110+export NIX_PATH="nixpkgs=$nixpkgs:nixos-config=$mountPoint/$NIXOS_CONFIG"
111+unset NIXOS_CONFIG
112113+# TODO: do I need to set NIX_SUBSTITUTERS here or is the --option binary-caches above enough?
00000001140000000115116+# A place to drop temporary closures
117+trap "rm -rf $tmpdir" EXIT
118+tmpdir="$(mktemp -d)"
0000119120+# Build a closure (on the host; we then copy it into the guest)
121+function closure() {
122+ nix-build "${extraBuildFlags[@]}" --no-out-link -E "with import <nixpkgs> {}; runCommand \"closure\" { exportReferencesGraph = [ \"x\" (buildEnv { name = \"env\"; paths = [ ($1) stdenv ]; }) ]; } \"cp x \$out\""
123+}
00000124125+system_closure="$tmpdir/system.closure"
126127if [ -z "$closure" ]; then
128+ expr="(import <nixpkgs/nixos> {}).system"
129+ system_root="$(nix-build -E "$expr")"
130+ system_closure="$(closure "$expr")"
0131else
132+ system_root=$closure
133+ # Create a temporary file ending in .closure (so nixos-prepare-root knows to --import it) to transport the store closure
134+ # to the filesytem we're preparing. Also delete it on exit!
135+ nix-store --export $(nix-store -qR $closure) > $system_closure
136fi
137138+channel_root="$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")"
139+channel_closure="$tmpdir/channel.closure"
140+nix-store --export $channel_root > $channel_closure
000000000000000000141142+# Populate the target root directory with the basics
143+@prepare_root@/bin/nixos-prepare-root $mountPoint $channel_root $system_root @nixClosure@ $system_closure $channel_closure
144145+# nixos-prepare-root doesn't currently do anything with file ownership, so we set it up here instead
146+chown @root_uid@:@nixbld_gid@ $mountPoint/nix/store
147148+mount --rbind /dev $mountPoint/dev
149+mount --rbind /proc $mountPoint/proc
150+mount --rbind /sys $mountPoint/sys
151152# Grub needs an mtab.
153ln -sfn /proc/mounts $mountPoint/etc/mtab
000000154155# Switch to the new system configuration. This will install Grub with
156# a menu default pointing at the kernel/initrd/etc of the new
···1+#! @shell@
2+3+# This script's goal is to perform all "static" setup of a filesystem structure from pre-built store paths. Everything
4+# in here should run in a non-root context and inside a Nix builder. It's designed primarily to be called from image-
5+# building scripts and from nixos-install, but because it makes very few assumptions about the context in which it runs,
6+# it could be useful in other contexts as well.
7+#
8+# Current behavior:
9+# - set up basic filesystem structure
10+# - make Nix store etc.
11+# - copy Nix, system, channel, and misceallaneous closures to target Nix store
12+# - register validity of all paths in the target store
13+# - set up channel and system profiles
14+15+# Ensure a consistent umask.
16+umask 0022
17+18+set -e
19+20+mountPoint="$1"
21+channel="$2"
22+system="$3"
23+shift 3
24+closures="$@"
25+26+PATH="@coreutils@/bin:@nix@/bin:@perl@/bin:@utillinux@/bin:@rsync@/bin"
27+28+if ! test -e "$mountPoint"; then
29+ echo "mount point $mountPoint doesn't exist"
30+ exit 1
31+fi
32+33+# Create a few of the standard directories in the target root directory.
34+mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/etc $mountPoint/run $mountPoint/home
35+mkdir -m 01777 -p $mountPoint/tmp
36+mkdir -m 0755 -p $mountPoint/tmp/root
37+mkdir -m 0755 -p $mountPoint/var
38+mkdir -m 0700 -p $mountPoint/root
39+40+ln -s /run $mountPoint/var/run
41+42+# Create the necessary Nix directories on the target device
43+mkdir -m 0755 -p \
44+ $mountPoint/nix/var/nix/gcroots \
45+ $mountPoint/nix/var/nix/temproots \
46+ $mountPoint/nix/var/nix/userpool \
47+ $mountPoint/nix/var/nix/profiles \
48+ $mountPoint/nix/var/nix/db \
49+ $mountPoint/nix/var/log/nix/drvs
50+51+mkdir -m 1775 -p $mountPoint/nix/store
52+53+# All Nix operations below should operate on our target store, not /nix/store.
54+# N.B: this relies on Nix 1.12 or higher
55+export NIX_REMOTE=local?root=$mountPoint
56+57+# Copy our closures to the Nix store on the target mount point, unless they're already there.
58+for i in $closures; do
59+ # We support closures both in the format produced by `nix-store --export` and by `exportReferencesGraph`,
60+ # mostly because there doesn't seem to be a single format that can be produced outside of a nix build and
61+ # inside one. See https://github.com/NixOS/nix/issues/1242 for more discussion.
62+ if [[ "$i" =~ \.closure$ ]]; then
63+ echo "importing serialized closure $i to $mountPoint..."
64+ nix-store --import < $i
65+ else
66+ # There has to be a better way to do this, right?
67+ echo "copying closure $i to $mountPoint..."
68+ for j in $(perl @pathsFromGraph@ $i); do
69+ echo " $j... "
70+ rsync -a $j $mountPoint/nix/store/
71+ done
72+73+ nix-store --register-validity < $i
74+ fi
75+done
76+77+# Create the required /bin/sh symlink; otherwise lots of things
78+# (notably the system() function) won't work.
79+if [ ! -x $mountPoint/@shell@ ]; then
80+ echo "Error: @shell@ wasn't included in the closure" >&2
81+ exit 1
82+fi
83+mkdir -m 0755 -p $mountPoint/bin
84+ln -sf @shell@ $mountPoint/bin/sh
85+86+echo "setting the system closure to '$system'..."
87+nix-env "${extraBuildFlags[@]}" -p $mountPoint/nix/var/nix/profiles/system --set "$system"
88+89+ln -sfn /nix/var/nix/profiles/system $mountPoint/run/current-system
90+91+# Copy the NixOS/Nixpkgs sources to the target as the initial contents of the NixOS channel.
92+mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles
93+mkdir -m 1777 -p $mountPoint/nix/var/nix/profiles/per-user
94+mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles/per-user/root
95+96+if [ -z "$noChannelCopy" ] && [ -n "$channel" ]; then
97+ echo "copying channel..."
98+ nix-env --option build-use-substitutes false "${extraBuildFlags[@]}" -p $mountPoint/nix/var/nix/profiles/per-user/root/channels --set "$channel" --quiet
99+fi
100+mkdir -m 0700 -p $mountPoint/root/.nix-defexpr
101+ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels
102+103+# Mark the target as a NixOS installation, otherwise switch-to-configuration will chicken out.
104+touch $mountPoint/etc/NIXOS
105+
···34 boot.loader.systemd-boot.enable = true;
35 ''}
3600000037 hardware.enableAllFirmware = lib.mkForce false;
3839 ${replaceChars ["\n"] ["\n "] extraConfig}
···96 $machine->shutdown;
9798 # Now see if we can boot the installation.
99- $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
100101 # For example to enter LUKS passphrase.
102 ${preBootCommands}
···118 $machine->waitForUnit("swap.target");
119 $machine->succeed("cat /proc/swaps | grep -q /dev");
120000121 # Check whether the channel works.
122 $machine->succeed("nix-env -iA nixos.procps >&2");
123 $machine->succeed("type -tP ps | tee /dev/stderr") =~ /.nix-profile/
124 or die "nix-env failed";
000125126 # We need to a writable nix-store on next boot.
127 $machine->copyFileFromHost(
···139 $machine->shutdown;
140141 # Check whether a writable store build works
142- $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
143 ${preBootCommands}
144 $machine->waitForUnit("multi-user.target");
145 $machine->copyFileFromHost(
···150151 # And just to be sure, check that the machine still boots after
152 # "nixos-rebuild switch".
153- $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
154 ${preBootCommands}
155 $machine->waitForUnit("network.target");
156 $machine->shutdown;
···34 boot.loader.systemd-boot.enable = true;
35 ''}
3637+ users.extraUsers.alice = {
38+ isNormalUser = true;
39+ home = "/home/alice";
40+ description = "Alice Foobar";
41+ };
42+43 hardware.enableAllFirmware = lib.mkForce false;
4445 ${replaceChars ["\n"] ["\n "] extraConfig}
···102 $machine->shutdown;
103104 # Now see if we can boot the installation.
105+ $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", name => "boot-after-install" });
106107 # For example to enter LUKS passphrase.
108 ${preBootCommands}
···124 $machine->waitForUnit("swap.target");
125 $machine->succeed("cat /proc/swaps | grep -q /dev");
126127+ # Check that the store is in good shape
128+ $machine->succeed("nix-store --verify --check-contents >&2");
129+130 # Check whether the channel works.
131 $machine->succeed("nix-env -iA nixos.procps >&2");
132 $machine->succeed("type -tP ps | tee /dev/stderr") =~ /.nix-profile/
133 or die "nix-env failed";
134+135+ # Check that the daemon works, and that non-root users can run builds (this will build a new profile generation through the daemon)
136+ $machine->succeed("su alice -l -c 'nix-env -iA nixos.procps' >&2");
137138 # We need to a writable nix-store on next boot.
139 $machine->copyFileFromHost(
···151 $machine->shutdown;
152153 # Check whether a writable store build works
154+ $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", name => "rebuild-switch" });
155 ${preBootCommands}
156 $machine->waitForUnit("multi-user.target");
157 $machine->copyFileFromHost(
···162163 # And just to be sure, check that the machine still boots after
164 # "nixos-rebuild switch".
165+ $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", "boot-after-rebuild-switch" });
166 ${preBootCommands}
167 $machine->waitForUnit("network.target");
168 $machine->shutdown;
+3-2
pkgs/tools/package-management/nix/default.nix
···131 sha256 = "69e0f398affec2a14c47b46fec712906429c85312d5483be43e4c34da4f63f67";
132 };
133134- # 1.11.8 doesn't yet have the patch to work on LLVM 4, so we patch it for now. Take this out once
135- # we move to a higher version. I'd pull the specific patch from upstream but it doesn't apply cleanly.
136 patchPhase = ''
137 substituteInPlace src/libexpr/json-to-value.cc \
138 --replace 'std::less<Symbol>, gc_allocator<Value *>' \
139 'std::less<Symbol>, gc_allocator<std::pair<const Symbol, Value *> >'
00140 '';
141 }) // { perl-bindings = nixStable; };
142
···131 sha256 = "69e0f398affec2a14c47b46fec712906429c85312d5483be43e4c34da4f63f67";
132 };
133134+ # Until 1.11.9 is released, we do this :)
0135 patchPhase = ''
136 substituteInPlace src/libexpr/json-to-value.cc \
137 --replace 'std::less<Symbol>, gc_allocator<Value *>' \
138 'std::less<Symbol>, gc_allocator<std::pair<const Symbol, Value *> >'
139+140+ sed -i '/if (settings.readOnlyMode) {/a curSchema = getSchema();' src/libstore/local-store.cc
141 '';
142 }) // { perl-bindings = nixStable; };
143