Subject: Re: [bug#77882] [PATCH] scripts: home: Support extracting home-environment from Guix System declaration.

From: Maxim Cournoyer <[email-masked]>
Date: Mon, 21 Apr 2025 10:33:12 +0900

Hi,

Hilton Chain <[email-masked]> writes:

> * guix/scripts/home.scm (process-action): Handle operating-system declaration
> and extract home environment for current user.
> * doc/guix.texi (Guix Services)[Guix Home Service]: Document it.

The use case is a bit unclear for me, despite reading...

> Change-Id: I995f79c2549e6edc76322542d0422159e0b79996
> ---
>  doc/guix.texi         |  5 +++++
>  guix/scripts/home.scm | 31 +++++++++++++++++++++++++++----
>  2 files changed, 32 insertions(+), 4 deletions(-)
>
> diff --git a/doc/guix.texi b/doc/guix.texi
> index 070528667f..a58326debf 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -42255,6 +42255,11 @@ Guix Services
>  everything consistently at once, saving users the need to run
>  @command{guix home reconfigure} independently.
>  
> +@command{guix home} can operate on the home environment configured for
> +current user via this service, but its effect won't last beyond the next
> +system activation.  This can be used for quick testing and may avoid the
> +need of keeping a separate home configuration.

... this.

How do you declare a home environment in an `operating-system'
declaration?  Is this already supported?

Oh! 'guix-home-service-type'.  It seems I'm late in the news.  That's
cool!

>  @defvar guix-home-service-type
>  Service type for the Guix Home service.  Its value must be a list of
>  lists containing user and home environment pairs.  The key of each pair
> diff --git a/guix/scripts/home.scm b/guix/scripts/home.scm
> index b4c82d275f..6d0a68166e 100644
> --- a/guix/scripts/home.scm
> +++ b/guix/scripts/home.scm
> @@ -35,6 +35,8 @@ (define-module (guix scripts home)
>                                               shepherd-service-requirement)
>    #:autoload   (guix modules) (source-module-closure)
>    #:autoload   (gnu build linux-container) (call-with-container %namespaces)
> +  #:use-module ((gnu system) #:select (operating-system?
> +                                       operating-system-user-services))
>    #:autoload   (gnu system linux-container) (eval/container)
>    #:autoload   (gnu system file-systems) (file-system-mapping
>                                            file-system-mapping-source
> @@ -478,10 +480,31 @@ (define (process-action action args opts)
>  declaration as an argument (a file name.)  OPTS is the raw alist of options
>  resulting from command-line parsing."
>    (define (ensure-home-environment file-or-exp obj)
> -    (unless (home-environment? obj)
> -      (leave (G_ "'~a' does not return a home environment~%")
> -             file-or-exp))
> -    obj)
> +    (let* ((username
> +            (or (getenv "LOGNAME")
> +                (passwd:name (getpwuid (getuid)))))

First time I've heard of LOGNAME :-).  Typically I see 'USER' used in
its place; shouldn't that be consulted as well, or used instead?

As for the second clause of the above or, it can be simplified to just
'(getpwnam (getuid))'.

> +           (os-home-env-config
> +            (and (operating-system? obj)
> +                 (and=> (find (lambda (%service)
> +                                (eq? (service-type-name (service-kind %service))
> +                                     'guix-home))
> +                              (operating-system-user-services obj))
> +                        service-value)))
> +           (os-home-env
> +            (and os-home-env-config
> +                 (and=> (find (lambda (home-env-config)
> +                                (string=? (first home-env-config) username))
> +                              os-home-env-config)
> +                        second)))
> +           (home-env
> +            (or os-home-env obj)))
> +      (unless (home-environment? home-env)
> +        (if (operating-system? obj)
> +            (leave (G_ "'~a' does not contain a home environment for user '~a'~%")
> +                   file-or-exp username)
> +            (leave (G_ "'~a' does not return a home environment~%")
> +                   file-or-exp)))
> +      home-env))

LGTM.

Reviewed-by: Maxim Cournoyer <maxim.cournoyer@gmail>

-- 
Thanks,
Maxim