summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorDaiderd Jordan <daiderd@gmail.com>2019-12-15 16:43:43 +0100
committerDaiderd Jordan <daiderd@gmail.com>2020-05-21 19:58:10 +0200
commit0726ad5825f60e543d9cf535c62673685adbf5c8 (patch)
treec5a9e4bd5491b02d65c22b0c38e8d53204dcceba /scripts
parent5d2d0a7b7fbb3a5e665c1f4a7b232cd1c92fa0a4 (diff)
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.
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/create-darwin-volume.sh107
-rw-r--r--scripts/install-nix-from-closure.sh95
2 files changed, 168 insertions, 34 deletions
diff --git a/scripts/create-darwin-volume.sh b/scripts/create-darwin-volume.sh
new file mode 100755
index 000000000..f3e0d46f1
--- /dev/null
+++ b/scripts/create-darwin-volume.sh
@@ -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 "$@"
diff --git a/scripts/install-nix-from-closure.sh b/scripts/install-nix-from-closure.sh
index e06530ddf..34be7ee6a 100644
--- a/scripts/install-nix-from-closure.sh
+++ b/scripts/install-nix-from-closure.sh
@@ -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]"
-
- 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
+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
+
+ 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