From: Richard Sent <richard@freakingpenguin.com>
To: 74837@debbugs.gnu.org
Cc: "Richard Sent" <richard@freakingpenguin.com>,
"Ludovic Courtès" <ludo@gnu.org>,
"Maxim Cournoyer" <maxim.cournoyer@gmail.com>
Subject: [bug#74837] [PATCH v3 2/2] gnu: services: Add resize-file-system-service.
Date: Sat, 14 Dec 2024 16:18:23 -0500 [thread overview]
Message-ID: <7dfc8384a8e73be14ae385b0761bd3f4280f405a.1734211103.git.richard@freakingpenguin.com> (raw)
In-Reply-To: <cover.1734211103.git.richard@freakingpenguin.com>
* gnu/services/admin.scm (resize-file-system-configuration): New configuration
type.
(resize-file-system-shepherd-service): New procedure.
(resize-file-system-service-type): New variable.
* doc/guix.texi (Miscallaneous Services): Document it.
Change-Id: Icae2fefc9a8d936d4c3add47520258b341f689a4
---
doc/guix.texi | 54 +++++++++++++++++
gnu/services/admin.scm | 133 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 186 insertions(+), 1 deletion(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index a2915de954..cc19fb6cff 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -41891,6 +41891,60 @@ Miscellaneous Services
@c End of auto-generated fail2ban documentation.
+@cindex resize-file-system
+@subsubheading Resize File System Service
+
+This service type lets you resize a live file system during boot, which
+can be convenient if a Guix image is flashed on an SD Card (e.g. for an
+embedded device) or uploaded to a VPS. In both cases the medium the
+image will reside upon may be larger than the image you want to produce.
+
+For an embedded device booting from an SD card you may use something like:
+@lisp
+(service resize-file-system-service-type
+ (resize-file-system-configuration
+ (file-system
+ (file-system (device (file-system-label "root"))
+ (type "ext4")))))
+@end lisp
+
+@quotation Warning
+Be extra cautious to use the correct device and type. The service has
+little error handling of its own and relies on the underlying tools.
+Wrong use could end in loss of data or the corruption of the operating
+system.
+@end quotation
+
+Partitions and file systems are grown to the maximum size available.
+File systems can only grow when they are on the last partition on a
+device and have empty space available.
+
+This service supports the ext2, ext3, ext4, btrfs, and bcachefs file
+systems.
+
+@table @asis
+
+@item @code{file-system} (default: @code{#f}) (type: file-system)
+The file-system object to resize (@pxref{File Systems}). This object
+must have the @code{device} and @code{type} fields set. Other fields
+are ignored.
+
+@item @code{cloud-utils} (default: @code{cloud-utils}) (type: file-like)
+The cloud-utils package to use. This package is used for the
+@code{growpart} command.
+
+@item @code{e2fsprogs} (default: @code{e2fsprogs}) (type: file-like)
+The e2fsprogs package to use, used for resizing ext2, ext3, and ext4
+file systems.
+
+@item @code{btrfs-progs} (default: @code{btrfs-progs}) (type: file-like)
+The btrfs-progs package to use, used for resizing the btrfs file system.
+
+@item @code{bcachefs-tools} (default: @code{bcachefs-tools}) (type: file-like)
+The bcachefs-tools package to use, used for resizing the bcachefs file system.
+
+@end table
+
@cindex Backup
@subsubheading Backup Services
diff --git a/gnu/services/admin.scm b/gnu/services/admin.scm
index 24ff659a01..4a2f5cb12d 100644
--- a/gnu/services/admin.scm
+++ b/gnu/services/admin.scm
@@ -3,6 +3,8 @@
;;; Copyright © 2016-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
+;;; Copyright © 2024 Gabriel Wicki <gabriel@erlikon.ch>
+;;; Copyright © 2024 Richard Sent <richard@freakingpenguin.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -20,11 +22,15 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (gnu services admin)
+ #:use-module (gnu system file-systems)
#:use-module (gnu packages admin)
#:use-module ((gnu packages base)
#:select (canonical-package findutils coreutils sed))
+ #:use-module (gnu packages file-systems)
#:use-module (gnu packages certs)
+ #:use-module (gnu packages disk)
#:use-module (gnu packages package-management)
+ #:use-module (gnu packages linux)
#:use-module (gnu services)
#:use-module (gnu services configuration)
#:use-module (gnu services mcron)
@@ -93,7 +99,16 @@ (define-module (gnu services admin)
unattended-upgrade-configuration-services-to-restart
unattended-upgrade-configuration-system-expiration
unattended-upgrade-configuration-maximum-duration
- unattended-upgrade-configuration-log-file))
+ 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))
;;; Commentary:
;;;
@@ -550,4 +565,120 @@ (define unattended-upgrade-service-type
"Periodically upgrade the system from the current configuration.")
(default-value (unattended-upgrade-configuration))))
+;;;
+;;; Resize file system.
+;;;
+
+(define-record-type* <resize-file-system-configuration>
+ resize-file-system-configuration make-resize-file-system-configuration
+ resize-file-system-configuration?
+ (file-system resize-file-system-file-system
+ (default #f))
+ (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
+ (compose list resize-file-system-shepherd-service))))
+ (default-value (resize-file-system-configuration))))
+
;;; admin.scm ends here
--
2.46.0
prev parent reply other threads:[~2024-12-14 21:36 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-12 20:16 [bug#74837] [PATCH 0/2] Add resize-fs service Richard Sent
2024-12-12 20:18 ` [bug#74837] [PATCH 1/2] gnu: services: Add resize-fs-service Richard Sent
2024-12-12 20:19 ` [bug#74837] [PATCH 2/2] packages: cloud-utils: Add missing growpart programs to path Richard Sent
2024-12-12 21:15 ` [bug#74837] [PATCH v2 1/2] gnu: services: Add resize-fs-service Richard Sent
2024-12-12 21:15 ` [bug#74837] [PATCH v2 2/2] packages: cloud-utils: Add missing growpart programs to path Richard Sent
2024-12-14 15:23 ` [bug#74837] [PATCH v2 1/2] gnu: services: Add resize-fs-service Ludovic Courtès
2024-12-14 21:18 ` [bug#74837] [PATCH v3 0/2] resize-file-system-service Richard Sent
2024-12-14 21:18 ` [bug#74837] [PATCH v3 1/2] packages: cloud-utils: Add missing growpart programs to path Richard Sent
2024-12-14 21:18 ` Richard Sent [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://guix.gnu.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7dfc8384a8e73be14ae385b0761bd3f4280f405a.1734211103.git.richard@freakingpenguin.com \
--to=richard@freakingpenguin.com \
--cc=74837@debbugs.gnu.org \
--cc=ludo@gnu.org \
--cc=maxim.cournoyer@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).