2016-09-08 01:20:43 +02:00
|
|
|
|
;;; GNU Guix --- Functional package management for GNU
|
|
|
|
|
|
;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
|
2024-12-11 16:12:29 +01:00
|
|
|
|
;;; Copyright © 2016-2025 Ludovic Courtès <ludo@gnu.org>
|
2020-04-29 09:34:01 +02:00
|
|
|
|
;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
|
2025-11-15 11:58:40 +01:00
|
|
|
|
;;; Copyright © 2023 Giacomo Leidi <therewasa@fishinthecalculator.me>
|
2024-12-14 16:18:23 -05:00
|
|
|
|
;;; Copyright © 2024 Gabriel Wicki <gabriel@erlikon.ch>
|
|
|
|
|
|
;;; Copyright © 2024 Richard Sent <richard@freakingpenguin.com>
|
2016-09-08 01:20:43 +02:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; 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.
|
|
|
|
|
|
;;;
|
2018-11-07 17:24:35 +01:00
|
|
|
|
;;; You should have received a copy of the GNU General Public License
|
2016-09-08 01:20:43 +02:00
|
|
|
|
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
(define-module (gnu services admin)
|
2024-12-14 16:18:23 -05:00
|
|
|
|
#:use-module (gnu system file-systems)
|
2016-09-08 01:20:43 +02:00
|
|
|
|
#:use-module (gnu packages admin)
|
2023-07-05 10:19:15 +02:00
|
|
|
|
#:use-module ((gnu packages base)
|
2023-08-22 10:20:11 +02:00
|
|
|
|
#:select (canonical-package findutils coreutils sed))
|
2024-12-14 16:18:23 -05:00
|
|
|
|
#:use-module (gnu packages file-systems)
|
2025-05-22 09:15:47 +09:00
|
|
|
|
#:use-module (gnu packages nss)
|
2024-12-14 16:18:23 -05:00
|
|
|
|
#:use-module (gnu packages disk)
|
2020-07-22 20:21:21 +02:00
|
|
|
|
#:use-module (gnu packages package-management)
|
2024-12-14 16:18:23 -05:00
|
|
|
|
#:use-module (gnu packages linux)
|
2016-09-08 01:20:43 +02:00
|
|
|
|
#:use-module (gnu services)
|
2023-07-05 10:19:15 +02:00
|
|
|
|
#:use-module (gnu services configuration)
|
2016-09-08 01:20:43 +02:00
|
|
|
|
#:use-module (gnu services mcron)
|
|
|
|
|
|
#:use-module (gnu services shepherd)
|
2023-07-05 11:49:34 +02:00
|
|
|
|
#:use-module (gnu system accounts)
|
|
|
|
|
|
#:use-module ((gnu system shadow) #:select (account-service-type))
|
2023-07-05 10:19:15 +02:00
|
|
|
|
#:use-module ((guix store) #:select (%store-prefix))
|
2024-12-11 23:52:19 +01:00
|
|
|
|
#:use-module (guix deprecation)
|
2016-09-08 01:20:43 +02:00
|
|
|
|
#:use-module (guix gexp)
|
2020-07-22 20:21:21 +02:00
|
|
|
|
#:use-module (guix modules)
|
2016-09-08 01:20:43 +02:00
|
|
|
|
#:use-module (guix packages)
|
|
|
|
|
|
#:use-module (guix records)
|
|
|
|
|
|
#:use-module (srfi srfi-1)
|
2023-07-05 10:19:15 +02:00
|
|
|
|
#:use-module (ice-9 match)
|
2017-06-08 20:12:38 +02:00
|
|
|
|
#:use-module (ice-9 vlist)
|
2024-12-11 16:12:29 +01:00
|
|
|
|
#:export (log-rotation-configuration
|
|
|
|
|
|
log-rotation-configuration?
|
|
|
|
|
|
log-rotation-configuration-provision
|
|
|
|
|
|
log-rotation-configuration-requirement
|
|
|
|
|
|
log-rotation-configuration-calendar-event
|
|
|
|
|
|
log-rotation-configuration-external-log-files
|
|
|
|
|
|
log-rotation-configuration-compression
|
|
|
|
|
|
log-rotation-configuration-expiry
|
|
|
|
|
|
log-rotation-configuration-size-threshold
|
|
|
|
|
|
log-rotation-service-type
|
|
|
|
|
|
|
2022-03-31 23:14:39 +02:00
|
|
|
|
log-cleanup-service-type
|
|
|
|
|
|
log-cleanup-configuration
|
|
|
|
|
|
log-cleanup-configuration?
|
|
|
|
|
|
log-cleanup-configuration-directory
|
|
|
|
|
|
log-cleanup-configuration-expiry
|
|
|
|
|
|
log-cleanup-configuration-schedule
|
|
|
|
|
|
|
2023-07-05 10:19:15 +02:00
|
|
|
|
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
|
|
|
|
|
|
|
2023-07-05 11:49:34 +02:00
|
|
|
|
package-database-service-type
|
|
|
|
|
|
package-database-configuration
|
|
|
|
|
|
package-database-configuration?
|
|
|
|
|
|
package-database-configuration-package
|
|
|
|
|
|
package-database-configuration-schedule
|
|
|
|
|
|
package-database-configuration-method
|
|
|
|
|
|
package-database-configuration-channels
|
|
|
|
|
|
|
2020-07-22 20:21:21 +02:00
|
|
|
|
unattended-upgrade-service-type
|
|
|
|
|
|
unattended-upgrade-configuration
|
|
|
|
|
|
unattended-upgrade-configuration?
|
2020-08-24 14:52:39 +02:00
|
|
|
|
unattended-upgrade-configuration-operating-system-file
|
2023-01-02 18:05:24 +01:00
|
|
|
|
unattended-upgrade-configuration-operating-system-expression
|
2020-07-22 20:21:21 +02:00
|
|
|
|
unattended-upgrade-configuration-channels
|
|
|
|
|
|
unattended-upgrade-configuration-schedule
|
|
|
|
|
|
unattended-upgrade-configuration-services-to-restart
|
|
|
|
|
|
unattended-upgrade-configuration-system-expiration
|
|
|
|
|
|
unattended-upgrade-configuration-maximum-duration
|
2024-12-14 16:18:23 -05:00
|
|
|
|
unattended-upgrade-configuration-log-file
|
|
|
|
|
|
|
|
|
|
|
|
resize-file-system-service-type
|
|
|
|
|
|
resize-file-system-configuration
|
|
|
|
|
|
resize-file-system-configuration?
|
|
|
|
|
|
resize-file-system-configuration-file-system
|
|
|
|
|
|
resize-file-system-configuration-cloud-utils
|
|
|
|
|
|
resize-file-system-configuration-e2fsprogs
|
|
|
|
|
|
resize-file-system-configuration-btrfs-progs
|
|
|
|
|
|
resize-file-system-configuration-bcachefs-tools))
|
2016-09-08 01:20:43 +02:00
|
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
;;;
|
2024-12-11 16:12:29 +01:00
|
|
|
|
;;; This module provides basic system administration tools: log rotation,
|
|
|
|
|
|
;;; unattended upgrades, etc.
|
2016-09-08 01:20:43 +02:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
2024-12-11 16:12:29 +01:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Shepherd's log rotation service.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define %default-log-rotation-calendar-event
|
|
|
|
|
|
;; Default calendar event when log rotation is triggered.
|
|
|
|
|
|
#~(calendar-event #:minutes '(0)
|
|
|
|
|
|
#:hours '(22)
|
|
|
|
|
|
#:days-of-week '(sunday)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (gexp-or-integer? x)
|
|
|
|
|
|
(or (gexp? x) (integer? x)))
|
|
|
|
|
|
|
2025-09-28 14:19:00 +02:00
|
|
|
|
(define (gexp-or-symbol? x)
|
|
|
|
|
|
(or (gexp? x) (symbol? x)))
|
|
|
|
|
|
|
2024-12-11 16:12:29 +01:00
|
|
|
|
(define-configuration log-rotation-configuration
|
|
|
|
|
|
(provision
|
|
|
|
|
|
(list-of-symbols '(log-rotation))
|
|
|
|
|
|
"The name(s) of the log rotation Shepherd service."
|
|
|
|
|
|
empty-serializer)
|
|
|
|
|
|
(requirement
|
|
|
|
|
|
(list-of-symbols (if for-home? '() '(user-processes)))
|
|
|
|
|
|
"Dependencies of the log rotation Shepherd service."
|
|
|
|
|
|
empty-serializer)
|
|
|
|
|
|
(calendar-event
|
|
|
|
|
|
(gexp %default-log-rotation-calendar-event)
|
|
|
|
|
|
"Gexp containing the @dfn{calendar event} when log rotation occurs.
|
|
|
|
|
|
@xref{Timers,,, shepherd, The GNU Shepherd Manual}, for more information on
|
|
|
|
|
|
calendar events."
|
|
|
|
|
|
empty-serializer)
|
|
|
|
|
|
(external-log-files
|
|
|
|
|
|
(list-of-strings '())
|
|
|
|
|
|
"List of file names, external log files that should also be
|
|
|
|
|
|
rotated."
|
|
|
|
|
|
empty-serializer)
|
|
|
|
|
|
(compression
|
2025-09-28 14:19:00 +02:00
|
|
|
|
(gexp-or-symbol 'zstd)
|
|
|
|
|
|
"The compression method used for rotated log files, one of @code{'none},
|
|
|
|
|
|
@code{'gzip}, and @code{'zstd}. Alternatively, it can be a gexp that evaluates
|
|
|
|
|
|
to a procedure; that procedure gets called with the file to be rotated."
|
2024-12-11 16:12:29 +01:00
|
|
|
|
empty-serializer)
|
|
|
|
|
|
(expiry
|
|
|
|
|
|
(gexp-or-integer #~(%default-log-expiry))
|
|
|
|
|
|
"Age in seconds after which a log file is deleted."
|
|
|
|
|
|
empty-serializer)
|
|
|
|
|
|
(size-threshold
|
|
|
|
|
|
(gexp-or-integer #~(%default-rotation-size-threshold))
|
|
|
|
|
|
"Size in bytes below which a log file is @emph{not} rotated."
|
|
|
|
|
|
empty-serializer))
|
|
|
|
|
|
|
|
|
|
|
|
(define (log-rotation-shepherd-services config)
|
2025-09-28 14:19:00 +02:00
|
|
|
|
(let* ((compression-raw (log-rotation-configuration-compression config))
|
|
|
|
|
|
(compression
|
|
|
|
|
|
(if (symbol? compression-raw)
|
|
|
|
|
|
#~'#$compression-raw
|
|
|
|
|
|
compression-raw)))
|
|
|
|
|
|
(list (shepherd-service
|
|
|
|
|
|
(provision (log-rotation-configuration-provision config))
|
|
|
|
|
|
(requirement (log-rotation-configuration-requirement config))
|
|
|
|
|
|
(modules '((shepherd service timer) ;for 'calendar-event'
|
|
|
|
|
|
(shepherd service log-rotation)))
|
|
|
|
|
|
(free-form #~(log-rotation-service
|
|
|
|
|
|
#$(log-rotation-configuration-calendar-event config)
|
|
|
|
|
|
#:provision
|
|
|
|
|
|
'#$(log-rotation-configuration-provision config)
|
|
|
|
|
|
#:requirement
|
|
|
|
|
|
'#$(log-rotation-configuration-requirement config)
|
|
|
|
|
|
#:external-log-files
|
|
|
|
|
|
'#$(log-rotation-configuration-external-log-files
|
|
|
|
|
|
config)
|
|
|
|
|
|
#:compression
|
|
|
|
|
|
#$compression
|
|
|
|
|
|
#:expiry
|
|
|
|
|
|
#$(log-rotation-configuration-expiry config)
|
|
|
|
|
|
#:rotation-size-threshold
|
|
|
|
|
|
#$(log-rotation-configuration-size-threshold
|
|
|
|
|
|
config)))))))
|
2024-12-11 16:12:29 +01:00
|
|
|
|
|
|
|
|
|
|
(define log-rotation-service-type
|
|
|
|
|
|
(service-type
|
|
|
|
|
|
(name 'log-rotation)
|
|
|
|
|
|
(description
|
|
|
|
|
|
"Periodically rotate log files using the Shepherd's log rotation service.
|
|
|
|
|
|
Run @command{herd status log-rotation} to view its status, @command{herd files
|
|
|
|
|
|
log-rotation} to list files subject to log rotation.")
|
|
|
|
|
|
(extensions (list (service-extension shepherd-root-service-type
|
|
|
|
|
|
log-rotation-shepherd-services)))
|
|
|
|
|
|
(compose concatenate)
|
|
|
|
|
|
(extend (lambda (config log-files)
|
|
|
|
|
|
(log-rotation-configuration
|
|
|
|
|
|
(inherit config)
|
|
|
|
|
|
(external-log-files
|
|
|
|
|
|
(append (log-rotation-configuration-external-log-files config)
|
|
|
|
|
|
log-files)))))
|
|
|
|
|
|
(default-value (log-rotation-configuration))))
|
|
|
|
|
|
|
2022-03-31 23:14:39 +02:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Build log removal.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define-record-type* <log-cleanup-configuration>
|
|
|
|
|
|
log-cleanup-configuration make-log-cleanup-configuration
|
|
|
|
|
|
log-cleanup-configuration?
|
|
|
|
|
|
(directory log-cleanup-configuration-directory) ;string
|
|
|
|
|
|
(expiry log-cleanup-configuration-expiry ;integer (seconds)
|
|
|
|
|
|
(default (* 6 30 24 3600)))
|
|
|
|
|
|
(schedule log-cleanup-configuration-schedule ;string or gexp
|
|
|
|
|
|
(default "30 12 01,08,15,22 * *")))
|
|
|
|
|
|
|
|
|
|
|
|
(define (log-cleanup-program directory expiry)
|
|
|
|
|
|
(program-file "delete-old-logs"
|
|
|
|
|
|
(with-imported-modules '((guix build utils))
|
|
|
|
|
|
#~(begin
|
|
|
|
|
|
(use-modules (guix build utils))
|
|
|
|
|
|
|
|
|
|
|
|
(let* ((now (car (gettimeofday)))
|
|
|
|
|
|
(logs (find-files #$directory
|
|
|
|
|
|
(lambda (file stat)
|
|
|
|
|
|
(> (- now (stat:mtime stat))
|
|
|
|
|
|
#$expiry)))))
|
|
|
|
|
|
(format #t "deleting ~a log files from '~a'...~%"
|
|
|
|
|
|
(length logs) #$directory)
|
|
|
|
|
|
(for-each delete-file logs))))))
|
|
|
|
|
|
|
2024-12-11 19:48:57 +01:00
|
|
|
|
(define (log-cleanup-shepherd-services configuration)
|
2022-03-31 23:14:39 +02:00
|
|
|
|
(match-record configuration <log-cleanup-configuration>
|
2024-12-11 19:48:57 +01:00
|
|
|
|
(directory expiry schedule)
|
|
|
|
|
|
(let ((program (log-cleanup-program directory expiry)))
|
|
|
|
|
|
(list (shepherd-service
|
|
|
|
|
|
(provision '(log-cleanup))
|
|
|
|
|
|
(requirement '(user-processes))
|
|
|
|
|
|
(modules '((shepherd service timer)))
|
|
|
|
|
|
(start #~(make-timer-constructor
|
|
|
|
|
|
#$(if (string? schedule)
|
|
|
|
|
|
#~(cron-string->calendar-event #$schedule)
|
|
|
|
|
|
schedule)
|
|
|
|
|
|
(command '(#$program))))
|
|
|
|
|
|
(stop #~(make-timer-destructor))
|
2025-03-12 11:32:54 +01:00
|
|
|
|
(actions (list shepherd-trigger-action))
|
2025-02-12 10:11:01 +01:00
|
|
|
|
(documentation "Periodically delete old log files."))))))
|
2022-03-31 23:14:39 +02:00
|
|
|
|
|
|
|
|
|
|
(define log-cleanup-service-type
|
|
|
|
|
|
(service-type
|
|
|
|
|
|
(name 'log-cleanup)
|
|
|
|
|
|
(extensions
|
2024-12-11 19:48:57 +01:00
|
|
|
|
(list (service-extension shepherd-root-service-type
|
|
|
|
|
|
log-cleanup-shepherd-services)))
|
2022-03-31 23:14:39 +02:00
|
|
|
|
(description
|
|
|
|
|
|
"Periodically delete old log files.")))
|
|
|
|
|
|
|
2023-07-05 10:19:15 +02:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; 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
|
2023-08-22 11:00:25 +02:00
|
|
|
|
;; Regexps of directories excluded from the 'locate' database.
|
2023-07-05 10:19:15 +02:00
|
|
|
|
(list (%store-prefix)
|
|
|
|
|
|
"/tmp" "/var/tmp" "/var/cache" ".*/\\.cache"
|
2025-03-12 11:50:40 +01:00
|
|
|
|
"/run/udev" "/dev"))
|
2023-07-05 10:19:15 +02:00
|
|
|
|
|
|
|
|
|
|
(define (string-or-gexp? obj)
|
|
|
|
|
|
(or (string? obj) (gexp? obj)))
|
|
|
|
|
|
|
|
|
|
|
|
(define string-list?
|
|
|
|
|
|
(match-lambda
|
|
|
|
|
|
(((? string?) ...) #t)
|
|
|
|
|
|
(_ #f)))
|
|
|
|
|
|
|
|
|
|
|
|
(define-configuration/no-serialization file-database-configuration
|
|
|
|
|
|
(package
|
|
|
|
|
|
(file-like (let-system (system target)
|
|
|
|
|
|
;; Unless we're cross-compiling, avoid pulling a second copy
|
|
|
|
|
|
;; of findutils.
|
|
|
|
|
|
(if target
|
|
|
|
|
|
findutils
|
|
|
|
|
|
(canonical-package findutils))))
|
2025-03-27 23:36:52 +01:00
|
|
|
|
"The package from which the @command{updatedb} command is taken.
|
|
|
|
|
|
Examples of such packages are GNU@tie{}Findutils and Plocate.")
|
2023-07-05 10:19:15 +02:00
|
|
|
|
(schedule
|
|
|
|
|
|
(string-or-gexp %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}).")
|
|
|
|
|
|
(excluded-directories
|
|
|
|
|
|
(string-list %default-file-database-excluded-directories)
|
2023-08-22 11:00:25 +02:00
|
|
|
|
"List of regular expressions of directories to ignore when building the
|
|
|
|
|
|
file database. By default, this includes @file{/tmp} and @file{/gnu/store};
|
|
|
|
|
|
the latter should instead be indexed by @command{guix locate} (@pxref{Invoking
|
|
|
|
|
|
guix locate}). This list is passed to the @option{--prunepaths} option of
|
2023-07-05 10:19:15 +02:00
|
|
|
|
@command{updatedb} (@pxref{Invoking updatedb,,, find, GNU@tie{}Findutils})."))
|
|
|
|
|
|
|
2025-03-12 11:48:39 +01:00
|
|
|
|
(define (file-database-shepherd-services configuration)
|
2023-07-05 10:19:15 +02:00
|
|
|
|
(match-record configuration <file-database-configuration>
|
|
|
|
|
|
(package schedule excluded-directories)
|
|
|
|
|
|
(let ((updatedb (program-file
|
|
|
|
|
|
"updatedb"
|
2023-08-22 10:20:11 +02:00
|
|
|
|
#~(begin
|
2025-03-27 23:36:52 +01:00
|
|
|
|
(define updatedb
|
|
|
|
|
|
(let ((try (lambda (file)
|
|
|
|
|
|
(and (file-exists? file) file))))
|
|
|
|
|
|
(or (try #$(file-append package "/bin/updatedb"))
|
|
|
|
|
|
(try #$(file-append package "/sbin/updatedb")))))
|
2023-08-22 10:20:11 +02:00
|
|
|
|
;; 'updatedb' is a shell script that expects various
|
|
|
|
|
|
;; commands in $PATH.
|
|
|
|
|
|
(setenv "PATH"
|
2025-03-27 23:36:52 +01:00
|
|
|
|
(string-append (dirname updatedb) ":"
|
2023-08-22 10:20:11 +02:00
|
|
|
|
#$(canonical-package coreutils)
|
|
|
|
|
|
"/bin:"
|
|
|
|
|
|
#$(canonical-package sed)
|
|
|
|
|
|
"/bin"))
|
2025-03-27 23:36:52 +01:00
|
|
|
|
(execl updatedb
|
2023-08-22 10:20:11 +02:00
|
|
|
|
"updatedb"
|
|
|
|
|
|
#$(string-append "--prunepaths="
|
|
|
|
|
|
(string-join
|
|
|
|
|
|
excluded-directories)))))))
|
2025-03-12 11:48:39 +01:00
|
|
|
|
(list (shepherd-service
|
|
|
|
|
|
(provision '(file-database-update))
|
|
|
|
|
|
(requirement '(user-processes))
|
|
|
|
|
|
(modules '((shepherd service timer)))
|
|
|
|
|
|
(start #~(make-timer-constructor
|
|
|
|
|
|
#$(if (string? schedule)
|
|
|
|
|
|
#~(cron-string->calendar-event #$schedule)
|
|
|
|
|
|
schedule)
|
|
|
|
|
|
(command '(#$updatedb))
|
|
|
|
|
|
#:wait-for-termination? #t))
|
|
|
|
|
|
(stop #~(make-timer-destructor))
|
|
|
|
|
|
(documentation
|
|
|
|
|
|
"Periodically update the system-wide file database that can be
|
|
|
|
|
|
queried by the 'locate' command.")
|
|
|
|
|
|
(actions (list shepherd-trigger-action)))))))
|
2023-07-05 10:19:15 +02:00
|
|
|
|
|
|
|
|
|
|
(define file-database-service-type
|
|
|
|
|
|
(service-type
|
|
|
|
|
|
(name 'file-database)
|
2025-03-12 11:48:39 +01:00
|
|
|
|
(extensions (list (service-extension shepherd-root-service-type
|
|
|
|
|
|
file-database-shepherd-services)))
|
2023-07-05 10:19:15 +02:00
|
|
|
|
(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))))
|
|
|
|
|
|
|
2023-07-05 11:49:34 +02:00
|
|
|
|
(define %default-package-database-update-schedule
|
|
|
|
|
|
;; Default mcron schedule for the periodic 'guix locate --update' job: once
|
|
|
|
|
|
;; every Monday.
|
|
|
|
|
|
"10 23 * * 1")
|
|
|
|
|
|
|
|
|
|
|
|
(define-configuration/no-serialization package-database-configuration
|
|
|
|
|
|
(package (file-like guix)
|
|
|
|
|
|
"The Guix package to use.")
|
|
|
|
|
|
(schedule (string-or-gexp
|
|
|
|
|
|
%default-package-database-update-schedule)
|
|
|
|
|
|
"String or G-exp denoting an mcron schedule for the periodic
|
|
|
|
|
|
@command{guix locate --update} job (@pxref{Guile Syntax,,, mcron,
|
|
|
|
|
|
GNU@tie{}mcron}).")
|
|
|
|
|
|
(method (symbol 'store)
|
|
|
|
|
|
"Indexing method for @command{guix locate}. The default value,
|
|
|
|
|
|
@code{'store}, yields a more complete database but is relatively expensive in
|
|
|
|
|
|
terms of CPU and input/output.")
|
|
|
|
|
|
(channels (gexp #~%default-channels)
|
|
|
|
|
|
"G-exp denoting the channels to use when updating the database
|
|
|
|
|
|
(@pxref{Channels})."))
|
|
|
|
|
|
|
2025-03-12 16:14:32 +01:00
|
|
|
|
(define (package-database-shepherd-services configuration)
|
2023-07-05 11:49:34 +02:00
|
|
|
|
(match-record configuration <package-database-configuration>
|
|
|
|
|
|
(package schedule method channels)
|
|
|
|
|
|
(let ((channels (scheme-file "channels.scm" channels)))
|
2025-03-12 16:14:32 +01:00
|
|
|
|
(list (shepherd-service
|
|
|
|
|
|
(provision '(package-database-update))
|
|
|
|
|
|
(requirement '(user-processes guix-daemon))
|
|
|
|
|
|
(modules '((shepherd service timer)))
|
|
|
|
|
|
;; XXX: The whole thing's running as "root" just because it needs
|
|
|
|
|
|
;; write access to /var/cache/guix/locate.
|
|
|
|
|
|
(start #~(make-timer-constructor
|
|
|
|
|
|
#$(if (string? schedule)
|
|
|
|
|
|
#~(cron-string->calendar-event #$schedule)
|
|
|
|
|
|
schedule)
|
|
|
|
|
|
(command '(#$(file-append package "/bin/guix")
|
|
|
|
|
|
"time-machine" "-C" #$channels
|
|
|
|
|
|
"--" "locate" "--update"
|
|
|
|
|
|
#$(string-append
|
|
|
|
|
|
"--method=" (symbol->string method))))
|
|
|
|
|
|
#:wait-for-termination? #t))
|
|
|
|
|
|
(stop #~(make-timer-destructor))
|
|
|
|
|
|
(documentation
|
|
|
|
|
|
"Periodically update the system-wide package database that can
|
|
|
|
|
|
be queried by the 'guix locate' command.")
|
|
|
|
|
|
(actions (list shepherd-trigger-action)))))))
|
2023-07-05 11:49:34 +02:00
|
|
|
|
|
|
|
|
|
|
(define package-database-service-type
|
|
|
|
|
|
(service-type
|
|
|
|
|
|
(name 'package-database)
|
2025-03-12 16:14:32 +01:00
|
|
|
|
(extensions (list (service-extension shepherd-root-service-type
|
|
|
|
|
|
package-database-shepherd-services)))
|
2023-07-05 11:49:34 +02:00
|
|
|
|
(description
|
|
|
|
|
|
"Periodically update the package database used by the @code{guix locate} command,
|
|
|
|
|
|
which lets you search for packages that provide a given file.")
|
|
|
|
|
|
(default-value (package-database-configuration))))
|
|
|
|
|
|
|
2020-07-22 20:21:21 +02:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Unattended upgrade.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define-record-type* <unattended-upgrade-configuration>
|
|
|
|
|
|
unattended-upgrade-configuration make-unattended-upgrade-configuration
|
|
|
|
|
|
unattended-upgrade-configuration?
|
2020-08-24 14:52:39 +02:00
|
|
|
|
(operating-system-file unattended-upgrade-operating-system-file
|
|
|
|
|
|
(default "/run/current-system/configuration.scm"))
|
2023-01-02 18:05:24 +01:00
|
|
|
|
(operating-system-expression unattended-upgrade-operating-system-expression
|
|
|
|
|
|
(default #f))
|
2020-07-22 20:21:21 +02:00
|
|
|
|
(schedule unattended-upgrade-configuration-schedule
|
|
|
|
|
|
(default "30 01 * * 0"))
|
|
|
|
|
|
(channels unattended-upgrade-configuration-channels
|
|
|
|
|
|
(default #~%default-channels))
|
2024-04-29 00:34:20 -04:00
|
|
|
|
(reboot? unattended-upgrade-configuration-reboot?
|
|
|
|
|
|
(default #f))
|
2020-07-22 20:21:21 +02:00
|
|
|
|
(services-to-restart unattended-upgrade-configuration-services-to-restart
|
2024-12-11 22:59:17 +01:00
|
|
|
|
(default '(unattended-upgrade)))
|
2020-07-22 20:21:21 +02:00
|
|
|
|
(system-expiration unattended-upgrade-system-expiration
|
|
|
|
|
|
(default (* 3 30 24 3600)))
|
|
|
|
|
|
(maximum-duration unattended-upgrade-maximum-duration
|
|
|
|
|
|
(default 3600))
|
|
|
|
|
|
(log-file unattended-upgrade-configuration-log-file
|
|
|
|
|
|
(default %unattended-upgrade-log-file)))
|
|
|
|
|
|
|
|
|
|
|
|
(define %unattended-upgrade-log-file
|
|
|
|
|
|
"/var/log/unattended-upgrade.log")
|
|
|
|
|
|
|
2024-12-11 22:59:17 +01:00
|
|
|
|
(define (unattended-upgrade-shepherd-services config)
|
2020-07-22 20:21:21 +02:00
|
|
|
|
(define channels
|
|
|
|
|
|
(scheme-file "channels.scm"
|
|
|
|
|
|
(unattended-upgrade-configuration-channels config)))
|
|
|
|
|
|
|
|
|
|
|
|
(define log
|
|
|
|
|
|
(unattended-upgrade-configuration-log-file config))
|
|
|
|
|
|
|
2024-12-11 22:59:17 +01:00
|
|
|
|
(define schedule
|
|
|
|
|
|
(unattended-upgrade-configuration-schedule config))
|
|
|
|
|
|
|
2020-07-22 20:21:21 +02:00
|
|
|
|
(define services
|
|
|
|
|
|
(unattended-upgrade-configuration-services-to-restart config))
|
|
|
|
|
|
|
2024-04-29 00:34:20 -04:00
|
|
|
|
(define reboot?
|
|
|
|
|
|
(unattended-upgrade-configuration-reboot? config))
|
|
|
|
|
|
|
2020-07-22 20:21:21 +02:00
|
|
|
|
(define expiration
|
|
|
|
|
|
(unattended-upgrade-system-expiration config))
|
|
|
|
|
|
|
2020-08-24 14:52:39 +02:00
|
|
|
|
(define config-file
|
|
|
|
|
|
(unattended-upgrade-operating-system-file config))
|
|
|
|
|
|
|
2023-01-02 18:05:24 +01:00
|
|
|
|
(define expression
|
|
|
|
|
|
(unattended-upgrade-operating-system-expression config))
|
|
|
|
|
|
|
|
|
|
|
|
(define arguments
|
|
|
|
|
|
(if expression
|
|
|
|
|
|
#~(list "-e" (object->string '#$expression))
|
|
|
|
|
|
#~(list #$config-file)))
|
|
|
|
|
|
|
2020-07-22 20:21:21 +02:00
|
|
|
|
(define code
|
|
|
|
|
|
(with-imported-modules (source-module-closure '((guix build utils)
|
|
|
|
|
|
(gnu services herd)))
|
|
|
|
|
|
#~(begin
|
|
|
|
|
|
(use-modules (guix build utils)
|
|
|
|
|
|
(gnu services herd)
|
|
|
|
|
|
(srfi srfi-34))
|
|
|
|
|
|
|
2024-12-11 22:59:17 +01:00
|
|
|
|
(setvbuf (current-output-port) 'line)
|
|
|
|
|
|
(setvbuf (current-error-port) 'line)
|
2020-07-22 20:21:21 +02:00
|
|
|
|
|
|
|
|
|
|
;; 'guix time-machine' needs X.509 certificates to authenticate the
|
|
|
|
|
|
;; Git host.
|
|
|
|
|
|
(setenv "SSL_CERT_DIR"
|
|
|
|
|
|
#$(file-append nss-certs "/etc/ssl/certs"))
|
|
|
|
|
|
|
2024-12-11 22:59:17 +01:00
|
|
|
|
(format #t "starting upgrade...~%")
|
2020-08-24 22:59:43 +02:00
|
|
|
|
(guard (c ((invoke-error? c)
|
2025-03-26 15:52:37 +01:00
|
|
|
|
(report-invoke-error c)
|
|
|
|
|
|
(exit 1)))
|
2023-01-02 18:05:24 +01:00
|
|
|
|
(apply invoke #$(file-append guix "/bin/guix")
|
|
|
|
|
|
"time-machine" "-C" #$channels
|
|
|
|
|
|
"--" "system" "reconfigure" #$arguments)
|
2020-08-24 22:59:43 +02:00
|
|
|
|
|
|
|
|
|
|
;; 'guix system delete-generations' fails when there's no
|
|
|
|
|
|
;; matching generation. Thus, catch 'invoke-error?'.
|
|
|
|
|
|
(guard (c ((invoke-error? c)
|
|
|
|
|
|
(report-invoke-error c)))
|
|
|
|
|
|
(invoke #$(file-append guix "/bin/guix")
|
|
|
|
|
|
"system" "delete-generations"
|
|
|
|
|
|
#$(string-append (number->string expiration)
|
|
|
|
|
|
"s")))
|
|
|
|
|
|
|
2024-12-03 18:28:13 -05:00
|
|
|
|
(unless #$reboot?
|
|
|
|
|
|
;; Rebooting effectively restarts services anyway and execution
|
|
|
|
|
|
;; would be halted here if mcron is restarted.
|
2024-12-11 22:59:17 +01:00
|
|
|
|
(format #t "restarting services...~%")
|
2024-12-03 18:28:13 -05:00
|
|
|
|
(for-each restart-service '#$services))
|
2020-08-24 22:59:43 +02:00
|
|
|
|
|
2024-12-11 22:59:17 +01:00
|
|
|
|
;; XXX: If this service has been restarted, this is not reached.
|
|
|
|
|
|
(format #t "upgrade complete~%")
|
2024-04-29 00:34:20 -04:00
|
|
|
|
|
|
|
|
|
|
;; Stopping the root shepherd service triggers a reboot.
|
|
|
|
|
|
(when #$reboot?
|
2024-12-11 22:59:17 +01:00
|
|
|
|
(format #t "rebooting system~%")
|
2024-04-29 00:34:20 -04:00
|
|
|
|
(force-output) ;ensure the entire log is written.
|
|
|
|
|
|
(stop-service 'root))))))
|
2020-07-22 20:21:21 +02:00
|
|
|
|
|
|
|
|
|
|
(define upgrade
|
|
|
|
|
|
(program-file "unattended-upgrade" code))
|
|
|
|
|
|
|
2024-12-11 22:59:17 +01:00
|
|
|
|
(list (shepherd-service
|
|
|
|
|
|
(provision '(unattended-upgrade))
|
|
|
|
|
|
(requirement '(user-processes networking))
|
|
|
|
|
|
(modules '((shepherd service timer)))
|
|
|
|
|
|
(start #~(make-timer-constructor
|
|
|
|
|
|
#$(if (string? schedule)
|
|
|
|
|
|
#~(cron-string->calendar-event #$schedule)
|
|
|
|
|
|
schedule)
|
|
|
|
|
|
(command '(#$upgrade))
|
|
|
|
|
|
|
|
|
|
|
|
#:log-file #$log
|
|
|
|
|
|
|
|
|
|
|
|
;; Make sure the upgrade doesn't take too long.
|
|
|
|
|
|
#:max-duration
|
|
|
|
|
|
#$(unattended-upgrade-maximum-duration config)
|
|
|
|
|
|
|
|
|
|
|
|
;; Wait for the previous attempt to terminate before trying
|
|
|
|
|
|
;; again.
|
|
|
|
|
|
#:wait-for-termination? #t))
|
|
|
|
|
|
(stop #~(make-timer-destructor))
|
2025-03-12 11:32:54 +01:00
|
|
|
|
(actions (list shepherd-trigger-action)))))
|
2020-07-22 20:21:21 +02:00
|
|
|
|
|
|
|
|
|
|
(define unattended-upgrade-service-type
|
|
|
|
|
|
(service-type
|
|
|
|
|
|
(name 'unattended-upgrade)
|
|
|
|
|
|
(extensions
|
2024-12-11 22:59:17 +01:00
|
|
|
|
(list (service-extension shepherd-root-service-type
|
2024-12-11 23:32:45 +01:00
|
|
|
|
unattended-upgrade-shepherd-services)))
|
2020-07-22 20:21:21 +02:00
|
|
|
|
(description
|
|
|
|
|
|
"Periodically upgrade the system from the current configuration.")
|
|
|
|
|
|
(default-value (unattended-upgrade-configuration))))
|
|
|
|
|
|
|
2024-12-14 16:18:23 -05:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; Resize file system.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define-record-type* <resize-file-system-configuration>
|
|
|
|
|
|
resize-file-system-configuration make-resize-file-system-configuration
|
|
|
|
|
|
resize-file-system-configuration?
|
2024-12-30 10:30:00 +01:00
|
|
|
|
(file-system resize-file-system-file-system)
|
2024-12-14 16:18:23 -05:00
|
|
|
|
(cloud-utils resize-file-system-cloud-utils
|
|
|
|
|
|
(default cloud-utils))
|
|
|
|
|
|
(e2fsprogs resize-file-system-e2fsprogs
|
|
|
|
|
|
(default e2fsprogs))
|
|
|
|
|
|
(btrfs-progs resize-file-system-btrfs-progs
|
|
|
|
|
|
(default btrfs-progs))
|
|
|
|
|
|
(bcachefs-tools resize-file-system-bcachefs-tools
|
|
|
|
|
|
(default bcachefs-tools)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (resize-file-system-shepherd-service config)
|
|
|
|
|
|
"Returns a <shepherd-service> for resize-file-system-service for CONFIG."
|
|
|
|
|
|
(match-record config <resize-file-system-configuration>
|
|
|
|
|
|
(file-system cloud-utils e2fsprogs btrfs-progs
|
|
|
|
|
|
bcachefs-tools)
|
|
|
|
|
|
(let ((fs-spec (file-system->spec file-system)))
|
|
|
|
|
|
(shepherd-service
|
|
|
|
|
|
(documentation "Resize a file system. Intended for Guix Systems that
|
|
|
|
|
|
are booted from a system image flashed onto a larger medium.")
|
|
|
|
|
|
;; XXX: This could be extended with file-system info.
|
|
|
|
|
|
(provision '(resize-file-system))
|
|
|
|
|
|
(requirement '(user-processes))
|
|
|
|
|
|
(one-shot? #t)
|
|
|
|
|
|
(respawn? #f)
|
|
|
|
|
|
(modules '((guix build utils)
|
|
|
|
|
|
(gnu build file-systems)
|
|
|
|
|
|
(gnu system file-systems)
|
|
|
|
|
|
(ice-9 control)
|
|
|
|
|
|
(ice-9 match)
|
|
|
|
|
|
(ice-9 ftw)
|
|
|
|
|
|
(ice-9 rdelim)
|
|
|
|
|
|
(srfi srfi-34)))
|
|
|
|
|
|
(start (with-imported-modules (source-module-closure
|
|
|
|
|
|
'((guix build utils)
|
|
|
|
|
|
(gnu build file-systems)
|
|
|
|
|
|
(gnu system file-systems)))
|
|
|
|
|
|
#~(lambda _
|
|
|
|
|
|
(use-modules (guix build utils)
|
|
|
|
|
|
(gnu build file-systems)
|
|
|
|
|
|
(gnu system file-systems)
|
|
|
|
|
|
(ice-9 control)
|
|
|
|
|
|
(ice-9 match)
|
|
|
|
|
|
(ice-9 ftw)
|
|
|
|
|
|
(ice-9 rdelim)
|
|
|
|
|
|
(srfi srfi-34))
|
|
|
|
|
|
|
|
|
|
|
|
(define file-system
|
|
|
|
|
|
(spec->file-system '#$fs-spec))
|
|
|
|
|
|
|
|
|
|
|
|
;; Shepherd recommends the start constructor takes <1
|
|
|
|
|
|
;; minute, canonicalize-device-spec will hang for up to
|
|
|
|
|
|
;; max-trials seconds (20 seconds) if an invalid device is
|
|
|
|
|
|
;; connected. Revisit this if max-trials increases.
|
|
|
|
|
|
(define device (canonicalize-device-spec
|
|
|
|
|
|
(file-system-device file-system)))
|
|
|
|
|
|
|
|
|
|
|
|
(define grow-partition-command
|
|
|
|
|
|
(let* ((sysfs-device
|
|
|
|
|
|
(string-append "/sys/class/block/"
|
|
|
|
|
|
(basename device)))
|
|
|
|
|
|
(partition-number
|
|
|
|
|
|
(with-input-from-file
|
|
|
|
|
|
(string-append sysfs-device
|
|
|
|
|
|
"/partition")
|
|
|
|
|
|
read-line))
|
|
|
|
|
|
(parent (string-append
|
|
|
|
|
|
"/dev/"
|
|
|
|
|
|
(basename (dirname (readlink sysfs-device))))))
|
|
|
|
|
|
(list #$(file-append cloud-utils "/bin/growpart")
|
|
|
|
|
|
parent partition-number)))
|
|
|
|
|
|
|
|
|
|
|
|
(define grow-filesystem-command
|
|
|
|
|
|
(match (file-system-type file-system)
|
|
|
|
|
|
((or "ext2" "ext3" "ext4")
|
|
|
|
|
|
(list #$(file-append e2fsprogs "/sbin/resize2fs") device))
|
|
|
|
|
|
("btrfs"
|
|
|
|
|
|
(list #$(file-append btrfs-progs "/bin/btrfs")
|
|
|
|
|
|
"filesystem" "resize" device))
|
|
|
|
|
|
("bcachefs"
|
|
|
|
|
|
(list #$(file-append bcachefs-tools "/sbin/bcachefs")
|
|
|
|
|
|
"device" "resize" device))
|
|
|
|
|
|
(e (error "Unsupported filesystem type" e))))
|
|
|
|
|
|
|
|
|
|
|
|
(let/ec return
|
|
|
|
|
|
(guard (c ((and (invoke-error? c)
|
|
|
|
|
|
;; growpart NOCHANGE exits with 1. It is
|
|
|
|
|
|
;; unlikely the partition was resized
|
|
|
|
|
|
;; while the file system was not. Just
|
|
|
|
|
|
;; exit.
|
|
|
|
|
|
(equal? (invoke-error-exit-status c) 1))
|
|
|
|
|
|
(format (current-error-port)
|
|
|
|
|
|
"The device ~a is already resized.~%" device)
|
|
|
|
|
|
;; Must return something or Shepherd considers
|
|
|
|
|
|
;; the service perpetually starting.
|
|
|
|
|
|
(return 0)))
|
|
|
|
|
|
(apply invoke grow-partition-command))
|
|
|
|
|
|
(apply invoke grow-filesystem-command)))))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define resize-file-system-service-type
|
|
|
|
|
|
(service-type
|
|
|
|
|
|
(name 'resize-file-system)
|
|
|
|
|
|
(description "Resize a partition and the underlying file system during boot.")
|
|
|
|
|
|
(extensions
|
|
|
|
|
|
(list
|
|
|
|
|
|
(service-extension shepherd-root-service-type
|
2024-12-30 10:30:00 +01:00
|
|
|
|
(compose list resize-file-system-shepherd-service))))))
|
2024-12-14 16:18:23 -05:00
|
|
|
|
|
2016-09-08 01:20:43 +02:00
|
|
|
|
;;; admin.scm ends here
|