Skip to content

Commit

Permalink
nixos/hot-resize: init
Browse files Browse the repository at this point in the history
  • Loading branch information
liberodark committed Dec 11, 2024
1 parent 1784028 commit 3706030
Showing 1 changed file with 140 additions and 0 deletions.
140 changes: 140 additions & 0 deletions nixos/modules/services/system/hot-resize.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
{
config,
lib,
pkgs,
...
}:

let
cfg = config.services.hotResize;
in
{
options.services.hotResize = {
enable = lib.mkEnableOption "the hot resize service for filesystems";

devices = lib.mkOption {
type = lib.types.listOf (
lib.types.submodule {
options = {
device = lib.mkOption {
type = lib.types.str;
example = "/dev/sda1";
description = "Block device path to resize";
};

fsType = lib.mkOption {
type = lib.types.enum [
"ext4"
"xfs"
"btrfs"
];
default = "ext4";
description = "Filesystem type (supported: ext4, xfs, btrfs)";
};

mountPoint = lib.mkOption {
type = lib.types.str;
example = "/";
description = "Mount point of the filesystem to resize";
};
};
}
);
default = [ ];
example = lib.literalExpression ''
[
{
device = "/dev/sda1";
fsType = "ext4";
mountPoint = "/";
}
{
device = "/dev/sdb1";
fsType = "xfs";
mountPoint = "/data";
}
]
'';
description = "List of devices to monitor for resizing";
};
};

config = lib.mkIf cfg.enable {
systemd.services.hotResize = {
description = "Hot resize service for filesystems";
wantedBy = [ "multi-user.target" ];

path = [
pkgs.parted
pkgs.cloud-utils
pkgs.coreutils
pkgs.util-linux
pkgs.e2fsprogs
pkgs.xfsprogs
pkgs.btrfs-progs
];

serviceConfig = {
Type = "oneshot";
RemainAfterExit = false;
ExecStart = pkgs.writeShellScript "resize-fs" ''
set -euo pipefail
process_device() {
local device="$1"
local fstype="$2"
local mountpoint="$3"
echo "Processing $device ($fstype) mounted at $mountpoint..."
REAL_DEVICE=$(readlink -f "$device")
DISK=$(lsblk -ndo pkname $REAL_DEVICE)
PART_NUM=$(lsblk -ndo part $REAL_DEVICE)
if [ -z "$DISK" ] || [ -z "$PART_NUM" ]; then
echo "Failed to determine disk and partition number for $device"
return 1
fi
echo "Growing partition /dev/$DISK partition $PART_NUM..."
GROWPART_OUTPUT=$(growpart "/dev/$DISK" "$PART_NUM" 2>&1) || {
EXIT_CODE=$?
if [ $EXIT_CODE -eq 2 ]; then
echo "Partition is already at maximum size, continuing with filesystem resize..."
else
echo "Failed to grow partition: $GROWPART_OUTPUT"
return $EXIT_CODE
fi
}
echo "Resizing filesystem..."
case "$fstype" in
"ext4")
resize2fs "$device"
;;
"xfs")
xfs_growfs "$mountpoint"
;;
"btrfs")
btrfs filesystem resize max "$mountpoint"
;;
*)
echo "Unsupported filesystem type: $fstype"
return 1
;;
esac
echo "Current size:"
df -h "$mountpoint"
echo "---"
}
# Process each device in sequence
${lib.concatMapStrings (dev: ''
process_device "${dev.device}" "${dev.fsType}" "${dev.mountPoint}"
'') cfg.devices}
'';
};
};
};
}

0 comments on commit 3706030

Please sign in to comment.