Skip to content

Commit

Permalink
add unmount feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Mic92 committed Nov 21, 2024
1 parent 0fe9019 commit ebe8ae3
Show file tree
Hide file tree
Showing 21 changed files with 415 additions and 4 deletions.
6 changes: 5 additions & 1 deletion cli.nix
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ let
destroy = "_cliDestroyNoDeps";
format = "_cliFormatNoDeps";
mount = "_cliMountNoDeps";
unmount = "_cliUnmountNoDeps";

"format,mount" = "_cliFormatMountNoDeps";
"destroy,format,mount" = "_cliDestroyFormatMountNoDeps";
Expand All @@ -32,6 +33,7 @@ let
destroy = "destroyNoDeps";
format = "formatNoDeps";
mount = "mountNoDeps";
unmount = "unmountNoDeps";

"format,mount" = "formatMountNoDeps";
"destroy,format,mount" = "destroyFormatMountNoDeps";
Expand All @@ -47,6 +49,7 @@ let
destroy = "_cliDestroy";
format = "_cliFormat";
mount = "_cliMount";
unmount = "_cliUnmount";

"format,mount" = "_cliFormatMount";
"destroy,format,mount" = "_cliDestroyFormatMount";
Expand All @@ -55,7 +58,8 @@ let
{
destroy = "destroy";
format = "format";
mount = "munt";
mount = "mount";
unmount = "unmount";

"format,mount" = "formatMount";
"destroy,format,mount" = "destroyFormatMount";
Expand Down
3 changes: 3 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ in
_cliMount = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).mount;
_cliMountNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).mountNoDeps;

_cliUnmount = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).unmount;
_cliUnmountNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).unmountNoDeps;

_cliFormatMount = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatMount;
_cliFormatMountNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatMountNoDeps;

