add unmount feature
This commit is contained in:
@@ -23,6 +23,7 @@ let
|
||||
destroy = "_cliDestroyNoDeps";
|
||||
format = "_cliFormatNoDeps";
|
||||
mount = "_cliMountNoDeps";
|
||||
unmount = "_cliUnmountNoDeps";
|
||||
|
||||
"format,mount" = "_cliFormatMountNoDeps";
|
||||
"destroy,format,mount" = "_cliDestroyFormatMountNoDeps";
|
||||
@@ -32,6 +33,7 @@ let
|
||||
destroy = "destroyNoDeps";
|
||||
format = "formatNoDeps";
|
||||
mount = "mountNoDeps";
|
||||
unmount = "unmountNoDeps";
|
||||
|
||||
"format,mount" = "formatMountNoDeps";
|
||||
"destroy,format,mount" = "destroyFormatMountNoDeps";
|
||||
@@ -47,6 +49,7 @@ let
|
||||
destroy = "_cliDestroy";
|
||||
format = "_cliFormat";
|
||||
mount = "_cliMount";
|
||||
unmount = "_cliUnmount";
|
||||
|
||||
"format,mount" = "_cliFormatMount";
|
||||
"destroy,format,mount" = "_cliDestroyFormatMount";
|
||||
@@ -55,7 +58,8 @@ let
|
||||
{
|
||||
destroy = "destroy";
|
||||
format = "format";
|
||||
mount = "munt";
|
||||
mount = "mount";
|
||||
unmount = "unmount";
|
||||
|
||||
"format,mount" = "formatMount";
|
||||
"destroy,format,mount" = "destroyFormatMount";
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -242,6 +242,8 @@ let
|
||||
postCreateHook = diskoLib.mkHook "shell commands to run after create";
|
||||
preMountHook = diskoLib.mkHook "shell commands to run before mount";
|
||||
postMountHook = diskoLib.mkHook "shell commands to run after mount";
|
||||
preUnmountHook = diskoLib.mkHook "shell commands to run before unmount";
|
||||
postUnmountHook = diskoLib.mkHook "shell commands to run after unmount";
|
||||
};
|
||||
config._module.args = {
|
||||
inherit diskoLib rootMountPoint;
|
||||
@@ -284,6 +286,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
|
||||
@@ -458,6 +479,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}
|
||||
@@ -477,6 +502,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}
|
||||
'';
|
||||
@@ -622,6 +650,26 @@ let
|
||||
${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 (lib.reverseList (attrValues 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;
|
||||
|
||||
@@ -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);
|
||||
@@ -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")
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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._unmount;
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+16
-1
@@ -45,7 +45,7 @@ in
|
||||
defaultText = ''
|
||||
if the parent is an mdadm device:
|
||||
/dev/disk/by-id/md-name-any:''${config._parent.name}-part''${toString partition.config._index}
|
||||
|
||||
|
||||
otherwise:
|
||||
/dev/disk/by-partlabel/''${diskoLib.hexEscapeUdevSymlink partition.config.label}
|
||||
'';
|
||||
@@ -249,6 +249,21 @@ in
|
||||
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
|
||||
)
|
||||
(lib.attrValues config.partitions));
|
||||
in
|
||||
{
|
||||
dev = partMounts.dev or "";
|
||||
fs = partMounts.fs or { };
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -170,6 +170,21 @@ in
|
||||
fs = lib.optionalAttrs (config.content != null) contentMount.fs or { };
|
||||
};
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
contentUnmount = config.content._unmount;
|
||||
in
|
||||
{
|
||||
dev = ''
|
||||
${lib.optionalString (config.content != null) contentUnmount.dev or ""}
|
||||
if cryptsetup status "${config.name}" >/dev/null 2>/dev/null; then
|
||||
cryptsetup close "${config.name}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
inherit config options;
|
||||
default = { };
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default = { };
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -127,6 +127,23 @@ 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 {
|
||||
dev = ''
|
||||
${lib.concatMapStrings (x: x.dev or "") (lib.attrValues lvMounts)}
|
||||
vgchange -a n
|
||||
'';
|
||||
fs = lvMounts.fs or { };
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -58,6 +58,20 @@
|
||||
lib.optionalAttrs (config.content != null) config.content._mount;
|
||||
# TODO we probably need to assemble the mdadm somehow
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default = let
|
||||
content = lib.optionalAttrs (config.content != null) config.content._unmount;
|
||||
in {
|
||||
fs = content.fs;
|
||||
dev = ''
|
||||
${content.dev or ""}
|
||||
if [ -e "/dev/md/${config.name}" ]; then
|
||||
mdadm --stop "/dev/md/${config.name}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
inherit config options;
|
||||
default = { };
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default = { };
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
inherit config options;
|
||||
default = { };
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default = { };
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -114,6 +114,18 @@
|
||||
};
|
||||
};
|
||||
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
lib.optionalAttrs (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
|
||||
fs.${config.mountpoint} = ''
|
||||
if findmnt ${config._name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
|
||||
umount "${rootMountPoint}${config.mountpoint}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -64,6 +64,11 @@
|
||||
default =
|
||||
lib.optionalAttrs (config.content != null) config.content._mount;
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
lib.optionalAttrs (config.content != null) config.content._unmount;
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
@@ -310,6 +310,23 @@ in
|
||||
fs = datasetMounts.fs or { };
|
||||
};
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
datasetUnmounts = diskoLib.deepMergeMap (dataset: dataset._unmount) (lib.attrValues config.datasets);
|
||||
in
|
||||
{
|
||||
dev = ''
|
||||
${lib.concatMapStrings (x: x.dev or "") (lib.attrValues datasetUnmounts)}
|
||||
|
||||
if zpool list "${config.name}" >/dev/null 2>/dev/null; then
|
||||
zpool export "${config.name}"
|
||||
fi
|
||||
'';
|
||||
fs = datasetUnmounts.fs or { };
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
|
||||
Reference in New Issue
Block a user