Skip to content

Commit

Permalink
Merge pull request #842 from nix-community/write-scripts-to-bin-dir
Browse files Browse the repository at this point in the history
outputs: make compatible with nix run and package lists
  • Loading branch information
Mic92 authored Nov 8, 2024
2 parents f3f8254 + 3fc91a7 commit 60d4914
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 52 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ a disk named /dev/sda, you would run the following command to partition, format
and mount the disk.

```console
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode disko /tmp/disk-config.nix
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount /tmp/disk-config.nix
```

## Related Tools
Expand Down
20 changes: 14 additions & 6 deletions cli.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,29 @@ let
diskoAttr =
if noDeps then
{
format = "formatScriptNoDeps";
mount = "mountScriptNoDeps";
disko = "diskoScriptNoDeps";
destroy = "_cliDestroyNoDeps";
format = "_cliFormatNoDeps";
mount = "_cliMountNoDeps";

"format,mount" = "_cliFormatMountNoDeps";
"destroy,format,mount" = "_cliDestroyFormatMountNoDeps";

# legacy aliases
disko = "diskoScriptNoDeps";
create = "createScriptNoDeps";
zap_create_mount = "diskoScriptNoDeps";
}.${mode}
else
{
format = "formatScript";
mount = "mountScript";
disko = "diskoScript";
destroy = "_cliDestroy";
format = "_cliFormat";
mount = "_cliMount";

"format,mount" = "_cliFormatMount";
"destroy,format,mount" = "_cliDestroyFormatMount";

# legacy aliases
disko = "diskoScript";
create = "createScript";
zap_create_mount = "diskoScript";
}.${mode};
Expand Down
48 changes: 33 additions & 15 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,47 @@ let
};
};
};
# We might instead reuse some of the deprecated output names to refer to the values the _cli* outputs currently do,
# but this warning allows us to get feedback from users early in case they have a use case we haven't considered.
warnDeprecated = name: lib.warn "the ${name} output is deprecated and will be removed, please open an issue if you're using it!";
in
{
lib = lib.warn "the .lib.lib output is deprecated" diskoLib;
lib = warnDeprecated ".lib.lib" diskoLib;

# legacy alias
create = cfg: builtins.trace "the create output is deprecated, use format instead" (eval cfg).config.disko.devices._create;
createScript = cfg: pkgs: builtins.trace "the create output is deprecated, use format instead" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatScript;
createScriptNoDeps = cfg: pkgs: builtins.trace "the create output is deprecated, use format instead" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatScriptNoDeps;
_cliDestroy = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).destroy;
_cliDestroyNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).destroyNoDeps;

format = cfg: (eval cfg).config.disko.devices._create;
formatScript = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatScript;
formatScriptNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatScriptNoDeps;
_cliFormat = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).format;
_cliFormatNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatNoDeps;

mount = cfg: (eval cfg).config.disko.devices._mount;
mountScript = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).mountScript;
mountScriptNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).mountScriptNoDeps;
_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;

disko = cfg: (eval cfg).config.disko.devices._disko;
diskoScript = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).diskoScript;
diskoScriptNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).diskoScriptNoDeps;
_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;

_cliDestroyFormatMount = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).destroyFormatMount;
_cliDestroyFormatMountNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).destroyFormatMountNoDeps;

# legacy aliases
create = cfg: warnDeprecated "create" (eval cfg).config.disko.devices._create;
createScript = cfg: pkgs: warnDeprecated "createScript" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatScript;
createScriptNoDeps = cfg: pkgs: warnDeprecated "createScriptNoDeps" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatScriptNoDeps;

format = cfg: warnDeprecated "format" (eval cfg).config.disko.devices._create;
formatScript = cfg: pkgs: warnDeprecated "formatScript" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatScript;
formatScriptNoDeps = cfg: pkgs: warnDeprecated "formatScriptNoDeps" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatScriptNoDeps;

mount = cfg: warnDeprecated "mount" (eval cfg).config.disko.devices._mount;
mountScript = cfg: pkgs: warnDeprecated "mountScript" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).mountScript;
mountScriptNoDeps = cfg: pkgs: warnDeprecated "mountScriptNoDeps" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).mountScriptNoDeps;

disko = cfg: warnDeprecated "disko" (eval cfg).config.disko.devices._disko;
diskoScript = cfg: pkgs: warnDeprecated "diskoScript" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).diskoScript;
diskoScriptNoDeps = cfg: pkgs: warnDeprecated "diskoScriptNoDeps" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).diskoScriptNoDeps;

# we keep this old output for backwards compatibility
diskoNoDeps = cfg: pkgs: builtins.trace "the diskoNoDeps output is deprecated, please use disko instead" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).diskoScriptNoDeps;
diskoNoDeps = cfg: pkgs: warnDeprecated "diskoNoDeps" ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).diskoScriptNoDeps;

config = cfg: (eval cfg).config.disko.devices._config;
packages = cfg: (eval cfg).config.disko.devices._packages;
Expand Down
38 changes: 30 additions & 8 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 All @@ -25,10 +26,12 @@ or else from the disko module of a NixOS configuration of that name under .nixos
Options:
* -m, --mode mode
set the mode, either format, mount or disko
format: create partition tables, zpools, lvms, raids and filesystems
mount: mount the partition at the specified root-mountpoint
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
set the mode, either distroy, format, mount, 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
format,mount: run format and mount in sequence
destroy,format,mount: run all three modes in sequence. Previously known as --mode disko
* -f, --flake uri
fetch the disko config relative to this flake's root
* --arg name value
Expand All @@ -42,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 @@ -93,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 @@ -126,8 +134,16 @@ nixBuild() {
fi
}

