diff mbox series

[bug#61744] services: base: Deprecate 'pam-limits-service' procedure.

Message ID d319522cc9ff3ca759a5d1ebd8d57d7165e4bdc5.1677197399.git.mirai@makinata.eu
State New
Headers show
Series [bug#61744] services: base: Deprecate 'pam-limits-service' procedure. | expand

Commit Message

Bruno Victal Feb. 24, 2023, 12:12 a.m. UTC
* doc/guix.texi (Base Services): Replace pam-limits-service with pam-limits-service-type.
* gnu/packages/benchmark.scm (python-locust)[description]: Update index anchor to manual.
* gnu/services/base.scm (pam-limits-service-type): Accept both lists and
file-like objects for compatibility.
(pam-limits-service): Deprecate procedure.
---

Sending this one for review now since this service is a bit unusual compared to the other ones.

 doc/guix.texi              | 18 ++++++++---------
 gnu/packages/benchmark.scm |  2 +-
 gnu/services/base.scm      | 41 +++++++++++++++++++++++++++-----------
 3 files changed, 39 insertions(+), 22 deletions(-)


base-commit: 5d10644371abd54d0edcd638691113f0a92de743

Comments

Ricardo Wurmus March 10, 2023, 5:52 p.m. UTC | #1
Hi,

thank you for the patches!

The effective change looks fine to me, but I’m confused about why these
are two patches.  The first one introduces this as an example in the
docs:

+(service
+  pam-limits-service-type
+  (plain-file
+    "limits.conf"
+    (string-join
+      (map pam-limits-entry->string
+        (list (pam-limits-entry "@@realtime" 'both 'rtprio 99)
+              (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited)))
+      "\n")))

But the second removes this again in favour of this prettier form:

+(service pam-limits-service-type
+         (list
+          (pam-limits-entry "@@realtime" 'both 'rtprio 99)
+          (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited)))

Which is really close to the original form:

-(pam-limits-service
- (list
-  (pam-limits-entry "@@realtime" 'both 'rtprio 99)
-  (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited)))

Could you merge these two patches to reduce the number of unnecessary
changes?  I don’t think we should change to file-likes as the argument
value for the pam-limits-service-type.

Another thing that confused me:

+            (test-equal "/etc/security/limits.conf content matches"
+              #$(string-join (map pam-limits-entry->string pam-limit-entries)
+                             "\n" 'suffix)
+              (marionette-eval
+               '(call-with-input-file "/etc/security/limits.conf"
+                  get-string-all)
+               marionette))

Why use the gexp with a computed value here instead of using just the
plain text of the expected contents of that file?  Computing
the expected value in a test where the compared value is computed in the
same way feels like begging the question.

Or perhaps I’m misunderstanding something here?
Bruno Victal March 11, 2023, 11:25 a.m. UTC | #2
Hi Ricardo,

On 2023-03-10 17:52, Ricardo Wurmus wrote:
> Hi,
> 
> thank you for the patches!
> 
> The effective change looks fine to me, but I’m confused about why these
> are two patches.  The first one introduces this as an example in the
> docs:

[...]

> 
> +(service
> +  pam-limits-service-type
> +  (plain-file
> +    "limits.conf"
> +    (string-join
> +      (map pam-limits-entry->string
> +        (list (pam-limits-entry "@@realtime" 'both 'rtprio 99)
> +              (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited)))
> +      "\n")))
> 
> But the second removes this again in favour of this prettier form:

This was to ensure that each commit is "atomic".

> 
> +(service pam-limits-service-type
> +         (list
> +          (pam-limits-entry "@@realtime" 'both 'rtprio 99)
> +          (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited)))
> 
> Which is really close to the original form:
> 
> -(pam-limits-service
> - (list
> -  (pam-limits-entry "@@realtime" 'both 'rtprio 99)
> -  (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited)))
> 
> Could you merge these two patches to reduce the number of unnecessary
> changes?  I don’t think we should change to file-likes as the argument
> value for the pam-limits-service-type.
The v2 patch-series are a dis-aggregation of the v1 series (save for a bug fix
in the match clauses, test suite and using raise instead of report-error)
as indicated in the 10/27 patch-series review from #61789.

> 
> Another thing that confused me:
> 
> +            (test-equal "/etc/security/limits.conf content matches"
> +              #$(string-join (map pam-limits-entry->string pam-limit-entries)
> +                             "\n" 'suffix)
> +              (marionette-eval
> +               '(call-with-input-file "/etc/security/limits.conf"
> +                  get-string-all)
> +               marionette))
> 
> Why use the gexp with a computed value here instead of using just the
> plain text of the expected contents of that file?  Computing
> the expected value in a test where the compared value is computed in the
> same way feels like begging the question.
> 
> Or perhaps I’m misunderstanding something here?
> 

