install: configure and bootstrap synthetic.conf on darwin
Starting macOS 10.15 /nix can't be creasted directly anymore due to the readonly filesystem, but synthetic.conf was introduced to enable creating mountpoints or symlinks for special usecases like package managers.
This commit is contained in:
parent
5d2d0a7b7f
commit
0726ad5825
3 changed files with 176 additions and 36 deletions
12
release.nix
12
release.nix
|
@ -177,10 +177,10 @@ let
|
|||
}
|
||||
''
|
||||
cp ${installerClosureInfo}/registration $TMPDIR/reginfo
|
||||
cp ${./scripts/create-darwin-volume.sh} $TMPDIR/create-darwin-volume.sh
|
||||
substitute ${./scripts/install-nix-from-closure.sh} $TMPDIR/install \
|
||||
--subst-var-by nix ${toplevel} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
|
||||
substitute ${./scripts/install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user.sh \
|
||||
--subst-var-by nix ${toplevel} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
|
@ -195,6 +195,7 @@ let
|
|||
# SC1090: Don't worry about not being able to find
|
||||
# $nix/etc/profile.d/nix.sh
|
||||
shellcheck --exclude SC1090 $TMPDIR/install
|
||||
shellcheck $TMPDIR/create-darwin-volume.sh
|
||||
shellcheck $TMPDIR/install-darwin-multi-user.sh
|
||||
shellcheck $TMPDIR/install-systemd-multi-user.sh
|
||||
|
||||
|
@ -210,6 +211,7 @@ let
|
|||
fi
|
||||
|
||||
chmod +x $TMPDIR/install
|
||||
chmod +x $TMPDIR/create-darwin-volume.sh
|
||||
chmod +x $TMPDIR/install-darwin-multi-user.sh
|
||||
chmod +x $TMPDIR/install-systemd-multi-user.sh
|
||||
chmod +x $TMPDIR/install-multi-user
|
||||
|
@ -222,11 +224,15 @@ let
|
|||
--absolute-names \
|
||||
--hard-dereference \
|
||||
--transform "s,$TMPDIR/install,$dir/install," \
|
||||
--transform "s,$TMPDIR/create-darwin-volume.sh,$dir/create-darwin-volume.sh," \
|
||||
--transform "s,$TMPDIR/reginfo,$dir/.reginfo," \
|
||||
--transform "s,$NIX_STORE,$dir/store,S" \
|
||||
$TMPDIR/install $TMPDIR/install-darwin-multi-user.sh \
|
||||
$TMPDIR/install \
|
||||
$TMPDIR/create-darwin-volume.sh \
|
||||
$TMPDIR/install-darwin-multi-user.sh \
|
||||
$TMPDIR/install-systemd-multi-user.sh \
|
||||
$TMPDIR/install-multi-user $TMPDIR/reginfo \
|
||||
$TMPDIR/install-multi-user \
|
||||
$TMPDIR/reginfo \
|
||||
$(cat ${installerClosureInfo}/store-paths)
|
||||
'');
|
||||
|
||||
|
|
107
scripts/create-darwin-volume.sh
Executable file
107
scripts/create-darwin-volume.sh
Executable file
|
@ -0,0 +1,107 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
root_disks() {
|
||||
diskutil list -plist /
|
||||
}
|
||||
|
||||
apfs_volumes_for() {
|
||||
disk=$1
|
||||
diskutil apfs list -plist "$disk"
|
||||
}
|
||||
|
||||
disk_identifier() {
|
||||
xpath "/plist/dict/key[text()='WholeDisks']/following-sibling::array[1]/string/text()" 2>/dev/null
|
||||
}
|
||||
|
||||
volume_get() {
|
||||
key=$1 i=$2
|
||||
xpath "/plist/dict/array/dict/key[text()='Volumes']/following-sibling::array/dict[$i]/key[text()='$key']/following-sibling::string[1]/text()" 2> /dev/null
|
||||
}
|
||||
|
||||
find_nix_volume() {
|
||||
disk=$1
|
||||
i=1
|
||||
volumes=$(apfs_volumes_for "$disk")
|
||||
while true; do
|
||||
name=$(echo "$volumes" | volume_get "Name" "$i")
|
||||
if [ -z "$name" ]; then
|
||||
break
|
||||
fi
|
||||
case "$name" in
|
||||
[Nn]ix*)
|
||||
echo "$name"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
i=$((i+1))
|
||||
done
|
||||
}
|
||||
|
||||
test_fstab() {
|
||||
grep -q "/nix" /etc/fstab 2>/dev/null
|
||||
}
|
||||
|
||||
test_synthetic_conf() {
|
||||
grep -q "^nix" /etc/synthetic.conf 2>/dev/null
|
||||
}
|
||||
|
||||
test_nix() {
|
||||
test -d "/nix"
|
||||
}
|
||||
|
||||
main() {
|
||||
(
|
||||
echo ""
|
||||
echo " ------------------------------------------------------------------ "
|
||||
echo " | This installer will create a volume for the nix store and |"
|
||||
echo " | configure it to mount at /nix. Follow these steps to uninstall. |"
|
||||
echo " ------------------------------------------------------------------ "
|
||||
echo ""
|
||||
echo " 1. Remove the entry from fstab using 'sudo vifs'"
|
||||
echo " 2. Destroy the data volume using 'diskutil apfs deleteVolume'"
|
||||
echo " 3. Delete /etc/synthetic.conf"
|
||||
echo ""
|
||||
) >&2
|
||||
|
||||
if [ -L "/nix" ]; then
|
||||
echo "error: /nix is a symlink, please remove it or edit synthetic.conf (requires reboot)" >&2
|
||||
echo " /nix -> $(readlink "/nix")" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if ! test_synthetic_conf; then
|
||||
echo "Configuring /etc/synthetic.conf..." >&2
|
||||
echo nix | sudo tee /etc/synthetic.conf
|
||||
/System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B
|
||||
fi
|
||||
|
||||
if ! test_nix; then
|
||||
echo "Creating mountpoint for /nix..." >&2
|
||||
sudo mkdir /nix
|
||||
fi
|
||||
|
||||
disk=$(root_disks | disk_identifier)
|
||||
volume=$(find_nix_volume "$disk")
|
||||
if [ -z "$volume" ]; then
|
||||
echo "Creating a Nix Store volume..." >&2
|
||||
sudo diskutil apfs addVolume "$disk" APFS 'Nix Store' -mountpoint /nix
|
||||
volume="Nix Store"
|
||||
else
|
||||
echo "Using existing '$volume' volume" >&2
|
||||
fi
|
||||
|
||||
if ! test_fstab; then
|
||||
echo "Configuring /etc/fstab..." >&2
|
||||
label=$(echo "$volume" | sed 's/ /\\040/g')
|
||||
printf "\$a\nLABEL=%s /nix apfs rw\n.\nwq\n" "$label" | EDITOR=ed sudo vifs
|
||||
fi
|
||||
|
||||
echo "The following options can be enabled to disable spotlight indexing" >&2
|
||||
echo "of the volume, which might be desirable." >&2
|
||||
echo "" >&2
|
||||
echo " $ mdutil -i off /nix" >&2
|
||||
echo "" >&2
|
||||
}
|
||||
|
||||
main "$@"
|
|
@ -40,44 +40,62 @@ elif [ "$(uname -s)" = "Linux" ] && [ -e /run/systemd/system ]; then
|
|||
fi
|
||||
|
||||
INSTALL_MODE=no-daemon
|
||||
|
||||
CREATE_DARWIN_VOLUME=0
|
||||
# handle the command line flags
|
||||
while [ "x${1:-}" != "x" ]; do
|
||||
if [ "x${1:-}" = "x--no-daemon" ]; then
|
||||
INSTALL_MODE=no-daemon
|
||||
elif [ "x${1:-}" = "x--daemon" ]; then
|
||||
INSTALL_MODE=daemon
|
||||
elif [ "x${1:-}" = "x--no-channel-add" ]; then
|
||||
NIX_INSTALLER_NO_CHANNEL_ADD=1
|
||||
elif [ "x${1:-}" = "x--no-modify-profile" ]; then
|
||||
NIX_INSTALLER_NO_MODIFY_PROFILE=1
|
||||
elif [ "x${1:-}" != "x" ]; then
|
||||
(
|
||||
echo "Nix Installer [--daemon|--no-daemon] [--no-channel-add] [--no-modify-profile]"
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--daemon)
|
||||
INSTALL_MODE=daemon;;
|
||||
--no-daemon)
|
||||
INSTALL_MODE=no-daemon;;
|
||||
--no-channel-add)
|
||||
NIX_INSTALLER_NO_CHANNEL_ADD=1;;
|
||||
--no-modify-profile)
|
||||
NIX_INSTALLER_NO_MODIFY_PROFILE=1;;
|
||||
--create-volume)
|
||||
CREATE_DARWIN_VOLUME=1;;
|
||||
*)
|
||||
(
|
||||
echo "Nix Installer [--daemon|--no-daemon] [--no-channel-add] [--no-modify-profile]"
|
||||
|
||||
echo "Choose installation method."
|
||||
echo ""
|
||||
echo " --daemon: Installs and configures a background daemon that manages the store,"
|
||||
echo " providing multi-user support and better isolation for local builds."
|
||||
echo " Both for security and reproducibility, this method is recommended if"
|
||||
echo " supported on your platform."
|
||||
echo " See https://nixos.org/nix/manual/#sect-multi-user-installation"
|
||||
echo ""
|
||||
echo " --no-daemon: Simple, single-user installation that does not require root and is"
|
||||
echo " trivial to uninstall."
|
||||
echo " (default)"
|
||||
echo ""
|
||||
echo " --no-channel-add: Don't add any channels. nixpkgs-unstable is installed by default."
|
||||
echo ""
|
||||
echo " --no-modify-profile: Skip channel installation. When not provided nixpkgs-unstable"
|
||||
echo " is installed by default."
|
||||
echo ""
|
||||
) >&2
|
||||
exit
|
||||
fi
|
||||
echo "Choose installation method."
|
||||
echo ""
|
||||
echo " --daemon: Installs and configures a background daemon that manages the store,"
|
||||
echo " providing multi-user support and better isolation for local builds."
|
||||
echo " Both for security and reproducibility, this method is recommended if"
|
||||
echo " supported on your platform."
|
||||
echo " See https://nixos.org/nix/manual/#sect-multi-user-installation"
|
||||
echo ""
|
||||
echo " --no-daemon: Simple, single-user installation that does not require root and is"
|
||||
echo " trivial to uninstall."
|
||||
echo " (default)"
|
||||
echo ""
|
||||
echo " --no-channel-add: Don't add any channels. nixpkgs-unstable is installed by default."
|
||||
echo ""
|
||||
echo " --no-modify-profile: Skip channel installation. When not provided nixpkgs-unstable"
|
||||
echo " is installed by default."
|
||||
echo ""
|
||||
) >&2
|
||||
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
(
|
||||
echo " --create-volume: Create an APFS volume for the store and create the /nix"
|
||||
echo " mountpoint for it using synthetic.conf."
|
||||
echo " (required on macOS >=10.15)"
|
||||
echo " See https://nixos.org/nix/manual/#sect-darwin-apfs-volume"
|
||||
echo ""
|
||||
) >&2
|
||||
fi
|
||||
exit;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "$(uname -s)" = "Darwin" ] && [ "$CREATE_DARWIN_VOLUME" = 1 ]; then
|
||||
printf '\e[1;31mCreating volume and mountpoint /nix.\e[0m\n'
|
||||
"$self/create-darwin-volume.sh"
|
||||
fi
|
||||
|
||||
if [ "$INSTALL_MODE" = "daemon" ]; then
|
||||
printf '\e[1;31mSwitching to the Daemon-based Installer\e[0m\n'
|
||||
exec "$self/install-multi-user"
|
||||
|
@ -95,6 +113,15 @@ if ! [ -e $dest ]; then
|
|||
echo "directory $dest does not exist; creating it by running '$cmd' using sudo" >&2
|
||||
if ! sudo sh -c "$cmd"; then
|
||||
echo "$0: please manually run '$cmd' as root to create $dest" >&2
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
(
|
||||
echo ""
|
||||
echo "Installing on macOS >=10.15 requires relocating the store to an apfs volume."
|
||||
echo "Use --create-volume or run the preparation steps manually."
|
||||
echo "See https://nixos.org/nix/manual/#sect-darwin-apfs-volume."
|
||||
echo ""
|
||||
) >&2
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
|
Loading…
Reference in a new issue