if ! { [[ $mode = "format" ]] || [[ $mode = "mount" ]] || [[ $mode = "disko" ]] || [[ $mode = "create" ]] || [[ $mode = "zap_create_mount" ]] ; }; then
abort "mode must be either format, mount or disko"
if ! {
# Base modes
[[ $mode = "destroy" ]] || [[ $mode = "format" ]] || [[ $mode = "mount" ]] ||
# Combined modes
[[ $mode = "format,mount" ]] ||
[[ $mode = "destroy,format,mount" ]] || # Replaces --mode disko
# Legacy modes, will be removed in next major version
[[ $mode = "disko" ]] || [[ $mode = "create" ]] || [[ $mode = "zap_create_mount" ]] ;
}; then
abort 'mode must be one of "destroy", "format", "mount", "destroy,format,mount" or "format,mount"'
fi

if [[ -n "${flake+x}" ]]; then
Expand Down Expand Up @@ -159,8 +175,14 @@ script=$(nixBuild "${libexec_dir}"/cli.nix \
--argstr mode "$mode" \
"${nix_args[@]}"
)

command=("$(echo "$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
2 changes: 1 addition & 1 deletion docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ The following step will partition and format your disk, and mount it to `/mnt`.
**Please note: This will erase any existing data on your disk.**

```console
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode disko /tmp/disk-config.nix
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount /tmp/disk-config.nix
```

After the command has run, your file system should have been formatted and
Expand Down
12 changes: 8 additions & 4 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ or else from the disko module of a NixOS configuration of that name under .nixos
Options:
* -m, --mode mode
set the mode, either format, mount or disko
format: create partition tables, zpools, lvms, raids and filesystems
mount: mount the partition at the specified root-mountpoint
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
set the mode, either distroy, format, mount, 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
format,mount: run format and mount in sequence
destroy,format,mount: run all three modes in sequence. Previously known as --mode disko
* -f, --flake uri
fetch the disko config relative to this flake's root
* --arg name value
Expand All @@ -40,4 +42,6 @@ Options:
requires all necessary dependencies to be available in the environment
* --debug
run with set -x
* --yes-wipe-all-disks
skip the safety check for destroying partitions, useful for automation
```
113 changes: 110 additions & 3 deletions lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -444,10 +444,54 @@ let
];
in
lib.mapAttrs throwIfNoDisksDetected {
destroyScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-destroy" ''
destroy = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "/bin/disko-destroy" ''
export PATH=${lib.makeBinPath destroyDependencies}:$PATH
${cfg.config._destroy}
'';
format = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "/bin/disko-format" ''
export PATH=${lib.makeBinPath (cfg.config._packages pkgs)}:$PATH
${cfg.config._create}
'';
mount = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "/bin/disko-mount" ''
export PATH=${lib.makeBinPath (cfg.config._packages pkgs)}:$PATH
${cfg.config._mount}
'';
formatMount = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "/bin/disko-format-mount" ''
export PATH=${lib.makeBinPath ((cfg.config._packages pkgs) ++ [ pkgs.bash ])}:$PATH
${cfg.config._formatMount}
'';
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._destroyFormatMount}
'';

# These are useful to skip copying executables uploading a script to an in-memory installer
destroyNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-destroy" ''
${cfg.config._destroy}
'';
formatNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-format" ''
${cfg.config._create}
'';
mountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-mount" ''
${cfg.config._mount}
'';
formatMountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-format-mount" ''
${cfg.config._formatMount}
'';
destroyFormatMountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-destroy-format-mount" ''
${cfg.config._destroyFormatMount}
'';


# Legacy scripts, to be removed in version 2.0.0
# They are generally less useful, because the scripts are directly written to their $out path instead of
# into the $out/bin directory, which makes them incompatible with `nix run`
# (see https://github.com/nix-community/disko/pull/78), `lib.buildEnv` and thus `environment.systemPackages`,
# `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._legacyDestroy}
'';

formatScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-format" ''
export PATH=${lib.makeBinPath (cfg.config._packages pkgs)}:$PATH
Expand All @@ -466,7 +510,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 @@ -482,11 +526,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 @@ -497,6 +542,44 @@ 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
# shellcheck disable=SC2043
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 -rp "Type 'yes' to continue, anything else to abort: " confirmation
if [ "$confirmation" != "yes" ]; then
echo "Aborted."
exit 1
fi
fi
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 @@ -542,13 +625,37 @@ 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}
${cfg.config._create}
${cfg.config._mount}
'';
};
_formatMount = lib.mkOption {
internal = true;
type = lib.types.str;
description = ''
The script to create and mount all devices defined by disko.devices, without wiping the disks first
'';
default = ''
${cfg.config._create}
${cfg.config._mount}
'';
};
_config = lib.mkOption {
internal = true;
description = ''
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 @@ -84,7 +84,7 @@ let
${lib.optionalString diskoCfg.testMode ''
export IN_DISKO_TEST=1
''}
${systemToInstall.config.system.build.diskoScript}
${lib.getExe systemToInstall.config.system.build.destroyFormatMount} --yes-wipe-all-disks
'';

installer = lib.optionalString cfg.copyNixStore ''
Expand Down
Loading

0 comments on commit 60d4914

Please sign in to comment.