1# This module automatically grows the root partition.
2# This allows an instance to be created with a bigger root filesystem
3# than provided by the machine image.
4
5{
6 config,
7 lib,
8 pkgs,
9 ...
10}:
11
12with lib;
13
14{
15 imports = [
16 (mkRenamedOptionModule [ "virtualisation" "growPartition" ] [ "boot" "growPartition" ])
17 ];
18
19 options = {
20 boot.growPartition = mkEnableOption "growing the root partition on boot";
21 };
22
23 config = mkIf config.boot.growPartition {
24 assertions = [
25 {
26 assertion = !config.boot.initrd.systemd.repart.enable && !config.systemd.repart.enable;
27 message = "systemd-repart already grows the root partition and thus you should not use boot.growPartition";
28 }
29 ];
30 systemd.services.growpart = {
31 wantedBy = [ "-.mount" ];
32 after = [ "-.mount" ];
33 before = [
34 "systemd-growfs-root.service"
35 "shutdown.target"
36 ];
37 conflicts = [ "shutdown.target" ];
38 unitConfig.DefaultDependencies = false;
39 serviceConfig = {
40 Type = "oneshot";
41 RemainAfterExit = true;
42 TimeoutSec = "infinity";
43 # growpart returns 1 if the partition is already grown
44 SuccessExitStatus = "0 1";
45 };
46
47 script = ''
48 rootDevice="${config.fileSystems."/".device}"
49 rootDevice="$(readlink -f "$rootDevice")"
50 parentDevice="$rootDevice"
51 while [ "''${parentDevice%[0-9]}" != "''${parentDevice}" ]; do
52 parentDevice="''${parentDevice%[0-9]}";
53 done
54 partNum="''${rootDevice#"''${parentDevice}"}"
55 if [ "''${parentDevice%[0-9]p}" != "''${parentDevice}" ] && [ -b "''${parentDevice%p}" ]; then
56 parentDevice="''${parentDevice%p}"
57 fi
58 "${pkgs.cloud-utils.guest}/bin/growpart" "$parentDevice" "$partNum"
59 '';
60 };
61 };
62}