summarylogtreecommitdiffstats
path: root/nix-multiuser.install
blob: 40ccbd4ec176fea0dc9ca006fac331276bad4024 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
function install_nix_sandbox() {
  version=$(echo $1 | sed 's/-.*$//')
  mkdir -p /nix/var/nix/profiles/arch-system
  NIX_REMOTE="" nix-build \
    --option build-use-sandbox false \
    -o /nix/var/nix/profiles/arch-system/build-sandbox \
    -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/$version.tar.gz \
    -E 'with import <nixpkgs> {}; buildEnv { name = "arch-system-build-sandbox"; paths = [ bash bzip2 coreutils gnutar gzip perl xz ]; }'
}

function nix_sandbox_path() {
  readlink -f "/nix/var/nix/profiles/arch-system/build-sandbox/bin/$1"
}

function nix_sandbox_paths() {
  echo "build-sandbox-paths = \
    /bin/sh=$(nix_sandbox_path bash) \
    /usr/bin/bash=$(nix_sandbox_path bash) \
    /usr/bin/bzip2=$(nix_sandbox_path bzip2) \
    /usr/bin/env=$(nix_sandbox_path env) \
    /usr/bin/gzip=$(nix_sandbox_path gzip) \
    /usr/bin/mkdir=$(nix_sandbox_path mkdir) \
    /usr/bin/mv=$(nix_sandbox_path mv) \
    /usr/bin/perl=$(nix_sandbox_path perl) \
    /usr/bin/tar=$(nix_sandbox_path tar) \
    /usr/bin/tr=$(nix_sandbox_path tr) \
    /usr/bin/xz=$(nix_sandbox_path xz)"
}

# Append the sandbox paths line either into the pacnew file, or the original.
function append_nix_sandbox_paths() {
  for conf_file in etc/nix/nix.conf{.pacnew,}; do
    if [ -f $conf_file ]; then
      # Delete existing auto-generated block
      sed -i '/^# Auto-generated by nix-multiuser/,/^# End of auto-generated content/ d' $conf_file

      echo '# Auto-generated by nix-multiuser' >> $conf_file
      echo '# If you edit this section, it will be overwritten on updating that package' >> $conf_file
      nix_sandbox_paths >> $conf_file
      echo "# End of auto-generated content" >> $conf_file

      break
    fi
  done
}

pre_install () {
  # Check that the group and users don't already exist
  if [[ -n $(cut -d: -f1 /etc/group | grep -w nixbld) ]]; then
    echo "The nixbld group already exists.  This install cannot proceed."
    exit 1
  fi

  for i in {1..10}; do
    if [[ -n $(cut -d: -f1 /etc/passwd | grep -w nixbld$i) ]]; then
      echo "The nixbld$i user already exists.  This install cannot proceed."
      exit 1
    fi
  done

  # Create a symlink for the utils that are needed inside the build sandbox
  install_nix_sandbox $1 || exit 1
}

create_users () {
  # Create a nixbld group.
  groupadd -r nixbld

  # Create 10 nixbld{i} users
  for i in {1..10}; do
    useradd -g nixbld -G nixbld -r -N -M -d /var/empty -s /sbin/nologin nixbld$i
  done
}

delete_users() {
  # Remove the users
  for i in {1..10}; do
    userdel nixbld$i
  done

  # Remove the group
  groupdel nixbld
}

create_store() {
  # Create nix folders and set permissions
  mkdir -p /nix/store
  chown root.nixbld /nix/store
  chmod 1775 /nix/store
  mkdir -p -m 1777 /nix/var/nix/gcroots/per-user
  mkdir -p -m 1777 /nix/var/nix/profiles/per-user
}

restore_store() {
  # Restore folder permissions
  chmod 755 /nix/store
  chown root.root /nix/store
}

daemon_info() {
  # Tell the user to update the config file and start the daemon
  echo "To start the nix daemon, execute one of the following:"
  echo
  echo "    systemctl enable nix-daemon.socket       # Sets the daemon to start on next boot"
  echo "    systemctl enable --now nix-daemon.socket # Starts now and on next boot too"
  echo
  echo "Also, if this is a new install, you need to start a new login shell or otherwise"
  echo "source /etc/profile.d/nix-multiuser.sh"
  echo
  echo "Once your environment is set-up, you will need to add some channels.  You can see how"
  echo "to do that here:"
  echo "  http://nixos.org/nixos/manual/index.html#sec-upgrading"
}

post_install() {
  create_users
  create_store
  append_nix_sandbox_paths
  daemon_info
}

pre_upgrade() {
  systemctl stop nix-daemon.socket
  systemctl stop nix-daemon

  install_nix_sandbox $1 || exit 1
}

post_upgrade() {
  delete_users
  create_users
  create_store
  append_nix_sandbox_paths
  daemon_info
}

pre_remove() {
  restore_store
  delete_users
}

post_remove() {
  echo "If you are still using Nix, but without multiuser mode, you will need to do some clean-up:"
  echo
  echo " - remove the 'build-users-group = nixbld' from /etc/nix/nix.conf"
  echo " - Stop/disable the nix-daemon.socket systemd unit"
}