diff options
Diffstat (limited to 'scripts/install-multi-user.sh')
-rw-r--r-- | scripts/install-multi-user.sh | 1042 |
1 files changed, 0 insertions, 1042 deletions
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 |