lib: Fix jsonTypes evaluation

This will be very useful for generating documentation and python type
definitions.
This commit is contained in:
Felix Uhl 2024-11-13 00:08:21 +01:00
parent 2bd9c4f8c7
commit a5c646bd93
5 changed files with 93 additions and 26 deletions

View file

@ -19,13 +19,15 @@
versionInfo = import ./version.nix;
version = versionInfo.version + (lib.optionalString (!versionInfo.released) "-dirty");
in
{
nixosModules.default = self.nixosModules.disko; # convention
nixosModules.disko.imports = [ ./module.nix ];
lib = import ./src/disko_lib {
diskoLib = import ./src/disko_lib {
inherit (nixpkgs) lib;
};
in
{
lib = diskoLib;
nixosModules.default = self.nixosModules.disko; # convention
nixosModules.disko.imports = [ ./module.nix ];
packages = forAllSystems (system:
let
pkgs = nixpkgs.legacyPackages.${system};
@ -73,11 +75,13 @@
shellcheck src/disk-deactivate/disk-deactivate disko disko2
touch $out
'';
jsonTypes = pkgs.writeTextFile { name = "jsonTypes"; text = (builtins.toJSON diskoLib.jsonTypes); };
in
# FIXME: aarch64-linux seems to hang on boot
lib.optionalAttrs pkgs.hostPlatform.isx86_64 (nixosTests // { inherit disko-install; }) //
pkgs.lib.optionalAttrs (!pkgs.buildPlatform.isRiscV64 && !pkgs.hostPlatform.isx86_32) {
inherit pytest-ci-only shellcheck;
inherit pytest-ci-only shellcheck jsonTypes;
inherit (self.packages.${system}) disko-doc;
});

View file

@ -22,9 +22,10 @@ let
};
# option for valid contents of partitions (basically like devices, but without tables)
_partitionTypes = { inherit (diskoLib.types) btrfs filesystem zfs mdraid luks lvm_pv swap; };
partitionType = extraArgs: lib.mkOption {
type = lib.types.nullOr (diskoLib.subType {
types = { inherit (diskoLib.types) btrfs filesystem zfs mdraid luks lvm_pv swap; };
types = diskoLib.partitionTypes;
inherit extraArgs;
});
default = null;
@ -32,9 +33,10 @@ let
};
# option for valid contents of devices
_deviceTypes = { inherit (diskoLib.types) table gpt btrfs filesystem zfs mdraid luks lvm_pv swap; };
deviceType = extraArgs: lib.mkOption {
type = lib.types.nullOr (diskoLib.subType {
types = { inherit (diskoLib.types) table gpt btrfs filesystem zfs mdraid luks lvm_pv swap; };
types = diskoLib.deviceTypes;
inherit extraArgs;
});
default = null;
@ -608,11 +610,22 @@ let
typesSerializerLib = {
rootMountPoint = "";
options = null;
config._module.args.name = "self.name";
lib = {
config = {
_module = {
args.name = "<self.name>";
args._parent.name = "<parent.name>";
args._parent.type = "<parent.type>";
};
name = "<config.name>";
};
parent = { };
device = "/dev/<device>";
# Spoof part of nixpkgs/lib to analyze the types
lib = lib // {
mkOption = option: {
inherit (option) type description;
default = option.default or null;
inherit (option) type;
description = option.description or null;
default = option.defaultText or option.default or null;
};
types = {
attrsOf = subType: {
@ -627,35 +640,63 @@ let
type = "nullOr";
inherit subType;
};
oneOf = types: {
type = "oneOf";
inherit types;
};
either = t1: t2: {
type = "oneOf";
types = [ t1 t2 ];
};
enum = choices: {
type = "enum";
inherit choices;
};
anything = "anything";
nonEmptyStr = "str";
strMatching = _: "str";
str = "str";
bool = "bool";
int = "int";
submodule = x: x { inherit (diskoLib.typesSerializerLib) lib config options; };
submodule = x: x {
inherit (diskoLib.typesSerializerLib) lib config options;
name = "<self.name>";
};
};
};
diskoLib = {
optionTypes.absolute-pathname = "absolute-pathname";
deviceType = "devicetype";
partitionType = "partitiontype";
subType = types: "onOf ${toString (lib.attrNames types)}";
# Spoof these tyeps
deviceType = _: "<deviceType>";
partitionType = _: "<partitionType>";
subType = { types, ... }: {
type = "oneOf";
types = lib.attrNames types;
};
mkCreateOption = option: "_create";
};
};
jsonTypes = lib.listToAttrs (
map
(file: lib.nameValuePair
(lib.removeSuffix ".nix" file)
(diskoLib.serializeType (import ./types/${file} diskoLib.typesSerializerLib))
)
(lib.attrNames (builtins.readDir ./types))
);
jsonTypes = lib.listToAttrs
(
map
(file: lib.nameValuePair
(lib.removeSuffix ".nix" file)
(diskoLib.serializeType (import ./types/${file} diskoLib.typesSerializerLib))
)
(lib.filter (name: lib.hasSuffix ".nix" name) (lib.attrNames (builtins.readDir ./types)))
) // {
partitionType = {
type = "oneOf";
types = lib.attrNames diskoLib._partitionTypes;
};
deviceType = {
type = "oneOf";
types = lib.attrNames diskoLib._deviceTypes;
};
};
};
outputs =
{ lib ? import <nixpkgs/lib>
, rootMountPoint ? "/mnt"

View file

@ -42,6 +42,13 @@ in
"/dev/disk/by-id/md-name-any:${config._parent.name}-part${toString partition.config._index}"
else
"/dev/disk/by-partlabel/${diskoLib.hexEscapeUdevSymlink partition.config.label}";
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}
'';
description = "Device to use for the partition";
};
priority = lib.mkOption {
@ -80,6 +87,11 @@ in
builtins.substring 0 limit (builtins.hashString "sha256" label)
else
label;
defaultText = ''
''${config._parent.type}-''${config._parent.name}-''${partition.config.name}
or a truncated hash of the above if it is longer than 36 characters
'';
};
size = lib.mkOption {
type = lib.types.either (lib.types.enum [ "100%" ]) (lib.types.strMatching "[0-9]+[KMGTP]?");
@ -93,6 +105,7 @@ in
alignment = lib.mkOption {
type = lib.types.int;
default = if (builtins.substring (builtins.stringLength partition.config.start - 1) 1 partition.config.start == "s" || (builtins.substring (builtins.stringLength partition.config.end - 1) 1 partition.config.end == "s")) then 1 else 0;
defaultText = "1 if the unit of start or end is sectors, 0 otherwise";
description = "Alignment of the partition, if sectors are used as start or end it can be aligned to 1";
};
start = lib.mkOption {
@ -103,6 +116,9 @@ in
end = lib.mkOption {
type = lib.types.str;
default = if partition.config.size == "100%" then "-0" else "+${partition.config.size}";
defaultText = ''
if partition.config.size == "100%" then "-0" else "+''${partition.config.size}";
'';
description = ''
End of the partition, in sgdisk format.
Use + for relative sizes from the partitions start
@ -142,8 +158,10 @@ in
description = "Entry to add to the Hybrid MBR table";
};
_index = lib.mkOption {
type = lib.types.int;
internal = true;
default = diskoLib.indexOf (x: x.name == partition.config.name) sortedPartitions 0;
defaultText = null;
};
};
}));

View file

@ -59,9 +59,11 @@ in
askPassword = lib.mkOption {
type = lib.types.bool;
default = config.keyFile == null && config.passwordFile == null && (! config.settings ? "keyFile");
defaultText = "true if neither keyFile nor passwordFile are set";
description = "Whether to ask for a password for initial encryption";
};
settings = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
default = { };
description = "LUKS settings (as defined in configuration.nix in boot.initrd.luks.devices.<name>)";
example = ''{

View file

@ -63,8 +63,10 @@
};
content = diskoLib.partitionType { parent = config; device = diskoLib.deviceNumbering config.device partition.config._index; };
_index = lib.mkOption {
type = lib.types.int;
internal = true;
default = lib.toInt (lib.head (builtins.match ".*entry ([[:digit:]]+)]" name));
defaultText = null;
};
};
}));