I wrote this test suite to simply check that both deprecated and "new" service-type forms
work correctly, i.e. the files are present in their locations.
(this actually caught a bug within the match clauses in the v1 patch)


Cheers,
Bruno
Felix Lechner March 20, 2023, 5:49 p.m. UTC | #3
Hi Bruno,

Thanks for this great and important work!

Can we refer to the limits.conf file in the store, please? I do not
believe we need a copy in /etc/security, and should not keep one
there.

The "conf=" argument to pam_limits(8) accepts an absolute path. [1] We
use that mechanism already (for the default path). Thanks!

Kind regards,
Felix Lechner

[1] https://linux.die.net/man/8/pam_limits
Ludovic Courtès March 30, 2023, 8:53 p.m. UTC | #4
Hi Felix,

Felix Lechner <felix.lechner@lease-up.com> skribis:

> Can we refer to the limits.conf file in the store, please? I do not
> believe we need a copy in /etc/security, and should not keep one
> there.

I’m generally in favor of not populating /etc and instead referring to
store file names.

In some cases (maybe this one), this can be a problem though, in
particular for upgrades (the module keeps referring to the old config
file in the store).  So I don’t know, but this needs to be taken into
account.

Ludo’.
Ludovic Courtès March 30, 2023, 9:08 p.m. UTC | #5
Hi Bruno,

Thanks for explaining.  It seems to me that none of the issues raised is
a blocker, so I went ahead and applied these two patches.

Thank you, and apologies for the delay!

Ludo’.
Felix Lechner March 30, 2023, 9:19 p.m. UTC | #6
Hi Ludovic,

On Thu, Mar 30, 2023 at 1:54 PM Ludovic Courtès <ludo@gnu.org> wrote:
>
> In some cases (maybe this one), this can be a problem

Thanks for pointing that out! I would like to learn more about that.

My next suggestion would have been to refer to the core PAM modules,
which ship with Linux-PAM, by absolute paths as well.

You can see the current inconsistencies in my PAM 'login' service,
which I included below. Which breakage do you expect?

On a side note, I am also working with the pam_mount maintainer on a
store path for /etc/security/pam_mount_conf.xml. [1] (Jan previously
accepted another suggestion of mine, and it became popular with
users.) Then we can drop the definition of 'greet-pam-mount' [2] which
is very nearly a duplicate of the regular 'pam-mount'. [3]

Kind regards
Felix

[1] https://codeberg.org/jengelh/pam_mount/issues/1
[2] https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/admin.scm#n5314
[3] https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/admin.scm#n4709

* * *

account required pam_unix.so
auth required pam_unix.so nullok
auth optional /gnu/store/zb9ns323p7yv8m1m155yfgrxlxaadx3d-greetd-pam-mount-2.18/lib/security/pam_mount.so
disable_interactive
password required pam_unix.so sha512 shadow
session required
/gnu/store/7sq4qp09fl1pn72jw828ndm13nbpknhv-elogind-246.10/lib/security/pam_elogind.so
session required pam_limits.so conf=/etc/security/limits.conf
session optional pam_motd.so
motd=/gnu/store/mrk0km6gqw4zn20az2bqidvajps7yy93-motd
session required pam_loginuid.so
session required pam_env.so
session required pam_unix.so
session optional
/gnu/store/zb9ns323p7yv8m1m155yfgrxlxaadx3d-greetd-pam-mount-2.18/lib/security/pam_mount.so
disable_interactive
diff mbox series

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index a7ef00f421..9127090d44 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -18926,7 +18926,6 @@  Base Services
 @var{device} does not exist.
 @end deffn
 
-@anchor{pam-limits-service}
 @cindex session limits
 @cindex ulimit
 @cindex priority
@@ -18934,19 +18933,20 @@  Base Services
 @cindex jackd
 @cindex nofile
 @cindex open file descriptors
-@deffn {Scheme Procedure} pam-limits-service [#:limits @code{'()}]
-
-Return a service that installs a configuration file for the
+@anchor{pam-limits-service-type}
+@defvar pam-limits-service-type
+Type of the service that installs a configuration file for the
 @uref{http://linux-pam.org/Linux-PAM-html/sag-pam_limits.html,
-@code{pam_limits} module}.  The procedure optionally takes a list of
-@code{pam-limits-entry} values, which can be used to specify
+@code{pam_limits} module}.  The value for this service type is
+a list of @code{pam-limits-entry} values, which can be used to specify
 @code{ulimit} limits and @code{nice} priority limits to user sessions.
+By default, the value is the empty list.
 
 The following limits definition sets two hard and soft limits for all
 login sessions of users in the @code{realtime} group:
 
 @lisp