Expand Down
4 changes: 2 additions & 2 deletions disko
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ or else from the disko module of a NixOS configuration of that name under .nixos
Options:
* -m, --mode mode
set the mode, either distroy, format, mount, format,mount or destroy,format,mount
set the mode, either distroy, format, mount, unmount, format,mount or destroy,format,mount
destroy: unmount filesystems and destroy partition tables of the selected disks
format: create partition tables, zpools, lvms, raids and filesystems if they don't exist yet
mount: mount the partitions at the specified root-mountpoint
Expand Down Expand Up @@ -136,7 +136,7 @@ nixBuild() {

if ! {
# Base modes
[[ $mode = "destroy" ]] || [[ $mode = "format" ]] || [[ $mode = "mount" ]] ||
[[ $mode = "destroy" ]] || [[ $mode = "format" ]] || [[ $mode = "mount" ]] || [[ $mode = "unmount" ]] ||
# Combined modes
[[ $mode = "format,mount" ]] ||
[[ $mode = "destroy,format,mount" ]] || # Replaces --mode disko
Expand Down
48 changes: 47 additions & 1 deletion lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,25 @@ let
description = "Mount script";
};

mkUnmountOption = { config, options, default }@attrs:
lib.mkOption {
internal = true;
readOnly = true;
type = diskoLib.jsonType;
default = lib.mapAttrsRecursive
(_name: value:
if builtins.isString value then ''
(
${diskoLib.indent (diskoLib.defineHookVariables { inherit options; })}
${diskoLib.indent config.preUnmountHook}
${diskoLib.indent value}
${diskoLib.indent config.postUnmountHook}
)
'' else value)
attrs.default;
description = "Unmount script";
};

/* Writer for optionally checking bash scripts before writing them to the store
writeCheckedBash :: AttrSet -> str -> str -> derivation
Expand Down Expand Up @@ -458,6 +477,10 @@ let
export PATH=${lib.makeBinPath (cfg.config._packages pkgs)}:$PATH
${cfg.config._mount}
'';
unmount = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "/bin/disko-unmount" ''
export PATH=${lib.makeBinPath (cfg.config._packages pkgs)}:$PATH
${cfg.config._unmount}
'';
formatMount = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "/bin/disko-format-mount" ''
export PATH=${lib.makeBinPath ((cfg.config._packages pkgs) ++ [ pkgs.bash ])}:$PATH
${cfg.config._formatMount}
Expand All @@ -477,6 +500,9 @@ let
mountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-mount" ''
${cfg.config._mount}
'';
unmountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-unmount" ''
${cfg.config._unmount}
'';
formatMountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-format-mount" ''
${cfg.config._formatMount}
'';
Expand Down Expand Up @@ -616,12 +642,32 @@ let
''
set -efux
# first create the necessary devices
${concatMapStrings (dev: (attrByPath (dev ++ [ "_mount" ]) {} devices).dev or "") sortedDeviceList}
${concatMapStrings (dev: (attrByPath (dev ++ [ "_mount" ]) {} devices).dev or "") (lib.reverseList sortedDeviceList)}
# and then mount the filesystems in alphabetical order
${concatStrings (attrValues fsMounts)}
'';
};
_unmount = lib.mkOption {
internal = true;
type = lib.types.str;
description = ''
The script to unmount all devices defined by disko.devices
'';
default =
with lib; let
fsMounts = diskoLib.deepMergeMap (dev: dev._unmount.fs or { }) (flatten (map attrValues (attrValues devices)));
sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }) devices;
in
''
set -efux
# first unmount the filesystems in reverse alphabetical order
${concatStrings (attrValues (lib.reverseList fsMounts))}
# Than close the devices
${concatMapStrings (dev: (attrByPath (dev ++ [ "_unmount" ]) {} devices).dev or "") (lib.reverseList sortedDeviceList)}
'';
};
_disko = lib.mkOption {
internal = true;
type = lib.types.str;
Expand Down
4 changes: 4 additions & 0 deletions lib/tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ let
tsp-generator = pkgs.callPackage ../. { checked = true; };
tsp-format = (tsp-generator._cliFormat testConfigInstall) pkgs;
tsp-mount = (tsp-generator._cliMount testConfigInstall) pkgs;
tsp-unmount = (tsp-generator._cliUnmount testConfigInstall) pkgs;
tsp-disko = (tsp-generator._cliDestroyFormatMount testConfigInstall) pkgs;
tsp-config = tsp-generator.config testConfigBooted;
num-disks = builtins.length (lib.attrNames testConfigBooted.disko.devices.disk);
Expand Down Expand Up @@ -282,6 +283,9 @@ let
machine.succeed("${lib.getExe tsp-format}")
machine.succeed("${lib.getExe tsp-mount}")
machine.succeed("${lib.getExe tsp-mount}") # verify that mount is idempotent
machine.succeed("${lib.getExe tsp-unmount}")
machine.succeed("${lib.getExe tsp-unmount}") # verify that umount is idempotent
machine.succeed("${lib.getExe tsp-mount}") # verify that mount is idempotent
machine.succeed("${lib.getExe tsp-disko} --yes-wipe-all-disks") # verify that we can destroy and recreate
machine.succeed("mkdir -p /mnt/home")
machine.succeed("touch /mnt/home/testfile")
Expand Down
28 changes: 28 additions & 0 deletions lib/types/btrfs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,34 @@ in
};
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default =
let
subvolMounts = lib.concatMapAttrs
(_: subvol:
lib.optionalAttrs
(subvol.mountpoint != null)
{
${subvol.mountpoint} = ''
if findmnt "${config.device}" "${rootMountPoint}${subvol.mountpoint}" > /dev/null 2>&1; then
umount "${rootMountPoint}${subvol.mountpoint}"
fi
'';
}
)
config.subvolumes;
in
{
fs = subvolMounts // lib.optionalAttrs (config.mountpoint != null) {
${config.mountpoint} = ''
if findmnt "${config.device}" "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then
umount "${rootMountPoint}${config.mountpoint}"
fi
'';
};
};
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
4 changes: 4 additions & 0 deletions lib/types/disk.nix
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
inherit config options;
default = lib.optionalAttrs (config.content != null) config.content._mount;
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default = lib.optionalAttrs (config.content != null) config.content._mount;
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
10 changes: 10 additions & 0 deletions lib/types/filesystem.nix
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@
'';
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default = lib.optionalAttrs (config.mountpoint != null) {
fs.${config.mountpoint} = ''
if findmnt "${config.device}" "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
umount "${rootMountPoint}${config.mountpoint}"
fi
'';
};
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
8 changes: 8 additions & 0 deletions lib/types/gpt.nix
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,14 @@ in
fs = partMounts.fs or { };
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default = ''
${lib.concatStrings (map (partition: ''
${lib.optionalString (partition.content != null) partition.content._unmount}
'') sortedPartitions)}
'';
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
10 changes: 10 additions & 0 deletions lib/types/luks.nix
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,16 @@ in
fs = lib.optionalAttrs (config.content != null) contentMount.fs or { };
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default = ''
${lib.optionalString (config.content != null) config.content._unmount}
if cryptsetup status "${config.name}" >/dev/null 2>/dev/null; then
cryptsetup close "${config.name}"
fi
'';
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
4 changes: 4 additions & 0 deletions lib/types/lvm_pv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
inherit config options;
default = { };
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default = { };
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
14 changes: 14 additions & 0 deletions lib/types/lvm_vg.nix
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,20 @@ in
fs = lvMounts.fs or { };
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default =
let
lvMounts = diskoLib.deepMergeMap
(lv:
lib.optionalAttrs (lv.content != null) lv.content._unmount
)
(lib.attrValues config.lvs);
in
''
${lib.concatMapStrings (x: x.dev or "") (lib.attrValues lvMounts)}
'';
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
9 changes: 9 additions & 0 deletions lib/types/mdadm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@
lib.optionalAttrs (config.content != null) config.content._mount;
# TODO we probably need to assemble the mdadm somehow
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default = {
fs = lib.optionalAttrs (config.content != null) config.content._unmount;
dev = ''
mdadm --stop "/dev/md/${config.name}"
'';
};
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
10 changes: 10 additions & 0 deletions lib/types/nodev.nix
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@
'';
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default = lib.optionalAttrs (config.mountpoint != null) {
fs.${config.mountpoint} = ''
if findmnt ${config.fsType} "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then
umount "${rootMountPoint}${config.mountpoint}"
fi
'';
};
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
10 changes: 10 additions & 0 deletions lib/types/swap.nix
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@
'';
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default = lib.optionalAttrs (!config.randomEncryption) {
fs.${config.device} = ''
if swapon --show | grep -q "^$(readlink -f "${config.device}") "; then
swapoff "${config.device}"
fi
'';
};
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
15 changes: 15 additions & 0 deletions lib/types/table.nix
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,21 @@
fs = partMounts.fs or { };
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default =
let
partMounts = lib.foldr lib.recursiveUpdate { } (map
(partition:
lib.optionalAttrs (partition.content != null) partition.content._unmount
)
config.partitions);
in
{
dev = partMounts.dev or "";
fs = partMounts.fs or { };
};
};
_config = lib.mkOption {
internal = true;
readOnly = true;
Expand Down
Loading

0 comments on commit ebe8ae3

Please sign in to comment.