Create a module for generating partition scripts
This commit is contained in:
parent
a2e3498268
commit
a233064815
1 changed files with 211 additions and 4 deletions
|
@ -1,18 +1,225 @@
|
||||||
{ lib, ... }:
|
{ lib, config, ... }:
|
||||||
let
|
let
|
||||||
|
inherit (lib) types mkOption;
|
||||||
|
diskVarName = "myDisk";
|
||||||
|
diskVar = ''''${${diskVarName}}'';
|
||||||
|
|
||||||
|
diskSelector = ''
|
||||||
|
. ${./../../scripts/Common/Scripts/choose-disk.sh};
|
||||||
|
chooseDisk ${diskVarName} "Which disk do you wish to install the OS on?";
|
||||||
|
'';
|
||||||
|
|
||||||
|
mkDiskType = osDisk: types.submodule (
|
||||||
|
{ config, name, ... }: {
|
||||||
|
options = {
|
||||||
|
wipe = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "A value indicating whether the disk should be wiped.";
|
||||||
|
default = !(lib.lists.any (_: _.keepExisting) (builtins.attrValues config.partitions));
|
||||||
|
};
|
||||||
|
|
||||||
|
deviceName = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = "The name of the device.";
|
||||||
|
default = if osDisk then null else name;
|
||||||
|
};
|
||||||
|
|
||||||
|
devicePath = mkOption {
|
||||||
|
type =
|
||||||
|
if osDisk
|
||||||
|
then types.nullOr types.str
|
||||||
|
else types.str;
|
||||||
|
description = "The path to the device.";
|
||||||
|
default =
|
||||||
|
if osDisk && config.deviceName == null
|
||||||
|
then null
|
||||||
|
else "/dev/${config.deviceName}";
|
||||||
|
};
|
||||||
|
|
||||||
|
partitions = mkOption {
|
||||||
|
type = types.attrsOf partitionType;
|
||||||
|
description = "The partitions of the disk.";
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
script = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The script for formatting the disk.";
|
||||||
|
internal = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
partitions = lib.lists.sortOn (_: _.order) (builtins.attrValues config.partitions);
|
||||||
|
cleanup = lib.strings.concatLines (builtins.map
|
||||||
|
(partition: ''sudo sfdisk --delete ${diskVar} ${toString partition.index}'')
|
||||||
|
(builtins.filter (_: !_.keepExisting) partitions));
|
||||||
|
fdiskCommands =
|
||||||
|
let
|
||||||
|
print = text: "echo ${text}";
|
||||||
|
in lib.strings.concatLines (
|
||||||
|
(lib.optional config.wipe (print "label: gpt")) ++
|
||||||
|
(builtins.concatMap (
|
||||||
|
partition:
|
||||||
|
let
|
||||||
|
inherit (partition)
|
||||||
|
index
|
||||||
|
keepExisting
|
||||||
|
sizeScript
|
||||||
|
type
|
||||||
|
;
|
||||||
|
|
||||||
|
sizeOption = ''
|
||||||
|
${sizeScript} | sed -e "s/.*[^[:space:]]/size=\0/"
|
||||||
|
'';
|
||||||
|
|
||||||
|
config = print "${toString index}: \"$(${sizeOption})\" type=${lib.strings.escapeShellArg type}";
|
||||||
|
fallback = ''
|
||||||
|
if ! { ls "${diskVar}"?(p)${toString partition.index} 2>&1; } > /dev/null
|
||||||
|
then
|
||||||
|
${config}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in [
|
||||||
|
(if keepExisting then fallback else config)
|
||||||
|
])
|
||||||
|
partitions)
|
||||||
|
);
|
||||||
|
fixup = lib.strings.concatLines (
|
||||||
|
builtins.concatMap
|
||||||
|
(partition: lib.optional
|
||||||
|
partition.keepExisting
|
||||||
|
''sudo sfdisk --part-type ${diskVar} ${toString partition.index} ${lib.strings.escapeShellArg partition.type}'')
|
||||||
|
partitions);
|
||||||
|
in {
|
||||||
|
script = ''
|
||||||
|
function partition() {
|
||||||
|
${
|
||||||
|
if osDisk && config.devicePath == null then ''
|
||||||
|
${diskSelector}
|
||||||
|
''
|
||||||
|
else
|
||||||
|
"local ${diskVarName}=${config.devicePath}"}
|
||||||
|
|
||||||
|
${if (!config.wipe) then cleanup else ""}
|
||||||
|
|
||||||
|
function input() {
|
||||||
|
${fdiskCommands}
|
||||||
|
}
|
||||||
|
|
||||||
|
input | tee /dev/stderr | sudo sfdisk ${if !config.wipe then "--append" else ""} "${diskVar}";
|
||||||
|
${fixup}
|
||||||
|
}
|
||||||
|
|
||||||
|
partition
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
partitionType = types.submodule (
|
||||||
|
{ name, config, ... }:
|
||||||
|
let
|
||||||
|
isSwap = builtins.elem config.type ["swap" 19];
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
index = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
description = "The index of the partition.";
|
||||||
|
};
|
||||||
|
|
||||||
|
order = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
description = "The sort order of the partition creation.";
|
||||||
|
default = if (!isSwap) && ((builtins.match ".*[^[:space:]].*" config.size) == null) then 1 else 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
label = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The label of the partition.";
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
|
||||||
|
keepExisting = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "A value indicating whether the partition should be left untouched if it already exists.";
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
size = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The size of the partition.";
|
||||||
|
};
|
||||||
|
|
||||||
|
sizeScript = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "A script for printing the size to the console.";
|
||||||
|
internal = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
type = mkOption {
|
||||||
|
type = types.nullOr (types.either types.str types.int);
|
||||||
|
description = "The type of the partition.";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
sizeScript = (
|
||||||
|
if isSwap
|
||||||
|
then
|
||||||
|
''echo "$(cat /proc/meminfo | awk -F " " '/^MemTotal/ { print $2 }' | awk '{ print int((($1 / 1024 / 1024) * 0.75) + 0.5)}')"G''
|
||||||
|
else
|
||||||
|
"echo ${lib.strings.escapeShellArg config.size}"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
partition = {
|
partition = {
|
||||||
script = lib.mkOption {
|
os = mkOption {
|
||||||
type = lib.types.lines;
|
type = mkDiskType true;
|
||||||
|
description = "The partition layout of the OS disk.";
|
||||||
|
};
|
||||||
|
|
||||||
|
disks = mkOption {
|
||||||
|
type = types.attrsOf (mkDiskType false);
|
||||||
|
};
|
||||||
|
|
||||||
|
script = mkOption {
|
||||||
|
type = types.lines;
|
||||||
description = "The script for partitioning the system's disks.";
|
description = "The script for partitioning the system's disks.";
|
||||||
|
internal = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
partition = {
|
partition = {
|
||||||
script = "echo 'hello world'";
|
os = {
|
||||||
|
partitions = {
|
||||||
|
Boot = {
|
||||||
|
index = 1;
|
||||||
|
type = "uefi";
|
||||||
|
size = "+100M";
|
||||||
|
keepExisting = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
Swap = {
|
||||||
|
index = 2;
|
||||||
|
type = "swap";
|
||||||
|
};
|
||||||
|
|
||||||
|
OS = {
|
||||||
|
index = 3;
|
||||||
|
type = "linux";
|
||||||
|
size = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
script = config.partition.os.script;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue