diff mbox series

[bug#64471,1/2] services: Add 'file-database' service.

Message ID fbf1fdda8cf716739bc47446f8a3948ececcced3.1688550926.git.ludo@gnu.org
State New
Headers show
Series File database update services | expand

Commit Message

Ludovic Courtès July 5, 2023, 10:16 a.m. UTC
* gnu/services/admin.scm (%default-file-database-update-schedule)
(%default-file-database-excluded-directories): New variables.
(<file-database-configuration>): New record type.
(file-database-mcron-jobs): New procedure.
(file-database-service-type): New variable.
* doc/guix.texi (File Search Services): New node.
---
 doc/guix.texi          | 62 ++++++++++++++++++++++++++++++++++++++
 gnu/services/admin.scm | 67 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+)

Comments

Bruno Victal July 13, 2023, 6 p.m. UTC | #1
Hi Ludo’,

On 2023-07-05 11:16, Ludovic Courtès wrote:
> +(define-record-type* <file-database-configuration>
> +  file-database-configuration make-file-database-configuration
> +  file-database-configuration?
> +  (package              file-database-configuration-package
> +                        (default
> +                          (let-system (system target)
> +                            ;; Unless we're cross-compiling, avoid pulling a
> +                            ;; second copy of findutils.
> +                            (if target
> +                                findutils
> +                                (canonical-package findutils)))))
> +  (schedule             file-database-configuration-schedule
> +                        (default %default-file-database-update-schedule))
> +  (excluded-directories file-database-configuration-excluded-directories
> +                        (default %default-file-database-excluded-directories)))

How about using define-configuration instead to have the documentation neatly
in sync with the fields?

> +
> +(define (file-database-mcron-jobs configuration)
> +  (match-record configuration <file-database-configuration>
> +    (package schedule excluded-directories)
> +    (let ((updatedb (program-file
> +                     "updatedb"
> +                     #~(execl #$(file-append package "/bin/updatedb")
> +                              "updatedb"
> +                              #$(string-append "--prunepaths="
> +                                               (string-join
> +                                                excluded-directories))))))
> +      (list #~(job #$schedule #$updatedb)))))

I'm afraid #$schedule might be insufficient if this is a _mcron_ time-spec.
There's an elaborate dance done by fstrim-service-type to handle the more exotic
mcron time expressions, perhaps you can reuse it here?
Ludovic Courtès July 17, 2023, 8:22 p.m. UTC | #2
Hello,

Bruno Victal <mirai@makinata.eu> skribis:

> On 2023-07-05 11:16, Ludovic Courtès wrote:
>> +(define-record-type* <file-database-configuration>
>> +  file-database-configuration make-file-database-configuration
>> +  file-database-configuration?
>> +  (package              file-database-configuration-package
>> +                        (default
>> +                          (let-system (system target)
>> +                            ;; Unless we're cross-compiling, avoid pulling a
>> +                            ;; second copy of findutils.
>> +                            (if target
>> +                                findutils
>> +                                (canonical-package findutils)))))
>> +  (schedule             file-database-configuration-schedule
>> +                        (default %default-file-database-update-schedule))
>> +  (excluded-directories file-database-configuration-excluded-directories
>> +                        (default %default-file-database-excluded-directories)))
>
> How about using define-configuration instead to have the documentation neatly
> in sync with the fields?

Hmm, good point, I’ll take a look.

>> +(define (file-database-mcron-jobs configuration)
>> +  (match-record configuration <file-database-configuration>
>> +    (package schedule excluded-directories)
>> +    (let ((updatedb (program-file
>> +                     "updatedb"
>> +                     #~(execl #$(file-append package "/bin/updatedb")
>> +                              "updatedb"
>> +                              #$(string-append "--prunepaths="
>> +                                               (string-join
>> +                                                excluded-directories))))))
>> +      (list #~(job #$schedule #$updatedb)))))
>
> I'm afraid #$schedule might be insufficient if this is a _mcron_ time-spec.
> There's an elaborate dance done by fstrim-service-type to handle the more exotic
> mcron time expressions, perhaps you can reuse it here?

I’m not sure what fstrim-service-type is trying to achieve with this:

    #~(job
       ;; Note: The “if” below is to ensure that
       ;; lists are ungexp'd correctly since @var{schedule}
       ;; can be either a procedure, a string or a list.
       #$(if (list? schedule)
             #~'(#$@schedule)
             schedule)
       …")

If we simply have:

  #~(job #$schedule …)

then ‘schedule’ can be anything you might expect, like:

  • "0 * * * *"         ;string

  • #~(next-hour …)     ;gexp

  • #~(lambda (x) …)    ;another gexp

What’s the problem? :-)

Ludo’.
Bruno Victal July 26, 2023, 1:22 p.m. UTC | #3
Hi Ludo’,

On 2023-07-17 21:22, Ludovic Courtès wrote:
> Bruno Victal <mirai@makinata.eu> skribis:
> 
>>
>> I'm afraid #$schedule might be insufficient if this is a _mcron_ time-spec.
>> There's an elaborate dance done by fstrim-service-type to handle the more exotic
>> mcron time expressions, perhaps you can reuse it here?
> 
> I’m not sure what fstrim-service-type is trying to achieve with this:
> 
>     #~(job
>        ;; Note: The “if” below is to ensure that
>        ;; lists are ungexp'd correctly since @var{schedule}
>        ;; can be either a procedure, a string or a list.
>        #$(if (list? schedule)
>              #~'(#$@schedule)
>              schedule)
>        …")
> 
> If we simply have:
> 
>   #~(job #$schedule …)
> 
> then ‘schedule’ can be anything you might expect, like:
> 
>   • "0 * * * *"         ;string
> 
>   • #~(next-hour …)     ;gexp
> 
>   • #~(lambda (x) …)    ;another gexp
> 
> What’s the problem? :-)

There's a third choice for that argument: a staged expression/list, hence
the gexp/ungexp dance.

[1]: <https://www.gnu.org/software/mcron/manual/mcron.html#Guile-Syntax>
[2]: <https://www.gnu.org/software/mcron/manual/mcron.html#Extended-Guile-examples>
diff mbox series

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index 853396f776..21ff15ccbc 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -388,6 +388,7 @@  Top
 * Printing Services::           Local and remote printer support.
 * Desktop Services::            D-Bus and desktop services.
 * Sound Services::              ALSA and Pulseaudio services.
+* File Search Services::        Tools to search for files.
 * Database Services::           SQL databases, key-value stores, etc.
 * Mail Services::               IMAP, POP3, SMTP, and all that.
 * Messaging Services::          Messaging services.
@@ -18414,6 +18415,7 @@  Services
 * Printing Services::           Local and remote printer support.
 * Desktop Services::            D-Bus and desktop services.
 * Sound Services::              ALSA and Pulseaudio services.
+* File Search Services::        Tools to search for files.
 * Database Services::           SQL databases, key-value stores, etc.
 * Mail Services::               IMAP, POP3, SMTP, and all that.
 * Messaging Services::          Messaging services.
@@ -24924,6 +24926,66 @@  Sound Services
 
 @end defvar
 
+@node File Search Services
+@subsection File Search Services
+
+@cindex file search
+@cindex searching for a file
+The services in this section populate @dfn{file databases} that let you
+search for files on your machine.  These services are provided by the
+@code{(gnu services admin)} module.
+
+The first one, @code{file-database-service-type}, periodically runs the
+venerable @command{updatedb} command (@pxref{Invoking updatedb,,, find,
+GNU Findutils}).  That command populates a database of file names that
+you can then search with the @command{locate} command (@pxref{Invoing
+locate,,, find, GNU Findutils}), as in this example:
+
+@example
+locate important-notes.txt
+@end example
+
+You can enable this service with its default settings by adding this
+snippet to your operating system services:
+
+@lisp
+(service file-database-service-type)
+@end lisp
+
+This updates the database once a week, excluding files from
+@file{/gnu/store}---these are more usefully handled by @command{guix
+locate} (@pxref{Invoking guix locate}).  You can of course provide a
+custom configuration, as described below.
+
+@defvar file-database-service-type
+This is the type of the file database service, which runs
+@command{updatedb} periodically.  Its associated value must be a
+@code{file-database-configuration} record, as described below.
+@end defvar
+
+@deftp {Data Type} file-database-configuration
+Record type for the @code{file-database-service-type} configuration,
+with the following fields:
+
+@table @asis
+@item @code{package} (default: @code{findutils})
+The GNU@tie{}Findutils package from which the @command{updatedb} command
+is taken.
+
+@item @code{schedule} (default: @code{%default-file-database-update-schedule})
+String or G-exp denoting an mcron schedule for the periodic
+@command{updatedb} job (@pxref{Guile Syntax,,, mcron, GNU@tie{}mcron}).
+
+@item @code{excluded-directories} (default @code{%default-file-database-excluded-directories})
+List of directories to ignore when building the file database.  By
+default, this includes @file{/tmp} and @file{/gnu/store}, which should
+instead be indexed by @command{guix locate} (@pxref{Invoking guix
+locate}).  This list is passed to the @option{--prunepaths} option of
+@command{updatedb} (@pxref{Invoking updatedb,,, find,
+GNU@tie{}Findutils}).
+@end table
+@end deftp
+
 @node Database Services
 @subsection Database Services
 
