diff options
author | Puck Meerburg <puck@puckipedia.com> | 2024-03-14 18:15:46 +0000 |
---|---|---|
committer | Puck Meerburg <puck@puckipedia.com> | 2024-03-14 18:15:46 +0000 |
commit | 93cc063344323a8b0d630d0a67acd121cdc3f86a (patch) | |
tree | bd302e9d9c087a8921ff6b5ad4ebe982762535f2 | |
parent | c26599b1430e4d06a0c32290837b58537a7c4600 (diff) |
Delete the existing installer
We're not going to use it.
Fixes: #31
Change-Id: Ib17a2eb6cae1ecbbf9ad1062e576ba6107a3c13b
-rw-r--r-- | flake.nix | 102 | ||||
-rwxr-xr-x | scripts/bigsur-nixbld-user-migration.sh | 46 | ||||
-rw-r--r-- | scripts/check-hydra-status.sh | 33 | ||||
-rwxr-xr-x | scripts/create-darwin-volume.sh | 875 | ||||
-rw-r--r-- | scripts/install-darwin-multi-user.sh | 226 | ||||
-rw-r--r-- | scripts/install-multi-user.sh | 1042 | ||||
-rw-r--r-- | scripts/install-nix-from-closure.sh | 284 | ||||
-rwxr-xr-x | scripts/install-systemd-multi-user.sh | 222 | ||||
-rwxr-xr-x | scripts/install.in | 119 | ||||
-rw-r--r-- | scripts/local.mk | 2 | ||||
-rw-r--r-- | scripts/nix-profile-daemon.fish.in | 57 | ||||
-rw-r--r-- | scripts/nix-profile-daemon.sh.in | 72 | ||||
-rwxr-xr-x | scripts/prepare-installer-for-github-actions | 10 |
13 files changed, 3 insertions, 3087 deletions
@@ -74,40 +74,6 @@ cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv"); }); - installScriptFor = systems: - with nixpkgsFor.x86_64-linux.native; - runCommand "installer-script" - { buildInputs = [ nix ]; - } - '' - mkdir -p $out/nix-support - - # Converts /nix/store/50p3qk8k...-nix-2.4pre20201102_550e11f/bin/nix to 50p3qk8k.../bin/nix. - tarballPath() { - # Remove the store prefix - local path=''${1#${builtins.storeDir}/} - # Get the path relative to the derivation root - local rest=''${path#*/} - # Get the derivation hash - local drvHash=''${path%%-*} - echo "$drvHash/$rest" - } - - substitute ${./scripts/install.in} $out/install \ - ${pkgs.lib.concatMapStrings - (system: let - tarball = if builtins.elem system crossSystems then self.hydraJobs.binaryTarballCross.x86_64-linux.${system} else self.hydraJobs.binaryTarball.${system}; - in '' \ - --replace '@tarballHash_${system}@' $(nix --experimental-features nix-command hash-file --base16 --type sha256 ${tarball}/*.tar.xz) \ - --replace '@tarballPath_${system}@' $(tarballPath ${tarball}/*.tar.xz) \ - '' - ) - systems - } --replace '@nixVersion@' ${version} - - echo "file installer $out/install" >> $out/nix-support/hydra-build-products - ''; - testNixVersions = pkgs: client: daemon: let nix = pkgs.callPackage ./package.nix { pname = @@ -146,8 +112,7 @@ binaryTarball = nix: pkgs: let inherit (pkgs) buildPackages; - inherit (pkgs) cacert; - installerClosureInfo = buildPackages.closureInfo { rootPaths = [ nix cacert ]; }; + installerClosureInfo = buildPackages.closureInfo { rootPaths = [ nix ]; }; in buildPackages.runCommand "nix-binary-tarball-${version}" @@ -156,45 +121,7 @@ } '' 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 ${nix} \ - --subst-var-by cacert ${cacert} - - substitute ${./scripts/install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user.sh \ - --subst-var-by nix ${nix} \ - --subst-var-by cacert ${cacert} - substitute ${./scripts/install-systemd-multi-user.sh} $TMPDIR/install-systemd-multi-user.sh \ - --subst-var-by nix ${nix} \ - --subst-var-by cacert ${cacert} - substitute ${./scripts/install-multi-user.sh} $TMPDIR/install-multi-user \ - --subst-var-by nix ${nix} \ - --subst-var-by cacert ${cacert} - - if type -p shellcheck; then - # 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 - - # SC1091: Don't panic about not being able to source - # /etc/profile - # SC2002: Ignore "useless cat" "error", when loading - # .reginfo, as the cat is a much cleaner - # implementation, even though it is "useless" - # SC2116: Allow ROOT_HOME=$(echo ~root) for resolving - # root's home directory - shellcheck --external-sources \ - --exclude SC1091,SC2002,SC2116 $TMPDIR/install-multi-user - 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 + dir=nix-${version}-${pkgs.system} fn=$out/$dir.tar.xz mkdir -p $out/nix-support @@ -204,15 +131,8 @@ --mtime='1970-01-01' \ --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/create-darwin-volume.sh \ - $TMPDIR/install-darwin-multi-user.sh \ - $TMPDIR/install-systemd-multi-user.sh \ - $TMPDIR/install-multi-user \ $TMPDIR/reginfo \ $(cat ${installerClosureInfo}/store-paths) ''; @@ -288,8 +208,7 @@ perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nix.perl-bindings); # Binary tarball for various platforms, containing a Nix store - # with the closure of 'nix' package, and the second half of - # the installation script. + # with the closure of 'nix' package. binaryTarball = forAllSystems (system: binaryTarball nixpkgsFor.${system}.native.nix nixpkgsFor.${system}.native); # docker image with Nix inside @@ -340,26 +259,11 @@ } ); }; - - installTests = forAllSystems (system: - let pkgs = nixpkgsFor.${system}.native; in - pkgs.runCommand "install-tests" { - againstSelf = testNixVersions pkgs pkgs.nix pkgs.pkgs.nix; - againstCurrentUnstable = - # FIXME: temporarily disable this on macOS because of #3605. - if system == "x86_64-linux" - then testNixVersions pkgs pkgs.nix pkgs.nixUnstable - else null; - # Disabled because the latest stable version doesn't handle - # `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work - # againstLatestStable = testNixVersions pkgs pkgs.nix pkgs.nixStable; - } "touch $out"); }; checks = forAllSystems (system: { binaryTarball = self.hydraJobs.binaryTarball.${system}; perlBindings = self.hydraJobs.perlBindings.${system}; - installTests = self.hydraJobs.installTests.${system}; nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system}; rl-next = let pkgs = nixpkgsFor.${system}.native; diff --git a/scripts/bigsur-nixbld-user-migration.sh b/scripts/bigsur-nixbld-user-migration.sh deleted file mode 100755 index f1619fd56..000000000 --- a/scripts/bigsur-nixbld-user-migration.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash - -((NEW_NIX_FIRST_BUILD_UID=301)) - -id_available(){ - dscl . list /Users UniqueID | grep -E '\b'$1'\b' >/dev/null -} - -change_nixbld_names_and_ids(){ - local name uid next_id - ((next_id=NEW_NIX_FIRST_BUILD_UID)) - echo "Attempting to migrate nixbld users." - echo "Each user should change from nixbld# to _nixbld#" - echo "and their IDs relocated to $next_id+" - while read -r name uid; do - echo " Checking $name (uid: $uid)" - # iterate for a clean ID - while id_available "$next_id"; do - ((next_id++)) - if ((next_id >= 400)); then - echo "We've hit UID 400 without placing all of your users :(" - echo "You should use the commands in this script as a starting" - echo "point to review your UID-space and manually move the" - echo "remaining users (or delete them, if you don't need them)." - exit 1 - fi - done - - if [[ $name == _* ]]; then - echo " It looks like $name has already been renamed--skipping." - else - # first 3 are cleanup, it's OK if they aren't here - sudo dscl . delete /Users/$name dsAttrTypeNative:_writers_passwd &>/dev/null || true - sudo dscl . change /Users/$name NFSHomeDirectory "/private/var/empty 1" "/var/empty" &>/dev/null || true - # remove existing user from group - sudo dseditgroup -o edit -t user -d $name nixbld || true - sudo dscl . change /Users/$name UniqueID $uid $next_id - sudo dscl . change /Users/$name RecordName $name _$name - # add renamed user to group - sudo dseditgroup -o edit -t user -a _$name nixbld - echo " $name migrated to _$name (uid: $next_id)" - fi - done < <(dscl . list /Users UniqueID | grep nixbld | sort -n -k2) -} - -change_nixbld_names_and_ids diff --git a/scripts/check-hydra-status.sh b/scripts/check-hydra-status.sh deleted file mode 100644 index e62705e94..000000000 --- a/scripts/check-hydra-status.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -# set -x - - -# mapfile BUILDS_FOR_LATEST_EVAL < <( -# curl -H 'Accept: application/json' https://hydra.nixos.org/jobset/nix/master/evals | \ -# jq -r '.evals[0].builds[] | @sh') -BUILDS_FOR_LATEST_EVAL=$( -curl -sS -H 'Accept: application/json' https://hydra.nixos.org/jobset/nix/master/evals | \ - jq -r '.evals[0].builds[]') - -someBuildFailed=0 - -for buildId in $BUILDS_FOR_LATEST_EVAL; do - buildInfo=$(curl --fail -sS -H 'Accept: application/json' "https://hydra.nixos.org/build/$buildId") - - finished=$(echo "$buildInfo" | jq -r '.finished') - - if [[ $finished = 0 ]]; then - continue - fi - - buildStatus=$(echo "$buildInfo" | jq -r '.buildstatus') - - if [[ $buildStatus != 0 ]]; then - someBuildFailed=1 - echo "Job “$(echo "$buildInfo" | jq -r '.job')” failed on hydra: $buildInfo" - fi -done - -exit "$someBuildFailed" diff --git a/scripts/create-darwin-volume.sh b/scripts/create-darwin-volume.sh deleted file mode 100755 index 103e1e391..000000000 --- a/scripts/create-darwin-volume.sh +++ /dev/null @@ -1,875 +0,0 @@ -#!/usr/bin/env bash -set -eu -set -o pipefail - -# I'm a little agnostic on the choices, but supporting a wide -# slate of uses for now, including: -# - import-only: `. create-darwin-volume.sh no-main[ ...]` -# - legacy: `./create-darwin-volume.sh` or `. create-darwin-volume.sh` -# (both will run main()) -# - external alt-routine: `./create-darwin-volume.sh no-main func[ ...]` -if [ "${1-}" = "no-main" ]; then - shift - readonly _CREATE_VOLUME_NO_MAIN=1 -else - readonly _CREATE_VOLUME_NO_MAIN=0 - # declare some things we expect to inherit from install-multi-user - # I don't love this (because it's a bit of a kludge). - # - # CAUTION: (Dec 19 2020) - # This is a stopgap. It doesn't cover the full slate of - # identifiers we inherit--just those necessary to: - # - avoid breaking direct invocations of this script (here/now) - # - avoid hard-to-reverse structural changes before the call to rm - # single-user support is verified - # - # In the near-mid term, I (personally) think we should: - # - decide to deprecate the direct call and add a notice - # - fold all of this into install-darwin-multi-user.sh - # - intentionally remove the old direct-invocation form (kill the - # routine, replace this script w/ deprecation notice and a note - # on the remove-after date) - # - readonly NIX_ROOT="${NIX_ROOT:-/nix}" - - _sudo() { - shift # throw away the 'explanation' - /usr/bin/sudo "$@" - } - failure() { - if [ "$*" = "" ]; then - cat - else - echo "$@" - fi - exit 1 - } - task() { - echo "$@" - } -fi - -# usually "disk1" -root_disk_identifier() { - # For performance (~10ms vs 280ms) I'm parsing 'diskX' from stat output - # (~diskXsY)--but I'm retaining the more-semantic approach since - # it documents intent better. - # /usr/sbin/diskutil info -plist / | xmllint --xpath "/plist/dict/key[text()='ParentWholeDisk']/following-sibling::string[1]/text()" - - # - local special_device - special_device="$(/usr/bin/stat -f "%Sd" /)" - echo "${special_device%s[0-9]*}" -} - -# make it easy to play w/ 'Case-sensitive APFS' -readonly NIX_VOLUME_FS="${NIX_VOLUME_FS:-APFS}" -readonly NIX_VOLUME_LABEL="${NIX_VOLUME_LABEL:-Nix Store}" -# Strongly assuming we'll make a volume on the device / is on -# But you can override NIX_VOLUME_USE_DISK to create it on some other device -readonly NIX_VOLUME_USE_DISK="${NIX_VOLUME_USE_DISK:-$(root_disk_identifier)}" -NIX_VOLUME_USE_SPECIAL="${NIX_VOLUME_USE_SPECIAL:-}" -NIX_VOLUME_USE_UUID="${NIX_VOLUME_USE_UUID:-}" -readonly NIX_VOLUME_MOUNTD_DEST="${NIX_VOLUME_MOUNTD_DEST:-/Library/LaunchDaemons/org.nixos.darwin-store.plist}" - -if /usr/bin/fdesetup isactive >/dev/null; then - test_filevault_in_use() { return 0; } - # no readonly; we may modify if user refuses from cure_volume - NIX_VOLUME_DO_ENCRYPT="${NIX_VOLUME_DO_ENCRYPT:-1}" -else - test_filevault_in_use() { return 1; } - NIX_VOLUME_DO_ENCRYPT="${NIX_VOLUME_DO_ENCRYPT:-0}" -fi - -should_encrypt_volume() { - test_filevault_in_use && (( NIX_VOLUME_DO_ENCRYPT == 1 )) -} - -substep() { - printf " %s\n" "" "- $1" "" "${@:2}" -} - - -volumes_labeled() { - local label="$1" - xsltproc --novalid --stringparam label "$label" - <(/usr/sbin/ioreg -ra -c "AppleAPFSVolume") <<'EOF' -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> - <xsl:output method="text"/> - <xsl:template match="/"> - <xsl:apply-templates select="/plist/array/dict/key[text()='IORegistryEntryName']/following-sibling::*[1][text()=$label]/.."/> - </xsl:template> - <xsl:template match="dict"> - <xsl:apply-templates match="string" select="key[text()='BSD Name']/following-sibling::*[1]"/> - <xsl:text>=</xsl:text> - <xsl:apply-templates match="string" select="key[text()='UUID']/following-sibling::*[1]"/> - <xsl:text>
</xsl:text> - </xsl:template> -</xsl:stylesheet> -EOF - # I cut label out of the extracted values, but here it is for reference: - # <xsl:apply-templates match="string" select="key[text()='IORegistryEntryName']/following-sibling::*[1]"/> - # <xsl:text>=</xsl:text> -} - -right_disk() { - local volume_special="$1" # (i.e., disk1s7) - [[ "$volume_special" == "$NIX_VOLUME_USE_DISK"s* ]] -} - -right_volume() { - local volume_special="$1" # (i.e., disk1s7) - # if set, it must match; otherwise ensure it's on the right disk - if [ -z "$NIX_VOLUME_USE_SPECIAL" ]; then - if right_disk "$volume_special"; then - NIX_VOLUME_USE_SPECIAL="$volume_special" # latch on - return 0 - else - return 1 - fi - else - [ "$volume_special" = "$NIX_VOLUME_USE_SPECIAL" ] - fi -} - -right_uuid() { - local volume_uuid="$1" - # if set, it must match; otherwise allow - if [ -z "$NIX_VOLUME_USE_UUID" ]; then - NIX_VOLUME_USE_UUID="$volume_uuid" # latch on - return 0 - else - [ "$volume_uuid" = "$NIX_VOLUME_USE_UUID" ] - fi -} - -cure_volumes() { - local found volume special uuid - # loop just in case they have more than one volume - # (nothing stops you from doing this) - for volume in $(volumes_labeled "$NIX_VOLUME_LABEL"); do - # CAUTION: this could (maybe) be a more normal read - # loop like: - # while IFS== read -r special uuid; do - # # ... - # done <<<"$(volumes_labeled "$NIX_VOLUME_LABEL")" - # - # I did it with for to skirt a problem with the obvious - # pattern replacing stdin and causing user prompts - # inside (which also use read and access stdin) to skip - # - # If there's an existing encrypted volume we can't find - # in keychain, the user never gets prompted to delete - # the volume, and the install fails. - # - # If you change this, a human needs to test a very - # specific scenario: you already have an encrypted - # Nix Store volume, and have deleted its credential - # from keychain. Ensure the script asks you if it can - # delete the volume, and then prompts for your sudo - # password to confirm. - # - # shellcheck disable=SC1097 - IFS== read -r special uuid <<< "$volume" - # take the first one that's on the right disk - if [ -z "${found:-}" ]; then - if right_volume "$special" && right_uuid "$uuid"; then - cure_volume "$special" "$uuid" - found="${special} (${uuid})" - else - warning <<EOF -Ignoring ${special} (${uuid}) because I am looking for: -disk=${NIX_VOLUME_USE_DISK} special=${NIX_VOLUME_USE_SPECIAL:-${NIX_VOLUME_USE_DISK}sX} uuid=${NIX_VOLUME_USE_UUID:-any} -EOF - # TODO: give chance to delete if ! headless? - fi - else - warning <<EOF -Ignoring ${special} (${uuid}), already found target: $found -EOF - # TODO reminder? I feel like I want one - # idiom that reminds some warnings, or warns - # some reminders? - # TODO: if ! headless, chance to delete? - fi - done - if [ -z "${found:-}" ]; then - readonly NIX_VOLUME_USE_SPECIAL NIX_VOLUME_USE_UUID - fi -} - -volume_encrypted() { - local volume_special="$1" # (i.e., disk1s7) - # Trying to match the first line of output; known first lines: - # No cryptographic users for <special> - # Cryptographic user for <special> (1 found) - # Cryptographic users for <special> (2 found) - /usr/sbin/diskutil apfs listCryptoUsers -plist "$volume_special" | /usr/bin/grep -q APFSCryptoUserUUID -} - -test_fstab() { - /usr/bin/grep -q "$NIX_ROOT apfs rw" /etc/fstab 2>/dev/null -} - -test_nix_root_is_symlink() { - [ -L "$NIX_ROOT" ] -} - -test_synthetic_conf_either(){ - /usr/bin/grep -qE "^${NIX_ROOT:1}($|\t.{3,}$)" /etc/synthetic.conf 2>/dev/null -} - -test_synthetic_conf_mountable() { - /usr/bin/grep -q "^${NIX_ROOT:1}$" /etc/synthetic.conf 2>/dev/null -} - -test_synthetic_conf_symlinked() { - /usr/bin/grep -qE "^${NIX_ROOT:1}\t.{3,}$" /etc/synthetic.conf 2>/dev/null -} - -test_nix_volume_mountd_installed() { - test -e "$NIX_VOLUME_MOUNTD_DEST" -} - -# current volume password -test_keychain_by_uuid() { - local volume_uuid="$1" - # Note: doesn't need sudo just to check; doesn't output pw - security find-generic-password -s "$volume_uuid" &>/dev/null -} - -get_volume_pass() { - local volume_uuid="$1" - _sudo \ - "to confirm keychain has a password that unlocks this volume" \ - security find-generic-password -s "$volume_uuid" -w -} - -verify_volume_pass() { - local volume_special="$1" # (i.e., disk1s7) - local volume_uuid="$2" - _sudo "to confirm the password actually unlocks the volume" \ - /usr/sbin/diskutil apfs unlockVolume "$volume_special" -verify -stdinpassphrase -user "$volume_uuid" -} - -volume_pass_works() { - local volume_special="$1" # (i.e., disk1s7) - local volume_uuid="$2" - get_volume_pass "$volume_uuid" | verify_volume_pass "$volume_special" "$volume_uuid" -} - -# Create the paths defined in synthetic.conf, saving us a reboot. -create_synthetic_objects() { - # Big Sur takes away the -B flag we were using and replaces it - # with a -t flag that appears to do the same thing (but they - # don't behave exactly the same way in terms of return values). - # This feels a little dirty, but as far as I can tell the - # simplest way to get the right one is to just throw away stderr - # and call both... :] - { - /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t || true # Big Sur - /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B || true # Catalina - } >/dev/null 2>&1 -} - -test_nix() { - test -d "$NIX_ROOT" -} - -test_voldaemon() { - test -f "$NIX_VOLUME_MOUNTD_DEST" -} - -generate_mount_command() { - local cmd_type="$1" # encrypted|unencrypted - local volume_uuid mountpoint cmd=() - printf -v volume_uuid "%q" "$2" - printf -v mountpoint "%q" "$NIX_ROOT" - - case "$cmd_type" in - encrypted) - cmd=(/bin/sh -c "/usr/bin/security find-generic-password -s '$volume_uuid' -w | /usr/sbin/diskutil apfs unlockVolume '$volume_uuid' -mountpoint '$mountpoint' -stdinpassphrase");; - unencrypted) - cmd=(/usr/sbin/diskutil mount -mountPoint "$mountpoint" "$volume_uuid");; - *) - failure "Invalid first arg $cmd_type to generate_mount_command";; - esac - - printf " <string>%s</string>\n" "${cmd[@]}" -} - -generate_mount_daemon() { - local cmd_type="$1" # encrypted|unencrypted - local volume_uuid="$2" - cat <<EOF -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>RunAtLoad</key> - <true/> - <key>Label</key> - <string>org.nixos.darwin-store</string> - <key>ProgramArguments</key> - <array> -$(generate_mount_command "$cmd_type" "$volume_uuid") - </array> -</dict> -</plist> -EOF -} - -_eat_bootout_err() { - /usr/bin/grep -v "Boot-out failed: 36: Operation now in progress" -} - -# TODO: remove with --uninstall? -uninstall_launch_daemon_directions() { - local daemon_label="$1" # i.e., org.nixos.blah-blah - local daemon_plist="$2" # abspath - substep "Uninstall LaunchDaemon $daemon_label" \ - " sudo launchctl bootout system/$daemon_label" \ - " sudo rm $daemon_plist" -} - -uninstall_launch_daemon_prompt() { - local daemon_label="$1" # i.e., org.nixos.blah-blah - local daemon_plist="$2" # abspath - local reason_for_daemon="$3" - cat <<EOF - -The installer adds a LaunchDaemon to $reason_for_daemon: $daemon_label -EOF - if ui_confirm "Can I remove it?"; then - _sudo "to terminate the daemon" \ - launchctl bootout "system/$daemon_label" 2> >(_eat_bootout_err >&2) || true - # this can "fail" with a message like: - # Boot-out failed: 36: Operation now in progress - _sudo "to remove the daemon definition" rm "$daemon_plist" - fi -} - -nix_volume_mountd_uninstall_directions() { - uninstall_launch_daemon_directions "org.nixos.darwin-store" \ - "$NIX_VOLUME_MOUNTD_DEST" -} - -nix_volume_mountd_uninstall_prompt() { - uninstall_launch_daemon_prompt "org.nixos.darwin-store" \ - "$NIX_VOLUME_MOUNTD_DEST" \ - "mount your Nix volume" -} - -# TODO: move nix_daemon to install-darwin-multi-user if/when uninstall_launch_daemon_prompt moves up to install-multi-user -nix_daemon_uninstall_prompt() { - uninstall_launch_daemon_prompt "org.nixos.nix-daemon" \ - "$NIX_DAEMON_DEST" \ - "run the nix-daemon" -} - -# TODO: remove with --uninstall? -nix_daemon_uninstall_directions() { - uninstall_launch_daemon_directions "org.nixos.nix-daemon" \ - "$NIX_DAEMON_DEST" -} - - -# TODO: remove with --uninstall? -synthetic_conf_uninstall_directions() { - # :1 to strip leading slash - substep "Remove ${NIX_ROOT:1} from /etc/synthetic.conf" \ - " If nix is the only entry: sudo rm /etc/synthetic.conf" \ - " Otherwise: sudo /usr/bin/sed -i '' -e '/^${NIX_ROOT:1}$/d' /etc/synthetic.conf" -} - -synthetic_conf_uninstall_prompt() { - cat <<EOF - -During install, I add '${NIX_ROOT:1}' to /etc/synthetic.conf, which instructs -macOS to create an empty root directory for mounting the Nix volume. -EOF - # make the edit to a copy - /usr/bin/grep -vE "^${NIX_ROOT:1}($|\t.{3,}$)" /etc/synthetic.conf > "$SCRATCH/synthetic.conf.edit" - - if test_synthetic_conf_symlinked; then - warning <<EOF - -/etc/synthetic.conf already contains a line instructing your system -to make '${NIX_ROOT}' as a symlink: - $(/usr/bin/grep -nE "^${NIX_ROOT:1}\t.{3,}$" /etc/synthetic.conf) - -This may mean your system has/had a non-standard Nix install. - -The volume-creation process in this installer is *not* compatible -with a symlinked store, so I'll have to remove this instruction to -continue. - -If you want/need to keep this instruction, answer 'n' to abort. - -EOF - fi - - # ask to rm if this left the file empty aside from comments, else edit - if /usr/bin/diff -q <(:) <(/usr/bin/grep -v "^#" "$SCRATCH/synthetic.conf.edit") &>/dev/null; then - if confirm_rm "/etc/synthetic.conf"; then - if test_nix_root_is_symlink; then - failure >&2 <<EOF -I removed /etc/synthetic.conf, but $NIX_ROOT is already a symlink -(-> $(readlink "$NIX_ROOT")). The system should remove it when you reboot. -Once you've rebooted, run the installer again. -EOF - fi - return 0 - fi - else - if confirm_edit "$SCRATCH/synthetic.conf.edit" "/etc/synthetic.conf"; then - if test_nix_root_is_symlink; then - failure >&2 <<EOF -I edited Nix out of /etc/synthetic.conf, but $NIX_ROOT is already a symlink -(-> $(readlink "$NIX_ROOT")). The system should remove it when you reboot. -Once you've rebooted, run the installer again. -EOF - fi - return 0 - fi - fi - # fallback instructions - echo "Manually remove nix from /etc/synthetic.conf" - return 1 -} - -add_nix_vol_fstab_line() { - local uuid="$1" - # shellcheck disable=SC1003,SC2026 - local escaped_mountpoint="${NIX_ROOT/ /'\\\'040}" - shift - - # wrap `ex` to work around problems w/ vim features breaking exit codes - # - plugins (see github.com/NixOS/nix/issues/5468): -u NONE - # - swap file: -n - # - # the first draft used `--noplugin`, but github.com/NixOS/nix/issues/6462 - # suggests we need the less-semantic `-u NONE` - # - # we'd prefer EDITOR="/usr/bin/ex -u NONE" but vifs doesn't word-split - # the EDITOR env. - # - # TODO: at some point we should switch to `--clean`, but it wasn't added - # until https://github.com/vim/vim/releases/tag/v8.0.1554 while the macOS - # minver 10.12.6 seems to have released with vim 7.4 - cat > "$SCRATCH/ex_cleanroom_wrapper" <<EOF -#!/bin/sh -/usr/bin/ex -u NONE -n "\$@" -EOF - chmod 755 "$SCRATCH/ex_cleanroom_wrapper" - - EDITOR="$SCRATCH/ex_cleanroom_wrapper" _sudo "to add nix to fstab" "$@" <<EOF -:a -UUID=$uuid $escaped_mountpoint apfs rw,noauto,nobrowse,suid,owners -. -:x -EOF - # TODO: preserving my notes on suid,owners above until resolved - # There *may* be some issue regarding volume ownership, see nix#3156 - # - # It seems like the cheapest fix is adding "suid,owners" to fstab, but: - # - We don't have much info on this condition yet - # - I'm not certain if these cause other problems? - # - There's a "chown" component some people claim to need to fix this - # that I don't understand yet - # (Note however that I've had to add a chown step to handle - # single->multi-user reinstalls, which may cover this) - # - # I'm not sure if it's safe to approach this way? - # - # I think I think the most-proper way to test for it is: - # diskutil info -plist "$NIX_VOLUME_LABEL" | xmllint --xpath "(/plist/dict/key[text()='GlobalPermissionsEnabled'])/following-sibling::*[1][name()='true']" -; echo $? - # - # There's also `sudo /usr/sbin/vsdbutil -c /path` (which is much faster, but is also - # deprecated and needs minor parsing). - # - # If no one finds a problem with doing so, I think the simplest approach - # is to just eagerly set this. I found a few imperative approaches: - # (diskutil enableOwnership, ~100ms), a cheap one (/usr/sbin/vsdbutil -a, ~40-50ms), - # a very cheap one (append the internal format to /var/db/volinfo.database). - # - # But vsdbutil's deprecation notice suggests using fstab, so I want to - # give that a whirl first. - # - # TODO: when this is workable, poke infinisil about reproducing the issue - # and confirming this fix? -} - -delete_nix_vol_fstab_line() { - # TODO: I'm scaffolding this to handle the new nix volumes - # but it might be nice to generalize a smidge further to - # go ahead and set up a pattern for curing "old" things - # we no longer do? - EDITOR="/usr/bin/patch" _sudo "to cut nix from fstab" "$@" < <(/usr/bin/diff /etc/fstab <(/usr/bin/grep -v "$NIX_ROOT apfs rw" /etc/fstab)) - # leaving some parts out of the grep; people may fiddle this a little? -} - -# TODO: hope to remove with --uninstall -fstab_uninstall_directions() { - substep "Remove ${NIX_ROOT} from /etc/fstab" \ - " If nix is the only entry: sudo rm /etc/fstab" \ - " Otherwise, run 'sudo /usr/sbin/vifs' to remove the nix line" -} - -fstab_uninstall_prompt() { - cat <<EOF -During install, I add '${NIX_ROOT}' to /etc/fstab so that macOS knows what -mount options to use for the Nix volume. -EOF - cp /etc/fstab "$SCRATCH/fstab.edit" - # technically doesn't need the _sudo path, but throwing away the - # output is probably better than mostly-duplicating the code... - delete_nix_vol_fstab_line patch "$SCRATCH/fstab.edit" &>/dev/null - - # if the patch test edit, minus comment lines, is equal to empty (:) - if /usr/bin/diff -q <(:) <(/usr/bin/grep -v "^#" "$SCRATCH/fstab.edit") &>/dev/null; then - # this edit would leave it empty; propose deleting it - if confirm_rm "/etc/fstab"; then - return 0 - else - echo "Remove nix from /etc/fstab (or remove the file)" - fi - else - echo "I might be able to help you make this edit. Here's the diff:" - if ! _diff "/etc/fstab" "$SCRATCH/fstab.edit" && ui_confirm "Does the change above look right?"; then - delete_nix_vol_fstab_line /usr/sbin/vifs - else - echo "Remove nix from /etc/fstab (or remove the file)" - fi - fi -} - -remove_volume() { - local volume_special="$1" # (i.e., disk1s7) - _sudo "to unmount the Nix volume" \ - /usr/sbin/diskutil unmount force "$volume_special" || true # might not be mounted - _sudo "to delete the Nix volume" \ - /usr/sbin/diskutil apfs deleteVolume "$volume_special" -} - -# aspiration: robust enough to both fix problems -# *and* update older darwin volumes -cure_volume() { - local volume_special="$1" # (i.e., disk1s7) - local volume_uuid="$2" - header "Found existing Nix volume" - row " special" "$volume_special" - row " uuid" "$volume_uuid" - - if volume_encrypted "$volume_special"; then - row "encrypted" "yes" - if volume_pass_works "$volume_special" "$volume_uuid"; then - NIX_VOLUME_DO_ENCRYPT=0 - ok "Found a working decryption password in keychain :)" - echo "" - else - # - this is a volume we made, and - # - the user encrypted it on their own - # - something deleted the credential - # - this is an old or BYO volume and the pw - # just isn't somewhere we can find it. - # - # We're going to explain why we're freaking out - # and prompt them to either delete the volume - # (requiring a sudo auth), or abort to fix - warning <<EOF - -This volume is encrypted, but I don't see a password to decrypt it. -The quick fix is to let me delete this volume and make you a new one. -If that's okay, enter your (sudo) password to continue. If not, you -can ensure the decryption password is in your system keychain with a -"Where" (service) field set to this volume's UUID: - $volume_uuid -EOF - if password_confirm "delete this volume"; then - remove_volume "$volume_special" - else - # TODO: this is a good design case for a warn-and - # remind idiom... - failure <<EOF -Your Nix volume is encrypted, but I couldn't find its password. Either: -- Delete or rename the volume out of the way -- Ensure its decryption password is in the system keychain with a - "Where" (service) field set to this volume's UUID: - $volume_uuid -EOF - fi - fi - elif test_filevault_in_use; then - row "encrypted" "no" - warning <<EOF -FileVault is on, but your $NIX_VOLUME_LABEL volume isn't encrypted. -EOF - # if we're interactive, give them a chance to - # encrypt the volume. If not, /shrug - if ! headless && (( NIX_VOLUME_DO_ENCRYPT == 1 )); then - if ui_confirm "Should I encrypt it and add the decryption key to your keychain?"; then - encrypt_volume "$volume_uuid" "$NIX_VOLUME_LABEL" - NIX_VOLUME_DO_ENCRYPT=0 - else - NIX_VOLUME_DO_ENCRYPT=0 - reminder "FileVault is on, but your $NIX_VOLUME_LABEL volume isn't encrypted." - fi - fi - else - row "encrypted" "no" - fi -} - -remove_volume_artifacts() { - if test_synthetic_conf_either; then - # NIX_ROOT is in synthetic.conf - if synthetic_conf_uninstall_prompt; then - # TODO: moot until we tackle uninstall, but when we're - # actually uninstalling, we should issue: - # reminder "macOS will clean up the empty mount-point directory at $NIX_ROOT on reboot." - : - fi - fi - if test_fstab; then - fstab_uninstall_prompt - fi - - if test_nix_volume_mountd_installed; then - nix_volume_mountd_uninstall_prompt - fi -} - -setup_synthetic_conf() { - if test_nix_root_is_symlink; then - if ! test_synthetic_conf_symlinked; then - failure >&2 <<EOF -error: $NIX_ROOT is a symlink (-> $(readlink "$NIX_ROOT")). -Please remove it. If nix is in /etc/synthetic.conf, remove it and reboot. -EOF - fi - fi - if ! test_synthetic_conf_mountable; then - task "Configuring /etc/synthetic.conf to make a mount-point at $NIX_ROOT" >&2 - # technically /etc/synthetic.d/nix is supported in Big Sur+ - # but handling both takes even more code... - # See earlier note; `-u NONE` disables vim plugins/rc, `-n` skips swapfile - _sudo "to add Nix to /etc/synthetic.conf" \ - /usr/bin/ex -u NONE -n /etc/synthetic.conf <<EOF -:a -${NIX_ROOT:1} -. -:x -EOF - if ! test_synthetic_conf_mountable; then - failure "error: failed to configure synthetic.conf" >&2 - fi - create_synthetic_objects - if ! test_nix; then - failure >&2 <<EOF -error: failed to bootstrap $NIX_ROOT -If you enabled FileVault after booting, this is likely a known issue -with macOS that you'll have to reboot to fix. If you didn't enable FV, -though, please open an issue describing how the system that you see -this error on was set up. -EOF - fi - fi -} - -setup_fstab() { - local volume_uuid="$1" - # fstab used to be responsible for mounting the volume. Now the last - # step adds a LaunchDaemon responsible for mounting. This is technically - # redundant for mounting, but diskutil appears to pick up mount options - # from fstab (and diskutil's support for specifying them directly is not - # consistent across versions/subcommands). - if ! test_fstab; then - task "Configuring /etc/fstab to specify volume mount options" >&2 - add_nix_vol_fstab_line "$volume_uuid" /usr/sbin/vifs - fi -} - -encrypt_volume() { - local volume_uuid="$1" - local volume_label="$2" - local password - - task "Encrypt the Nix volume" >&2 - - # Note: mount/unmount are late additions to support the right order - # of operations for creating the volume and then baking its uuid into - # other artifacts; not as well-trod wrt to potential errors, race - # conditions, etc. - - _sudo "to mount your Nix volume for encrypting" \ - /usr/sbin/diskutil mount "$volume_label" - - password="$(/usr/bin/xxd -l 32 -p -c 256 /dev/random)" - _sudo "to add your Nix volume's password to Keychain" \ - /usr/bin/security -i <<EOF -add-generic-password -a "$volume_label" -s "$volume_uuid" -l "$volume_label encryption password" -D "Encrypted volume password" -j "Added automatically by the Nix installer for use by $NIX_VOLUME_MOUNTD_DEST" -w "$password" -T /System/Library/CoreServices/APFSUserAgent -T /System/Library/CoreServices/CSUserAgent -T /usr/bin/security "/Library/Keychains/System.keychain" -EOF - builtin printf "%s" "$password" | _sudo "to actually encrypt your Nix volume" \ - /usr/sbin/diskutil apfs encryptVolume "$volume_label" -user disk -stdinpassphrase - - _sudo "to unmount the encrypted volume" \ - /usr/sbin/diskutil unmount force "$volume_label" -} - -create_volume() { - # Notes: - # 1) using `-nomount` instead of `-mountpoint "$NIX_ROOT"` to get - # its UUID and set mount opts in fstab before first mount - # - # 2) system is in some sense less secure than user keychain... (it's - # possible to read the password for decrypting the keychain) but - # the user keychain appears to be available too late. As far as I - # can tell, the file with this password (/var/db/SystemKey) is - # inside the FileVault envelope. If that isn't true, it may make - # sense to store the password inside the envelope? - # - # 3) At some point it would be ideal to have a small binary to serve - # as the daemon itself, and for it to replace /usr/bin/security here. - # - # 4) *UserAgent exemptions should let the system seamlessly supply the - # password if noauto is removed from fstab entry. This is intentional; - # the user will hopefully look for help if the volume stops mounting, - # rather than failing over into subtle race-condition problems. - # - # 5) If we ever get users griping about not having space to do - # anything useful with Nix, it is possibly to specify - # `-reserve 10g` or something, which will fail w/o that much - # - # 6) getting special w/ awk may be fragile, but doing it to: - # - save time over running slow diskutil commands - # - skirt risk we grab wrong volume if multiple match - _sudo "to create a new APFS volume '$NIX_VOLUME_LABEL' on $NIX_VOLUME_USE_DISK" \ - /usr/sbin/diskutil apfs addVolume "$NIX_VOLUME_USE_DISK" "$NIX_VOLUME_FS" "$NIX_VOLUME_LABEL" -nomount | /usr/bin/awk '/Created new APFS Volume/ {print $5}' -} - -volume_uuid_from_special() { - local volume_special="$1" # (i.e., disk1s7) - # For reasons I won't pretend to fathom, this returns 253 when it works - /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -k "$volume_special" || true -} - -# this sometimes clears immediately, and AFAIK clears -# within about 1s. diskutil info on an unmounted path -# fails in around 50-100ms and a match takes about -# 250-300ms. I suspect it's usually ~250-750ms -await_volume() { - # caution: this could, in theory, get stuck - until /usr/sbin/diskutil info "$NIX_ROOT" &>/dev/null; do - : - done -} - -setup_volume() { - local use_special use_uuid profile_packages - task "Creating a Nix volume" >&2 - - use_special="${NIX_VOLUME_USE_SPECIAL:-$(create_volume)}" - - _sudo "to ensure the Nix volume is not mounted" \ - /usr/sbin/diskutil unmount force "$use_special" || true # might not be mounted - - use_uuid=${NIX_VOLUME_USE_UUID:-$(volume_uuid_from_special "$use_special")} - - setup_fstab "$use_uuid" - - if should_encrypt_volume; then - encrypt_volume "$use_uuid" "$NIX_VOLUME_LABEL" - setup_volume_daemon "encrypted" "$use_uuid" - # TODO: might be able to save ~60ms by caching or setting - # this somewhere rather than re-checking here. - elif volume_encrypted "$use_special"; then - setup_volume_daemon "encrypted" "$use_uuid" - else - setup_volume_daemon "unencrypted" "$use_uuid" - fi - - await_volume - - if [ "$(/usr/sbin/diskutil info -plist "$NIX_ROOT" | xmllint --xpath "(/plist/dict/key[text()='GlobalPermissionsEnabled'])/following-sibling::*[1]" -)" = "<false/>" ]; then - _sudo "to set enableOwnership (enabling users to own files)" \ - /usr/sbin/diskutil enableOwnership "$NIX_ROOT" - fi - - # TODO: below is a vague kludge for now; I just don't know - # what if any safe action there is to take here. Also, the - # reminder isn't very helpful. - # I'm less sure where this belongs, but it also wants mounted, pre-install - if type -p nix-env; then - profile_packages="$(nix-env --query --installed)" - # TODO: can probably do below faster w/ read - # intentionally unquoted string to eat whitespace in wc output - # shellcheck disable=SC2046,SC2059 - if ! [ $(printf "$profile_packages" | /usr/bin/wc -l) = "0" ]; then - reminder <<EOF -Nix now supports only multi-user installs on Darwin/macOS, and your user's -Nix profile has some packages in it. These packages may obscure those in the -default profile, including the Nix this installer will add. You should -review these packages: -$profile_packages -EOF - fi - fi - -} - -setup_volume_daemon() { - local cmd_type="$1" # encrypted|unencrypted - local volume_uuid="$2" - if ! test_voldaemon; then - task "Configuring LaunchDaemon to mount '$NIX_VOLUME_LABEL'" >&2 - # See earlier note; `-u NONE` disables vim plugins/rc, `-n` skips swapfile - _sudo "to install the Nix volume mounter" /usr/bin/ex -u NONE -n "$NIX_VOLUME_MOUNTD_DEST" <<EOF -:a -$(generate_mount_daemon "$cmd_type" "$volume_uuid") -. -:x -EOF - - # TODO: should probably alert the user if this is disabled? - _sudo "to launch the Nix volume mounter" \ - launchctl bootstrap system "$NIX_VOLUME_MOUNTD_DEST" || true - # TODO: confirm whether kickstart is necessesary? - # I feel a little superstitous, but it can guard - # against multiple problems (doesn't start, old - # version still running for some reason...) - _sudo "to launch the Nix volume mounter" \ - launchctl kickstart -k system/org.nixos.darwin-store - fi -} - -setup_darwin_volume() { - setup_synthetic_conf - setup_volume -} - -if [ "$_CREATE_VOLUME_NO_MAIN" = 1 ]; then - if [ -n "$*" ]; then - "$@" # expose functions in case we want multiple routines? - fi -else - # no reason to pay for bash to process this - main() { - { - echo "" - echo " ------------------------------------------------------------------ " - echo " | This installer will create a volume for the nix store and |" - echo " | configure it to mount at $NIX_ROOT. Follow these steps to uninstall. |" - echo " ------------------------------------------------------------------ " - echo "" - echo " 1. Remove the entry from fstab using 'sudo /usr/sbin/vifs'" - echo " 2. Run 'sudo launchctl bootout system/org.nixos.darwin-store'" - echo " 3. Remove $NIX_VOLUME_MOUNTD_DEST" - echo " 4. Destroy the data volume using '/usr/sbin/diskutil apfs deleteVolume'" - echo " 5. Remove the 'nix' line from /etc/synthetic.conf (or the file)" - echo "" - } >&2 - - setup_darwin_volume - } - - main "$@" -fi diff --git a/scripts/install-darwin-multi-user.sh b/scripts/install-darwin-multi-user.sh deleted file mode 100644 index 24c9052f9..000000000 --- a/scripts/install-darwin-multi-user.sh +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/env bash - -set -eu -set -o pipefail - -# System specific settings -export NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-301}" -export NIX_BUILD_USER_NAME_TEMPLATE="_nixbld%d" - -readonly NIX_DAEMON_DEST=/Library/LaunchDaemons/org.nixos.nix-daemon.plist -# create by default; set 0 to DIY, use a symlink, etc. -readonly NIX_VOLUME_CREATE=${NIX_VOLUME_CREATE:-1} # now default - -# caution: may update times on / if not run as normal non-root user -read_only_root() { - # this touch command ~should~ always produce an error - # as of this change I confirmed /usr/bin/touch emits: - # "touch: /: Operation not permitted" Monterey - # "touch: /: Read-only file system" Catalina+ and Big Sur - # "touch: /: Permission denied" Mojave - # (not matching prefix for compat w/ coreutils touch in case using - # an explicit path causes problems; its prefix differs) - case "$(/usr/bin/touch / 2>&1)" in - *"Read-only file system") # Catalina, Big Sur - return 0 - ;; - *"Operation not permitted") # Monterey - return 0 - ;; - *) - return 1 - ;; - esac - - # Avoiding the slow semantic way to get this information (~330ms vs ~8ms) - # unless using touch causes problems. Just in case, that approach is: - # diskutil info -plist / | <find the Writable or WritableVolume keys>, i.e. - # diskutil info -plist / | xmllint --xpath "name(/plist/dict/key[text()='Writable']/following-sibling::*[1])" - -} - -if read_only_root && [ "$NIX_VOLUME_CREATE" = 1 ]; then - should_create_volume() { return 0; } -else - should_create_volume() { return 1; } -fi - -# shellcheck source=./create-darwin-volume.sh -. "$EXTRACTED_NIX_PATH/create-darwin-volume.sh" "no-main" - -dsclattr() { - /usr/bin/dscl . -read "$1" \ - | /usr/bin/awk "/$2/ { print \$2 }" -} - -test_nix_daemon_installed() { - test -e "$NIX_DAEMON_DEST" -} - -poly_cure_artifacts() { - if should_create_volume; then - task "Fixing any leftover Nix volume state" - cat <<EOF -Before I try to install, I'll check for any existing Nix volume config -and ask for your permission to remove it (so that the installer can -start fresh). I'll also ask for permission to fix any issues I spot. -EOF - cure_volumes - remove_volume_artifacts - fi -} - -poly_service_installed_check() { - if should_create_volume; then - test_nix_daemon_installed || test_nix_volume_mountd_installed - else - test_nix_daemon_installed - fi -} - -poly_service_uninstall_directions() { - echo "$1. Remove macOS-specific components:" - if should_create_volume && test_nix_volume_mountd_installed; then - nix_volume_mountd_uninstall_directions - fi - if test_nix_daemon_installed; then - nix_daemon_uninstall_directions - fi -} - -poly_service_setup_note() { - if should_create_volume; then - echo " - create a Nix volume and a LaunchDaemon to mount it" - fi - echo " - create a LaunchDaemon (at $NIX_DAEMON_DEST) for nix-daemon" - echo "" -} - -poly_extra_try_me_commands() { - : -} - -poly_configure_nix_daemon_service() { - task "Setting up the nix-daemon LaunchDaemon" - _sudo "to set up the nix-daemon as a LaunchDaemon" \ - /usr/bin/install -m "u=rw,go=r" "/nix/var/nix/profiles/default$NIX_DAEMON_DEST" "$NIX_DAEMON_DEST" - - _sudo "to load the LaunchDaemon plist for nix-daemon" \ - launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist - - _sudo "to start the nix-daemon" \ - launchctl kickstart -k system/org.nixos.nix-daemon -} - -poly_group_exists() { - /usr/bin/dscl . -read "/Groups/$1" > /dev/null 2>&1 -} - -poly_group_id_get() { - dsclattr "/Groups/$1" "PrimaryGroupID" -} - -poly_create_build_group() { - _sudo "Create the Nix build group, $NIX_BUILD_GROUP_NAME" \ - /usr/sbin/dseditgroup -o create \ - -r "Nix build group for nix-daemon" \ - -i "$NIX_BUILD_GROUP_ID" \ - "$NIX_BUILD_GROUP_NAME" >&2 -} - -poly_user_exists() { - /usr/bin/dscl . -read "/Users/$1" > /dev/null 2>&1 -} - -poly_user_id_get() { - dsclattr "/Users/$1" "UniqueID" -} - -poly_user_hidden_get() { - dsclattr "/Users/$1" "IsHidden" -} - -poly_user_hidden_set() { - _sudo "in order to make $1 a hidden user" \ - /usr/bin/dscl . -create "/Users/$1" "IsHidden" "1" -} - -poly_user_home_get() { - dsclattr "/Users/$1" "NFSHomeDirectory" -} - -poly_user_home_set() { - # This can trigger a permission prompt now: - # "Terminal" would like to administer your computer. Administration can include modifying passwords, networking, and system settings. - _sudo "in order to give $1 a safe home directory" \ - /usr/bin/dscl . -create "/Users/$1" "NFSHomeDirectory" "$2" -} - -poly_user_note_get() { - dsclattr "/Users/$1" "RealName" -} - -poly_user_note_set() { - _sudo "in order to give $username a useful note" \ - /usr/bin/dscl . -create "/Users/$1" "RealName" "$2" -} - -poly_user_shell_get() { - dsclattr "/Users/$1" "UserShell" -} - -poly_user_shell_set() { - _sudo "in order to give $1 a safe shell" \ - /usr/bin/dscl . -create "/Users/$1" "UserShell" "$2" -} - -poly_user_in_group_check() { - username=$1 - group=$2 - /usr/sbin/dseditgroup -o checkmember -m "$username" "$group" > /dev/null 2>&1 -} - -poly_user_in_group_set() { - username=$1 - group=$2 - - _sudo "Add $username to the $group group"\ - /usr/sbin/dseditgroup -o edit -t user \ - -a "$username" "$group" -} - -poly_user_primary_group_get() { - dsclattr "/Users/$1" "PrimaryGroupID" -} - -poly_user_primary_group_set() { - _sudo "to let the nix daemon use this user for builds (this might seem redundant, but there are two concepts of group membership)" \ - /usr/bin/dscl . -create "/Users/$1" "PrimaryGroupID" "$2" -} - -poly_create_build_user() { - username=$1 - uid=$2 - builder_num=$3 - - _sudo "Creating the Nix build user (#$builder_num), $username" \ - /usr/bin/dscl . create "/Users/$username" \ - UniqueID "${uid}" -} - -poly_prepare_to_install() { - if should_create_volume; then - header "Preparing a Nix volume" - # intentional indent below to match task indent - cat <<EOF - Nix traditionally stores its data in the root directory $NIX_ROOT, but - macOS now (starting in 10.15 Catalina) has a read-only root directory. - To support Nix, I will create a volume and configure macOS to mount it - at $NIX_ROOT. -EOF - setup_darwin_volume - fi - - if [ "$(/usr/sbin/diskutil info -plist /nix | xmllint --xpath "(/plist/dict/key[text()='GlobalPermissionsEnabled'])/following-sibling::*[1]" -)" = "<false/>" ]; then - failure "This script needs a /nix volume with global permissions! This may require running sudo /usr/sbin/diskutil enableOwnership /nix." - fi -} diff --git a/scripts/install-multi-user.sh b/scripts/install-multi-user.sh deleted file mode 100644 index d846f5b5c..000000000 --- a/scripts/install-multi-user.sh +++ /dev/null @@ -1,1042 +0,0 @@ -#!/usr/bin/env bash - -set -eu -set -o pipefail - -# Sourced from: -# - https://github.com/LnL7/nix-darwin/blob/8c29d0985d74b4a990238497c47a2542a5616b3c/bootstrap.sh -# - https://gist.github.com/expipiplus1/e571ce88c608a1e83547c918591b149f/ac504c6c1b96e65505fbda437a28ce563408ecb0 -# - https://github.com/NixOS/nixos-org-configurations/blob/a122f418797713d519aadf02e677fce0dc1cb446/delft/scripts/nix-mac-installer.sh -# - https://github.com/matthewbauer/macNixOS/blob/f6045394f9153edea417be90c216788e754feaba/install-macNixOS.sh -# - https://gist.github.com/LnL7/9717bd6cdcb30b086fd7f2093e5f8494/86b26f852ce563e973acd30f796a9a416248c34a -# -# however tracking which bits came from which would be impossible. - -readonly ESC='\033[0m' -readonly BOLD='\033[1m' -readonly BLUE='\033[34m' -readonly BLUE_UL='\033[4;34m' -readonly GREEN='\033[32m' -readonly GREEN_UL='\033[4;32m' -readonly RED='\033[31m' - -# installer allows overriding build user count to speed up installation -# as creating each user takes non-trivial amount of time on macos -readonly NIX_USER_COUNT=${NIX_USER_COUNT:-32} -readonly NIX_BUILD_GROUP_ID="${NIX_BUILD_GROUP_ID:-30000}" -readonly NIX_BUILD_GROUP_NAME="nixbld" -# each system specific installer must set these: -# NIX_FIRST_BUILD_UID -# NIX_BUILD_USER_NAME_TEMPLATE -# Please don't change this. We don't support it, because the -# default shell profile that comes with Nix doesn't support it. -readonly NIX_ROOT="/nix" -readonly NIX_EXTRA_CONF=${NIX_EXTRA_CONF:-} - -readonly PROFILE_TARGETS=("/etc/bashrc" "/etc/profile.d/nix.sh" "/etc/zshrc" "/etc/bash.bashrc" "/etc/zsh/zshrc") -readonly PROFILE_BACKUP_SUFFIX=".backup-before-nix" -readonly PROFILE_NIX_FILE="$NIX_ROOT/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" - -# Fish has different syntax than zsh/bash, treat it separate -readonly PROFILE_FISH_SUFFIX="conf.d/nix.fish" -readonly PROFILE_FISH_PREFIXES=( - # each of these are common values of $__fish_sysconf_dir, - # under which Fish will look for a file named - # $PROFILE_FISH_SUFFIX. - "/etc/fish" # standard - "/usr/local/etc/fish" # their installer .pkg for macOS - "/opt/homebrew/etc/fish" # homebrew - "/opt/local/etc/fish" # macports -) -readonly PROFILE_NIX_FILE_FISH="$NIX_ROOT/var/nix/profiles/default/etc/profile.d/nix-daemon.fish" - -readonly NIX_INSTALLED_NIX="@nix@" -readonly NIX_INSTALLED_CACERT="@cacert@" -#readonly NIX_INSTALLED_NIX="/nix/store/j8dbv5w6jl34caywh2ygdy88knx1mdf7-nix-2.3.6" -#readonly NIX_INSTALLED_CACERT="/nix/store/7dxhzymvy330i28ii676fl1pqwcahv2f-nss-cacert-3.49.2" -readonly EXTRACTED_NIX_PATH="$(dirname "$0")" - -readonly ROOT_HOME=~root - -if [ -t 0 ] && [ -z "${NIX_INSTALLER_YES:-}" ]; then - readonly IS_HEADLESS='no' -else - readonly IS_HEADLESS='yes' -fi - -headless() { - if [ "$IS_HEADLESS" = "yes" ]; then - return 0 - else - return 1 - fi -} - -is_root() { - if [ "$EUID" -eq 0 ]; then - return 0 - else - return 1 - fi -} - -is_os_linux() { - if [ "$(uname -s)" = "Linux" ]; then - return 0 - else - return 1 - fi -} - -is_os_darwin() { - if [ "$(uname -s)" = "Darwin" ]; then - return 0 - else - return 1 - fi -} - -contact_us() { - echo "You can open an issue at" - echo "https://github.com/NixOS/nix/issues/new?labels=installer&template=installer.md" - echo "" - echo "Or get in touch with the community: https://nixos.org/community" -} -get_help() { - echo "We'd love to help if you need it." - echo "" - contact_us -} - -uninstall_directions() { - subheader "Uninstalling nix:" - local step=0 - - if poly_service_installed_check; then - step=$((step + 1)) - poly_service_uninstall_directions "$step" - fi - - for profile_target in "${PROFILE_TARGETS[@]}"; do - if [ -e "$profile_target" ] && [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then - step=$((step + 1)) - cat <<EOF -$step. Restore $profile_target$PROFILE_BACKUP_SUFFIX back to $profile_target - - sudo mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target - -(after this one, you may need to re-open any terminals that were -opened while it existed.) - -EOF - fi - done - - step=$((step + 1)) - cat <<EOF -$step. Delete the files Nix added to your system: - - sudo rm -rf "/etc/nix" "$NIX_ROOT" "$ROOT_HOME/.nix-profile" "$ROOT_HOME/.nix-defexpr" "$ROOT_HOME/.nix-channels" "$ROOT_HOME/.local/state/nix" "$ROOT_HOME/.cache/nix" "$HOME/.nix-profile" "$HOME/.nix-defexpr" "$HOME/.nix-channels" "$HOME/.local/state/nix" "$HOME/.cache/nix" - -and that is it. - -EOF -} - -nix_user_for_core() { - printf "$NIX_BUILD_USER_NAME_TEMPLATE" "$1" -} - -nix_uid_for_core() { - echo $((NIX_FIRST_BUILD_UID + $1 - 1)) -} - -_textout() { - echo -en "$1" - shift - if [ "$*" = "" ]; then - cat - else - echo "$@" - fi - echo -en "$ESC" -} - -header() { - follow="---------------------------------------------------------" - header=$(echo "---- $* $follow$follow$follow" | head -c 80) - echo "" - _textout "$BLUE" "$header" -} - -warningheader() { - follow="---------------------------------------------------------" - header=$(echo "---- $* $follow$follow$follow" | head -c 80) - echo "" - _textout "$RED" "$header" -} - -subheader() { - echo "" - _textout "$BLUE_UL" "$*" -} - -row() { - printf "$BOLD%s$ESC:\\t%s\\n" "$1" "$2" -} - -task() { - echo "" - ok "~~> $1" -} - -bold() { - echo "$BOLD$*$ESC" -} - -ok() { - _textout "$GREEN" "$@" -} - -warning() { - warningheader "warning!" - cat - echo "" -} - -failure() { - header "oh no!" - _textout "$RED" "$@" - echo "" - _textout "$RED" "$(get_help)" - trap finish_cleanup EXIT - exit 1 -} - -ui_confirm() { - _textout "$GREEN$GREEN_UL" "$1" - - if headless; then - echo "No TTY, assuming you would say yes :)" - return 0 - fi - - local prompt="[y/n] " - echo -n "$prompt" - while read -r y; do - if [ "$y" = "y" ]; then - echo "" - return 0 - elif [ "$y" = "n" ]; then - echo "" - return 1 - else - _textout "$RED" "Sorry, I didn't understand. I can only understand answers of y or n" - echo -n "$prompt" - fi - done - echo "" - return 1 -} - -printf -v _UNCHANGED_GRP_FMT "%b" $'\033[2m%='"$ESC" # "dim" -# bold+invert+red and bold+invert+green just for the +/- below -# red/green foreground for rest of the line -printf -v _OLD_LINE_FMT "%b" $'\033[1;7;31m-'"$ESC ${RED}%L${ESC}" -printf -v _NEW_LINE_FMT "%b" $'\033[1;7;32m+'"$ESC ${GREEN}%L${ESC}" - -_diff() { - # macOS Ventura doesn't ship with GNU diff. Print similar output except - # without +/- markers or dimming - if diff --version | grep -q "Apple diff"; then - printf -v CHANGED_GROUP_FORMAT "%b" "${GREEN}%>${RED}%<${ESC}" - diff --changed-group-format="$CHANGED_GROUP_FORMAT" "$@" - else - # simple colorized diff comatible w/ pre `--color` versions - diff --unchanged-group-format="$_UNCHANGED_GRP_FMT" --old-line-format="$_OLD_LINE_FMT" --new-line-format="$_NEW_LINE_FMT" --unchanged-line-format=" %L" "$@" - fi -} - -confirm_rm() { - local path="$1" - if ui_confirm "Can I remove $path?"; then - _sudo "to remove $path" rm "$path" - fi -} - -confirm_edit() { - local path="$1" - local edit_path="$2" - cat <<EOF - -Nix isn't the only thing in $path, -but I think I know how to edit it out. -Here's the diff: -EOF - - # could technically test the diff, but caller should do it - _diff "$path" "$edit_path" - if ui_confirm "Does the change above look right?"; then - _sudo "remove nix from $path" cp "$edit_path" "$path" - fi -} - -_SERIOUS_BUSINESS="${RED}%s:${ESC} " -password_confirm() { - local do_something_consequential="$1" - if ui_confirm "Can I $do_something_consequential?"; then - # shellcheck disable=SC2059 - sudo -kv --prompt="$(printf "${_SERIOUS_BUSINESS}" "Enter your password to $do_something_consequential")" - else - return 1 - fi -} - -# Support accumulating reminders over the course of a run and showing -# them at the end. An example where this helps: the installer changes -# something, but it won't work without a reboot. If you tell the user -# when you do it, they may miss it in the stream. The value of the -# setting isn't enough to decide whether to message because you only -# need to message if you *changed* it. - -# reminders stored in array delimited by empty entry; if ! headless, -# user is asked to confirm after each delimiter. -_reminders=() -((_remind_num=1)) - -remind() { - # (( arithmetic expression )) - if (( _remind_num > 1 )); then - header "Reminders" - for line in "${_reminders[@]}"; do - echo "$line" - if ! headless && [ "${#line}" = 0 ]; then - if read -r -p "Press enter/return to acknowledge."; then - printf $'\033[A\33[2K\r' - fi - fi - done - fi -} - -reminder() { - printf -v label "${BLUE}[ %d ]${ESC}" "$_remind_num" - _reminders+=("$label") - if [[ "$*" = "" ]]; then - while read -r line; do - _reminders+=("$line") - done - else - # this expands each arg to an array entry (and each entry will - # ultimately be a separate line in the output) - _reminders+=("$@") - fi - _reminders+=("") - ((_remind_num++)) -} - -__sudo() { - local expl="$1" - local cmd="$2" - shift - header "sudo execution" - - echo "I am executing:" - echo "" - printf " $ sudo %s\\n" "$cmd" - echo "" - echo "$expl" - echo "" - - return 0 -} - -_sudo() { - local expl="$1" - shift - if ! headless || is_root; then - __sudo "$expl" "$*" >&2 - fi - - if is_root; then - env "$@" - else - sudo "$@" - fi -} - -# Ensure that $TMPDIR exists if defined. -if [[ -n "${TMPDIR:-}" ]] && [[ ! -d "${TMPDIR:-}" ]]; then - mkdir -m 0700 -p "${TMPDIR:-}" -fi - -readonly SCRATCH=$(mktemp -d) -finish_cleanup() { - rm -rf "$SCRATCH" -} - -finish_fail() { - finish_cleanup - - failure <<EOF -Oh no, something went wrong. If you can take all the output and open -an issue, we'd love to fix the problem so nobody else has this issue. - -:( -EOF -} -trap finish_fail EXIT - -finish_success() { - ok "Alright! We're done!" - - cat <<EOF -Try it! Open a new terminal, and type: -$(poly_extra_try_me_commands) - $ nix-shell -p nix-info --run "nix-info -m" - -Thank you for using this installer. If you have any feedback or need -help, don't hesitate: - -$(contact_us) -EOF - remind - finish_cleanup -} - -finish_uninstall_success() { - ok "Alright! Nix should be removed!" - - cat <<EOF -If you spot anything this uninstaller missed or have feedback, -don't hesitate: - -$(contact_us) -EOF - remind - finish_cleanup -} - -remove_nix_artifacts() { - failure "Not implemented yet" -} - -cure_artifacts() { - poly_cure_artifacts - # remove_nix_artifacts (LATER) -} - -validate_starting_assumptions() { - task "Checking for artifacts of previous installs" - cat <<EOF -Before I try to install, I'll check for signs Nix already is or has -been installed on this system. -EOF - if type nix-env 2> /dev/null >&2; then - warning <<EOF -Nix already appears to be installed. This installer may run into issues. -If an error occurs, try manually uninstalling, then rerunning this script. - -$(uninstall_directions) -EOF - fi - - # TODO: I think it would be good for this step to accumulate more - # knowledge of older obsolete artifacts, if there are any. - # We could issue a "reminder" here that the user might want - # to clean them up? - - for profile_target in "${PROFILE_TARGETS[@]}"; do - # TODO: I think it would be good to accumulate a list of all - # of the copies so that people don't hit this 2 or 3x in - # a row for different files. - if [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then - # this backup process first released in Nix 2.1 - failure <<EOF -I back up shell profile/rc scripts before I add Nix to them. -I need to back up $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX, -but the latter already exists. - -Here's how to clean up the old backup file: - -1. Back up (copy) $profile_target and $profile_target$PROFILE_BACKUP_SUFFIX - to another location, just in case. - -2. Ensure $profile_target$PROFILE_BACKUP_SUFFIX does not have anything - Nix-related in it. If it does, something is probably quite - wrong. Please open an issue or get in touch immediately. - -3. Once you confirm $profile_target is backed up and - $profile_target$PROFILE_BACKUP_SUFFIX doesn't mention Nix, run: - mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target -EOF - fi - done - - if is_os_linux && [ ! -e /run/systemd/system ]; then - warning <<EOF -We did not detect systemd on your system. With a multi-user install -without systemd you will have to manually configure your init system to -launch the Nix daemon after installation. -EOF - if ! ui_confirm "Do you want to proceed with a multi-user installation?"; then - failure <<EOF -You have aborted the installation. -EOF - fi - fi -} - -setup_report() { - header "Nix config report" - row " Temp Dir" "$SCRATCH" - row " Nix Root" "$NIX_ROOT" - row " Build Users" "$NIX_USER_COUNT" - row " Build Group ID" "$NIX_BUILD_GROUP_ID" - row "Build Group Name" "$NIX_BUILD_GROUP_NAME" - if [ "${ALLOW_PREEXISTING_INSTALLATION:-}" != "" ]; then - row "Preexisting Install" "Allowed" - fi - - subheader "build users:" - - row " Username" "UID" - for i in $(seq 1 "$NIX_USER_COUNT"); do - row " $(nix_user_for_core "$i")" "$(nix_uid_for_core "$i")" - done - echo "" -} - -create_build_group() { - local primary_group_id - - task "Setting up the build group $NIX_BUILD_GROUP_NAME" - if ! poly_group_exists "$NIX_BUILD_GROUP_NAME"; then - poly_create_build_group - row " Created" "Yes" - else - primary_group_id=$(poly_group_id_get "$NIX_BUILD_GROUP_NAME") - if [ "$primary_group_id" -ne "$NIX_BUILD_GROUP_ID" ]; then - failure <<EOF -It seems the build group $NIX_BUILD_GROUP_NAME already exists, but -with the UID $primary_group_id. This script can't really handle -that right now, so I'm going to give up. - -You can fix this by editing this script and changing the -NIX_BUILD_GROUP_ID variable near the top to from $NIX_BUILD_GROUP_ID -to $primary_group_id and re-run. -EOF - else - row " Exists" "Yes" - fi - fi -} - -create_build_user_for_core() { - local coreid - local username - local uid - - coreid="$1" - username=$(nix_user_for_core "$coreid") - uid=$(nix_uid_for_core "$coreid") - - task "Setting up the build user $username" - - if ! poly_user_exists "$username"; then - poly_create_build_user "$username" "$uid" "$coreid" - row " Created" "Yes" - else - actual_uid=$(poly_user_id_get "$username") - if [ "$actual_uid" != "$uid" ]; then - failure <<EOF -It seems the build user $username already exists, but with the UID -with the UID '$actual_uid'. This script can't really handle that right -now, so I'm going to give up. - -If you already created the users and you know they start from -$actual_uid and go up from there, you can edit this script and change -NIX_FIRST_BUILD_UID near the top of the file to $actual_uid and try -again. -EOF - else - row " Exists" "Yes" - fi - fi - - if [ "$(poly_user_hidden_get "$username")" = "1" ]; then - row " Hidden" "Yes" - else - poly_user_hidden_set "$username" - row " Hidden" "Yes" - fi - - if [ "$(poly_user_home_get "$username")" = "/var/empty" ]; then - row " Home Directory" "/var/empty" - else - poly_user_home_set "$username" "/var/empty" - row " Home Directory" "/var/empty" - fi - - # We use grep instead of an equality check because it is difficult - # to extract _just_ the user's note, instead it is prefixed with - # some plist junk. This was causing the user note to always be set, - # even if there was no reason for it. - if poly_user_note_get "$username" | grep -q "Nix build user $coreid"; then - row " Note" "Nix build user $coreid" - else - poly_user_note_set "$username" "Nix build user $coreid" - row " Note" "Nix build user $coreid" - fi - - if [ "$(poly_user_shell_get "$username")" = "/sbin/nologin" ]; then - row " Logins Disabled" "Yes" - else - poly_user_shell_set "$username" "/sbin/nologin" - row " Logins Disabled" "Yes" - fi - - if poly_user_in_group_check "$username" "$NIX_BUILD_GROUP_NAME"; then - row " Member of $NIX_BUILD_GROUP_NAME" "Yes" - else - poly_user_in_group_set "$username" "$NIX_BUILD_GROUP_NAME" - row " Member of $NIX_BUILD_GROUP_NAME" "Yes" - fi - - if [ "$(poly_user_primary_group_get "$username")" = "$NIX_BUILD_GROUP_ID" ]; then - row " PrimaryGroupID" "$NIX_BUILD_GROUP_ID" - else - poly_user_primary_group_set "$username" "$NIX_BUILD_GROUP_ID" - row " PrimaryGroupID" "$NIX_BUILD_GROUP_ID" - fi -} - -create_build_users() { - for i in $(seq 1 "$NIX_USER_COUNT"); do - create_build_user_for_core "$i" - done -} - -create_directories() { - # FIXME: remove all of this because it duplicates LocalStore::LocalStore(). - task "Setting up the basic directory structure" - if [ -d "$NIX_ROOT" ]; then - # if /nix already exists, take ownership - # - # Caution: notes below are macOS-y - # This is a bit of a goldilocks zone for taking ownership - # if there are already files on the volume; the volume is - # now mounted, but we haven't added a bunch of new files - - # this is probably a bit slow; I've been seeing 3.3-4s even - # when promptly installed over a fresh single-user install. - # In case anyone's aware of a shortcut. - # `|| true`: .Trashes errors w/o full disk perm - - # rumor per #4488 that macOS 11.2 may not have - # sbin on path, and that's where chown is, but - # since this bit is cross-platform: - # - first try with `command -vp` to try and find - # chown in the usual places - # * to work around some sort of deficiency in - # `command -p` in macOS bash 3.2, we also add - # PATH="$(getconf PATH 2>/dev/null)". As long as - # getconf is found, this should set a sane PATH - # which `command -p` in bash 3.2 appears to use. - # A bash with a properly-working `command -p` - # should ignore this hard-set PATH in favor of - # whatever it obtains internally. See - # github.com/NixOS/nix/issues/5768 - # - fall back on `command -v` which would find - # any chown on path - # if we don't find one, the command is already - # hiding behind || true, and the general state - # should be one the user can repair once they - # figure out where chown is... - local get_chr_own="$(PATH="$(getconf PATH 2>/dev/null)" command -vp chown)" - if [[ -z "$get_chr_own" ]]; then - get_chr_own="$(command -v chown)" - fi - - if [[ -z "$get_chr_own" ]]; then - reminder <<EOF -I wanted to take root ownership of existing Nix store files, -but I couldn't locate 'chown'. (You may need to fix your PATH.) -To manually change file ownership, you can run: - sudo chown -R 'root:$NIX_BUILD_GROUP_NAME' '$NIX_ROOT' -EOF - else - _sudo "to take root ownership of existing Nix store files" \ - "$get_chr_own" -R "root:$NIX_BUILD_GROUP_NAME" "$NIX_ROOT" || true - fi - fi - _sudo "to make the basic directory structure of Nix (part 1)" \ - install -dv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool,/daemon-socket} /nix/var/nix/{gcroots,profiles}/per-user - - _sudo "to make the basic directory structure of Nix (part 2)" \ - install -dv -g "$NIX_BUILD_GROUP_NAME" -m 1775 /nix/store - - _sudo "to place the default nix daemon configuration (part 1)" \ - install -dv -m 0555 /etc/nix -} - -place_channel_configuration() { - if [ -z "${NIX_INSTALLER_NO_CHANNEL_ADD:-}" ]; then - echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$SCRATCH/.nix-channels" - _sudo "to set up the default system channel (part 1)" \ - install -m 0664 "$SCRATCH/.nix-channels" "$ROOT_HOME/.nix-channels" - fi -} - -check_selinux() { - if command -v getenforce > /dev/null 2>&1; then - if [ "$(getenforce)" = "Enforcing" ]; then - failure <<EOF -Nix does not work with selinux enabled yet! -see https://github.com/NixOS/nix/issues/2374 -EOF - fi - fi -} - -check_required_system_specific_settings() { - if [ -z "${NIX_FIRST_BUILD_UID+x}" ] || [ -z "${NIX_BUILD_USER_NAME_TEMPLATE+x}" ]; then - failure "Internal error: System specific installer for $(uname) ($1) does not export required settings." - fi -} - -welcome_to_nix() { - local -r NIX_UID_RANGES="${NIX_FIRST_BUILD_UID}..$((NIX_FIRST_BUILD_UID + NIX_USER_COUNT - 1))" - local -r RANGE_TEXT=$(echo -ne "${BLUE}(uids [${NIX_UID_RANGES}])${ESC}") - local -r GROUP_TEXT=$(echo -ne "${BLUE}(gid ${NIX_BUILD_GROUP_ID})${ESC}") - - ok "Welcome to the Multi-User Nix Installation" - - cat <<EOF - -This installation tool will set up your computer with the Nix package -manager. This will happen in a few stages: - -1. Make sure your computer doesn't already have Nix. If it does, I - will show you instructions on how to clean up your old install. - -2. Show you what I am going to install and where. Then I will ask - if you are ready to continue. - -3. Create the system users ${RANGE_TEXT} and groups ${GROUP_TEXT} - that the Nix daemon uses to run builds. To create system users - in a different range, exit and run this tool again with - NIX_FIRST_BUILD_UID set. - -4. Perform the basic installation of the Nix files daemon. - -5. Configure your shell to import special Nix Profile files, so you - can use Nix. - -6. Start the Nix daemon. - -EOF - - if ui_confirm "Would you like to see a more detailed list of what I will do?"; then - cat <<EOF - -I will: - - - make sure your computer doesn't already have Nix files - (if it does, I will tell you how to clean them up.) - - create local users (see the list above for the users I'll make) - - create a local group ($NIX_BUILD_GROUP_NAME) - - install Nix in to $NIX_ROOT - - create a configuration file in /etc/nix - - set up the "default profile" by creating some Nix-related files in - $ROOT_HOME -EOF - for profile_target in "${PROFILE_TARGETS[@]}"; do - if [ -e "$profile_target" ]; then - cat <<EOF - - back up $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX - - update $profile_target to include some Nix configuration -EOF - fi - done - poly_service_setup_note - if ! ui_confirm "Ready to continue?"; then - failure <<EOF -Okay, maybe you would like to talk to the team. -EOF - fi - fi -} - -chat_about_sudo() { - header "let's talk about sudo" - - if headless; then - cat <<EOF -This script is going to call sudo a lot. Normally, it would show you -exactly what commands it is running and why. However, the script is -run in a headless fashion, like this: - - $ curl -L https://nixos.org/nix/install | sh - -or maybe in a CI pipeline. Because of that, I'm going to skip the -verbose output in the interest of brevity. - -If you would like to -see the output, try like this: - - $ curl -L -o install-nix https://nixos.org/nix/install - $ sh ./install-nix - -EOF - return 0 - fi - - cat <<EOF -This script is going to call sudo a lot. Every time I do, it'll -output exactly what it'll do, and why. - -Just like this: -EOF - - __sudo "to demonstrate how our sudo prompts look" \ - echo "this is a sudo prompt" - - cat <<EOF - -This might look scary, but everything can be undone by running just a -few commands. I used to ask you to confirm each time sudo ran, but it -was too many times. Instead, I'll just ask you this one time: - -EOF - if ui_confirm "Can I use sudo?"; then - ok "Yay! Thanks! Let's get going!" - else - failure <<EOF -That is okay, but I can't install. -EOF - fi -} - -install_from_extracted_nix() { - task "Installing Nix" - ( - cd "$EXTRACTED_NIX_PATH" - - _sudo "to copy the basic Nix files to the new store at $NIX_ROOT/store" \ - cp -RPp ./store/* "$NIX_ROOT/store/" - - _sudo "to make the new store non-writable at $NIX_ROOT/store" \ - chmod -R ugo-w "$NIX_ROOT/store/" - - if [ -d "$NIX_INSTALLED_NIX" ]; then - echo " Alright! We have our first nix at $NIX_INSTALLED_NIX" - else - failure <<EOF -Something went wrong, and I didn't find Nix installed at -$NIX_INSTALLED_NIX. -EOF - fi - - _sudo "to load data for the first time in to the Nix Database" \ - HOME="$ROOT_HOME" "$NIX_INSTALLED_NIX/bin/nix-store" --load-db < ./.reginfo - - echo " Just finished getting the nix database ready." - ) -} - -shell_source_lines() { - cat <<EOF - -# Nix -if [ -e '$PROFILE_NIX_FILE' ]; then - . '$PROFILE_NIX_FILE' -fi -# End Nix - -EOF -} - -# Fish has differing syntax -fish_source_lines() { - cat <<EOF - -# Nix -if test -e '$PROFILE_NIX_FILE_FISH' - . '$PROFILE_NIX_FILE_FISH' -end -# End Nix - -EOF -} - -configure_shell_profile() { - task "Setting up shell profiles: ${PROFILE_TARGETS[*]}" - for profile_target in "${PROFILE_TARGETS[@]}"; do - if [ -e "$profile_target" ]; then - _sudo "to back up your current $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX" \ - cp "$profile_target" "$profile_target$PROFILE_BACKUP_SUFFIX" - else - # try to create the file if its directory exists - target_dir="$(dirname "$profile_target")" - if [ -d "$target_dir" ]; then - _sudo "to create a stub $profile_target which will be updated" \ - touch "$profile_target" - fi - fi - - if [ -e "$profile_target" ]; then - shell_source_lines \ - | _sudo "extend your $profile_target with nix-daemon settings" \ - tee -a "$profile_target" - fi - done - - task "Setting up shell profiles for Fish with ${PROFILE_FISH_SUFFIX} inside ${PROFILE_FISH_PREFIXES[*]}" - for fish_prefix in "${PROFILE_FISH_PREFIXES[@]}"; do - if [ ! -d "$fish_prefix" ]; then - # this specific prefix (ie: /etc/fish) is very likely to exist - # if Fish is installed with this sysconfdir. - continue - fi - - profile_target="${fish_prefix}/${PROFILE_FISH_SUFFIX}" - conf_dir=$(dirname "$profile_target") - if [ ! -d "$conf_dir" ]; then - _sudo "create $conf_dir for our Fish hook" \ - mkdir "$conf_dir" - fi - - fish_source_lines \ - | _sudo "write nix-daemon settings to $profile_target" \ - tee "$profile_target" - done - - # TODO: should we suggest '. $PROFILE_NIX_FILE'? It would get them on - # their way less disruptively, but a counter-argument is that they won't - # immediately notice if something didn't get set up right? - reminder "Nix won't work in active shell sessions until you restart them." -} - -cert_in_store() { - # in a subshell - # - change into the cert-file dir - # - get the phyiscal pwd - # and test if this path is in the Nix store - [[ "$(cd -- "$(dirname "$NIX_SSL_CERT_FILE")" && exec pwd -P)" == "$NIX_ROOT/store/"* ]] -} - -setup_default_profile() { - task "Setting up the default profile" - _sudo "to install a bootstrapping Nix in to the default profile" \ - HOME="$ROOT_HOME" "$NIX_INSTALLED_NIX/bin/nix-env" -i "$NIX_INSTALLED_NIX" - - if [ -z "${NIX_SSL_CERT_FILE:-}" ] || ! [ -f "${NIX_SSL_CERT_FILE:-}" ] || cert_in_store; then - _sudo "to install a bootstrapping SSL certificate just for Nix in to the default profile" \ - HOME="$ROOT_HOME" "$NIX_INSTALLED_NIX/bin/nix-env" -i "$NIX_INSTALLED_CACERT" - export NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt - fi - - if [ -z "${NIX_INSTALLER_NO_CHANNEL_ADD:-}" ]; then - # Have to explicitly pass NIX_SSL_CERT_FILE as part of the sudo call, - # otherwise it will be lost in environments where sudo doesn't pass - # all the environment variables by default. - if ! _sudo "to update the default channel in the default profile" \ - HOME="$ROOT_HOME" NIX_SSL_CERT_FILE="$NIX_SSL_CERT_FILE" "$NIX_INSTALLED_NIX/bin/nix-channel" --update nixpkgs; then - reminder <<EOF -I had trouble fetching the nixpkgs channel (are you offline?) -To try again later, run: sudo -i nix-channel --update nixpkgs -EOF - fi - fi -} - - -place_nix_configuration() { - cat <<EOF > "$SCRATCH/nix.conf" -$NIX_EXTRA_CONF -build-users-group = $NIX_BUILD_GROUP_NAME -EOF - _sudo "to place the default nix daemon configuration (part 2)" \ - install -m 0664 "$SCRATCH/nix.conf" /etc/nix/nix.conf -} - - -main() { - check_selinux - - if is_os_darwin; then - # shellcheck source=./install-darwin-multi-user.sh - . "$EXTRACTED_NIX_PATH/install-darwin-multi-user.sh" - check_required_system_specific_settings "install-darwin-multi-user.sh" - elif is_os_linux; then - # shellcheck source=./install-systemd-multi-user.sh - . "$EXTRACTED_NIX_PATH/install-systemd-multi-user.sh" # most of this works on non-systemd distros also - check_required_system_specific_settings "install-systemd-multi-user.sh" - else - failure "Sorry, I don't know what to do on $(uname)" - fi - - - welcome_to_nix - - if ! is_root; then - chat_about_sudo - fi - - cure_artifacts - # TODO: there's a tension between cure and validate. I moved the - # the sudo/root check out of validate to the head of this func. - # Cure is *intended* to subsume the validate-and-abort approach, - # so it may eventually obsolete it. - validate_starting_assumptions - - setup_report - - if ! ui_confirm "Ready to continue?"; then - ok "Alright, no changes have been made :)" - get_help - trap finish_cleanup EXIT - exit 1 - fi - - poly_prepare_to_install - - create_build_group - create_build_users - create_directories - place_channel_configuration - install_from_extracted_nix - - configure_shell_profile - - set +eu - # shellcheck disable=SC1091 - . /etc/profile - set -eu - - setup_default_profile - place_nix_configuration - - poly_configure_nix_daemon_service - - trap finish_success EXIT -} - -# set an empty initial arg for bare invocations in case we need to -# disambiguate someone directly invoking this later. -if [ "${#@}" = 0 ]; then - set "" -fi - -# ACTION for override -case "${1-}" in - # uninstall) - # shift - # uninstall "$@";; - # install == same as the no-arg condition for now (but, explicit) - ""|install) - main;; - *) # holding space for future options (like uninstall + install?) - failure "install-multi-user: invalid argument";; -esac diff --git a/scripts/install-nix-from-closure.sh b/scripts/install-nix-from-closure.sh deleted file mode 100644 index 794622530..000000000 --- a/scripts/install-nix-from-closure.sh +++ /dev/null @@ -1,284 +0,0 @@ -#!/bin/sh - -set -e - -umask 0022 - -dest="/nix" -self="$(dirname "$0")" -nix="@nix@" -cacert="@cacert@" - - -if ! [ -e "$self/.reginfo" ]; then - echo "$0: incomplete installer (.reginfo is missing)" >&2 -fi - -if [ -z "$USER" ] && ! USER=$(id -u -n); then - echo "$0: \$USER is not set" >&2 - exit 1 -fi - -if [ -z "$HOME" ]; then - echo "$0: \$HOME is not set" >&2 - exit 1 -fi - -# macOS support for 10.12.6 or higher -if [ "$(uname -s)" = "Darwin" ]; then - IFS='.' read -r macos_major macos_minor macos_patch << EOF -$(sw_vers -productVersion) -EOF - if [ "$macos_major" -lt 10 ] || { [ "$macos_major" -eq 10 ] && [ "$macos_minor" -lt 12 ]; } || { [ "$macos_minor" -eq 12 ] && [ "$macos_patch" -lt 6 ]; }; then - # patch may not be present; command substitution for simplicity - echo "$0: macOS $(sw_vers -productVersion) is not supported, upgrade to 10.12.6 or higher" - exit 1 - fi -fi - -# Determine if we could use the multi-user installer or not -if [ "$(uname -s)" = "Linux" ]; then - echo "Note: a multi-user installation is possible. See https://nixos.org/manual/nix/stable/installation/installing-binary.html#multi-user-installation" >&2 -fi - -case "$(uname -s)" in - "Darwin") - INSTALL_MODE=daemon;; - *) - INSTALL_MODE=no-daemon;; -esac - -# space-separated string -ACTIONS= - -# handle the command line flags -while [ $# -gt 0 ]; do - case $1 in - --daemon) - INSTALL_MODE=daemon - ACTIONS="${ACTIONS}install " - ;; - --no-daemon) - if [ "$(uname -s)" = "Darwin" ]; then - printf '\e[1;31mError: --no-daemon installs are no-longer supported on Darwin/macOS!\e[0m\n' >&2 - exit 1 - fi - INSTALL_MODE=no-daemon - # intentional tail space - ACTIONS="${ACTIONS}install " - ;; - # --uninstall) - # # intentional tail space - # ACTIONS="${ACTIONS}uninstall " - # ;; - --yes) - export NIX_INSTALLER_YES=1;; - --no-channel-add) - export NIX_INSTALLER_NO_CHANNEL_ADD=1;; - --daemon-user-count) - export NIX_USER_COUNT=$2 - shift;; - --no-modify-profile) - NIX_INSTALLER_NO_MODIFY_PROFILE=1;; - --darwin-use-unencrypted-nix-store-volume) - { - echo "Warning: the flag --darwin-use-unencrypted-nix-store-volume" - echo " is no longer needed and will be removed in the future." - echo "" - } >&2;; - --nix-extra-conf-file) - # shellcheck disable=SC2155 - export NIX_EXTRA_CONF="$(cat "$2")" - shift;; - *) - { - echo "Nix Installer [--daemon|--no-daemon] [--daemon-user-count INT] [--yes] [--no-channel-add] [--no-modify-profile] [--nix-extra-conf-file FILE]" - - 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/manual/nix/stable/installation/installing-binary.html#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 " --yes: Run the script non-interactively, accepting all prompts." - echo "" - echo " --no-channel-add: Don't add any channels. nixpkgs-unstable is installed by default." - echo "" - echo " --no-modify-profile: Don't modify the user profile to automatically load nix." - echo "" - echo " --daemon-user-count: Number of build users to create. Defaults to 32." - echo "" - echo " --nix-extra-conf-file: Path to nix.conf to prepend when installing /etc/nix/nix.conf" - echo "" - if [ -n "${INVOKED_FROM_INSTALL_IN:-}" ]; then - echo " --tarball-url-prefix URL: Base URL to download the Nix tarball from." - fi - } >&2 - - exit;; - esac - shift -done - -if [ "$INSTALL_MODE" = "daemon" ]; then - printf '\e[1;31mSwitching to the Multi-user Installer\e[0m\n' - exec "$self/install-multi-user" $ACTIONS # let ACTIONS split - exit 0 -fi - -if [ "$(id -u)" -eq 0 ]; then - printf '\e[1;31mwarning: installing Nix as root is not supported by this script!\e[0m\n' -fi - -echo "performing a single-user installation of Nix..." >&2 - -if ! [ -e "$dest" ]; then - cmd="mkdir -m 0755 $dest && chown $USER $dest" - 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 - exit 1 - fi -fi - -if ! [ -w "$dest" ]; then - echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see https://nixos.org/manual/nix/stable/installation/multi-user.html. If you wish to continue with a single-user install for $USER please run 'chown -R $USER $dest' as root." >&2 - exit 1 -fi - -# The auto-chroot code in openFromNonUri() checks for the -# non-existence of /nix/var/nix, so we need to create it here. -mkdir -p "$dest/store" "$dest/var/nix" - -printf "copying Nix to %s..." "${dest}/store" >&2 -# Insert a newline if no progress is shown. -if [ ! -t 0 ]; then - echo "" -fi - -for i in $(cd "$self/store" >/dev/null && echo ./*); do - if [ -t 0 ]; then - printf "." >&2 - fi - i_tmp="$dest/store/$i.$$" - if [ -e "$i_tmp" ]; then - rm -rf "$i_tmp" - fi - if ! [ -e "$dest/store/$i" ]; then - cp -RPp "$self/store/$i" "$i_tmp" - chmod -R a-w "$i_tmp" - chmod +w "$i_tmp" - mv "$i_tmp" "$dest/store/$i" - chmod -w "$dest/store/$i" - fi -done -echo "" >&2 - -if ! "$nix/bin/nix-store" --load-db < "$self/.reginfo"; then - echo "$0: unable to register valid paths" >&2 - exit 1 -fi - -# shellcheck source=./nix-profile.sh.in -. "$nix/etc/profile.d/nix.sh" - -NIX_LINK="$HOME/.nix-profile" - -if ! "$nix/bin/nix-env" -i "$nix"; then - echo "$0: unable to install Nix into your default profile" >&2 - exit 1 -fi - -# Install an SSL certificate bundle. -if [ -z "$NIX_SSL_CERT_FILE" ] || ! [ -f "$NIX_SSL_CERT_FILE" ]; then - "$nix/bin/nix-env" -i "$cacert" - export NIX_SSL_CERT_FILE="$NIX_LINK/etc/ssl/certs/ca-bundle.crt" -fi - -# Subscribe the user to the Nixpkgs channel and fetch it. -if [ -z "$NIX_INSTALLER_NO_CHANNEL_ADD" ]; then - if ! "$nix/bin/nix-channel" --list | grep -q "^nixpkgs "; then - "$nix/bin/nix-channel" --add https://nixos.org/channels/nixpkgs-unstable - fi - if [ -z "$_NIX_INSTALLER_TEST" ]; then - if ! "$nix/bin/nix-channel" --update nixpkgs; then - echo "Fetching the nixpkgs channel failed. (Are you offline?)" - echo "To try again later, run \"nix-channel --update nixpkgs\"." - fi - fi -fi - -added= -p= -p_sh=$NIX_LINK/etc/profile.d/nix.sh -p_fish=$NIX_LINK/etc/profile.d/nix.fish -if [ -z "$NIX_INSTALLER_NO_MODIFY_PROFILE" ]; then - # Make the shell source nix.sh during login. - for i in .bash_profile .bash_login .profile; do - fn="$HOME/$i" - if [ -w "$fn" ]; then - if ! grep -q "$p_sh" "$fn"; then - echo "modifying $fn..." >&2 - printf '\nif [ -e %s ]; then . %s; fi # added by Nix installer\n' "$p_sh" "$p_sh" >> "$fn" - fi - added=1 - p=${p_sh} - break - fi - done - for i in .zshenv .zshrc; do - fn="$HOME/$i" - if [ -w "$fn" ]; then - if ! grep -q "$p_sh" "$fn"; then - echo "modifying $fn..." >&2 - printf '\nif [ -e %s ]; then . %s; fi # added by Nix installer\n' "$p_sh" "$p_sh" >> "$fn" - fi - added=1 - p=${p_sh} - break - fi - done - - if [ -d "$HOME/.config/fish" ]; then - fishdir=$HOME/.config/fish/conf.d - if [ ! -d "$fishdir" ]; then - mkdir -p "$fishdir" - fi - - fn="$fishdir/nix.fish" - echo "placing $fn..." >&2 - printf '\nif test -e %s; . %s; end # added by Nix installer\n' "$p_fish" "$p_fish" > "$fn" - added=1 - p=${p_fish} - fi -else - p=${p_sh} -fi - -if [ -z "$added" ]; then - cat >&2 <<EOF - -Installation finished! To ensure that the necessary environment -variables are set, please add the line - - . $p - -to your shell profile (e.g. ~/.profile). -EOF -else - cat >&2 <<EOF - -Installation finished! To ensure that the necessary environment -variables are set, either log in again, or type - - . $p - -in your shell. -EOF -fi diff --git a/scripts/install-systemd-multi-user.sh b/scripts/install-systemd-multi-user.sh deleted file mode 100755 index 202a9bb54..000000000 --- a/scripts/install-systemd-multi-user.sh +++ /dev/null @@ -1,222 +0,0 @@ -#!/usr/bin/env bash - -set -eu -set -o pipefail - -# System specific settings -export NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-30001}" -export NIX_BUILD_USER_NAME_TEMPLATE="nixbld%d" - -readonly SERVICE_SRC=/lib/systemd/system/nix-daemon.service -readonly SERVICE_DEST=/etc/systemd/system/nix-daemon.service - -readonly SOCKET_SRC=/lib/systemd/system/nix-daemon.socket -readonly SOCKET_DEST=/etc/systemd/system/nix-daemon.socket - -readonly TMPFILES_SRC=/lib/tmpfiles.d/nix-daemon.conf -readonly TMPFILES_DEST=/etc/tmpfiles.d/nix-daemon.conf - -# Path for the systemd override unit file to contain the proxy settings -readonly SERVICE_OVERRIDE=${SERVICE_DEST}.d/override.conf - -create_systemd_override() { - header "Configuring proxy for the nix-daemon service" - _sudo "create directory for systemd unit override" mkdir -p "$(dirname "$SERVICE_OVERRIDE")" - cat <<EOF | _sudo "create systemd unit override" tee "$SERVICE_OVERRIDE" -[Service] -$1 -EOF -} - -escape_systemd_env() { - temp_var="${1//\'/\\\'}" - echo "${temp_var//\%/%%}" -} - -# Gather all non-empty proxy environment variables into a string -create_systemd_proxy_env() { - vars="http_proxy https_proxy ftp_proxy no_proxy HTTP_PROXY HTTPS_PROXY FTP_PROXY NO_PROXY" - for v in $vars; do - if [ "x${!v:-}" != "x" ]; then - echo "Environment=${v}=$(escape_systemd_env ${!v})" - fi - done -} - -handle_network_proxy() { - # Create a systemd unit override with proxy environment variables - # if any proxy environment variables are not empty. - PROXY_ENV_STRING=$(create_systemd_proxy_env) - if [ -n "${PROXY_ENV_STRING}" ]; then - create_systemd_override "${PROXY_ENV_STRING}" - fi -} - -poly_cure_artifacts() { - : -} - -poly_service_installed_check() { - [ "$(systemctl is-enabled nix-daemon.service)" = "linked" ] \ - || [ "$(systemctl is-enabled nix-daemon.socket)" = "enabled" ] -} - -poly_service_uninstall_directions() { - cat <<EOF -$1. Delete the systemd service and socket units - - sudo systemctl stop nix-daemon.socket - sudo systemctl stop nix-daemon.service - sudo systemctl disable nix-daemon.socket - sudo systemctl disable nix-daemon.service - sudo systemctl daemon-reload -EOF -} - -poly_service_setup_note() { - cat <<EOF - - load and start a service (at $SERVICE_DEST - and $SOCKET_DEST) for nix-daemon - -EOF -} - -poly_extra_try_me_commands() { - if [ -e /run/systemd/system ]; then - : - else - cat <<EOF - $ sudo nix-daemon -EOF - fi -} - -poly_configure_nix_daemon_service() { - if [ -e /run/systemd/system ]; then - task "Setting up the nix-daemon systemd service" - - _sudo "to create the nix-daemon tmpfiles config" \ - ln -sfn "/nix/var/nix/profiles/default$TMPFILES_SRC" "$TMPFILES_DEST" - - _sudo "to run systemd-tmpfiles once to pick that path up" \ - systemd-tmpfiles --create --prefix=/nix/var/nix - - _sudo "to set up the nix-daemon service" \ - systemctl link "/nix/var/nix/profiles/default$SERVICE_SRC" - - _sudo "to set up the nix-daemon socket service" \ - systemctl enable "/nix/var/nix/profiles/default$SOCKET_SRC" - - handle_network_proxy - - _sudo "to load the systemd unit for nix-daemon" \ - systemctl daemon-reload - - _sudo "to start the nix-daemon.socket" \ - systemctl start nix-daemon.socket - - _sudo "to start the nix-daemon.service" \ - systemctl restart nix-daemon.service - else - reminder "I don't support your init system yet; you may want to add nix-daemon manually." - fi -} - -poly_group_exists() { - getent group "$1" > /dev/null 2>&1 -} - -poly_group_id_get() { - getent group "$1" | cut -d: -f3 -} - -poly_create_build_group() { - _sudo "Create the Nix build group, $NIX_BUILD_GROUP_NAME" \ - groupadd -g "$NIX_BUILD_GROUP_ID" --system \ - "$NIX_BUILD_GROUP_NAME" >&2 -} - -poly_user_exists() { - getent passwd "$1" > /dev/null 2>&1 -} - -poly_user_id_get() { - getent passwd "$1" | cut -d: -f3 -} - -poly_user_hidden_get() { - echo "1" -} - -poly_user_hidden_set() { - true -} - -poly_user_home_get() { - getent passwd "$1" | cut -d: -f6 -} - -poly_user_home_set() { - _sudo "in order to give $1 a safe home directory" \ - usermod --home "$2" "$1" -} - -poly_user_note_get() { - getent passwd "$1" | cut -d: -f5 -} - -poly_user_note_set() { - _sudo "in order to give $1 a useful comment" \ - usermod --comment "$2" "$1" -} - -poly_user_shell_get() { - getent passwd "$1" | cut -d: -f7 -} - -poly_user_shell_set() { - _sudo "in order to prevent $1 from logging in" \ - usermod --shell "$2" "$1" -} - -poly_user_in_group_check() { - groups "$1" | grep -q "$2" > /dev/null 2>&1 -} - -poly_user_in_group_set() { - _sudo "Add $1 to the $2 group"\ - usermod --append --groups "$2" "$1" -} - -poly_user_primary_group_get() { - getent passwd "$1" | cut -d: -f4 -} - -poly_user_primary_group_set() { - _sudo "to let the nix daemon use this user for builds (this might seem redundant, but there are two concepts of group membership)" \ - usermod --gid "$2" "$1" - -} - -poly_create_build_user() { - username=$1 - uid=$2 - builder_num=$3 - - _sudo "Creating the Nix build user, $username" \ - useradd \ - --home-dir /var/empty \ - --comment "Nix build user $builder_num" \ - --gid "$NIX_BUILD_GROUP_ID" \ - --groups "$NIX_BUILD_GROUP_NAME" \ - --no-user-group \ - --system \ - --shell /sbin/nologin \ - --uid "$uid" \ - --password "!" \ - "$username" -} - -poly_prepare_to_install() { - : -} diff --git a/scripts/install.in b/scripts/install.in deleted file mode 100755 index 7d2e52b26..000000000 --- a/scripts/install.in +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh - -# This script installs the Nix package manager on your system by -# downloading a binary distribution and running its installer script -# (which in turn creates and populates /nix). - -{ # Prevent execution if this script was only partially downloaded -oops() { - echo "$0:" "$@" >&2 - exit 1 -} - -umask 0022 - -tmpDir="$(mktemp -d -t nix-binary-tarball-unpack.XXXXXXXXXX || \ - oops "Can't create temporary directory for downloading the Nix binary tarball")" -cleanup() { - rm -rf "$tmpDir" -} -trap cleanup EXIT INT QUIT TERM - -require_util() { - command -v "$1" > /dev/null 2>&1 || - oops "you do not have '$1' installed, which I need to $2" -} - -case "$(uname -s).$(uname -m)" in - Linux.x86_64) - hash=@tarballHash_x86_64-linux@ - path=@tarballPath_x86_64-linux@ - system=x86_64-linux - ;; - Linux.i?86) - hash=@tarballHash_i686-linux@ - path=@tarballPath_i686-linux@ - system=i686-linux - ;; - Linux.aarch64) - hash=@tarballHash_aarch64-linux@ - path=@tarballPath_aarch64-linux@ - system=aarch64-linux - ;; - Linux.armv6l) - hash=@tarballHash_armv6l-linux@ - path=@tarballPath_armv6l-linux@ - system=armv6l-linux - ;; - Linux.armv7l) - hash=@tarballHash_armv7l-linux@ - path=@tarballPath_armv7l-linux@ - system=armv7l-linux - ;; - Darwin.x86_64) - hash=@tarballHash_x86_64-darwin@ - path=@tarballPath_x86_64-darwin@ - system=x86_64-darwin - ;; - Darwin.arm64|Darwin.aarch64) - hash=@tarballHash_aarch64-darwin@ - path=@tarballPath_aarch64-darwin@ - system=aarch64-darwin - ;; - *) oops "sorry, there is no binary distribution of Nix for your platform";; -esac - -# Use this command-line option to fetch the tarballs using nar-serve or Cachix -if [ "${1:-}" = "--tarball-url-prefix" ]; then - if [ -z "${2:-}" ]; then - oops "missing argument for --tarball-url-prefix" - fi - url=${2}/${path} - shift 2 -else - url=https://releases.nixos.org/nix/nix-@nixVersion@/nix-@nixVersion@-$system.tar.xz -fi - -tarball=$tmpDir/nix-@nixVersion@-$system.tar.xz - -require_util tar "unpack the binary tarball" -if [ "$(uname -s)" != "Darwin" ]; then - require_util xz "unpack the binary tarball" -fi - -if command -v curl > /dev/null 2>&1; then - fetch() { curl --fail -L "$1" -o "$2"; } -elif command -v wget > /dev/null 2>&1; then - fetch() { wget "$1" -O "$2"; } -else - oops "you don't have wget or curl installed, which I need to download the binary tarball" -fi - -echo "downloading Nix @nixVersion@ binary tarball for $system from '$url' to '$tmpDir'..." -fetch "$url" "$tarball" || oops "failed to download '$url'" - -if command -v sha256sum > /dev/null 2>&1; then - hash2="$(sha256sum -b "$tarball" | cut -c1-64)" -elif command -v shasum > /dev/null 2>&1; then - hash2="$(shasum -a 256 -b "$tarball" | cut -c1-64)" -elif command -v openssl > /dev/null 2>&1; then - hash2="$(openssl dgst -r -sha256 "$tarball" | cut -c1-64)" -else - oops "cannot verify the SHA-256 hash of '$url'; you need one of 'shasum', 'sha256sum', or 'openssl'" -fi - -if [ "$hash" != "$hash2" ]; then - oops "SHA-256 hash mismatch in '$url'; expected $hash, got $hash2" -fi - -unpack=$tmpDir/unpack -mkdir -p "$unpack" -tar -xJf "$tarball" -C "$unpack" || oops "failed to unpack '$url'" - -script=$(echo "$unpack"/*/install) - -[ -e "$script" ] || oops "installation script is missing from the binary tarball!" -export INVOKED_FROM_INSTALL_IN=1 -"$script" "$@" - -} # End of wrapping diff --git a/scripts/local.mk b/scripts/local.mk index 46255e432..cf2288bb6 100644 --- a/scripts/local.mk +++ b/scripts/local.mk @@ -7,7 +7,5 @@ profiledir = $(sysconfdir)/profile.d $(eval $(call install-file-as, $(d)/nix-profile.sh, $(profiledir)/nix.sh, 0644)) $(eval $(call install-file-as, $(d)/nix-profile.fish, $(profiledir)/nix.fish, 0644)) -$(eval $(call install-file-as, $(d)/nix-profile-daemon.sh, $(profiledir)/nix-daemon.sh, 0644)) -$(eval $(call install-file-as, $(d)/nix-profile-daemon.fish, $(profiledir)/nix-daemon.fish, 0644)) clean-files += $(nix_noinst_scripts) diff --git a/scripts/nix-profile-daemon.fish.in b/scripts/nix-profile-daemon.fish.in deleted file mode 100644 index c23aa64f0..000000000 --- a/scripts/nix-profile-daemon.fish.in +++ /dev/null @@ -1,57 +0,0 @@ -function add_path --argument-names new_path - if type -q fish_add_path - # fish 3.2.0 or newer - fish_add_path --prepend --global $new_path - else - # older versions of fish - if not contains $new_path $fish_user_paths - set --global fish_user_paths $new_path $fish_user_paths - end - end -end - -# Only execute this file once per shell. -if test -n "$__ETC_PROFILE_NIX_SOURCED" - exit -end - -set __ETC_PROFILE_NIX_SOURCED 1 - -set --export NIX_PROFILES "@localstatedir@/nix/profiles/default $HOME/.nix-profile" - -# Populate bash completions, .desktop files, etc -if test -z "$XDG_DATA_DIRS" - # According to XDG spec the default is /usr/local/share:/usr/share, don't set something that prevents that default - set --export XDG_DATA_DIRS "/usr/local/share:/usr/share:/nix/var/nix/profiles/default/share" -else - set --export XDG_DATA_DIRS "$XDG_DATA_DIRS:/nix/var/nix/profiles/default/share" -end - -# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work. -if test -n "$NIX_SSH_CERT_FILE" - : # Allow users to override the NIX_SSL_CERT_FILE -else if test -e /etc/ssl/certs/ca-certificates.crt # NixOS, Ubuntu, Debian, Gentoo, Arch - set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt -else if test -e /etc/ssl/ca-bundle.pem # openSUSE Tumbleweed - set --export NIX_SSL_CERT_FILE /etc/ssl/ca-bundle.pem -else if test -e /etc/ssl/certs/ca-bundle.crt # Old NixOS - set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-bundle.crt -else if test -e /etc/pki/tls/certs/ca-bundle.crt # Fedora, CentOS - set --export NIX_SSL_CERT_FILE /etc/pki/tls/certs/ca-bundle.crt -else if test -e "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" # fall back to cacert in Nix profile - set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" -else if test -e "$NIX_LINK/etc/ca-bundle.crt" # old cacert in Nix profile - set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ca-bundle.crt" -else - # Fall back to what is in the nix profiles, favouring whatever is defined last. - for i in $NIX_PROFILES - if test -e "$i/etc/ssl/certs/ca-bundle.crt" - set --export NIX_SSL_CERT_FILE "$i/etc/ssl/certs/ca-bundle.crt" - end - end -end - -add_path "@localstatedir@/nix/profiles/default/bin" -add_path "$HOME/.nix-profile/bin" - -functions -e add_path diff --git a/scripts/nix-profile-daemon.sh.in b/scripts/nix-profile-daemon.sh.in deleted file mode 100644 index d256b24ed..000000000 --- a/scripts/nix-profile-daemon.sh.in +++ /dev/null @@ -1,72 +0,0 @@ -# Only execute this file once per shell. -if [ -n "${__ETC_PROFILE_NIX_SOURCED:-}" ]; then return; fi -__ETC_PROFILE_NIX_SOURCED=1 - -NIX_LINK=$HOME/.nix-profile -if [ -n "${XDG_STATE_HOME-}" ]; then - NIX_LINK_NEW="$XDG_STATE_HOME/nix/profile" -else - NIX_LINK_NEW=$HOME/.local/state/nix/profile -fi -if [ -e "$NIX_LINK_NEW" ]; then - NIX_LINK="$NIX_LINK_NEW" -else - if [ -t 2 ] && [ -e "$NIX_LINK_NEW" ]; then - warning="\033[1;35mwarning:\033[0m" - printf "$warning Both %s and legacy %s exist; using the latter.\n" "$NIX_LINK_NEW" "$NIX_LINK" 1>&2 - if [ "$(realpath "$NIX_LINK")" = "$(realpath "$NIX_LINK_NEW")" ]; then - printf " Since the profiles match, you can safely delete either of them.\n" 1>&2 - else - # This should be an exceptionally rare occasion: the only way to get it would be to - # 1. Update to newer Nix; - # 2. Remove .nix-profile; - # 3. Set the $NIX_LINK_NEW to something other than the default user profile; - # 4. Roll back to older Nix. - # If someone did all that, they can probably figure out how to migrate the profile. - printf "$warning Profiles do not match. You should manually migrate from %s to %s.\n" "$NIX_LINK" "$NIX_LINK_NEW" 1>&2 - fi - fi -fi - -export NIX_PROFILES="@localstatedir@/nix/profiles/default $NIX_LINK" - -# Populate bash completions, .desktop files, etc -if [ -z "${XDG_DATA_DIRS-}" ]; then - # According to XDG spec the default is /usr/local/share:/usr/share, don't set something that prevents that default - export XDG_DATA_DIRS="/usr/local/share:/usr/share:$NIX_LINK/share:/nix/var/nix/profiles/default/share" -else - export XDG_DATA_DIRS="$XDG_DATA_DIRS:$NIX_LINK/share:/nix/var/nix/profiles/default/share" -fi - -# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work. -if [ -n "${NIX_SSL_CERT_FILE:-}" ]; then - : # Allow users to override the NIX_SSL_CERT_FILE -elif [ -e /etc/ssl/certs/ca-certificates.crt ]; then # NixOS, Ubuntu, Debian, Gentoo, Arch - export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt -elif [ -e /etc/ssl/ca-bundle.pem ]; then # openSUSE Tumbleweed - export NIX_SSL_CERT_FILE=/etc/ssl/ca-bundle.pem -elif [ -e /etc/ssl/certs/ca-bundle.crt ]; then # Old NixOS - export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt -elif [ -e /etc/pki/tls/certs/ca-bundle.crt ]; then # Fedora, CentOS - export NIX_SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt -else - # Fall back to what is in the nix profiles, favouring whatever is defined last. - check_nix_profiles() { - if [ -n "$ZSH_VERSION" ]; then - # Zsh by default doesn't split words in unquoted parameter expansion. - # Set local_options for these options to be reverted at the end of the function - # and shwordsplit to force splitting words in $NIX_PROFILES below. - setopt local_options shwordsplit - fi - for i in $NIX_PROFILES; do - if [ -e "$i/etc/ssl/certs/ca-bundle.crt" ]; then - export NIX_SSL_CERT_FILE=$i/etc/ssl/certs/ca-bundle.crt - fi - done - } - check_nix_profiles - unset -f check_nix_profiles -fi - -export PATH="$NIX_LINK/bin:@localstatedir@/nix/profiles/default/bin:$PATH" -unset NIX_LINK diff --git a/scripts/prepare-installer-for-github-actions b/scripts/prepare-installer-for-github-actions deleted file mode 100755 index 4b994a753..000000000 --- a/scripts/prepare-installer-for-github-actions +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -set -e - -script=$(nix-build -A outputs.hydraJobs.installerScriptForGHA --no-out-link) -installerHash=$(echo "$script" | cut -b12-43 -) - -installerURL=https://$CACHIX_NAME.cachix.org/serve/$installerHash/install - -echo "::set-output name=installerURL::$installerURL" |