From 2921165a9d14b80fd4a7e350e72ec2b83791682c Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Wed, 28 Mar 2018 09:16:13 -0400 Subject: [PATCH] Expand the multi-user installer to support Linuxes with systemd - darwin installer: delete hardware report, not necessary - moves os-specific code from the darwin installer to to `poly_*` functions - adds profile.d support to the profile targets, which automatically handles many distros which don't have a /etc/bashrc but do have an /etc/profile.d - /bin/bash -> /usr/bin/env bash - document why each excluded shellcheck check is excluded - rename the multi-user to Daemon-based --- release.nix | 34 +- scripts/install-darwin-multi-user.sh | 831 +++----------------------- scripts/install-multi-user.sh | 793 ++++++++++++++++++++++++ scripts/install-nix-from-closure.sh | 11 +- scripts/install-systemd-multi-user.sh | 154 +++++ 5 files changed, 1063 insertions(+), 760 deletions(-) create mode 100644 scripts/install-multi-user.sh create mode 100644 scripts/install-systemd-multi-user.sh diff --git a/release.nix b/release.nix index 91c782c5191..492065df985 100644 --- a/release.nix +++ b/release.nix @@ -127,17 +127,39 @@ let substitute ${./scripts/install-nix-from-closure.sh} $TMPDIR/install \ --subst-var-by nix ${toplevel} \ --subst-var-by cacert ${cacert} - substitute ${./scripts/install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user \ + + substitute ${./scripts/install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user.sh \ + --subst-var-by nix ${toplevel} \ + --subst-var-by cacert ${cacert} + substitute ${./scripts/install-systemd-multi-user.sh} $TMPDIR/install-systemd-multi-user.sh \ + --subst-var-by nix ${toplevel} \ + --subst-var-by cacert ${cacert} + substitute ${./scripts/install-multi-user.sh} $TMPDIR/install-multi-user \ --subst-var-by nix ${toplevel} \ --subst-var-by cacert ${cacert} if type -p shellcheck; then - shellcheck -e SC1090 $TMPDIR/install - shellcheck -e SC1091,SC2002 $TMPDIR/install-darwin-multi-user + # SC1090: Don't worry about not being able to find + # $nix/etc/profile.d/nix.sh + shellcheck --exclude SC1090 $TMPDIR/install + 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/install-darwin-multi-user + 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}-${system} fn=$out/$dir.tar.bz2 mkdir -p $out/nix-support @@ -149,7 +171,9 @@ let --transform "s,$TMPDIR/install,$dir/install," \ --transform "s,$TMPDIR/reginfo,$dir/.reginfo," \ --transform "s,$NIX_STORE,$dir/store,S" \ - $TMPDIR/install $TMPDIR/install-darwin-multi-user $TMPDIR/reginfo \ + $TMPDIR/install $TMPDIR/install-darwin-multi-user.sh \ + $TMPDIR/install-systemd-multi-user.sh \ + $TMPDIR/install-multi-user $TMPDIR/reginfo \ $(cat ${installerClosureInfo}/store-paths) ''); diff --git a/scripts/install-darwin-multi-user.sh b/scripts/install-darwin-multi-user.sh index 716b6e9bc9a..87c4c2b0582 100644 --- a/scripts/install-darwin-multi-user.sh +++ b/scripts/install-darwin-multi-user.sh @@ -1,819 +1,144 @@ -#!/bin/bash +#!/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[38;1m' -readonly BLUE='\033[38;34m' -readonly BLUE_UL='\033[38;4;34m' -readonly GREEN='\033[38;32m' -readonly GREEN_UL='\033[38;4;32m' -readonly RED='\033[38;31m' -readonly RED_UL='\033[38;4;31m' -readonly YELLOW='\033[38;33m' -readonly YELLOW_UL='\033[38;4;33m' - -readonly CORES=$(sysctl -n hw.ncpu) -readonly NIX_USER_COUNT="32" -readonly NIX_BUILD_GROUP_ID="30000" -readonly NIX_BUILD_GROUP_NAME="nixbld" -readonly NIX_FIRST_BUILD_UID="30001" -# 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 PLIST_DEST=/Library/LaunchDaemons/org.nixos.nix-daemon.plist -readonly PROFILE_TARGETS=("/etc/bashrc" "/etc/zshrc") -readonly PROFILE_BACKUP_SUFFIX=".backup-before-nix" -readonly PROFILE_NIX_FILE="$NIX_ROOT/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" - -readonly NIX_INSTALLED_NIX="@nix@" -readonly NIX_INSTALLED_CACERT="@cacert@" -readonly EXTRACTED_NIX_PATH="$(dirname "$0")" - -readonly ROOT_HOME="/var/root" - -if [ -t 0 ]; then - readonly IS_HEADLESS='no' -else - readonly IS_HEADLESS='yes' -fi +dsclattr() { + /usr/bin/dscl . -read "$1" \ + | awk "/$2/ { print \$2 }" +} -headless() { - if [ "$IS_HEADLESS" = "yes" ]; then - return 0 - else - return 1 +poly_validate_assumptions() { + if [ "$(uname -s)" != "Darwin" ]; then + failure "This script is for use with macOS!" fi } -contactme() { - echo "We'd love to help if you need it." - echo "" - echo "If you can, open an issue at https://github.com/nixos/nix/issues" - echo "" - echo "Or feel free to contact the team," - echo " - on IRC #nixos on irc.freenode.net" - echo " - on twitter @nixos_org" +poly_service_installed_check() { + [ -e "$PLIST_DEST" ] } -uninstall_directions() { - subheader "Uninstalling nix:" - local step=0 - - if [ -e "$PLIST_DEST" ]; then - step=$((step + 1)) +poly_service_uninstall_directions() { cat < $1" -} - -bold() { - echo "$BOLD$*$ESC" -} - -ok() { - _textout "$GREEN" "$@" -} - -warning() { - warningheader "warning!" - cat - echo "" -} - -failure() { - header "oh no!" - _textout "$RED" "$@" - echo "" - _textout "$RED" "$(contactme)" - 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 -} - -__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 -} +poly_configure_nix_daemon_service() { + _sudo "to set up the nix-daemon as a LaunchDaemon" \ + ln -sfn "/nix/var/nix/profiles/default$PLIST_DEST" "$PLIST_DEST" -_sudo() { - local expl="$1" - shift - if ! headless; then - __sudo "$expl" "$*" - fi - sudo "$@" -} + _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 start org.nixos.nix-daemon -readonly SCRATCH=$(mktemp -d -t tmp.XXXXXXXXXX) -function finish_cleanup { - rm -rf "$SCRATCH" } -function finish_fail { - finish_cleanup - - failure < /dev/null 2>&1 } -trap finish_fail EXIT - -function finish_success { - finish_cleanup - ok "Alright! We're done!" - cat < /dev/null >&2; then - failure <&2 } -setup_report() { - header "hardware report" - row " Cores" "$CORES" - - 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 "" +poly_user_exists() { + /usr/bin/dscl . -read "/Users/$1" > /dev/null 2>&1 } -create_build_group() { - local primary_group_id - - task "Setting up the build group $NIX_BUILD_GROUP_NAME" - if ! /usr/bin/dscl . -read "/Groups/$NIX_BUILD_GROUP_NAME" > /dev/null 2>&1; then - _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 - row " Created" "Yes" - else - primary_group_id=$(dsclattr "/Groups/$NIX_BUILD_GROUP_NAME" "PrimaryGroupID") - if [ "$primary_group_id" -ne "$NIX_BUILD_GROUP_ID" ]; then - failure < /dev/null 2>&1; then - _sudo "Creating the Nix build user, $username" \ - /usr/bin/dscl . create "$dsclpath" \ - UniqueID "${uid}" - row " Created" "Yes" - else - actual_uid=$(dsclattr "$dsclpath" "UniqueID") - if [ "$actual_uid" -ne "$uid" ]; then - failure <