-(pam-limits-service
+(service pam-limits-service-type
  (list
   (pam-limits-entry "@@realtime" 'both 'rtprio 99)
   (pam-limits-entry "@@realtime" 'both 'memlock 'unlimited)))
@@ -18961,7 +18961,7 @@  Base Services
 descriptors that can be used:
 
 @lisp
-(pam-limits-service
+(service pam-limits-service-type
  (list
   (pam-limits-entry "*" 'both 'nofile 100000)))
 @end lisp
@@ -18972,7 +18972,7 @@  Base Services
 else the users would be prevented from login in.  For more information
 about the Pluggable Authentication Module (PAM) limits, refer to the
 @samp{pam_limits} man page from the @code{linux-pam} package.
-@end deffn
+@end defvar
 
 @defvar greetd-service-type
 @uref{https://git.sr.ht/~kennylevinsen/greetd, @code{greetd}} is a minimal and
diff --git a/gnu/packages/benchmark.scm b/gnu/packages/benchmark.scm
index 33e2466da9..fd8513f41d 100644
--- a/gnu/packages/benchmark.scm
+++ b/gnu/packages/benchmark.scm
@@ -458,7 +458,7 @@  (define-public python-locust
 
 Note: Locust will complain if the available open file descriptors limit for
 the user is too low.  To raise such limit on a Guix System, refer to
-@samp{info guix --index-search=pam-limits-service}.")
+@samp{info guix --index-search=pam-limits-service-type}.")
     (license license:expat)))
 
 (define-public interbench
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 35b03a877b..5a2e0263e4 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -40,7 +40,7 @@ 
 (define-module (gnu services base)
   #:use-module (guix store)
   #:use-module (guix deprecation)
-  #:autoload   (guix diagnostics) (warning &fix-hint)
+  #:autoload   (guix diagnostics) (warning report-error &fix-hint)
   #:autoload   (guix i18n) (G_)
   #:use-module (guix combinators)
   #:use-module (gnu services)
@@ -245,7 +245,7 @@  (define-module (gnu services base)
             kmscon-service-type
 
             pam-limits-service-type
-            pam-limits-service
+            pam-limits-service  ; deprecated
 
             greetd-service-type
             greetd-configuration
@@ -1570,17 +1570,13 @@  (define* (syslog-service #:optional (config (syslog-configuration)))
 
 
 (define pam-limits-service-type
-  (let ((security-limits
-         ;; Create /etc/security containing the provided "limits.conf" file.
-         (lambda (limits-file)
-           `(("security/limits.conf"
-              ,limits-file))))
-        (pam-extension
+  (let ((pam-extension
          (lambda (pam)
            (let ((pam-limits (pam-entry
                               (control "required")
                               (module "pam_limits.so")
-                              (arguments '("conf=/etc/security/limits.conf")))))
+                              (arguments
+                               '("conf=/etc/security/limits.conf")))))
              (if (member (pam-service-name pam)
                          '("login" "greetd" "su" "slim" "gdm-password" "sddm"
                            "sudo" "sshd"))
@@ -1588,7 +1584,26 @@  (define pam-limits-service-type
                   (inherit pam)
                   (session (cons pam-limits
                                  (pam-service-session pam))))
-                 pam)))))
+                 pam))))
+
+        ;; XXX: Using file-like objects is deprecated, use lists instead.
+        ;;      This is to be reduced into the list? case when the deprecated
+        ;;      code gets removed.
+        ;; Create /etc/security containing the provided "limits.conf" file.
+        (security-limits
+         (match-lambda
+           ((? file-like? obj)
+            (warning (G_ "Using file-like value for 'pam-limits-service-type'
+is deprecated~%"))
+            obj)
+           ((? list? lst)
+            `(("security/limits.conf"
+               ,(plain-file "limits.conf"
+                            (string-join (map pam-limits-entry->string lst)
+                                         "\n" 'suffix)))))
+           (_ (report-error
+               (G_ "invalid input for 'pam-limits-service-type'~%"))))))
+
     (service-type
      (name 'limits)
      (extensions
@@ -1598,9 +1613,11 @@  (define pam-limits-service-type
      (description
       "Install the specified resource usage limits by populating
 @file{/etc/security/limits.conf} and using the @code{pam_limits}
-authentication module."))))
+authentication module.")
+     (default-value '()))))
 
-(define* (pam-limits-service #:optional (limits '()))
+(define-deprecated (pam-limits-service #:optional (limits '()))
+  pam-limits-service-type
   "Return a service that makes selected programs respect the list of
 pam-limits-entry specified in LIMITS via pam_limits.so."
   (service pam-limits-service-type