1#!/usr/bin/env bash
2
3set -eu
4set -o pipefail
5
6# Sourced from:
7# - https://github.com/LnL7/nix-darwin/blob/8c29d0985d74b4a990238497c47a2542a5616b3c/bootstrap.sh
8# - https://gist.github.com/expipiplus1/e571ce88c608a1e83547c918591b149f/ac504c6c1b96e65505fbda437a28ce563408ecb0
9# - https://github.com/NixOS/nixos-org-configurations/blob/a122f418797713d519aadf02e677fce0dc1cb446/delft/scripts/nix-mac-installer.sh
10# - https://github.com/matthewbauer/macNixOS/blob/f6045394f9153edea417be90c216788e754feaba/install-macNixOS.sh
11# - https://gist.github.com/LnL7/9717bd6cdcb30b086fd7f2093e5f8494/86b26f852ce563e973acd30f796a9a416248c34a
12#
13# however tracking which bits came from which would be impossible.
14
15readonly ESC='\033[0m'
16readonly BOLD='\033[1m'
17readonly BLUE='\033[34m'
18readonly BLUE_UL='\033[4;34m'
19readonly GREEN='\033[32m'
20readonly GREEN_UL='\033[4;32m'
21readonly RED='\033[31m'
22
23# installer allows overriding build user count to speed up installation
24# as creating each user takes non-trivial amount of time on macos
25readonly NIX_USER_COUNT=${NIX_USER_COUNT:-32}
26readonly NIX_BUILD_GROUP_ID="30000"
27readonly NIX_BUILD_GROUP_NAME="nixbld"
28readonly NIX_FIRST_BUILD_UID="30001"
29# Please don't change this. We don't support it, because the
30# default shell profile that comes with Nix doesn't support it.
31readonly NIX_ROOT="/nix"
32readonly NIX_EXTRA_CONF=${NIX_EXTRA_CONF:-}
33
34readonly PROFILE_TARGETS=("/etc/bashrc" "/etc/profile.d/nix.sh" "/etc/zshrc")
35readonly PROFILE_BACKUP_SUFFIX=".backup-before-nix"
36readonly PROFILE_NIX_FILE="$NIX_ROOT/var/nix/profiles/default/etc/profile.d/nix-daemon.sh"
37
38readonly NIX_INSTALLED_NIX="@nix@"
39readonly NIX_INSTALLED_CACERT="@cacert@"
40readonly EXTRACTED_NIX_PATH="$(dirname "$0")"
41
42readonly ROOT_HOME=$(echo ~root)
43
44if [ -t 0 ]; then
45    readonly IS_HEADLESS='no'
46else
47    readonly IS_HEADLESS='yes'
48fi
49
50headless() {
51    if [ "$IS_HEADLESS" = "yes" ]; then
52        return 0
53    else
54        return 1
55    fi
56}
57
58contactme() {
59    echo "We'd love to help if you need it."
60    echo ""
61    echo "If you can, open an issue at https://github.com/nixos/nix/issues"
62    echo ""
63    echo "Or feel free to contact the team,"
64    echo " - on IRC #nixos on irc.freenode.net"
65    echo " - on twitter @nixos_org"
66}
67
68uninstall_directions() {
69    subheader "Uninstalling nix:"
70    local step=0
71
72    if poly_service_installed_check; then
73        step=$((step + 1))
74        poly_service_uninstall_directions "$step"
75    fi
76
77    for profile_target in "${PROFILE_TARGETS[@]}"; do
78        if [ -e "$profile_target" ] && [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then
79            step=$((step + 1))
80            cat <<EOF
81$step. Restore $profile_target$PROFILE_BACKUP_SUFFIX back to $profile_target
82
83  sudo mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
84
85(after this one, you may need to re-open any terminals that were
86opened while it existed.)
87
88EOF
89        fi
90    done
91
92    step=$((step + 1))
93    cat <<EOF
94$step. Delete the files Nix added to your system:
95
96  sudo rm -rf /etc/nix $NIX_ROOT $ROOT_HOME/.nix-profile $ROOT_HOME/.nix-defexpr $ROOT_HOME/.nix-channels $HOME/.nix-profile $HOME/.nix-defexpr $HOME/.nix-channels
97
98and that is it.
99
100EOF
101
102}
103
104nix_user_for_core() {
105    printf "nixbld%d" "$1"
106}
107
108nix_uid_for_core() {
109    echo $((NIX_FIRST_BUILD_UID + $1 - 1))
110}
111
112_textout() {
113    echo -en "$1"
114    shift
115    if [ "$*" = "" ]; then
116        cat
117    else
118        echo "$@"
119    fi
120    echo -en "$ESC"
121}
122
123header() {
124    follow="---------------------------------------------------------"
125    header=$(echo "---- $* $follow$follow$follow" | head -c 80)
126    echo ""
127    _textout "$BLUE" "$header"
128}
129
130warningheader() {
131    follow="---------------------------------------------------------"
132    header=$(echo "---- $* $follow$follow$follow" | head -c 80)
133    echo ""
134    _textout "$RED" "$header"
135}
136
137subheader() {
138    echo ""
139    _textout "$BLUE_UL" "$*"
140}
141
142row() {
143    printf "$BOLD%s$ESC:\\t%s\\n" "$1" "$2"
144}
145
146task() {
147    echo ""
148    ok "~~> $1"
149}
150
151bold() {
152    echo "$BOLD$*$ESC"
153}
154
155ok() {
156    _textout "$GREEN" "$@"
157}
158
159warning() {
160    warningheader "warning!"
161    cat
162    echo ""
163}
164
165failure() {
166    header "oh no!"
167    _textout "$RED" "$@"
168    echo ""
169    _textout "$RED" "$(contactme)"
170    trap finish_cleanup EXIT
171    exit 1
172}
173
174ui_confirm() {
175    _textout "$GREEN$GREEN_UL" "$1"
176
177    if headless; then
178        echo "No TTY, assuming you would say yes :)"
179        return 0
180    fi
181
182    local prompt="[y/n] "
183    echo -n "$prompt"
184    while read -r y; do
185        if [ "$y" = "y" ]; then
186            echo ""
187            return 0
188        elif [ "$y" = "n" ]; then
189            echo ""
190            return 1
191        else
192            _textout "$RED" "Sorry, I didn't understand. I can only understand answers of y or n"
193            echo -n "$prompt"
194        fi
195    done
196    echo ""
197    return 1
198}
199
200__sudo() {
201    local expl="$1"
202    local cmd="$2"
203    shift
204    header "sudo execution"
205
206    echo "I am executing:"
207    echo ""
208    printf "    $ sudo %s\\n" "$cmd"
209    echo ""
210    echo "$expl"
211    echo ""
212
213    return 0
214}
215
216_sudo() {
217    local expl="$1"
218    shift
219    if ! headless; then
220        __sudo "$expl" "$*"
221    fi
222    sudo "$@"
223}
224
225
226readonly SCRATCH=$(mktemp -d -t tmp.XXXXXXXXXX)
227function finish_cleanup {
228    rm -rf "$SCRATCH"
229}
230
231function finish_fail {
232    finish_cleanup
233
234    failure <<EOF
235Jeeze, something went wrong. If you can take all the output and open
236an issue, we'd love to fix the problem so nobody else has this issue.
237
238:(
239EOF
240}
241trap finish_fail EXIT
242
243channel_update_failed=0
244function finish_success {
245    finish_cleanup
246
247    ok "Alright! We're done!"
248    if [ "x$channel_update_failed" = x1 ]; then
249        echo ""
250        echo "But fetching the nixpkgs channel failed. (Are you offline?)"
251        echo "To try again later, run \"sudo -i nix-channel --update nixpkgs\"."
252    fi
253    cat <<EOF
254
255Before Nix will work in your existing shells, you'll need to close
256them and open them again. Other than that, you should be ready to go.
257
258Try it! Open a new terminal, and type:
259
260  $ nix-shell -p nix-info --run "nix-info -m"
261
262Thank you for using this installer. If you have any feedback, don't
263hesitate:
264
265$(contactme)
266EOF
267}
268
269
270validate_starting_assumptions() {
271    poly_validate_assumptions
272
273    if [ $EUID -eq 0 ]; then
274        failure <<EOF
275Please do not run this script with root privileges. We will call sudo
276when we need to.
277EOF
278    fi
279
280    if type nix-env 2> /dev/null >&2; then
281        failure <<EOF
282Nix already appears to be installed, and this tool assumes it is
283_not_ yet installed.
284
285$(uninstall_directions)
286EOF
287    fi
288
289    if [ "${NIX_REMOTE:-}" != "" ]; then
290        failure <<EOF
291For some reason, \$NIX_REMOTE is set. It really should not be set
292before this installer runs, and it hints that Nix is currently
293installed. Please delete the old Nix installation and start again.
294
295Note: You might need to close your shell window and open a new shell
296to clear the variable.
297EOF
298    fi
299
300    if echo "${SSL_CERT_FILE:-}" | grep -qE "(nix/var/nix|nix-profile)"; then
301        failure <<EOF
302It looks like \$SSL_CERT_FILE is set to a path that used to be part of
303the old Nix installation. Please unset that variable and try again:
304
305  $ unset SSL_CERT_FILE
306
307EOF
308    fi
309
310    for file in ~/.bash_profile ~/.bash_login ~/.profile ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin; do
311        if [ -f "$file" ]; then
312            if grep -l "^[^#].*.nix-profile" "$file"; then
313                failure <<EOF
314I found a reference to a ".nix-profile" in $file.
315This has a high chance of breaking a new nix installation. It was most
316likely put there by a previous Nix installer.
317
318Please remove this reference and try running this again. You should
319also look for similar references in:
320
321 - ~/.bash_profile
322 - ~/.bash_login
323 - ~/.profile
324
325or other shell init files that you may have.
326
327$(uninstall_directions)
328EOF
329            fi
330        fi
331    done
332
333    if [ -d /nix/store ] || [ -d /nix/var ]; then
334        failure <<EOF
335There are some relics of a previous installation of Nix at /nix, and
336this scripts assumes Nix is _not_ yet installed. Please delete the old
337Nix installation and start again.
338
339$(uninstall_directions)
340EOF
341    fi
342
343    if [ -d /etc/nix ]; then
344        failure <<EOF
345There are some relics of a previous installation of Nix at /etc/nix, and
346this scripts assumes Nix is _not_ yet installed. Please delete the old
347Nix installation and start again.
348
349$(uninstall_directions)
350EOF
351    fi
352
353    for profile_target in "${PROFILE_TARGETS[@]}"; do
354        if [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then
355        failure <<EOF
356When this script runs, it backs up the current $profile_target to
357$profile_target$PROFILE_BACKUP_SUFFIX. This backup file already exists, though.
358
359Please follow these instructions to clean up the old backup file:
360
3611. Copy $profile_target and $profile_target$PROFILE_BACKUP_SUFFIX to another place, just
362in case.
363
3642. Take care to make sure that $profile_target$PROFILE_BACKUP_SUFFIX doesn't look like
365it has anything nix-related in it. If it does, something is probably
366quite wrong. Please open an issue or get in touch immediately.
367
3683. Take care to make sure that $profile_target doesn't look like it has
369anything nix-related in it. If it does, and $profile_target _did not_,
370run:
371
372  $ /usr/bin/sudo /bin/mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
373
374and try again.
375EOF
376        fi
377
378        if [ -e "$profile_target" ] && grep -qi "nix" "$profile_target"; then
379            failure <<EOF
380It looks like $profile_target already has some Nix configuration in
381there. There should be no reason to run this again. If you're having
382trouble, please open an issue.
383EOF
384        fi
385    done
386
387    danger_paths=("$ROOT_HOME/.nix-defexpr" "$ROOT_HOME/.nix-channels" "$ROOT_HOME/.nix-profile")
388    for danger_path in "${danger_paths[@]}"; do
389        if _sudo "making sure that $danger_path doesn't exist" \
390           test -e "$danger_path"; then
391            failure <<EOF
392I found a file at $danger_path, which is a relic of a previous
393installation. You must first delete this file before continuing.
394
395$(uninstall_directions)
396EOF
397        fi
398    done
399}
400
401setup_report() {
402    header "Nix config report"
403    row "        Temp Dir" "$SCRATCH"
404    row "        Nix Root" "$NIX_ROOT"
405    row "     Build Users" "$NIX_USER_COUNT"
406    row "  Build Group ID" "$NIX_BUILD_GROUP_ID"
407    row "Build Group Name" "$NIX_BUILD_GROUP_NAME"
408    if [ "${ALLOW_PREEXISTING_INSTALLATION:-}" != "" ]; then
409        row "Preexisting Install" "Allowed"
410    fi
411
412    subheader "build users:"
413
414    row "    Username" "UID"
415    for i in $(seq 1 "$NIX_USER_COUNT"); do
416        row "     $(nix_user_for_core "$i")" "$(nix_uid_for_core "$i")"
417    done
418    echo ""
419}
420
421create_build_group() {
422    local primary_group_id
423
424    task "Setting up the build group $NIX_BUILD_GROUP_NAME"
425    if ! poly_group_exists "$NIX_BUILD_GROUP_NAME"; then
426        poly_create_build_group
427        row "            Created" "Yes"
428    else
429        primary_group_id=$(poly_group_id_get "$NIX_BUILD_GROUP_NAME")
430        if [ "$primary_group_id" -ne "$NIX_BUILD_GROUP_ID" ]; then
431            failure <<EOF
432It seems the build group $NIX_BUILD_GROUP_NAME already exists, but
433with the UID $primary_group_id. This script can't really handle
434that right now, so I'm going to give up.
435
436You can fix this by editing this script and changing the
437NIX_BUILD_GROUP_ID variable near the top to from $NIX_BUILD_GROUP_ID
438to $primary_group_id and re-run.
439EOF
440        else
441            row "            Exists" "Yes"
442        fi
443    fi
444}
445
446create_build_user_for_core() {
447    local coreid
448    local username
449    local uid
450
451    coreid="$1"
452    username=$(nix_user_for_core "$coreid")
453    uid=$(nix_uid_for_core "$coreid")
454
455    task "Setting up the build user $username"
456
457    if ! poly_user_exists "$username"; then
458        poly_create_build_user "$username" "$uid" "$coreid"
459        row "           Created" "Yes"
460    else
461        actual_uid=$(poly_user_id_get "$username")
462        if [ "$actual_uid" != "$uid" ]; then
463            failure <<EOF
464It seems the build user $username already exists, but with the UID
465with the UID '$actual_uid'. This script can't really handle that right
466now, so I'm going to give up.
467
468If you already created the users and you know they start from
469$actual_uid and go up from there, you can edit this script and change
470NIX_FIRST_BUILD_UID near the top of the file to $actual_uid and try
471again.
472EOF
473        else
474            row "            Exists" "Yes"
475        fi
476    fi
477
478    if [ "$(poly_user_hidden_get "$username")" = "1" ]; then
479        row "            Hidden" "Yes"
480    else
481        poly_user_hidden_set "$username"
482        row "            Hidden" "Yes"
483    fi
484
485    if [ "$(poly_user_home_get "$username")" = "/var/empty" ]; then
486        row "    Home Directory" "/var/empty"
487    else
488        poly_user_home_set "$username" "/var/empty"
489        row "    Home Directory" "/var/empty"
490    fi
491
492    # We use grep instead of an equality check because it is difficult
493    # to extract _just_ the user's note, instead it is prefixed with
494    # some plist junk. This was causing the user note to always be set,
495    # even if there was no reason for it.
496    if ! poly_user_note_get "$username" | grep -q "Nix build user $coreid"; then
497        row "              Note" "Nix build user $coreid"
498    else
499        poly_user_note_set "$username" "Nix build user $coreid"
500        row "              Note" "Nix build user $coreid"
501    fi
502
503    if [ "$(poly_user_shell_get "$username")" = "/sbin/nologin" ]; then
504        row "   Logins Disabled" "Yes"
505    else
506        poly_user_shell_set "$username" "/sbin/nologin"
507        row "   Logins Disabled" "Yes"
508    fi
509
510    if poly_user_in_group_check "$username" "$NIX_BUILD_GROUP_NAME"; then
511        row "  Member of $NIX_BUILD_GROUP_NAME" "Yes"
512    else
513        poly_user_in_group_set "$username" "$NIX_BUILD_GROUP_NAME"
514        row "  Member of $NIX_BUILD_GROUP_NAME" "Yes"
515    fi
516
517    if [ "$(poly_user_primary_group_get "$username")" = "$NIX_BUILD_GROUP_ID" ]; then
518        row "    PrimaryGroupID" "$NIX_BUILD_GROUP_ID"
519    else
520        poly_user_primary_group_set "$username" "$NIX_BUILD_GROUP_ID"
521        row "    PrimaryGroupID" "$NIX_BUILD_GROUP_ID"
522    fi
523}
524
525create_build_users() {
526    for i in $(seq 1 "$NIX_USER_COUNT"); do
527        create_build_user_for_core "$i"
528    done
529}
530
531create_directories() {
532    # FIXME: remove all of this because it duplicates LocalStore::LocalStore().
533
534    _sudo "to make the basic directory structure of Nix (part 1)" \
535          mkdir -pv -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} /nix/var/nix/{gcroots,profiles}/per-user
536
537    _sudo "to make the basic directory structure of Nix (part 2)" \
538          mkdir -pv -m 1775 /nix/store
539
540    _sudo "to make the basic directory structure of Nix (part 3)" \
541          chgrp "$NIX_BUILD_GROUP_NAME" /nix/store
542
543    _sudo "to place the default nix daemon configuration (part 1)" \
544          mkdir -pv -m 0555 /etc/nix
545}
546
547place_channel_configuration() {
548    if [ -z "${NIX_INSTALLER_NO_CHANNEL_ADD:-}" ]; then
549        echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$SCRATCH/.nix-channels"
550        _sudo "to set up the default system channel (part 1)" \
551            install -m 0664 "$SCRATCH/.nix-channels" "$ROOT_HOME/.nix-channels"
552    fi
553}
554
555welcome_to_nix() {
556    ok "Welcome to the Multi-User Nix Installation"
557
558    cat <<EOF
559
560This installation tool will set up your computer with the Nix package
561manager. This will happen in a few stages:
562
5631. Make sure your computer doesn't already have Nix. If it does, I
564   will show you instructions on how to clean up your old one.
565
5662. Show you what we are going to install and where. Then we will ask
567   if you are ready to continue.
568
5693. Create the system users and groups that the Nix daemon uses to run
570   builds.
571
5724. Perform the basic installation of the Nix files daemon.
573
5745. Configure your shell to import special Nix Profile files, so you
575   can use Nix.
576
5776. Start the Nix daemon.
578
579EOF
580
581    if ui_confirm "Would you like to see a more detailed list of what we will do?"; then
582        cat <<EOF
583
584We will:
585
586 - make sure your computer doesn't already have Nix files
587   (if it does, I will tell you how to clean them up.)
588 - create local users (see the list above for the users we'll make)
589 - create a local group ($NIX_BUILD_GROUP_NAME)
590 - install Nix in to $NIX_ROOT
591 - create a configuration file in /etc/nix
592 - set up the "default profile" by creating some Nix-related files in
593   $ROOT_HOME
594EOF
595        for profile_target in "${PROFILE_TARGETS[@]}"; do
596            if [ -e "$profile_target" ]; then
597                cat <<EOF
598 - back up $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX
599 - update $profile_target to include some Nix configuration
600EOF
601            fi
602        done
603        poly_service_setup_note
604        if ! ui_confirm "Ready to continue?"; then
605            failure <<EOF
606Okay, maybe you would like to talk to the team.
607EOF
608        fi
609    fi
610}
611
612chat_about_sudo() {
613    header "let's talk about sudo"
614
615    if headless; then
616        cat <<EOF
617This script is going to call sudo a lot. Normally, it would show you
618exactly what commands it is running and why. However, the script is
619run in a headless fashion, like this:
620
621  $ curl -L https://nixos.org/nix/install | sh
622
623or maybe in a CI pipeline. Because of that, we're going to skip the
624verbose output in the interest of brevity.
625
626If you would like to
627see the output, try like this:
628
629  $ curl -L -o install-nix https://nixos.org/nix/install
630  $ sh ./install-nix
631
632EOF
633        return 0
634    fi
635
636    cat <<EOF
637This script is going to call sudo a lot. Every time we do, it'll
638output exactly what it'll do, and why.
639
640Just like this:
641EOF
642
643    __sudo "to demonstrate how our sudo prompts look" \
644           echo "this is a sudo prompt"
645
646    cat <<EOF
647
648This might look scary, but everything can be undone by running just a
649few commands. We used to ask you to confirm each time sudo ran, but it
650was too many times. Instead, I'll just ask you this one time:
651
652EOF
653    if ui_confirm "Can we use sudo?"; then
654        ok "Yay! Thanks! Let's get going!"
655    else
656        failure <<EOF
657That is okay, but we can't install.
658EOF
659    fi
660}
661
662install_from_extracted_nix() {
663    (
664        cd "$EXTRACTED_NIX_PATH"
665
666        _sudo "to copy the basic Nix files to the new store at $NIX_ROOT/store" \
667              rsync -rlpt --chmod=-w ./store/* "$NIX_ROOT/store/"
668
669        if [ -d "$NIX_INSTALLED_NIX" ]; then
670            echo "      Alright! We have our first nix at $NIX_INSTALLED_NIX"
671        else
672            failure <<EOF
673Something went wrong, and I didn't find Nix installed at
674$NIX_INSTALLED_NIX.
675EOF
676        fi
677
678        cat ./.reginfo \
679            | _sudo "to load data for the first time in to the Nix Database" \
680                   "$NIX_INSTALLED_NIX/bin/nix-store" --load-db
681
682        echo "      Just finished getting the nix database ready."
683    )
684}
685
686shell_source_lines() {
687    cat <<EOF
688
689# Nix
690if [ -e '$PROFILE_NIX_FILE' ]; then
691  . '$PROFILE_NIX_FILE'
692fi
693# End Nix
694
695EOF
696}
697
698configure_shell_profile() {
699    # If there is an /etc/profile.d directory, we want to ensure there
700    # is a nix.sh within it, so we can use the following loop to add
701    # the source lines to it. Note that I'm _not_ adding the source
702    # lines here, because we want to be using the regular machinery.
703    #
704    # If we go around that machinery, it becomes more complicated and
705    # adds complications to the uninstall instruction generator and
706    # old instruction sniffer as well.
707    if [ -d /etc/profile.d ]; then
708        _sudo "create a stub /etc/profile.d/nix.sh which will be updated" \
709              touch /etc/profile.d/nix.sh
710    fi
711
712    for profile_target in "${PROFILE_TARGETS[@]}"; do
713        if [ -e "$profile_target" ]; then
714            _sudo "to back up your current $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX" \
715                  cp "$profile_target" "$profile_target$PROFILE_BACKUP_SUFFIX"
716
717            shell_source_lines \
718                | _sudo "extend your $profile_target with nix-daemon settings" \
719                        tee -a "$profile_target"
720        fi
721    done
722}
723
724setup_default_profile() {
725    _sudo "to installing a bootstrapping Nix in to the default Profile" \
726          HOME="$ROOT_HOME" "$NIX_INSTALLED_NIX/bin/nix-env" -i "$NIX_INSTALLED_NIX"
727
728    if [ -z "${NIX_SSL_CERT_FILE:-}" ] || ! [ -f "${NIX_SSL_CERT_FILE:-}" ]; then
729        _sudo "to installing a bootstrapping SSL certificate just for Nix in to the default Profile" \
730              HOME="$ROOT_HOME" "$NIX_INSTALLED_NIX/bin/nix-env" -i "$NIX_INSTALLED_CACERT"
731        export NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt
732    fi
733
734    if [ -z "${NIX_INSTALLER_NO_CHANNEL_ADD:-}" ]; then
735        # Have to explicitly pass NIX_SSL_CERT_FILE as part of the sudo call,
736        # otherwise it will be lost in environments where sudo doesn't pass
737        # all the environment variables by default.
738        _sudo "to update the default channel in the default profile" \
739            HOME="$ROOT_HOME" NIX_SSL_CERT_FILE="$NIX_SSL_CERT_FILE" "$NIX_INSTALLED_NIX/bin/nix-channel" --update nixpkgs \
740            || channel_update_failed=1
741    fi
742}
743
744
745place_nix_configuration() {
746    cat <<EOF > "$SCRATCH/nix.conf"
747$NIX_EXTRA_CONF
748build-users-group = $NIX_BUILD_GROUP_NAME
749EOF
750    _sudo "to place the default nix daemon configuration (part 2)" \
751          install -m 0664 "$SCRATCH/nix.conf" /etc/nix/nix.conf
752}
753
754main() {
755    if [ "$(uname -s)" = "Darwin" ]; then
756        # shellcheck source=./install-darwin-multi-user.sh
757        . "$EXTRACTED_NIX_PATH/install-darwin-multi-user.sh"
758    elif [ "$(uname -s)" = "Linux" ]; then
759        if [ -e /run/systemd/system ]; then
760            # shellcheck source=./install-systemd-multi-user.sh
761            . "$EXTRACTED_NIX_PATH/install-systemd-multi-user.sh"
762        else
763            failure "Sorry, the multi-user installation requires systemd on Linux (detected using /run/systemd/system)"
764        fi
765    else
766        failure "Sorry, I don't know what to do on $(uname)"
767    fi
768
769    welcome_to_nix
770    chat_about_sudo
771
772    if [ "${ALLOW_PREEXISTING_INSTALLATION:-}" = "" ]; then
773        validate_starting_assumptions
774    fi
775
776    setup_report
777
778    if ! ui_confirm "Ready to continue?"; then
779        ok "Alright, no changes have been made :)"
780        contactme
781        trap finish_cleanup EXIT
782        exit 1
783    fi
784
785    create_build_group
786    create_build_users
787    create_directories
788    place_channel_configuration
789    install_from_extracted_nix
790
791    configure_shell_profile
792
793    set +eu
794    . /etc/profile
795    set -eu
796
797    setup_default_profile
798    place_nix_configuration
799    poly_configure_nix_daemon_service
800
801    trap finish_success EXIT
802}
803
804
805main
806