Skip to content

Commit

Permalink
mode destroy: Add confirmation dialogue
Browse files Browse the repository at this point in the history
The new confirmation dialogue is only shown for the new outputs
introduced in the previous commits. The existing outputs do not change
behavior to keep backwards compatibility.

Fixes #725
  • Loading branch information
iFreilicht committed Oct 22, 2024
1 parent dddd4b6 commit 663dbb2
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 10 deletions.
16 changes: 14 additions & 2 deletions disko
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ declare disko_config
# mount was chosen as the default mode because it's less destructive
mode=mount
nix_args=()
skip_destroy_safety_check=false

# DISKO_VERSION is set by the wrapper in package.nix
DISKO_VERSION="${DISKO_VERSION:="unknown! This is a bug, please report it!"}"
Expand Down Expand Up @@ -44,6 +45,8 @@ Options:
* --no-deps
avoid adding another dependency closure to an in-memory installer
requires all necessary dependencies to be available in the environment
* --yes-wipe-all-disks
skip the safety check for destroying partitions, useful for automation
* --debug
run with set -x
* --help
Expand Down Expand Up @@ -95,6 +98,9 @@ while [[ $# -gt 0 ]]; do
--no-deps)
nix_args+=(--arg noDeps true)
;;
--yes-wipe-all-disks)
skip_destroy_safety_check=true
;;
--show-trace)
nix_args+=("$1")
;;
Expand Down Expand Up @@ -169,8 +175,14 @@ script=$(nixBuild "${libexec_dir}"/cli.nix \
--argstr mode "$mode" \
"${nix_args[@]}"
)

command="$script"/bin/*
if [[ $mode = "destroy,format,mount" && $skip_destroy_safety_check = true ]]; then
command+=' --yes-wipe-all-disks'
fi

if [[ -n "${dry_run+x}" ]]; then
echo "$script"
echo $command
else
exec "$script"
exec $command
fi
64 changes: 59 additions & 5 deletions lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ let
'';
destroyFormatMount = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "/bin/disko-destroy-format-mount" ''
export PATH=${lib.makeBinPath ((cfg.config._packages pkgs) ++ [ pkgs.bash ] ++ destroyDependencies)}:$PATH
${cfg.config._disko}
${cfg.config._destroyFormatMount}
'';

# These are useful to skip copying executables uploading a script to an in-memory installer
Expand All @@ -473,7 +473,7 @@ let
${cfg.config._formatMount}
'';
destroyFormatMountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-destroy-format-mount" ''
${cfg.config._disko}
${cfg.config._destroyFormatMount}
'';


Expand All @@ -484,7 +484,7 @@ let
# `user.users.<name>.packages` and `home.packages`, see https://github.com/nix-community/disko/issues/454
destroyScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-destroy" ''
export PATH=${lib.makeBinPath destroyDependencies}:$PATH
${cfg.config._destroy}
${cfg.config._legacyDestroy}
'';

formatScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-format" ''
Expand All @@ -504,7 +504,7 @@ let

# These are useful to skip copying executables uploading a script to an in-memory installer
destroyScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-destroy" ''
${cfg.config._destroy}
${cfg.config._legacyDestroy}
'';

formatScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-format" ''
Expand All @@ -520,11 +520,12 @@ let
'';
};
};
_destroy = lib.mkOption {
_legacyDestroy = lib.mkOption {
internal = true;
type = lib.types.str;
description = ''
The script to unmount (& destroy) all devices defined by disko.devices
Does not ask for confirmation! Depracated in favor of _destroy
'';
default = ''
umount -Rv "${rootMountPoint}" || :
Expand All @@ -535,6 +536,46 @@ let
done
'';
};
_destroy = lib.mkOption {
internal = true;
type = lib.types.str;
description = ''
The script to unmount (& destroy) all devices defined by disko.devices
'';
default =
let
selectedDisks = lib.escapeShellArgs (lib.catAttrs "device" (lib.attrValues devices.disk));
in
''
if [ "$1" != "--yes-wipe-all-disks" ]; then
echo "WARNING: This will destroy all data on the disks defined in disko.devices, which are:"
echo
for dev in ${selectedDisks}; do
echo " - $dev"
done
echo
echo " (If you want to skip this dialogue, pass --yes-wipe-all-disks)"
echo
echo "Are you sure you want to wipe the devices listed above?"
read -p "Type 'yes' to continue, anything else to abort: " confirmation
if [ "$confirmation" != "yes" ]; then
echo "Aborted."
exit 1
fi
fi
echo "Aborting for testing"
exit 0
umount -Rv "${rootMountPoint}" || :
shellcheck disable=SC2043
for dev in ${selectedDisks}; do
$BASH ${../disk-deactivate}/disk-deactivate "$dev"
done
'';
};
_create = lib.mkOption {
internal = true;
type = lib.types.str;
Expand Down Expand Up @@ -580,6 +621,19 @@ let
type = lib.types.str;
description = ''
The script to umount, create and mount all devices defined by disko.devices
Deprecated in favor of _destroyFormatMount
'';
default = ''
${cfg.config._legacyDestroy}
${cfg.config._create}
${cfg.config._mount}
'';
};
_destroyFormatMount = lib.mkOption {
internal = true;
type = lib.types.str;
description = ''
The script to unmount, create and mount all devices defined by disko.devices
'';
default = ''
${cfg.config._destroy}
Expand Down
2 changes: 1 addition & 1 deletion lib/make-disk-image.nix
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ let
${lib.optionalString diskoCfg.testMode ''
export IN_DISKO_TEST=1
''}
${lib.getExe systemToInstall.config.system.build.destroyFormatMount}
${lib.getExe systemToInstall.config.system.build.destroyFormatMount} --yes-wipe-all-disks
'';

installer = lib.optionalString cfg.copyNixStore ''
Expand Down
4 changes: 2 additions & 2 deletions lib/tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ 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-disko}") # verify that we can destroy and recreate
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")
machine.succeed("${lib.getExe tsp-format}") # verify that format is idempotent
Expand All @@ -274,7 +274,7 @@ let
machine.succeed("${lib.getExe nodes.machine.system.build.format}")
machine.succeed("${lib.getExe nodes.machine.system.build.mount}")
machine.succeed("${lib.getExe nodes.machine.system.build.mount}") # verify that mount is idempotent
machine.succeed("${lib.getExe nodes.machine.system.build.destroyFormatMount}") # verify that we can destroy and recreate again
machine.succeed("${lib.getExe nodes.machine.system.build.destroyFormatMount} --yes-wipe-all-disks") # verify that we can destroy and recreate again
machine.succeed("mkdir -p /mnt/home")
machine.succeed("touch /mnt/home/testfile")
machine.succeed("${lib.getExe nodes.machine.system.build.format}") # verify that format is idempotent
Expand Down

0 comments on commit 663dbb2

Please sign in to comment.