[bug#75810,v4,13/14] guix-install.sh: Support the unprivileged daemon where possible.
Commit Message
* etc/guix-install.sh (create_account): New function.
(sys_create_build_user): Use it. When ‘guix-daemon.service’ contains
“User=guix-daemon” only create the ‘guix-daemon’ user and group.
(sys_delete_build_user): Delete the ‘guix-daemon’ user and group.
(can_install_unprivileged_daemon): New function.
(sys_create_store): When installing the unprivileged daemon, change
ownership of /gnu and /var/guix, and create /var/log/guix.
(sys_authorize_build_farms): When the ‘guix-daemon’ account exists,
change ownership of /etc/guix.
Change-Id: I73e573f1cc5c0cb3794aaaa6b576616b66e0c5e9
---
etc/guix-install.sh | 106 ++++++++++++++++++++++++++++++++++----------
1 file changed, 82 insertions(+), 24 deletions(-)
@@ -414,6 +414,11 @@ sys_create_store()
cd "$tmp_path"
_msg_info "Installing /var/guix and /gnu..."
# Strip (skip) the leading ‘.’ component, which fails on read-only ‘/’.
+ #
+ # TODO: Eventually extract with ‘--owner=guix-daemon’ when installing
+ # and unprivileged guix-daemon service; for now, this script may install
+ # from both an old release that does not support unprivileged guix-daemon
+ # and a new release that does, so ‘chown -R’ later if needed.
tar --extract --strip-components=1 --file "$pkg" -C /
_msg_info "Linking the root user's profile"
@@ -441,38 +446,80 @@ sys_delete_store()
rm -rf ~root/.config/guix
}
+create_account()
+{
+ local user="$1"
+ local group="$2"
+ local supplementary_groups="$3"
+ local comment="$4"
+
+ if id "$user" &>/dev/null; then
+ _msg_info "user '$user' is already in the system, reset"
+ usermod -g "$group" -G "$supplementary_groups" \
+ -d /var/empty -s "$(which nologin)" \
+ -c "$comment" "$user"
+ else
+ useradd -g "$group" -G "$supplementary_groups" \
+ -d /var/empty -s "$(which nologin)" \
+ -c "$comment" --system "$user"
+ _msg_pass "user added <$user>"
+ fi
+}
+
+can_install_unprivileged_daemon()
+{ # Return true if we can install guix-daemon running without privileges.
+ [ "$INIT_SYS" = systemd ] && \
+ grep -q "User=guix-daemon" \
+ ~root/.config/guix/current/lib/systemd/system/guix-daemon.service \
+ && ([ ! -f /proc/sys/kernel/unprivileged_userns_clone ] \
+ || [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" -eq 1 ])
+}
+
sys_create_build_user()
{ # Create the group and user accounts for build users.
_debug "--- [ ${FUNCNAME[0]} ] ---"
- if getent group guixbuild > /dev/null; then
- _msg_info "group guixbuild exists"
- else
- groupadd --system guixbuild
- _msg_pass "group <guixbuild> created"
- fi
-
if getent group kvm > /dev/null; then
_msg_info "group kvm exists and build users will be added to it"
local KVMGROUP=,kvm
fi
- for i in $(seq -w 1 10); do
- if id "guixbuilder${i}" &>/dev/null; then
- _msg_info "user is already in the system, reset"
- usermod -g guixbuild -G guixbuild"$KVMGROUP" \
- -d /var/empty -s "$(which nologin)" \
- -c "Guix build user $i" \
- "guixbuilder${i}";
- else
- useradd -g guixbuild -G guixbuild"$KVMGROUP" \
- -d /var/empty -s "$(which nologin)" \
- -c "Guix build user $i" --system \
- "guixbuilder${i}";
- _msg_pass "user added <guixbuilder${i}>"
- fi
- done
+ if can_install_unprivileged_daemon
+ then
+ if getent group guix-daemon > /dev/null; then
+ _msg_info "group guix-daemon exists"
+ else
+ groupadd --system guix-daemon
+ _msg_pass "group guix-daemon created"
+ fi
+
+ create_account guix-daemon guix-daemon \
+ guix-daemon$KVMGROUP \
+ "Unprivileged Guix Daemon User"
+
+ # ‘tar xf’ creates root:root files. Change that.
+ chown -R guix-daemon:guix-daemon \
+ /gnu /var/guix
+
+ # The unprivileged cannot create the log directory by itself.
+ mkdir /var/log/guix
+ chown guix-daemon:guix-daemon /var/log/guix
+ chmod 755 /var/log/guix
+ else
+ if getent group guixbuild > /dev/null; then
+ _msg_info "group guixbuild exists"
+ else
+ groupadd --system guixbuild
+ _msg_pass "group <guixbuild> created"
+ fi
+
+ for i in $(seq -w 1 10); do
+ create_account "guixbuilder${i}" "guixbuild" \
+ "guixbuild${KVMGROUP}" \
+ "Guix build user $i"
+ done
+ fi
}
sys_delete_build_user()
@@ -487,6 +534,14 @@ sys_delete_build_user()
if getent group guixbuild &>/dev/null; then
groupdel -f guixbuild
fi
+
+ _msg_info "remove guix-daemon user"
+ if id guix-daemon &>/dev/null; then
+ userdel -f guix-daemon
+ fi
+ if getent group guix-daemon &>/dev/null; then
+ groupdel -f guix-daemon
+ fi
}
sys_enable_guix_daemon()
@@ -529,8 +584,7 @@ sys_enable_guix_daemon()
# Install after guix-daemon.service to avoid a harmless warning.
# systemd .mount units must be named after the target directory.
- # Here we assume a hard-coded name of /gnu/store.
- install_unit gnu-store.mount
+ install_unit gnu-store.mount
systemctl daemon-reload &&
systemctl start guix-daemon; } &&
@@ -654,6 +708,10 @@ project's build farms?"; then
&& guix archive --authorize < "$key" \
&& _msg_pass "Authorized public key for $host"
done
+ if id guix-daemon &>/dev/null; then
+ # /etc/guix/acl must be readable by the unprivileged guix-daemon.
+ chown -R guix-daemon:guix-daemon /etc/guix
+ fi
else
_msg_info "Skipped authorizing build farm public keys"
fi