mirror of
https://github.com/nix-community/disko
synced 2024-11-10 06:14:14 +00:00
lib: refactor outputs into toplevel
This commit is contained in:
parent
7eb0940839
commit
cdaff66b57
4 changed files with 166 additions and 81 deletions
|
@ -10,7 +10,7 @@ let
|
||||||
imports = lib.singleton { disko.devices = cfg.disko.devices; };
|
imports = lib.singleton { disko.devices = cfg.disko.devices; };
|
||||||
options = {
|
options = {
|
||||||
disko.devices = lib.mkOption {
|
disko.devices = lib.mkOption {
|
||||||
type = diskoLib.devices;
|
type = diskoLib.toplevel;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
2
doc.nix
2
doc.nix
|
@ -10,7 +10,7 @@ let
|
||||||
{
|
{
|
||||||
options.disko = {
|
options.disko = {
|
||||||
devices = lib.mkOption {
|
devices = lib.mkOption {
|
||||||
type = diskoLib.devices;
|
type = diskoLib.toplevel;
|
||||||
default = { };
|
default = { };
|
||||||
description = "The devices to set up";
|
description = "The devices to set up";
|
||||||
};
|
};
|
||||||
|
|
197
lib/default.nix
197
lib/default.nix
|
@ -250,71 +250,39 @@ let
|
||||||
|
|
||||||
meta :: lib.types.devices -> AttrSet
|
meta :: lib.types.devices -> AttrSet
|
||||||
*/
|
*/
|
||||||
meta = devices: diskoLib.deepMergeMap (dev: dev._meta) (flatten (map attrValues (attrValues devices)));
|
meta = toplevel: toplevel._meta;
|
||||||
|
|
||||||
/* Takes a disko device specification and returns a string which formats the disks
|
/* Takes a disko device specification and returns a string which formats the disks
|
||||||
|
|
||||||
create :: lib.types.devices -> str
|
create :: lib.types.devices -> str
|
||||||
*/
|
*/
|
||||||
create = devices:
|
create = toplevel: toplevel._create;
|
||||||
let
|
|
||||||
sortedDeviceList = diskoLib.sortDevicesByDependencies ((diskoLib.meta devices).deviceDependencies or { }) devices;
|
|
||||||
in
|
|
||||||
''
|
|
||||||
set -efux
|
|
||||||
|
|
||||||
disko_devices_dir=$(mktemp -d)
|
|
||||||
trap 'rm -rf "$disko_devices_dir"' EXIT
|
|
||||||
mkdir -p "$disko_devices_dir"
|
|
||||||
|
|
||||||
${concatMapStrings (dev: (attrByPath (dev ++ [ "_create" ]) "" devices)) sortedDeviceList}
|
|
||||||
'';
|
|
||||||
/* Takes a disko device specification and returns a string which mounts the disks
|
/* Takes a disko device specification and returns a string which mounts the disks
|
||||||
|
|
||||||
mount :: lib.types.devices -> str
|
mount :: lib.types.devices -> str
|
||||||
*/
|
*/
|
||||||
mount = devices:
|
mount = toplevel: toplevel._mount;
|
||||||
let
|
|
||||||
fsMounts = diskoLib.deepMergeMap (dev: dev._mount.fs or { }) (flatten (map attrValues (attrValues devices)));
|
|
||||||
sortedDeviceList = diskoLib.sortDevicesByDependencies ((diskoLib.meta devices).deviceDependencies or { }) devices;
|
|
||||||
in
|
|
||||||
''
|
|
||||||
set -efux
|
|
||||||
# first create the necessary devices
|
|
||||||
${concatMapStrings (dev: ((attrByPath (dev ++ [ "_mount" ]) {} devices)).dev or "") sortedDeviceList}
|
|
||||||
|
|
||||||
# and then mount the filesystems in alphabetical order
|
|
||||||
${concatStrings (attrValues fsMounts)}
|
|
||||||
'';
|
|
||||||
|
|
||||||
/* takes a disko device specification and returns a string which unmounts, destroys all disks and then runs create and mount
|
/* takes a disko device specification and returns a string which unmounts, destroys all disks and then runs create and mount
|
||||||
|
|
||||||
zapCreateMount :: lib.types.devices -> str
|
zapCreateMount :: lib.types.devices -> str
|
||||||
*/
|
*/
|
||||||
zapCreateMount = devices: ''
|
zapCreateMount = toplevel:
|
||||||
|
''
|
||||||
set -efux
|
set -efux
|
||||||
umount -Rv "${rootMountPoint}" || :
|
${toplevel._disko}
|
||||||
|
|
||||||
# shellcheck disable=SC2043
|
|
||||||
for dev in ${toString (lib.catAttrs "device" (lib.attrValues devices.disk))}; do
|
|
||||||
${../disk-deactivate}/disk-deactivate "$dev" | bash -x
|
|
||||||
done
|
|
||||||
|
|
||||||
echo 'creating partitions...'
|
|
||||||
${diskoLib.create devices}
|
|
||||||
echo 'mounting partitions...'
|
|
||||||
${diskoLib.mount devices}
|
|
||||||
'';
|
'';
|
||||||
/* Takes a disko device specification and returns a nixos configuration
|
/* Takes a disko device specification and returns a nixos configuration
|
||||||
|
|
||||||
config :: lib.types.devices -> nixosConfig
|
config :: lib.types.devices -> nixosConfig
|
||||||
*/
|
*/
|
||||||
config = devices: flatten (map (dev: dev._config) (flatten (map attrValues (attrValues devices))));
|
config = toplevel: toplevel._config;
|
||||||
|
|
||||||
/* Takes a disko device specification and returns a function to get the needed packages to format/mount the disks
|
/* Takes a disko device specification and returns a function to get the needed packages to format/mount the disks
|
||||||
|
|
||||||
packages :: lib.types.devices -> pkgs -> [ derivation ]
|
packages :: lib.types.devices -> pkgs -> [ derivation ]
|
||||||
*/
|
*/
|
||||||
packages = devices: pkgs: unique (flatten (map (dev: dev._pkgs pkgs) (flatten (map attrValues (attrValues devices)))));
|
packages = toplevel: toplevel._packages;
|
||||||
|
|
||||||
optionTypes = rec {
|
optionTypes = rec {
|
||||||
filename = lib.mkOptionType {
|
filename = lib.mkOptionType {
|
||||||
|
@ -348,7 +316,9 @@ let
|
||||||
|
|
||||||
/* topLevel type of the disko config, takes attrsets of disks, mdadms, zpools, nodevs, and lvm vgs.
|
/* topLevel type of the disko config, takes attrsets of disks, mdadms, zpools, nodevs, and lvm vgs.
|
||||||
*/
|
*/
|
||||||
devices = lib.types.submodule {
|
toplevel = lib.types.submodule (cfg: let
|
||||||
|
devices = { inherit (cfg.config) disk mdadm zpool lvm_vg nodev; };
|
||||||
|
in {
|
||||||
options = {
|
options = {
|
||||||
disk = lib.mkOption {
|
disk = lib.mkOption {
|
||||||
type = lib.types.attrsOf diskoLib.types.disk;
|
type = lib.types.attrsOf diskoLib.types.disk;
|
||||||
|
@ -375,8 +345,149 @@ let
|
||||||
default = { };
|
default = { };
|
||||||
description = "A non-block device";
|
description = "A non-block device";
|
||||||
};
|
};
|
||||||
|
_meta = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
meta informationen generated by disko
|
||||||
|
currently used for building a dependency list so we know in which order to create the devices
|
||||||
|
'';
|
||||||
|
default = diskoLib.deepMergeMap (dev: dev._meta) (flatten (map attrValues (attrValues devices)));
|
||||||
|
};
|
||||||
|
_packages = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
packages required by the disko configuration
|
||||||
|
'';
|
||||||
|
default = pkgs: unique (flatten (map (dev: dev._pkgs pkgs) (flatten (map attrValues (attrValues devices)))));
|
||||||
|
};
|
||||||
|
_scripts = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
The scripts generated by disko
|
||||||
|
'';
|
||||||
|
default = { pkgs, checked ? false }: {
|
||||||
|
umountScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-umount" ''
|
||||||
|
export PATH=${lib.makeBinPath (with pkgs; [
|
||||||
|
util-linux
|
||||||
|
e2fsprogs
|
||||||
|
mdadm
|
||||||
|
zfs
|
||||||
|
lvm2
|
||||||
|
])}:$PATH
|
||||||
|
${cfg.config._umount}
|
||||||
|
'';
|
||||||
|
|
||||||
|
formatScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-format" ''
|
||||||
|
export PATH=${lib.makeBinPath (cfg.config._packages pkgs)}:$PATH
|
||||||
|
${cfg.config._create}
|
||||||
|
'';
|
||||||
|
|
||||||
|
mountScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-mount" ''
|
||||||
|
export PATH=${lib.makeBinPath (cfg.config._packages pkgs)}:$PATH
|
||||||
|
${cfg.config._mount}
|
||||||
|
'';
|
||||||
|
|
||||||
|
diskoScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko" ''
|
||||||
|
export PATH=${lib.makeBinPath ((cfg.config._packages pkgs) ++ [ pkgs.bash ])}:$PATH
|
||||||
|
${cfg.config._disko}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# These are useful to skip copying executables uploading a script to an in-memory installer
|
||||||
|
umountScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-umount" ''
|
||||||
|
${cfg.config._umount}
|
||||||
|
'';
|
||||||
|
|
||||||
|
formatScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-format" ''
|
||||||
|
${cfg.config._create}
|
||||||
|
'';
|
||||||
|
|
||||||
|
system.build.mountScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-mount" ''
|
||||||
|
${cfg.config._mount}
|
||||||
|
'';
|
||||||
|
|
||||||
|
diskoScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko" ''
|
||||||
|
${cfg.config._disko}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
_umount = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The script to unmount (& destroy) all devices defined by disko.devices
|
||||||
|
'';
|
||||||
|
default = ''
|
||||||
|
umount -Rv "${rootMountPoint}" || :
|
||||||
|
|
||||||
|
# shellcheck disable=SC2043
|
||||||
|
for dev in ${toString (lib.catAttrs "device" (lib.attrValues devices.disk))}; do
|
||||||
|
${../disk-deactivate}/disk-deactivate "$dev" | bash -x
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
_create = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The script to create all devices defined by disko.devices
|
||||||
|
'';
|
||||||
|
default = let
|
||||||
|
sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }) devices;
|
||||||
|
in
|
||||||
|
''
|
||||||
|
set -efux
|
||||||
|
|
||||||
|
disko_devices_dir=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$disko_devices_dir"' EXIT
|
||||||
|
mkdir -p "$disko_devices_dir"
|
||||||
|
|
||||||
|
${concatMapStrings (dev: (attrByPath (dev ++ [ "_create" ]) {} devices)) sortedDeviceList}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
_mount = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The script to mount all devices defined by disko.devices
|
||||||
|
'';
|
||||||
|
default = let
|
||||||
|
fsMounts = diskoLib.deepMergeMap (dev: dev._mount.fs or { }) (flatten (map attrValues (attrValues devices)));
|
||||||
|
sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }) devices;
|
||||||
|
in ''
|
||||||
|
set -efux
|
||||||
|
# first create the necessary devices
|
||||||
|
${concatMapStrings (dev: ((attrByPath (dev ++ [ "_mount" ]) {} devices)).dev or "") sortedDeviceList}
|
||||||
|
|
||||||
|
# and then mount the filesystems in alphabetical order
|
||||||
|
${concatStrings (attrValues fsMounts)}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
_disko = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The script to umount, create and mount all devices defined by disko.devices
|
||||||
|
'';
|
||||||
|
default = ''
|
||||||
|
${cfg.config._umount}
|
||||||
|
${cfg.config._create}
|
||||||
|
${cfg.config._mount}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
_config = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
The NixOS config generated by disko
|
||||||
|
'';
|
||||||
|
default =
|
||||||
|
let
|
||||||
|
configKeys = flatten (map attrNames (flatten (map (dev: dev._config) (flatten (map attrValues (attrValues devices))))));
|
||||||
|
collectedConfigs = flatten (map (dev: dev._config) (flatten (map attrValues (attrValues devices))));
|
||||||
|
in
|
||||||
|
lib.genAttrs configKeys (key: lib.mkMerge (lib.catAttrs key collectedConfigs));
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
});
|
||||||
|
|
||||||
# import all tge types from the types directory
|
# import all tge types from the types directory
|
||||||
types = lib.listToAttrs (
|
types = lib.listToAttrs (
|
||||||
|
|
46
module.nix
46
module.nix
|
@ -5,12 +5,11 @@ let
|
||||||
rootMountPoint = config.disko.rootMountPoint;
|
rootMountPoint = config.disko.rootMountPoint;
|
||||||
};
|
};
|
||||||
cfg = config.disko;
|
cfg = config.disko;
|
||||||
checked = cfg.checkScripts;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.disko = {
|
options.disko = {
|
||||||
devices = lib.mkOption {
|
devices = lib.mkOption {
|
||||||
type = diskoLib.devices;
|
type = diskoLib.toplevel;
|
||||||
default = { };
|
default = { };
|
||||||
description = "The devices to set up";
|
description = "The devices to set up";
|
||||||
};
|
};
|
||||||
|
@ -37,43 +36,18 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = lib.mkIf (cfg.devices.disk != { }) {
|
config = lib.mkIf (cfg.devices.disk != { }) {
|
||||||
system.build.formatScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-create" ''
|
system.build = (cfg.devices._scripts { inherit pkgs; checked = cfg.checkScripts; }) // {
|
||||||
export PATH=${lib.makeBinPath (diskoLib.packages cfg.devices pkgs)}:$PATH
|
|
||||||
${diskoLib.create cfg.devices}
|
|
||||||
'';
|
|
||||||
|
|
||||||
system.build.mountScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-mount" ''
|
# we keep this old outputs for compatibility
|
||||||
export PATH=${lib.makeBinPath (diskoLib.packages cfg.devices pkgs)}:$PATH
|
disko = builtins.trace "the .disko output is deprecated, plase use .diskoScript instead" cfg.devices._scripts.diskoScript;
|
||||||
${diskoLib.mount cfg.devices}
|
diskoNoDeps = builtins.trace "the .diskoNoDeps output is deprecated, plase use .diskoScriptNoDeps instead" cfg.devices._scripts.diskoScriptNoDeps;
|
||||||
'';
|
};
|
||||||
|
|
||||||
# we keep this old output for compatibility
|
|
||||||
system.build.disko = builtins.trace "the .disko output is deprecated, plase use .diskoScript instead" config.system.build.diskoScript;
|
|
||||||
|
|
||||||
system.build.diskoScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko" ''
|
|
||||||
export PATH=${lib.makeBinPath ((diskoLib.packages cfg.devices pkgs) ++ [ pkgs.bash ])}:$PATH
|
|
||||||
${diskoLib.zapCreateMount cfg.devices}
|
|
||||||
'';
|
|
||||||
|
|
||||||
# These are useful to skip copying executables uploading a script to an in-memory installer
|
|
||||||
system.build.formatScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-create" ''
|
|
||||||
${diskoLib.create cfg.devices}
|
|
||||||
'';
|
|
||||||
|
|
||||||
system.build.mountScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-mount" ''
|
|
||||||
${diskoLib.mount cfg.devices}
|
|
||||||
'';
|
|
||||||
|
|
||||||
# we keep this old output for compatibility
|
|
||||||
system.build.diskoNoDeps = builtins.trace "the .diskoNoDeps output is deprecated, plase use .diskoScriptNoDeps instead" config.system.build.diskoScriptNoDeps;
|
|
||||||
|
|
||||||
system.build.diskoScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko" ''
|
|
||||||
${diskoLib.zapCreateMount cfg.devices}
|
|
||||||
'';
|
|
||||||
|
|
||||||
|
# we need to specify the keys here, so we don't get an infinite recursion error
|
||||||
# Remember to add config keys here if they are added to types
|
# Remember to add config keys here if they are added to types
|
||||||
fileSystems = lib.mkIf cfg.enableConfig (lib.mkMerge (lib.catAttrs "fileSystems" (diskoLib.config cfg.devices)));
|
fileSystems = lib.mkIf cfg.enableConfig cfg.devices._config.fileSystems or {};
|
||||||
boot = lib.mkIf cfg.enableConfig (lib.mkMerge (lib.catAttrs "boot" (diskoLib.config cfg.devices)));
|
boot = lib.mkIf cfg.enableConfig cfg.devices._config.boot or {};
|
||||||
swapDevices = lib.mkIf cfg.enableConfig (lib.mkMerge (lib.catAttrs "swapDevices" (diskoLib.config cfg.devices)));
|
swapDevices = lib.mkIf cfg.enableConfig cfg.devices._config.swapDevices or [];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue