[bug#77288,v3,2/8] doc: Document migration to the unprivileged daemon.

Message ID e551a3a7145f24c44e2c764c78930722f32798b3.1745005408.git.ludo@gnu.org
State New
Headers
Series Rootless guix-daemon on Guix System |

Commit Message

Ludovic Courtès April 18, 2025, 7:46 p.m. UTC
  * doc/guix.texi (Build Environment Setup): Add “Migrating to the
Unprivileged Daemon” section.
(Upgrading Guix): Link to it.

Change-Id: I2bac3f4419d85b7c718c6c4a3908387b4f6ee582
---
 doc/guix.texi | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)
  

Comments

pelzflorian (Florian Pelz) April 19, 2025, 12:21 a.m. UTC | #1
Works great now.  I can now with v3 merrily switch back and forth the
(privileged? #f) on Guix System, except ownerships of /gnu/store/ files
are funny when I guix system roll-back to the time before guix-ownership
services existed.

Then I try the

     chown -R root:root                        \
       /gnu                                                  \
       /var/guix/{daemon-socket,db,discover}                 \
       /var/guix/{gcroots,offload,substitute,temproots}      \
       /var/log/guix                                         \
       /etc/guix

from this “Migrating to the Unprivileged Daemon” with root:root instead
of guix-daemon:guix-daemon.  But it does not work unless I mount -o
remount,rw /gnu/store (a command from the subsequent SELinux section).

While I have not tested this “Migrating to the Unprivileged Daemon”
section on a foreign distro, should not etc/gnu-store.mount require
remounting on foreign distros, too?

Regards,
Florian
  
Ludovic Courtès April 19, 2025, 9:07 a.m. UTC | #2
Hey Florian,

"pelzflorian (Florian Pelz)" <pelzflorian@pelzflorian.de> writes:

> Works great now.  I can now with v3 merrily switch back and forth the
> (privileged? #f) on Guix System,

Good, thanks for testing again!

> except ownerships of /gnu/store/ files are funny when I guix system
> roll-back to the time before guix-ownership services existed.

Uh, right.  There’s little we can do here, except perhaps adding a
warning in the doc?

> Then I try the
>
>      chown -R root:root                        \
>        /gnu                                                  \
>        /var/guix/{daemon-socket,db,discover}                 \
>        /var/guix/{gcroots,offload,substitute,temproots}      \
>        /var/log/guix                                         \
>        /etc/guix
>
> from this “Migrating to the Unprivileged Daemon” with root:root instead
> of guix-daemon:guix-daemon.  But it does not work unless I mount -o
> remount,rw /gnu/store (a command from the subsequent SELinux section).
>
> While I have not tested this “Migrating to the Unprivileged Daemon”
> section on a foreign distro, should not etc/gnu-store.mount require
> remounting on foreign distros, too?

Users are invited to stop the daemon before doing that, which should
stop ‘gnu-store.mount’ as well.  Do you think that needs to be
clarified?

Thanks,
Ludo’.
  
pelzflorian (Florian Pelz) April 19, 2025, 8:22 p.m. UTC | #3
Ludovic Courtès <ludo@gnu.org> writes:
>> except ownerships of /gnu/store/ files are funny when I guix system
>> roll-back to the time before guix-ownership services existed.
>
> Uh, right.  There’s little we can do here, except perhaps adding a
> warning in the doc?

No, I was just trying to provoke an error.  No warning in the doc is
needed.  Because (privileged #t) remains the default for some time and
guix-ownership already exists, wrong ownership will not affect many
users when they do not provoke it.  Also files owned by a user id, group
id that no longer exists can happen on system roll-backs.  And it can
obviously be fixed by following the “Migrating to the Unprivileged
Daemon” docs with root:root.

What I should have written to you is that I want the command

mount -o remount,rw /gnu/store

to come before the chown for the migrating foreign distro users.

> Users are invited to stop the daemon before doing that, which should
> stop ‘gnu-store.mount’ as well.[…]

No.  I set up a Debian VM now with Guix from the install script and guix
pulled as root with this patch series.  “systemctl stop guix-daemon”
does not change the mount command outputting:

“/dev/sda1 on /gnu/store type ext4 (ro,relatime,errors=remount-ro)”,

And the chown from “Migrating to the Unprivileged Daemon” prints lines
like:

chown: changing ownership of '/gnu/store/4ab…-mpfr-4.2.1-builder':
Read-only file system

Above mount command from the examples in Guix manual section on SELinux
Policy makes chown work.


I would just write down the “mount -o remount,rw /gnu/store” command,
even though it is not needed when a user is not on systemd or has not
set up gnu-store.mount.


Another observation; I get errors
guix shell: error: opening global GC lock '/var/guix/gc.lock':
Permission denied

I had to chown guix-daemon:guix-daemon /var/guix/gc.lock as well.

Other than that your docs work well for me.  Thanks again!

Regards,
Florian
  
Ludovic Courtès April 20, 2025, 4:52 p.m. UTC | #4
Hi Florian,

"pelzflorian (Florian Pelz)" <pelzflorian@pelzflorian.de> writes:

> No, I was just trying to provoke an error.  No warning in the doc is
> needed.  Because (privileged #t) remains the default for some time and
> guix-ownership already exists, wrong ownership will not affect many
> users when they do not provoke it.  Also files owned by a user id, group
> id that no longer exists can happen on system roll-backs.  And it can
> obviously be fixed by following the “Migrating to the Unprivileged
> Daemon” docs with root:root.

Right.

> What I should have written to you is that I want the command
>
> mount -o remount,rw /gnu/store
>
> to come before the chown for the migrating foreign distro users.

Indeed.  I’ve now added it.

> Another observation; I get errors
> guix shell: error: opening global GC lock '/var/guix/gc.lock':
> Permission denied
>
> I had to chown guix-daemon:guix-daemon /var/guix/gc.lock as well.

Oh right, added as well.

Thanks a lot for testing all this and suggesting fixes!

Ludo’.
  

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index 070528667f..377cb65326 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -1026,13 +1026,75 @@  Build Environment Setup
 In this configuration, @file{/gnu/store} is owned by the
 @code{guix-daemon} user.
 
+@anchor{unprivileged-daemon-migration}
+@unnumberedsubsubsec Migrating to the Unprivileged Daemon
+
+@cindex unprivileged daemon, migration
+@cindex rootless daemon, migration
+To switch an existing installation to the unprivileged execution mode, a
+number of steps must be taken: creating a new dedicated
+@code{guix-daemon} user account, changing ownership of the relevant
+files to @code{guix-daemon}, and ensuring that the @command{guix-daemon}
+program runs as @code{guix-daemon}.
+
+@quotation Warning
+Follow the instructions below only after making sure you have a recent
+version of @command{guix-daemon} with support for unprivileged
+execution.
+@end quotation
+
+File ownership can be changed, after stopping the daemon, by running the
+following commands as root (the @command{chown} can take a while if
+there are many files in @file{/gnu/store}):
+
+@example
+groupadd --system guix-daemon
+useradd -g guix-daemon -G guix-daemon,kvm               \
+        -d /var/empty -s $(which nologin)               \
+        -c "Guix daemon privilege separation user"      \
+        --system guix-daemon
+
+chown -R guix-daemon:guix-daemon                        \
+  /gnu                                                  \
+  /var/guix/@{daemon-socket,db,discover@}                 \
+  /var/guix/@{gcroots,offload,substitute,temproots@}      \
+  /var/log/guix                                         \
+  /etc/guix
+@end example
+
+If your system uses the systemd service manager, running the daemon as
+@code{guix-daemon} will be a matter of copying the relevant
+configuration files---make sure to review any changes you might have
+made in your own @file{.service} files before overwriting them:
+
+@example
+cp /var/guix/profiles/per-user/root/current-guix/lib/systemd/system/*.service \
+   /etc/systemd/system
+systemctl daemon-reload
+systemctl start guix-daemon
+@end example
+
+@quotation Warning
+The commands above assume that @command{guix pull} was run for the root
+user.  You can check whether this is the case by running this command:
+
+@example
+grep User=guix-daemon \
+  /var/guix/profiles/per-user/root/current-guix/lib/systemd/system/guix-daemon.service
+@end example
+
+If that command does not show the @code{User=guix-daemon} line, then run
+@command{guix pull} as the root user.
+@end quotation
+
 @unnumberedsubsubsec The Isolated Build Environment
 
 @cindex chroot
 @cindex build environment isolation
 @cindex isolated build environment
 @cindex hermetic build environment
-In both cases, the daemon starts build processes without privileges in
+In both cases, privileged and unprivileged,
+the daemon starts build processes without privileges in
 an @emph{isolated} or @emph{hermetic} build environment---a ``chroot''.
 On GNU/Linux, by default, the build environment contains nothing but:
 
@@ -2035,6 +2097,10 @@  Upgrading Guix
 On Guix System, upgrading the daemon is achieved by reconfiguring the
 system (@pxref{Invoking guix system, @code{guix system reconfigure}}).
 
+To migrate an existing installation to the @emph{unprivileged daemon}
+where @command{guix-daemon} does not run as root,
+@pxref{unprivileged-daemon-migration}.
+
 @c TODO What else?
 
 @c *********************************************************************