Quiliro Ordonez Baca <quil...@riseup.net> writes: > Very nice thread: very descriptive and enlighting. Thank you. > > I have just one question: In GuixSD, the root user needs updating for the > Guix-daemon to update as you say is needed on a foreign distro?
Basically, yes, on a foreign distro, the reason you should run "guix pull" and "guix package -u ." as root is to ensure that guix-daemon is up-to-date. This assumes that the "guix" package (which provides the guix-daemon executable) is installed in the root user's profile, and that you have configured your system so that at boot, it automatically starts the guix-daemon that is installed in root's profile (info '(guix) Binary Installation'). The truth is, it's a little complicated. With the current implementation, the behavior can be influenced through environment variables, so the exact answer to the question of "What should I do?" depends on how your system is configured and on how you invoke the "guix" program.I've just spent some time refreshing myself on how this works, so I'll take a few minutes to try to clarify the behavior. Let's take a look at the "guix" launcher script to see what happens when we invoke a command like "guix package -i" or "guix pull". If you look at the guix launcher script [1], you'll find that it invokes the following procedure: (define (maybe-augment-load-paths!) (unless (getenv "GUIX_UNINSTALLED") (let ((module-dir (config-lookup "guilemoduledir")) (object-dir (config-lookup "guileobjectdir"))) (push! module-dir %load-path) (push! object-dir %load-compiled-path)) (let ((updates-dir (and=> (or (getenv "XDG_CONFIG_HOME") (and=> (getenv "HOME") (cut string-append <> "/.config"))) (cut string-append <> "/guix/latest")))) (when (and updates-dir (file-exists? updates-dir)) ;; XXX: Currently 'guix pull' puts both .scm and .go files in ;; UPDATES-DIR. (push! updates-dir %load-path) (push! updates-dir %load-compiled-path))))) This procedure modifies the Guile load paths (info '(guile) Load Paths'), which is the mechanism by which Guile finds modules to use. Specifically, if XDG_CONFIG_HOME is set, the procedure adds $XDG_CONFIG_HOME/guix/latest to the front of the load paths; if XDG_CONFIG_HOME is not set, but HOME is set, then the procedure adds $HOME/.config/guix/latest to the front of the load paths; if neither XDG_CONFIG_HOME nor HOME are set (or if one of them was set, but it points to a non-existent file), then the procedure takes no action. After the launcher script (maybe) augments the load paths, it invokes the following procedure: (define (run-guix-main) (let ((guix-main (module-ref (resolve-interface '(guix ui)) 'guix-main))) (bindtextdomain "guix" (config-lookup "localedir")) (bindtextdomain "guix-packages" (config-lookup "localedir")) (apply guix-main (command-line)))) Note that it uses the procedure resolve-interface to find the module named (guix ui). Because the program previously added a directory such as $HOME/.config/guix/latest to front of the load paths, that is where Guile will find the (guix ui) module [2]. Within (guix ui), we use similar tricks to run the requested command. What is the point of doing it this way? Well, consider what happens when a user alice runs "guix package -i hello". In a normal setup, the "guix" command that alice invokes does not reside in Alice's profile; it resides elsewhere (run "which guix" to see where!). On GuixSD, this is normally /run/current-system/profile/bin/guix, and on a foreign distro, this might be /usr/local/bin/guix (a symlink to /var/guix/profiles/per-user/root/guix-profile/bin/guix). As described above, this "guix" command is a very thin shim; its sole purpose is to find the (guix ui) module and run the guix-main procedure defined there. Let's assume that alice runs "guix package -i hello" in an environment in which XDG_CONFIG_HOME is unset, but HOME is set to /home/alice. This is a common configuration, and it's the one I have on both my GuixSD system and on my Ubuntu system. Now, when alice runs "guix package -i hello" in this environment, the "guix" executable will wind up finding (guix ui) under /home/alice/.config/guix/latest. Because the "guix" executable is simply a thin shim as described above, it will find (guix ui) in that location regardless of where the "guix" executable happens to reside. Likewise, the guix-main procedure defined in (guix ui) will search for the (guix scripts package) module, it will also find it under /home/alice/.config/guix/latest, and it will delegate control to the guix-package procedure defined there [3]. As a result, even though alice's invocation of "guix package -i hello" might start by invoking a "guix" launcher script that resides outside of her home directory (e.g., at /usr/local/bin/guix), all of the code which defines the business logic of the "guix package" command will come from /home/alice/.config/guix/latest. When I say "all of the code which defines the business logic of the "guix package" command, I mean everything in (guix ui), (guix scripts package), all of the package definitions in modules with names like (gnu packages *), and all of the supporting Guix code that these Guile modules might use (e.g., (guix monads)). If a different user bob runs the same "guix package -i hello" command using the same "guix" executable as alice, then (assuming that in bob's environment, XDG_CONFIG_HOME is unset, and HOME is set to /home/bob) all the code which defines the business logic will come from /home/bob/.config/guix/latest. In this way, alice and bob have two independent installations of Guix, including the package definitions. When alice runs "guix package -i hello", she'll use her package definition for GNU Hello, and when bob runs it, he'll use his. "guix pull" is just another example of this. When alice runs "guix pull," it will ultimately run code from the (guix scripts pull) module defined in /home/alice/.config/guix/latest/guix/scripts/pull.scm. The code for (guix scripts pull) is currently designed to deploy the latest version of Guix (which contains all the modules, including the various scripts and the package definitions) to /home/alice/.config/guix/latest. It does this by downloading a more recent version, compiling it, and then flipping the /home/alice/.config/guix/latest symlink to point to the newly built version. Once this is complete, every command that alice runs, like "guix package -i hello", will use the new code (and new package definitions) that have been installed to /home/alice/.config/guix/latest. However, if bob runs the same command, he will continue to use whatever version of the code (and package definitions) that he was using before; it will not change for bob until bob runs "guix pull" himself. The root user is no different. Assuming a normal setup, the root user has a deployment of Guix under /root/.config/guix/latest, which can only be updated by running "guix pull" as root. Because the delegation mechanism described above relies on indirection via environment variables, it's possible that if you configure your system differently, things might behave differently. For example, on my Ubuntu machine, by default sudo is configured so that it will not change the HOME environment variable. As a result, if a user named alice runs "sudo guix pull" on my Ubuntu machine, it will cause /home/alice/.config/guix/latest to become a symlink owned by root, which is not what I intended. For this reason, on my Ubuntu machine I always run "sudo -H guix pull" instead of "sudo guix pull" when I want to update root's Guix installation (this causes sudo to set the HOME environment variable to /root; see 'man 8 sudo' for details). On GuixSD, this same problem does not occur (because sudo is already configured to set HOME to /root). In any case, you should test on your own system and figure out what environment variables are set in various situations. You can find out easily by running commands like "env" and "sudo env". On GuixSD, the guix-daemon is usually deployed at the system level (the guix-service-type implicitly installs the guix package to the system profile [4]). Therefore, on GuixSD, you upgrade the guix-daemon like you would upgrade any other part of the overall system: by running "guix system reconfigure" as root. On a foreign distro, the guix-daemon is usually deployed in root's profile. Therefore, on a foreign distro, you upgrade the guix-daemon like you would upgrade any other package in root's profile: by running "guix package -u ." as root. Regardless of whether you use GuixSD or a foreign distro, when you run a "guix" command as root, it will usually use whatever script implementations and package definitions are present in root's deployment of Guix, so before you run those commands as root, you should first run "guix pull" as root to ensure that you're using the latest and greatest. Note that in the future, the behavior of "guix pull" is likely to change [5]. I hope my attempt to explain things has helped to clarify how it works today and how it enables multiple users to have independent installations of Guix (including package definitions). I hope it helps you understand when you should run what commands. If anything is unclear, just remember that you can always look into the source code (it's free software, after all!), and the people on the email list or IRC are usually very helpful. Footnotes: [1] https://git.savannah.gnu.org/cgit/guix.git/tree/scripts/guix.in [2] https://git.savannah.gnu.org/cgit/guix.git/tree/guix/ui.scm [3] https://git.savannah.gnu.org/cgit/guix.git/tree/guix/scripts/package.scm [4] https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/services/base.scm [5] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22629 -- Chris
signature.asc
Description: PGP signature