diff mbox series

[bug#35305] LightDM service

Message ID 87sghcir5k.fsf@lprndn.info
State Superseded
Headers show
Series [bug#35305] LightDM service | expand

Checks

Context Check Description
cbaines/comparison success View comparision
cbaines/git branch success View Git branch
cbaines/applying patch fail View Laminar job

Commit Message

L p R n d n April 9, 2020, 4:02 p.m. UTC
Hello,

Brice Waegeneire <brice@waegenei.re> writes:

> Hello L p R n d n,
>
> I never did a review before but I would like to see this patch merged, so
> bear with me.

Thank you for the review! It's my first service for guix so we're
probably even here. ;)

> The indentation of lightdm's origin should probably be done in the commit
> 01 not 03.

Done.

>> `("XDG_DATA_DIRS" ":" prefix (,(string-append (assoc-ref inputs
>> "hicolor-icon-theme")
>>                                               "/share")
>>                               ,(string-append (assoc-ref inputs "glib")
>>                                               "/share")
>>                               ,(string-append (assoc-ref inputs
>> "shared-mime-info")
>>                                               "/share")
>>                               ,(string-append (assoc-ref inputs "gtk+")
>>                                               "/share")
>>                               ,(string-append (assoc-ref inputs "exo")
>>                                               "/share")
>>                               ,(string-append (assoc-ref outputs "out")
>>                                               "/share")
>>                               "/run/current-system/profile/share"))
> This part can use a map procedure.

Done. + cleaned some things that weren't necessary.

> It would be nice if “lightdm-service-type” support “set-xorg-configuration”
> like the other login manager now does by using “handle-xorg-configuration”
> see 50be0da7bfd5c108697679effeb2a893d2f37598 for how it's done in GDM, SLIM
> and co.
>
>> +         (comment "LighDM user")
>                           ^ a “t” is missing here

Huh.. Done (I think...) and done!

>> +(define (lightdm-shepherd-service config)
>> +  "Return a <lightdm-service> for LightDM with CONFIG."
>> +
>> +  (define lightdm-command
>> +    #~(list (string-append #$(lightdm-configuration-lightdm config)
>> "/sbin/lightdm")))
> […]
>> + (fork+exec-command
>> + (list #$(file-append
>> + (lightdm-configuration-lightdm config)
>> + "/sbin/lightdm"))
>
> “lightdm-command” isn't used, I get the hint it ought to be the argument of
> “fork+exec-command.”

Done.

>
>> +(define (lightdm-etc-service config)
>> +  (list `("xdg/lightdm/lightdm.conf.d/lightdm.conf"
>> +          ,(lightdm-configuration-file config))
>> +        `(,(string-append "xdg/lightdm/"
>> +                          (computed-file-name
>> +                           (lightdm-configuration-greeter-configuration
>> config)))
>> +          ,(lightdm-configuration-greeter-configuration config))))
>
> I've been told, in Guix, it's better to avoid putting configuration in
> “/etc” since it cause edge case during rollback and such, specifying the
> configuration by passing the “--config” argument to “lightdm” would be more
> appropriate.

Need some advices here as even if "--config" works for LightDM, greeters
also search their config in /etc. They're all different so they might or
might not provide a convenient way to do it... :/
In the meantime, kept the etc-service-extension + prevented errors in
case a file wasn't provided.

>> +        (define %user
>> +          (getpw "lightdm"))
>> +        (let ((directory "/var/lib/lightdm-data"))
>> +          (mkdir-p directory)
>> +          (chown directory (passwd:uid %user) (passwd:gid %user))))))
>
> “%user” could go in the “let”. BTW can't lightdm use its user home
> directory instead of “/var/lib/lightdm-data” or the reverse; IOW does it
> need to have to own two directories in “/var/lib”?

Reworked everything a little bit to match what is done for gdm.
I think we can use a CFLAG to change "/var/lib/lightdm-data" to
"/var/lib/lightdm/lightdm-data" for example. However, I think lightdm
sometime cleans or delete stuff in "/var/lib/lightdm" so it might
explain why there are two directories. I don't know what
"/var/lib/lightdm-data" is used for but LightDM does complain if it
doesn't exist. Advices needed here too.

> Several lines in “gnu/services/lightdm.scm” exceed the maximal line length.
>

Tried to keep them below 80. Is it ok?

>
> Thank you very much for this patch series. I'm impatient seeing it in Guix
> proper.
>
> - Brice


+ Corrected some typos in the documentation and added an extra-config
field to lightd and lightdm-gtk-greeter's configuration.

Hope it's better now, new patches are attached below.

Have a nice day,

L  p R n  d n

Comments

Brice Waegeneire April 12, 2020, 9:53 a.m. UTC | #1
Hello L p R n d n,

Using `set-xorg-configuration` with `lightdm-service-type` seems to be
working.

There is an error on vt1 at startup about some dbus stuff related to
“accountservice”. The cursor theme isn't set as well as the icon theme, 
it
seems; it may come from some missing environment variable as NixOS set a
few of them in their service[0].

After digging in the new service file I keep wondering if it's the right
way to go about implementing it. I tried to set a simple setting
for `lightdm-gtk-greeter` and I ended up with the following which 
doesn't
look intuitive:

--8<---------------cut here---------------start------------->8---
(service lightdm-service-type
          (lightdm-configuration
           (greeter-configuration-file
            (lightdm-gtk-greeter-configuration-file
             (lightdm-gtk-greeter-configuration
              (extra-config "hide-user-image=true"))))))
--8<---------------cut here---------------end--------------->8---

Furthermore `lightdm-service-type` only set a single seat while lightdm 
can
have many of them. So maybe there should be a lightdm-seat` record used 
as
a list of seats in `lightdm-service-type`. Each greater will be able to
expand `lightdm-service-type` by appending a seat to it. Then the
configuration could look like this:

--8<---------------cut here---------------start------------->8---
(service lightdm-service-type)
(service lightdm-gtk-greeter-service-type
          (lightdm-gtk-greeter-configuration
           (assets (list guix-artwork))
           (theme-name "Guix")
           (extra-config "hide-user-image=true")))
--8<---------------cut here---------------end--------------->8---

Using this approch would also avoid populating “/etc”, at least for
`lightdm-grk-greeter`, since each greeter would be defined as a service 
and
could expand “/etc” if it really needs it. For `lightdm-gtk-greeter`
specifically avoiding putting config in “/etc/” can be done by compiling 
it
with `-DCONFIG_FILE` pointing to `/run/current-system` And `lightdm` can 
be
started with `--config`.

Here is an example in how to make a conjuration file procedure more
readable while keeping under the line length limit by using 
`match-record`:

--8<---------------cut here---------------start------------->8---
(define (lightdm-gtk-greeter-configuration-file config)
   (match-record config <lightdm-gtk-greeter-configuration>
     (theme-name icon-theme-name cursor-theme-name cursor-size background
                 extra-config)
    (mixed-text-file "lightdm-gtk-greeter.conf" "
[greeter]
theme-name = "           theme-name                   "
icon-theme-name = "      icon-theme-name              "
cursor-theme-name = "    cursor-theme-name            "
cursor-theme-size = "    (number->string cursor-size) "
background = "           background                   "
" extra-config                                        "
")))
--8<---------------cut here---------------end--------------->8---

BTW the default background could use one from Guix artwork repo like
“(file-append %artwork-repository "/grub/GuixSD-fully-black-16-9.svg")”.

WDYT? I may be completely off on the `lightdm-seat` part.

[0]: 
https://github.com/NixOS/nixpkgs/blob/release-19.09/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix#L18

Cheers,
- Brice
L p R n d n April 14, 2020, 9:38 a.m. UTC | #2
Hello,

Thanks again for the feedbacks.

Brice Waegeneire <brice@waegenei.re> writes:

[...]
> There is an error on vt1 at startup about some dbus stuff related to
> “accountservice”. The cursor theme isn't set as well as the icon theme, 
> it
> seems; it may come from some missing environment variable as NixOS set a
> few of them in their service[0].

For the cursor, setting "XCURSOR_PATH" seems to solve the problem.
Preparing a patch.

As for dbus, from what I found at NixOS[0][1], it's a accountsservice
bug. I'll send a bug report. In the meantime, it doesn't appear to
affect LightDM too much so it might be ok...?

> After digging in the new service file I keep wondering if it's the right
> way to go about implementing it. I tried to set a simple setting
> for `lightdm-gtk-greeter` and I ended up with the following which 
> doesn't
> look intuitive:
>
> (service lightdm-service-type
>           (lightdm-configuration
>            (greeter-configuration-file
>             (lightdm-gtk-greeter-configuration-file
>              (lightdm-gtk-greeter-configuration
>               (extra-config "hide-user-image=true"))))))

Yeah, far from elegant. Did it that way in case someone wanted to
provide its own file but dropping
lightdm-gtk-greeter-configuration-file gives one level less of nesting.

> Furthermore `lightdm-service-type` only set a single seat while lightdm 
> can
> have many of them. So maybe there should be a lightdm-seat` record used 
> as
> a list of seats in `lightdm-service-type`. Each greater will be able to
> expand `lightdm-service-type` by appending a seat to it. Then the
> configuration could look like this:
>
> (service lightdm-service-type)
> (service lightdm-gtk-greeter-service-type
>           (lightdm-gtk-greeter-configuration
>            (assets (list guix-artwork))
>            (theme-name "Guix")
>            (extra-config "hide-user-image=true")))

I didn't know one could use a different greeter for each seat. Indeed,
it would be nice to have that feature!
The only thing that bothers me is that you don't get a working
default LightDM service by default. I feel that just adding (service
lightdm-service-type) to your configuration should get you a fully
working LightDM, specially for newcomers. Here one would lack a greeter.
:/

I believe there is a solution that would give us the best of both
worlds. If someone has a clue, an idea or even a patch, please share it!
:)

Also, merging as is and improving the service later is possible too.

>
> Using this approch would also avoid populating “/etc”, at least for
> `lightdm-grk-greeter`, since each greeter would be defined as a service 
> and
> could expand “/etc” if it really needs it. For `lightdm-gtk-greeter`
> specifically avoiding putting config in “/etc/” can be done by compiling 
> it
> with `-DCONFIG_FILE` pointing to `/run/current-system` And `lightdm` can 
> be
> started with `--config`.

I will make a patch to use --config for lightdm.
For lightdm-gtk-greeter, how would one put the config file in
"/run/current-system"? Do we need to make a package out of it?

> Here is an example in how to make a conjuration file procedure more
> readable while keeping under the line length limit by using 
> `match-record`:
>
> (define (lightdm-gtk-greeter-configuration-file config)
>    (match-record config <lightdm-gtk-greeter-configuration>
>      (theme-name icon-theme-name cursor-theme-name cursor-size background
>                  extra-config)
>     (mixed-text-file "lightdm-gtk-greeter.conf" "
> [greeter]
> theme-name = "           theme-name                   "
> icon-theme-name = "      icon-theme-name              "
> cursor-theme-name = "    cursor-theme-name            "
> cursor-theme-size = "    (number->string cursor-size) "
> background = "           background                   "
> " extra-config                                        "
> ")))

Way better! Preparing a patch for that.

> BTW the default background could use one from Guix artwork repo like
> “(file-append %artwork-repository "/grub/GuixSD-fully-black-16-9.svg")”.

Yeap!

> WDYT? I may be completely off on the `lightdm-seat` part.
>
> [0]: 
> https://github.com/NixOS/nixpkgs/blob/release-19.09/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix#L18
>
> Cheers,
> - Brice

Have a nice day!

L  p R n  d n
L p R n d n April 14, 2020, 1:17 p.m. UTC | #3
Hey!

Le 14.04.2020 11:38, L  p R n  d n a écrit :
> Hello,
> 
> Thanks again for the feedbacks.
> 
> Brice Waegeneire <brice@waegenei.re> writes:
> 
> [...]
>> There is an error on vt1 at startup about some dbus stuff related to
>> “accountservice”. The cursor theme isn't set as well as the icon 
>> theme,
>> it
>> seems; it may come from some missing environment variable as NixOS set 
>> a
>> few of them in their service[0].
> 
> For the cursor, setting "XCURSOR_PATH" seems to solve the problem.
> Preparing a patch.
> 
> As for dbus, from what I found at NixOS[0][1], it's a accountsservice
> bug. I'll send a bug report. In the meantime, it doesn't appear to
> affect LightDM too much so it might be ok...?

Better with actual links:

[0]: https://github.com/NixOS/nixpkgs/pull/45107
[1]: https://github.com/NixOS/nixpkgs/issues/72396

Have a nice day,

L  p R n  d n
diff mbox series

Patch

From 5be647a2c7e1994f7cf970fa79fe693ffd4415b8 Mon Sep 17 00:00:00 2001
From: L  p R n  d n <guix@lprndn.info>
Date: Thu, 18 Apr 2019 17:58:56 +0200
Subject: [PATCH 10/10] services: Add lightdm-service-type.

* gnu/services/lightdm.scm: Add file.
* doc/guix.texi (@deftp, @deffn): Add documentation.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
---
 doc/guix.texi            |  88 +++++++++++
 gnu/local.mk             |   1 +
 gnu/services/lightdm.scm | 313 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 402 insertions(+)
 create mode 100644 gnu/services/lightdm.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index a0920adc1c..2d0230d5e6 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -14664,6 +14664,94 @@  auto-login session.
 @end table
 @end deftp
 
+@defvr {Scheme Variable} lightdm-service-type
+Service type for the LightDM graphical login manager.
+It uses the @code{lightdm-gtk-greeter} as default greeter.
+See @code{lightdm-configuration} below for configuration of both lightdm
+and lightdm-gtk-greeter or even using a different greeter.
+@end defvr
+
+@deftp {Data Type} lightdm-configuration
+Data type representing the lightDM service configuration.
+
+@table @asis
+@item @code{session-directory} (default:"/run/current-system/profile/share/xsessions:/run/current-system/profile/share/wayland-sessions")
+Directories where LightDM will search for sessions' @code{.desktop} files.
+
+@item @code{allow-empty-passwords?} (default: @code{#f})
+Whether to allow logins with empty passwords.
+
+@item @code{greeter-name} (default: "lightdm-gtk-greeter")
+The name of the default greeter to be used by LightDM.
+
+@item @code{greeter-package} (default: @code{lightdm-gtk-greeter})
+The package containing the greeter described by @code{greeter-name}
+and that will be included in the system's profile.
+
+@item @code{greeter-assets} (default: @code{(list adwaita-icon-theme gnome-themes-standard)})
+A list of packages needed by the greeter: icons, themes, fonts etc.
+
+@item @code{greeter-configuration-file} (default: (lightdm-gtk-greeter-configuration-file (lightdm-gtk-greeter-configuration)))
+This file will be placed in @code{/etc/xdg/lightdm/} directory.
+A @code{computed-file} is expected.
+
+@item @code{xorg-configuration} (default: @code{(xorg-configuration)})
+Configuration of the Xorg graphical server.
+
+@item @code{session-wrapper} (default: @code{(xinitrc)})
+Script to run before starting a X session.
+
+@item @code{default-session-name} (default: "")
+The name of the default @code{.desktop} file describing a session.
+If @code {autologin-user} and @code{autologin-timeout} are defined,
+LightDM logs in directly using the session described by @code{default-session-name}.
+
+@item @code{autologin-user} (default: "")
+If @code {default-session-name} and @code{autologin-timeout} are defined,
+LightDM logs in directly as @code{autologin-user}.
+
+@item @code{autologin-timeout} (default: @code{#f})
+If @code {default-session-name} and @code{autologin-user} are defined,
+LightDM logs in automatically after @code{autologin-timeout} seconds.
+Any user activity during that time will cancel autologin
+and allow usual login through authentification.
+
+@item @code{lightdm} (default: @code{lightdm})
+The LightDM package to use.
+
+@item @code{extra-config} (default: "")
+String to append to the LightDM configuration file.
+
+@end table
+@end deftp
+
+@deftp {Data Type} lightdm-gtk-greeter-configuration
+This data type represents the configuration for ligtdm-gtk-greeter.
+Use it as an argument of lightdm-gtk-greeter-configuration-file to
+get the corresponding file.
+
+@table @asis
+@item @code{theme-name} (default: "Adwaita")
+The name of the GTK+ theme to be used.
+
+@item @code{icon-theme-name} (default: "Adwaita")
+The name of the icon theme to be used for displaying icons.
+
+@item @code{cursor-theme-name} (default: "Adwaita")
+The name of the theme to be used for the cursor.
+
+@item @code{cursor-size} (default: @code{16})
+The size of the cursor.
+
+@item @code{background} (default: "")
+Path to the background image to be used.
+
+@item @code{extra-config} (default: "")
+String to append to the @code{lightdm-gtk-greeter.conf}.
+
+@end table
+@end deftp
+
 @cindex Xorg, configuration
 @deftp {Data Type} xorg-configuration
 This data type represents the configuration of the Xorg graphical display
diff --git a/gnu/local.mk b/gnu/local.mk
index fc9030b7f9..5ab96c121e 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -561,6 +561,7 @@  GNU_SYSTEM_MODULES =				\
   %D%/services/getmail.scm				\
   %D%/services/guix.scm			\
   %D%/services/kerberos.scm			\
+  %D%/services/lightdm.scm      		\
   %D%/services/lirc.scm				\
   %D%/services/virtualization.scm		\
   %D%/services/mail.scm				\
diff --git a/gnu/services/lightdm.scm b/gnu/services/lightdm.scm
new file mode 100644
index 0000000000..4d69daaa49
--- /dev/null
+++ b/gnu/services/lightdm.scm
@@ -0,0 +1,313 @@ 
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2019,2020 L  p R n  d n   <guix@lprndn.info>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+
+(define-module (gnu services lightdm)
+  #:use-module (guix gexp)
+  #:use-module (guix records)
+
+  #:use-module (gnu system pam)
+  #:use-module (gnu system shadow)
+
+  #:use-module (gnu services)
+  #:use-module (gnu services dbus)
+  #:use-module (gnu services desktop)
+  #:use-module (gnu services shepherd)
+  #:use-module (gnu services xorg)
+
+  #:use-module (gnu packages admin)
+  #:use-module (gnu packages display-managers)
+  #:use-module (gnu packages freedesktop)
+  #:use-module (gnu packages gnome)
+  #:use-module (gnu packages xorg)
+
+  #:export (lightdm-configuration
+            lightdm-configuration?
+            lightdm-service-type
+            lightdm-gtk-greeter-configuration
+            lightdm-gtk-greeter-configuration-file))
+
+;; GREETERS
+
+(define-record-type* <lightdm-gtk-greeter-configuration>
+  lightdm-gtk-greeter-configuration make-lightdm-gtk-greeter-configuration
+  lightdm-gtk-greeter-configuration?
+  (theme-name lightdm-gtk-greeter-configuration-theme-name
+              (default "Adwaita"))
+  (icon-theme-name
+   lightdm-gtk-greeter-configuration-icon-theme-name
+   (default "Adwaita"))
+  (cursor-theme-name
+   lightdm-gtk-greeter-configuration-cursor-theme-name
+   (default "Adwaita"))
+  (cursor-size lightdm-gtk-greeter-configuration-cursor-size
+               (default 16))
+  (background lightdm-gtk-greeter-configuration-background
+              (default ""))
+  (extra-config lightdm-gtk-greeter-configuration-extra-config
+                 (default "")))
+
+(define (lightdm-gtk-greeter-configuration-file config)
+  (mixed-text-file "lightdm-gtk-greeter.conf" "
+[greeter]
+theme-name = " (lightdm-gtk-greeter-configuration-theme-name config) "
+icon-theme-name = "
+(lightdm-gtk-greeter-configuration-icon-theme-name config) "
+cursor-theme-name = "
+(lightdm-gtk-greeter-configuration-cursor-theme-name config) "
+cursor-theme-size = " (number->string
+                       (lightdm-gtk-greeter-configuration-cursor-size config))
+(if (string-null? (lightdm-gtk-greeter-configuration-background config)) ""
+    (string-append "
+background = " (lightdm-gtk-greeter-configuration-background config))) "
+" (lightdm-gtk-greeter-configuration-extra-config config)))
+
+;; LIGHTDM
+
+(define-record-type* <lightdm-configuration>
+  lightdm-configuration make-lightdm-configuration
+  lightdm-configuration?
+
+  (lightdm lightdm-configuration-lightdm
+           (default lightdm))
+  (sessions-directory
+   lightdm-configuration-sessions-directory
+   (default (string-append
+             "/run/current-system/profile/share/xsessions"
+             ":/run/current-system/profile/share/wayland-sessions")))
+  (allow-empty-passwords? lightdm-configuration-allow-empty-passwords?
+                          (default #f))
+  ;; [Seat]
+  (xorg-configuration lightdm-configuration-xorg
+                      (default (xorg-configuration)))
+  (session-wrapper lightdm-configuration-session-wrapper
+                   (default (xinitrc)))
+  (default-session-name lightdm-configuration-default-session
+    (default ""))
+
+  ;; [Autologin]
+  (autologin-user lightdm-configuration-autologin-user
+                  (default ""))
+  (autologin-timeout lightdm-configuration-autologin-timeout
+                     (default #f))
+  ;; [Greeter]
+  (greeter-name lightdm-configuration-greeter-name
+                (default "lightdm-gtk-greeter"))
+  (greeter-package lightdm-configuration-greeter-package
+                   (default lightdm-gtk-greeter))
+  (greeter-assets lightdm-configuration-greeter-assets
+                  (default (list adwaita-icon-theme
+                                 gnome-themes-standard)))
+  (greeter-configuration-file lightdm-configuration-greeter-configuration-file
+                              (default (lightdm-gtk-greeter-configuration-file
+                                        (lightdm-gtk-greeter-configuration))))
+  (extra-config lightdm-configuration-extra-config
+                 (default "")))
+
+(define %lightdm-accounts
+  (list (user-group (name "lightdm") (system? #t))
+        (user-account
+         (name "lightdm")
+         (group "lightdm")
+         (system? #t)
+         (comment "LightDM user")
+         (home-directory "/var/lib/lightdm")
+         (shell (file-append shadow "/sbin/nologin")))))
+
+(define %lightdm-activation
+  ;; Ensure /var/lib/lightdm is owned by the "lightdm" user.
+  ;; Mimics what is done for gdm
+  ;; see a43e9157ef479e94c19951cc9d228cf153bf78ee
+  (with-imported-modules '((guix build utils))
+    #~(begin
+        (use-modules (guix build utils))
+
+        (define (ensure-ownership directory)
+          (let* ((lightdm (getpwnam "lightdm"))
+                 (uid (passwd:uid lightdm))
+                 (gid (passwd:gid lightdm))
+                 (st  (stat directory #f)))
+            ;; Recurse into directory only if it has wrong ownership.
+            (when (and st
+                       (or (not (= uid (stat:uid st)))
+                           (not (= gid (stat:gid st)))))
+              (for-each (lambda (file)
+                          (chown file uid gid))
+                        (find-files "directory"
+                                    #:directories? #t)))))
+
+        (when (not (stat "/var/lib/lightdm-data" #f))
+          (mkdir-p "/var/lib/lightdm-data"))
+        (for-each ensure-ownership
+                  '("/var/lib/lightdm"
+                    "/var/lib/lightdm-data")))))
+
+(define (lightdm-configuration-file config)
+  (mixed-text-file "lightdm.conf" "
+[LightDM]
+greeter-user = lightdm
+greeters-directory = /run/current-system/profile/share/xgreeters
+sessions-directory = "  (lightdm-configuration-sessions-directory config) "
+
+
+[Seat:*]
+xserver-command = "  (xorg-start-command (lightdm-configuration-xorg config)) "
+greeter-session = "       (lightdm-configuration-greeter-name config) "
+user-session = "          (lightdm-configuration-default-session config)
+(if (string-null? (lightdm-configuration-autologin-user config)) ""
+    (string-append "
+autologin-user = " (lightdm-configuration-autologin-user config)))
+(if (string-null? (lightdm-configuration-default-session config)) ""
+    (string-append "
+autologin-session = " (lightdm-configuration-default-session config)))
+(if (lightdm-configuration-autologin-timeout config)
+    (string-append "
+autologin-user-timeout = " (number->string
+                            (lightdm-configuration-autologin-timeout config)))
+    "") "
+session-wrapper = " (lightdm-configuration-session-wrapper config) "
+" (lightdm-configuration-extra-config config)))
+
+
+(define (lightdm-pam-service config)
+  "Return a PAM service for @command{lightdm}."
+  (unix-pam-service
+   "lightdm"
+   #:allow-empty-passwords?
+   (lightdm-configuration-allow-empty-passwords? config)))
+
+
+(define (lightdm-greeter-pam-service)
+  "Return a PAM service for @command{lightdm-greeter}}."
+  (pam-service
+   (name "lightdm-greeter")
+   (auth
+    (list
+     ;; Load environment from /etc/environment and ~/.pam_environment
+     (pam-entry (control "required") (module "pam_env.so"))
+     ;; Always let the greeter start without authentication
+     (pam-entry (control "required") (module "pam_permit.so"))))
+   ;; No action required for account management
+   (account
+    (list
+     (pam-entry (control "required") (module "pam_permit.so"))))
+   ;; Can't change password
+   (password
+    (list
+     (pam-entry (control "required") (module "pam_deny.so"))))
+   ;; Setup session
+   (session
+    (list
+     (pam-entry (control "required") (module "pam_unix.so"))
+     (pam-entry (control "required") (module "pam_env.so"))))))
+
+
+(define (lightdm-autologin-pam-service)
+  "Return a PAM service for @command{lightdm-autologin}}."
+  (pam-service
+   (name "lightdm-autologin")
+   (auth
+    (list
+     ;; Block login if they are globally disabled
+     (pam-entry (control "required") (module "pam_nologin.so"))
+     ;; Load environment from /etc/environment and ~/.pam_environment
+     (pam-entry (control "required") (module "pam_env.so"))
+     ;; Allow access without authentication
+     (pam-entry (control "required") (module "pam_permit.so"))))
+   ;; Stop autologin if account requires action
+   (account
+    (list
+     (pam-entry (control "required") (module "pam_unix.so"))))
+   ;; Can't change password
+   (password
+    (list
+     (pam-entry (control "required") (module "pam_deny.so"))))
+   ;; Setup session
+   (session
+    (list
+     (pam-entry (control "required") (module "pam_unix.so"))))))
+
+(define (lightdm-shepherd-service config)
+  "Return a <lightdm-service> for LightDM with CONFIG."
+
+  (define lightdm-command
+    #~(list #$(file-append (lightdm-configuration-lightdm config)
+                           "/sbin/lightdm")))
+ 
+  (list (shepherd-service
+         (documentation "LightDM display manager.")
+         (requirement '(dbus-system user-processes host-name))
+         (provision '(display-manager))
+         (respawn? #f)
+         (start #~(lambda ()
+                    (fork+exec-command
+                     #$lightdm-command
+                     #:environment-variables
+                     (list
+                      (string-append
+                       "PATH=/run/current-system/profile/sbin"
+                       ":/run/current-system/profile/bin")))))
+         (stop #~(make-kill-destructor)))))
+
+(define (lightdm-etc-service config)
+  (let ((lightdm-conf-file
+         (lightdm-configuration-file config))
+        (greeter-conf-file
+         (lightdm-configuration-greeter-configuration-file config)))
+    (if greeter-conf-file
+        (list `("xdg/lightdm/lightdm.conf.d/lightdm.conf"
+                ,lightdm-conf-file)
+              `(,(string-append
+                  "xdg/lightdm/" (computed-file-name greeter-conf-file))
+                ,greeter-conf-file))
+        (list  `("xdg/lightdm/lightdm.conf.d/lightdm.conf"
+                ,lightdm-conf-file)))))
+
+(define (lightdm-pam-services config)
+  (list (lightdm-pam-service config)
+        (lightdm-greeter-pam-service)
+        (lightdm-autologin-pam-service)))
+
+(define (lightdm-profile-service config)
+  (append (list lightdm
+                (lightdm-configuration-greeter-package config))
+          (lightdm-configuration-greeter-assets config)))
+
+(define lightdm-service-type
+  (handle-xorg-configuration lightdm-configuration
+   (service-type (name 'lightdm)
+                 (extensions
+                  (list
+                   (service-extension shepherd-root-service-type
+                                      lightdm-shepherd-service)
+                   (service-extension activation-service-type
+                                      (const %lightdm-activation))
+                   (service-extension etc-service-type
+                                      lightdm-etc-service)
+                   (service-extension pam-root-service-type
+                                      lightdm-pam-services)
+                   (service-extension dbus-root-service-type
+                                      (compose list
+                                               lightdm-configuration-lightdm))
+                   (service-extension account-service-type
+                                      (const %lightdm-accounts))
+                   (service-extension profile-service-type
+                                      lightdm-profile-service)))
+                 (default-value (lightdm-configuration))
+                 (description "Return a service that spawns the
+ LightDM graphical login manager."))))
-- 
2.25.1