diff --git a/gnu/services/admin.scm b/gnu/services/admin.scm
index 1c10cfb1f6..57fdfc35c0 100644
--- a/gnu/services/admin.scm
+++ b/gnu/services/admin.scm
@@ -21,11 +21,14 @@ 
 
 (define-module (gnu services admin)
   #:use-module (gnu packages admin)
+  #:use-module ((gnu packages base)
+                #:select (canonical-package findutils))
   #:use-module (gnu packages certs)
   #:use-module (gnu packages package-management)
   #:use-module (gnu services)
   #:use-module (gnu services mcron)
   #:use-module (gnu services shepherd)
+  #:use-module ((guix store) #:select (%store-prefix))
   #:use-module (guix gexp)
   #:use-module (guix modules)
   #:use-module (guix packages)
@@ -55,6 +58,15 @@  (define-module (gnu services admin)
             log-cleanup-configuration-expiry
             log-cleanup-configuration-schedule
 
+            file-database-service-type
+            file-database-configuration
+            file-database-configuration?
+            file-database-configuration-package
+            file-database-configuration-schedule
+            file-database-configuration-excluded-directories
+            %default-file-database-update-schedule
+            %default-file-database-excluded-directories
+
             unattended-upgrade-service-type
             unattended-upgrade-configuration
             unattended-upgrade-configuration?
@@ -255,6 +267,61 @@  (define log-cleanup-service-type
    (description
     "Periodically delete old log files.")))
 
+
+;;;
+;;; File databases.
+;;;
+
+(define %default-file-database-update-schedule
+  ;; Default mcron schedule for the periodic 'updatedb' job: once every
+  ;; Sunday.
+  "10 23 * * 0")
+
+(define %default-file-database-excluded-directories
+  ;; Directories excluded from the 'locate' database.
+  (list (%store-prefix)
+        "/tmp" "/var/tmp" "/var/cache" ".*/\\.cache"
+        "/run/udev"))
+
+(define-record-type* <file-database-configuration>
+  file-database-configuration make-file-database-configuration
+  file-database-configuration?
+  (package              file-database-configuration-package
+                        (default
+                          (let-system (system target)
+                            ;; Unless we're cross-compiling, avoid pulling a
+                            ;; second copy of findutils.
+                            (if target
+                                findutils
+                                (canonical-package findutils)))))
+  (schedule             file-database-configuration-schedule
+                        (default %default-file-database-update-schedule))
+  (excluded-directories file-database-configuration-excluded-directories
+                        (default %default-file-database-excluded-directories)))
+
+(define (file-database-mcron-jobs configuration)
+  (match-record configuration <file-database-configuration>
+    (package schedule excluded-directories)
+    (let ((updatedb (program-file
+                     "updatedb"
+                     #~(execl #$(file-append package "/bin/updatedb")
+                              "updatedb"
+                              #$(string-append "--prunepaths="
+                                               (string-join
+                                                excluded-directories))))))
+      (list #~(job #$schedule #$updatedb)))))
+
+(define file-database-service-type
+  (service-type
+   (name 'file-database)
+   (extensions (list (service-extension mcron-service-type
+                                        file-database-mcron-jobs)))
+   (description
+    "Periodically update the file database used by the @command{locate} command,
+which lets you search for files by name.  The database is created by running
+the @command{updatedb} command.")
+   (default-value (file-database-configuration))))
+
 
 ;;;
 ;;; Unattended upgrade.