treewide: format all files
This commit is contained in:
143
cli.nix
143
cli.nix
@@ -1,12 +1,13 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, lib ? pkgs.lib
|
||||
, mode ? "mount"
|
||||
, flake ? null
|
||||
, flakeAttr ? null
|
||||
, diskoFile ? null
|
||||
, rootMountPoint ? "/mnt"
|
||||
, noDeps ? false
|
||||
, ...
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
lib ? pkgs.lib,
|
||||
mode ? "mount",
|
||||
flake ? null,
|
||||
flakeAttr ? null,
|
||||
diskoFile ? null,
|
||||
rootMountPoint ? "/mnt",
|
||||
noDeps ? false,
|
||||
...
|
||||
}@args:
|
||||
let
|
||||
disko = import ./. {
|
||||
@@ -17,66 +18,77 @@ let
|
||||
hasDiskoFile = diskoFile != null;
|
||||
|
||||
diskoAttr =
|
||||
(if noDeps then
|
||||
(if hasDiskoFile then
|
||||
{
|
||||
destroy = "_cliDestroyNoDeps";
|
||||
format = "_cliFormatNoDeps";
|
||||
mount = "_cliMountNoDeps";
|
||||
unmount = "_cliUnmountNoDeps";
|
||||
(
|
||||
if noDeps then
|
||||
(
|
||||
if hasDiskoFile then
|
||||
{
|
||||
destroy = "_cliDestroyNoDeps";
|
||||
format = "_cliFormatNoDeps";
|
||||
mount = "_cliMountNoDeps";
|
||||
unmount = "_cliUnmountNoDeps";
|
||||
|
||||
"format,mount" = "_cliFormatMountNoDeps";
|
||||
"destroy,format,mount" = "_cliDestroyFormatMountNoDeps";
|
||||
"format,mount" = "_cliFormatMountNoDeps";
|
||||
"destroy,format,mount" = "_cliDestroyFormatMountNoDeps";
|
||||
}
|
||||
else
|
||||
{
|
||||
destroy = "destroyNoDeps";
|
||||
format = "formatNoDeps";
|
||||
mount = "mountNoDeps";
|
||||
unmount = "unmountNoDeps";
|
||||
|
||||
"format,mount" = "formatMountNoDeps";
|
||||
"destroy,format,mount" = "destroyFormatMountNoDeps";
|
||||
}
|
||||
)
|
||||
// {
|
||||
# legacy aliases
|
||||
disko = "diskoScriptNoDeps";
|
||||
create = "createScriptNoDeps";
|
||||
zap_create_mount = "diskoScriptNoDeps";
|
||||
}
|
||||
else
|
||||
{
|
||||
destroy = "destroyNoDeps";
|
||||
format = "formatNoDeps";
|
||||
mount = "mountNoDeps";
|
||||
unmount = "unmountNoDeps";
|
||||
(
|
||||
if hasDiskoFile then
|
||||
{
|
||||
destroy = "_cliDestroy";
|
||||
format = "_cliFormat";
|
||||
mount = "_cliMount";
|
||||
unmount = "_cliUnmount";
|
||||
|
||||
"format,mount" = "formatMountNoDeps";
|
||||
"destroy,format,mount" = "destroyFormatMountNoDeps";
|
||||
}) // {
|
||||
# legacy aliases
|
||||
disko = "diskoScriptNoDeps";
|
||||
create = "createScriptNoDeps";
|
||||
zap_create_mount = "diskoScriptNoDeps";
|
||||
}
|
||||
else
|
||||
(if hasDiskoFile then
|
||||
{
|
||||
destroy = "_cliDestroy";
|
||||
format = "_cliFormat";
|
||||
mount = "_cliMount";
|
||||
unmount = "_cliUnmount";
|
||||
"format,mount" = "_cliFormatMount";
|
||||
"destroy,format,mount" = "_cliDestroyFormatMount";
|
||||
}
|
||||
else
|
||||
{
|
||||
destroy = "destroy";
|
||||
format = "format";
|
||||
mount = "mount";
|
||||
unmount = "unmount";
|
||||
|
||||
"format,mount" = "_cliFormatMount";
|
||||
"destroy,format,mount" = "_cliDestroyFormatMount";
|
||||
"format,mount" = "formatMount";
|
||||
"destroy,format,mount" = "destroyFormatMount";
|
||||
}
|
||||
)
|
||||
// {
|
||||
# legacy aliases
|
||||
disko = "diskoScript";
|
||||
create = "createScript";
|
||||
zap_create_mount = "diskoScript";
|
||||
}
|
||||
else
|
||||
{
|
||||
destroy = "destroy";
|
||||
format = "format";
|
||||
mount = "mount";
|
||||
unmount = "unmount";
|
||||
|
||||
"format,mount" = "formatMount";
|
||||
"destroy,format,mount" = "destroyFormatMount";
|
||||
}) // {
|
||||
# legacy aliases
|
||||
disko = "diskoScript";
|
||||
create = "createScript";
|
||||
zap_create_mount = "diskoScript";
|
||||
}
|
||||
).${mode};
|
||||
|
||||
hasDiskoConfigFlake =
|
||||
hasDiskoFile || lib.hasAttrByPath [ "diskoConfigurations" flakeAttr ] (builtins.getFlake flake);
|
||||
|
||||
hasDiskoModuleFlake =
|
||||
lib.hasAttrByPath [ "nixosConfigurations" flakeAttr "config" "disko" "devices" ] (builtins.getFlake flake);
|
||||
|
||||
hasDiskoModuleFlake = lib.hasAttrByPath [
|
||||
"nixosConfigurations"
|
||||
flakeAttr
|
||||
"config"
|
||||
"disko"
|
||||
"devices"
|
||||
] (builtins.getFlake flake);
|
||||
|
||||
diskFormat =
|
||||
let
|
||||
@@ -86,20 +98,16 @@ let
|
||||
else
|
||||
(builtins.getFlake flake).diskoConfigurations.${flakeAttr};
|
||||
in
|
||||
if builtins.isFunction diskoConfig then
|
||||
diskoConfig ({ inherit lib; } // args)
|
||||
else
|
||||
diskoConfig;
|
||||
if builtins.isFunction diskoConfig then diskoConfig ({ inherit lib; } // args) else diskoConfig;
|
||||
|
||||
diskoEval =
|
||||
disko.${diskoAttr} diskFormat pkgs;
|
||||
diskoEval = disko.${diskoAttr} diskFormat pkgs;
|
||||
|
||||
diskoScript =
|
||||
if hasDiskoConfigFlake then
|
||||
diskoEval
|
||||
else if hasDiskoModuleFlake then
|
||||
(builtins.getFlake flake).nixosConfigurations.${flakeAttr}.config.system.build.${diskoAttr} or (
|
||||
pkgs.writeShellScriptBin "disko-compat-error" ''
|
||||
(builtins.getFlake flake).nixosConfigurations.${flakeAttr}.config.system.build.${diskoAttr}
|
||||
or (pkgs.writeShellScriptBin "disko-compat-error" ''
|
||||
echo 'Error: Attribute `nixosConfigurations.${flakeAttr}.config.system.build.${diskoAttr}` >&2
|
||||
echo ' not found in flake `${flake}`!' >&2
|
||||
echo ' This is probably caused by the locked version of disko in the flake' >&2
|
||||
@@ -107,8 +115,7 @@ let
|
||||
echo 'EITHER set the `disko` input of your flake to `github:nix-community/disko/latest`,' >&2
|
||||
echo ' run `nix flake update disko` in the flake directory and then try again,' >&2
|
||||
echo 'OR run `nix run github:nix-community/disko/v1.9.0 -- --help` and use one of its modes.' >&2
|
||||
exit 1;''
|
||||
)
|
||||
exit 1;'')
|
||||
else
|
||||
(builtins.abort "couldn't find `diskoConfigurations.${flakeAttr}` or `nixosConfigurations.${flakeAttr}.config.disko.devices`");
|
||||
|
||||
|
107
default.nix
107
default.nix
@@ -1,64 +1,107 @@
|
||||
{ lib ? import <nixpkgs/lib>
|
||||
, rootMountPoint ? "/mnt"
|
||||
, checked ? false
|
||||
, diskoLib ? import ./lib { inherit lib rootMountPoint; }
|
||||
{
|
||||
lib ? import <nixpkgs/lib>,
|
||||
rootMountPoint ? "/mnt",
|
||||
checked ? false,
|
||||
diskoLib ? import ./lib { inherit lib rootMountPoint; },
|
||||
}:
|
||||
let
|
||||
eval = cfg: lib.evalModules {
|
||||
modules = lib.singleton {
|
||||
# _file = toString input;
|
||||
imports = lib.singleton { disko.devices = cfg.disko.devices; };
|
||||
options = {
|
||||
disko.devices = lib.mkOption {
|
||||
type = diskoLib.toplevel;
|
||||
eval =
|
||||
cfg:
|
||||
lib.evalModules {
|
||||
modules = lib.singleton {
|
||||
# _file = toString input;
|
||||
imports = lib.singleton { disko.devices = cfg.disko.devices; };
|
||||
options = {
|
||||
disko.devices = lib.mkOption {
|
||||
type = diskoLib.toplevel;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
# 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!";
|
||||
warnDeprecated =
|
||||
name:
|
||||
lib.warn "the ${name} output is deprecated and will be removed, please open an issue if you're using it!";
|
||||
in
|
||||
{
|
||||
lib = warnDeprecated ".lib.lib" diskoLib;
|
||||
|
||||
_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;
|
||||
_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;
|
||||
|
||||
_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;
|
||||
_cliFormatNoDeps =
|
||||
cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).formatNoDeps;
|
||||
|
||||
_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;
|
||||
_cliMountNoDeps =
|
||||
cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).mountNoDeps;
|
||||
|
||||
_cliUnmount = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).unmount;
|
||||
_cliUnmountNoDeps = cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).unmountNoDeps;
|
||||
_cliUnmount =
|
||||
cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).unmount;
|
||||
_cliUnmountNoDeps =
|
||||
cfg: pkgs: ((eval cfg).config.disko.devices._scripts { inherit pkgs checked; }).unmountNoDeps;
|
||||
|
||||
_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;
|
||||
_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;
|
||||
_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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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: warnDeprecated "diskoNoDeps" ((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;
|
||||
|
28
doc.nix
28
doc.nix
@@ -1,4 +1,10 @@
|
||||
{ lib, nixosOptionsDoc, runCommand, fetchurl, pandoc }:
|
||||
{
|
||||
lib,
|
||||
nixosOptionsDoc,
|
||||
runCommand,
|
||||
fetchurl,
|
||||
pandoc,
|
||||
}:
|
||||
|
||||
let
|
||||
diskoLib = import ./lib {
|
||||
@@ -21,16 +27,18 @@ let
|
||||
options = nixosOptionsDoc {
|
||||
options = eval.options;
|
||||
};
|
||||
md = (runCommand "disko-options.md" { } ''
|
||||
cat >$out <<EOF
|
||||
# Disko options
|
||||
md =
|
||||
(runCommand "disko-options.md" { } ''
|
||||
cat >$out <<EOF
|
||||
# Disko options
|
||||
|
||||
EOF
|
||||
cat ${options.optionsCommonMark} >>$out
|
||||
'').overrideAttrs (_o: {
|
||||
# Work around https://github.com/hercules-ci/hercules-ci-agent/issues/168
|
||||
allowSubstitutes = true;
|
||||
});
|
||||
EOF
|
||||
cat ${options.optionsCommonMark} >>$out
|
||||
'').overrideAttrs
|
||||
(_o: {
|
||||
# Work around https://github.com/hercules-ci/hercules-ci-agent/issues/168
|
||||
allowSubstitutes = true;
|
||||
});
|
||||
css = fetchurl {
|
||||
url = "https://gist.githubusercontent.com/killercup/5917178/raw/40840de5352083adb2693dc742e9f75dbb18650f/pandoc.css";
|
||||
sha256 = "sha256-SzSvxBIrylxBF6B/mOImLlZ+GvCfpWNLzGFViLyOeTk=";
|
||||
|
@@ -26,7 +26,10 @@
|
||||
type = "btrfs";
|
||||
extraArgs = [ "-f" ]; # Override existing partition
|
||||
mountpoint = "/";
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
mountOptions = [
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -35,4 +38,3 @@
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -41,7 +41,10 @@
|
||||
"/home/user" = { };
|
||||
# Parent is not mounted so the mountpoint must be set
|
||||
"/nix" = {
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
mountOptions = [
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
mountpoint = "/nix";
|
||||
};
|
||||
# This subvolume will be created but not mounted
|
||||
@@ -74,4 +77,3 @@
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -38,4 +38,3 @@
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -35,15 +35,24 @@
|
||||
subvolumes = {
|
||||
"/root" = {
|
||||
mountpoint = "/";
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
mountOptions = [
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
"/home" = {
|
||||
mountpoint = "/home";
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
mountOptions = [
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
"/nix" = {
|
||||
mountpoint = "/nix";
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
mountOptions = [
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
"/swap" = {
|
||||
mountpoint = "/.swapvol";
|
||||
|
@@ -56,4 +56,3 @@
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
{ pkgs
|
||||
, lib
|
||||
, ...
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# We just import from the repository for testing here:
|
||||
|
@@ -1,5 +1,10 @@
|
||||
# Example to create a bios compatible gpt partition
|
||||
{ disks ? [ "/dev/vdb" ], lib, ... }: {
|
||||
{
|
||||
disks ? [ "/dev/vdb" ],
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
disko.devices = {
|
||||
disk = lib.genAttrs disks (device: {
|
||||
name = lib.replaceStrings [ "/" ] [ "_" ] device;
|
||||
|
@@ -23,7 +23,10 @@
|
||||
type = "filesystem";
|
||||
format = "xfs";
|
||||
mountpoint = "/";
|
||||
mountOptions = [ "defaults" "pquota" ];
|
||||
mountOptions = [
|
||||
"defaults"
|
||||
"pquota"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@@ -251,14 +251,20 @@
|
||||
}
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "data2" "data3" ];
|
||||
members = [
|
||||
"data2"
|
||||
"data3"
|
||||
];
|
||||
}
|
||||
];
|
||||
spare = [ "spare" ];
|
||||
log = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "log1" "log2" ];
|
||||
members = [
|
||||
"log1"
|
||||
"log2"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "log3" ];
|
||||
@@ -267,7 +273,10 @@
|
||||
dedup = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "dedup1" "dedup2" ];
|
||||
members = [
|
||||
"dedup1"
|
||||
"dedup2"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "dedup3" ];
|
||||
@@ -276,7 +285,10 @@
|
||||
special = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "special1" "special2" ];
|
||||
members = [
|
||||
"special1"
|
||||
"special2"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "special3" ];
|
||||
|
50
flake.nix
50
flake.nix
@@ -6,7 +6,8 @@
|
||||
#inputs.nixpkgs.url = "nixpkgs";
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
|
||||
outputs = { self, nixpkgs, ... }:
|
||||
outputs =
|
||||
{ self, nixpkgs, ... }:
|
||||
let
|
||||
lib = nixpkgs.lib;
|
||||
supportedSystems = [
|
||||
@@ -28,7 +29,8 @@
|
||||
nixosModules.default = self.nixosModules.disko; # convention
|
||||
nixosModules.disko = ./module.nix;
|
||||
lib = diskoLib;
|
||||
packages = forAllSystems (system:
|
||||
packages = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
@@ -41,27 +43,35 @@
|
||||
default = self.packages.${system}.disko;
|
||||
|
||||
create-release = pkgs.callPackage ./scripts/create-release.nix { };
|
||||
} // pkgs.lib.optionalAttrs (!pkgs.stdenv.buildPlatform.isRiscV64) {
|
||||
}
|
||||
// pkgs.lib.optionalAttrs (!pkgs.stdenv.buildPlatform.isRiscV64) {
|
||||
disko-doc = pkgs.callPackage ./doc.nix { };
|
||||
});
|
||||
}
|
||||
);
|
||||
# TODO: disable bios-related tests on aarch64...
|
||||
# Run checks: nix flake check -L
|
||||
checks = forAllSystems (system:
|
||||
checks = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
# FIXME: aarch64-linux seems to hang on boot
|
||||
nixosTests = lib.optionalAttrs pkgs.stdenv.hostPlatform.isx86_64 (import ./tests {
|
||||
inherit pkgs;
|
||||
makeTest = import (pkgs.path + "/nixos/tests/make-test-python.nix");
|
||||
eval-config = import (pkgs.path + "/nixos/lib/eval-config.nix");
|
||||
});
|
||||
nixosTests = lib.optionalAttrs pkgs.stdenv.hostPlatform.isx86_64 (
|
||||
import ./tests {
|
||||
inherit pkgs;
|
||||
makeTest = import (pkgs.path + "/nixos/tests/make-test-python.nix");
|
||||
eval-config = import (pkgs.path + "/nixos/lib/eval-config.nix");
|
||||
}
|
||||
);
|
||||
|
||||
disko-install = pkgs.callPackage ./tests/disko-install {
|
||||
inherit self;
|
||||
diskoVersion = version;
|
||||
};
|
||||
|
||||
jsonTypes = pkgs.writeTextFile { name = "jsonTypes"; text = (builtins.toJSON diskoLib.jsonTypes); };
|
||||
jsonTypes = pkgs.writeTextFile {
|
||||
name = "jsonTypes";
|
||||
text = (builtins.toJSON diskoLib.jsonTypes);
|
||||
};
|
||||
|
||||
treefmt = pkgs.runCommand "treefmt" { } ''
|
||||
${self.formatter.${system}}/bin/treefmt --ci --working-dir ${self}
|
||||
@@ -69,11 +79,14 @@
|
||||
'';
|
||||
in
|
||||
# FIXME: aarch64-linux seems to hang on boot
|
||||
lib.optionalAttrs pkgs.stdenv.hostPlatform.isx86_64 (nixosTests // { inherit disko-install; }) //
|
||||
pkgs.lib.optionalAttrs (!pkgs.stdenv.buildPlatform.isRiscV64 && !pkgs.stdenv.hostPlatform.isx86_32) {
|
||||
inherit jsonTypes treefmt;
|
||||
inherit (self.packages.${system}) disko-doc;
|
||||
});
|
||||
lib.optionalAttrs pkgs.stdenv.hostPlatform.isx86_64 (nixosTests // { inherit disko-install; })
|
||||
//
|
||||
pkgs.lib.optionalAttrs (!pkgs.stdenv.buildPlatform.isRiscV64 && !pkgs.stdenv.hostPlatform.isx86_32)
|
||||
{
|
||||
inherit jsonTypes treefmt;
|
||||
inherit (self.packages.${system}) disko-doc;
|
||||
}
|
||||
);
|
||||
|
||||
nixosConfigurations.testmachine = lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
@@ -83,7 +96,8 @@
|
||||
./module.nix
|
||||
];
|
||||
};
|
||||
formatter = forAllSystems (system:
|
||||
formatter = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
@@ -104,6 +118,6 @@
|
||||
self.formatter.${system}
|
||||
];
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
{ flake
|
||||
, flakeAttr
|
||||
, diskMappings
|
||||
, extraSystemConfig ? "{}"
|
||||
, writeEfiBootEntries ? false
|
||||
, rootMountPoint ? "/mnt"
|
||||
,
|
||||
{
|
||||
flake,
|
||||
flakeAttr,
|
||||
diskMappings,
|
||||
extraSystemConfig ? "{}",
|
||||
writeEfiBootEntries ? false,
|
||||
rootMountPoint ? "/mnt",
|
||||
}:
|
||||
let
|
||||
originalSystem = (builtins.getFlake "${flake}").nixosConfigurations."${flakeAttr}";
|
||||
@@ -17,21 +17,19 @@ let
|
||||
else
|
||||
throw "No device passed for disk '${name}'. Pass `--disk ${name} /dev/name` via commandline";
|
||||
|
||||
modifiedDisks = builtins.mapAttrs
|
||||
(
|
||||
name: value:
|
||||
let
|
||||
dev = deviceName name;
|
||||
in
|
||||
value
|
||||
// {
|
||||
device = dev;
|
||||
content = value.content // {
|
||||
device = dev;
|
||||
};
|
||||
}
|
||||
)
|
||||
originalSystem.config.disko.devices.disk;
|
||||
modifiedDisks = builtins.mapAttrs (
|
||||
name: value:
|
||||
let
|
||||
dev = deviceName name;
|
||||
in
|
||||
value
|
||||
// {
|
||||
device = dev;
|
||||
content = value.content // {
|
||||
device = dev;
|
||||
};
|
||||
}
|
||||
) originalSystem.config.disko.devices.disk;
|
||||
|
||||
# filter all nixos module internal attributes
|
||||
cleanedDisks = lib.filterAttrsRecursive (n: _: !lib.hasPrefix "_" n) modifiedDisks;
|
||||
|
@@ -1,25 +1,33 @@
|
||||
{ lib, diskoLib, pkgs, imagePkgs, ... }:
|
||||
{
|
||||
lib,
|
||||
diskoLib,
|
||||
pkgs,
|
||||
imagePkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
# from https://github.com/NixOS/nixpkgs/blob/851f7fc119e9597c26cc43e10938ce7272d0af9d/nixos/modules/system/boot/binfmt.nix
|
||||
makeBinfmtLine =
|
||||
{ name
|
||||
, recognitionType
|
||||
, offset
|
||||
, magicOrExtension
|
||||
, mask
|
||||
, preserveArgvZero
|
||||
, openBinary
|
||||
, matchCredentials
|
||||
, fixBinary
|
||||
, interpreter
|
||||
, ...
|
||||
{
|
||||
name,
|
||||
recognitionType,
|
||||
offset,
|
||||
magicOrExtension,
|
||||
mask,
|
||||
preserveArgvZero,
|
||||
openBinary,
|
||||
matchCredentials,
|
||||
fixBinary,
|
||||
interpreter,
|
||||
...
|
||||
}:
|
||||
let
|
||||
type = if recognitionType == "magic" then "M" else "E";
|
||||
offset' = toString offset;
|
||||
mask' = toString mask;
|
||||
flags = with lib;
|
||||
flags =
|
||||
with lib;
|
||||
if !(matchCredentials -> openBinary) then
|
||||
throw "boot.binfmt.registrations.${name}: you can't specify openBinary = false when matchCredentials = true."
|
||||
else
|
||||
@@ -144,29 +152,30 @@ let
|
||||
in
|
||||
{
|
||||
binfmtRegistration =
|
||||
let
|
||||
system = imagePkgs.stdenv.hostPlatform.system;
|
||||
enabled = system != pkgs.stdenv.hostPlatform.system;
|
||||
elaborated = lib.systems.elaborate { inherit system; };
|
||||
useStaticEmulator = true; # needed for chroot
|
||||
interpreter = elaborated.emulator (if useStaticEmulator then pkgs.pkgsStatic else pkgs);
|
||||
let
|
||||
system = imagePkgs.stdenv.hostPlatform.system;
|
||||
enabled = system != pkgs.stdenv.hostPlatform.system;
|
||||
elaborated = lib.systems.elaborate { inherit system; };
|
||||
useStaticEmulator = true; # needed for chroot
|
||||
interpreter = elaborated.emulator (if useStaticEmulator then pkgs.pkgsStatic else pkgs);
|
||||
|
||||
inherit (elaborated) qemuArch;
|
||||
isQemu = "qemu-${qemuArch}" == baseNameOf interpreter;
|
||||
in makeBinfmtLine (
|
||||
{
|
||||
name = system;
|
||||
inherit interpreter;
|
||||
recognitionType = "magic";
|
||||
offset = null;
|
||||
openBinary = false;
|
||||
matchCredentials = false;
|
||||
inherit (elaborated) qemuArch;
|
||||
isQemu = "qemu-${qemuArch}" == baseNameOf interpreter;
|
||||
in
|
||||
makeBinfmtLine (
|
||||
{
|
||||
name = system;
|
||||
inherit interpreter;
|
||||
recognitionType = "magic";
|
||||
offset = null;
|
||||
openBinary = false;
|
||||
matchCredentials = false;
|
||||
|
||||
preserveArgvZero = isQemu;
|
||||
preserveArgvZero = isQemu;
|
||||
|
||||
fixBinary = useStaticEmulator;
|
||||
}
|
||||
// (magics.${system} or (throw "Cannot create binfmt registration for system ${system}"))
|
||||
);
|
||||
fixBinary = useStaticEmulator;
|
||||
}
|
||||
// (magics.${system} or (throw "Cannot create binfmt registration for system ${system}"))
|
||||
);
|
||||
systemsAreDifferent = imagePkgs.stdenv.hostPlatform.system != pkgs.stdenv.hostPlatform.system;
|
||||
}
|
||||
|
891
lib/default.nix
891
lib/default.nix
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,30 @@
|
||||
{ diskoLib, modulesPath, config, pkgs, lib, ... }:
|
||||
{
|
||||
diskoLib,
|
||||
modulesPath,
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
vm_disko = (diskoLib.testLib.prepareDiskoConfig config diskoLib.testLib.devices).disko;
|
||||
cfg_ = (lib.evalModules {
|
||||
modules = lib.singleton {
|
||||
# _file = toString input;
|
||||
imports = lib.singleton { disko.devices = vm_disko.devices; };
|
||||
options = {
|
||||
disko.devices = lib.mkOption {
|
||||
type = diskoLib.toplevel;
|
||||
};
|
||||
disko.testMode = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
cfg_ =
|
||||
(lib.evalModules {
|
||||
modules = lib.singleton {
|
||||
# _file = toString input;
|
||||
imports = lib.singleton { disko.devices = vm_disko.devices; };
|
||||
options = {
|
||||
disko.devices = lib.mkOption {
|
||||
type = diskoLib.toplevel;
|
||||
};
|
||||
disko.testMode = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}).config;
|
||||
}).config;
|
||||
disks = lib.attrValues cfg_.disko.devices.disk;
|
||||
rootDisk = {
|
||||
name = "root";
|
||||
@@ -26,13 +34,11 @@ let
|
||||
deviceExtraOpts.bootindex = "1";
|
||||
deviceExtraOpts.serial = "root";
|
||||
};
|
||||
otherDisks = map
|
||||
(disk: {
|
||||
name = disk.name;
|
||||
file = ''"$tmp"/${lib.escapeShellArg disk.name}.qcow2'';
|
||||
driveExtraOpts.werror = "report";
|
||||
})
|
||||
(builtins.tail disks);
|
||||
otherDisks = map (disk: {
|
||||
name = disk.name;
|
||||
file = ''"$tmp"/${lib.escapeShellArg disk.name}.qcow2'';
|
||||
driveExtraOpts.werror = "report";
|
||||
}) (builtins.tail disks);
|
||||
|
||||
diskoBasedConfiguration = {
|
||||
# generated from disko config
|
||||
|
@@ -1,10 +1,11 @@
|
||||
{ config
|
||||
, diskoLib
|
||||
, lib
|
||||
, extendModules
|
||||
, options
|
||||
, imagePkgs
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
diskoLib,
|
||||
lib,
|
||||
extendModules,
|
||||
options,
|
||||
imagePkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
diskoCfg = config.disko;
|
||||
@@ -13,33 +14,45 @@ let
|
||||
checked = diskoCfg.checkScripts;
|
||||
|
||||
configSupportsZfs = config.boot.supportedFilesystems.zfs or false;
|
||||
binfmt = diskoLib.binfmt { inherit diskoLib lib pkgs imagePkgs; };
|
||||
binfmt = diskoLib.binfmt {
|
||||
inherit
|
||||
diskoLib
|
||||
lib
|
||||
pkgs
|
||||
imagePkgs
|
||||
;
|
||||
};
|
||||
binfmtSetup = lib.optionalString (cfg.enableBinfmt && binfmt.systemsAreDifferent) ''
|
||||
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
|
||||
${pkgs.systemdMinimal}/lib/systemd/systemd-binfmt <(echo ${lib.strings.escapeShellArg binfmt.binfmtRegistration})
|
||||
'';
|
||||
|
||||
vmTools = pkgs.vmTools.override
|
||||
({
|
||||
rootModules = [
|
||||
"9p" "9pnet_virtio" # we can drop those in future if we stop supporting 24.11
|
||||
vmTools = pkgs.vmTools.override (
|
||||
{
|
||||
rootModules =
|
||||
[
|
||||
"9p"
|
||||
"9pnet_virtio" # we can drop those in future if we stop supporting 24.11
|
||||
|
||||
"virtiofs"
|
||||
"virtio_pci"
|
||||
"virtio_blk"
|
||||
"virtio_balloon"
|
||||
"virtio_rng"
|
||||
]
|
||||
"virtiofs"
|
||||
"virtio_pci"
|
||||
"virtio_blk"
|
||||
"virtio_balloon"
|
||||
"virtio_rng"
|
||||
]
|
||||
++ (lib.optional configSupportsZfs "zfs")
|
||||
++ cfg.extraRootModules;
|
||||
kernel = pkgs.aggregateModules
|
||||
([ cfg.kernelPackages.kernel ]
|
||||
++ lib.optional (lib.elem "zfs" cfg.extraRootModules || configSupportsZfs) cfg.kernelPackages.${config.boot.zfs.package.kernelModuleAttribute});
|
||||
kernel = pkgs.aggregateModules (
|
||||
[ cfg.kernelPackages.kernel ]
|
||||
++ lib.optional (
|
||||
lib.elem "zfs" cfg.extraRootModules || configSupportsZfs
|
||||
) cfg.kernelPackages.${config.boot.zfs.package.kernelModuleAttribute}
|
||||
);
|
||||
}
|
||||
// lib.optionalAttrs (diskoLib.vmToolsSupportsCustomQemu lib)
|
||||
{
|
||||
// lib.optionalAttrs (diskoLib.vmToolsSupportsCustomQemu lib) {
|
||||
customQemu = cfg.qemu;
|
||||
});
|
||||
}
|
||||
);
|
||||
cleanedConfig = diskoLib.testLib.prepareDiskoConfig config diskoLib.testLib.devices;
|
||||
systemToInstall = extendModules {
|
||||
modules = [
|
||||
@@ -51,34 +64,41 @@ let
|
||||
}
|
||||
];
|
||||
};
|
||||
systemToInstallNative = if binfmt.systemsAreDifferent then extendModules {
|
||||
modules = [
|
||||
cfg.extraConfig
|
||||
{
|
||||
disko.testMode = true;
|
||||
disko.devices = lib.mkForce cleanedConfig.disko.devices;
|
||||
boot.loader.grub.devices = lib.mkForce cleanedConfig.boot.loader.grub.devices;
|
||||
nixpkgs.hostPlatform = lib.mkForce pkgs.stdenv.hostPlatform;
|
||||
systemToInstallNative =
|
||||
if binfmt.systemsAreDifferent then
|
||||
extendModules {
|
||||
modules = [
|
||||
cfg.extraConfig
|
||||
{
|
||||
disko.testMode = true;
|
||||
disko.devices = lib.mkForce cleanedConfig.disko.devices;
|
||||
boot.loader.grub.devices = lib.mkForce cleanedConfig.boot.loader.grub.devices;
|
||||
nixpkgs.hostPlatform = lib.mkForce pkgs.stdenv.hostPlatform;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
else systemToInstall;
|
||||
dependencies = with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
gnused
|
||||
parted # for partprobe
|
||||
systemdMinimal
|
||||
nix
|
||||
util-linux
|
||||
findutils
|
||||
kmod
|
||||
] ++ cfg.extraDependencies;
|
||||
else
|
||||
systemToInstall;
|
||||
dependencies =
|
||||
with pkgs;
|
||||
[
|
||||
bash
|
||||
coreutils
|
||||
gnused
|
||||
parted # for partprobe
|
||||
systemdMinimal
|
||||
nix
|
||||
util-linux
|
||||
findutils
|
||||
kmod
|
||||
]
|
||||
++ cfg.extraDependencies;
|
||||
preVM = ''
|
||||
# shellcheck disable=SC2154
|
||||
mkdir -p "$out"
|
||||
${lib.concatMapStringsSep "\n" (disk:
|
||||
# shellcheck disable=SC2154
|
||||
${lib.concatMapStringsSep "\n" (
|
||||
disk:
|
||||
# shellcheck disable=SC2154
|
||||
"${pkgs.qemu}/bin/qemu-img create -f ${imageFormat} \"$out/${disk.imageName}.${imageFormat}\" ${disk.imageSize}"
|
||||
) (lib.attrValues diskoCfg.devices.disk)}
|
||||
# This makes disko work, when canTouchEfiVariables is set to true.
|
||||
@@ -127,24 +147,26 @@ let
|
||||
umount -Rv ${systemToInstall.config.disko.rootMountPoint}
|
||||
'';
|
||||
|
||||
QEMU_OPTS = lib.concatStringsSep " " ([
|
||||
"-drive if=pflash,format=raw,unit=0,readonly=on,file=${pkgs.OVMF.firmware}"
|
||||
"-drive if=pflash,format=raw,unit=1,file=efivars.fd"
|
||||
] ++ builtins.map
|
||||
(disk:
|
||||
QEMU_OPTS = lib.concatStringsSep " " (
|
||||
[
|
||||
"-drive if=pflash,format=raw,unit=0,readonly=on,file=${pkgs.OVMF.firmware}"
|
||||
"-drive if=pflash,format=raw,unit=1,file=efivars.fd"
|
||||
]
|
||||
++ builtins.map (
|
||||
disk:
|
||||
"-drive file=\"$out\"/${disk.imageName}.${imageFormat},if=virtio,cache=unsafe,werror=report,format=${imageFormat}"
|
||||
)
|
||||
(lib.attrValues diskoCfg.devices.disk));
|
||||
) (lib.attrValues diskoCfg.devices.disk)
|
||||
);
|
||||
in
|
||||
{
|
||||
system.build.diskoImages = vmTools.runInLinuxVM (pkgs.runCommand cfg.name
|
||||
{
|
||||
system.build.diskoImages = vmTools.runInLinuxVM (
|
||||
pkgs.runCommand cfg.name {
|
||||
buildInputs = dependencies;
|
||||
inherit preVM QEMU_OPTS;
|
||||
postVM = cfg.extraPostVM;
|
||||
inherit (diskoCfg) memSize;
|
||||
}
|
||||
(binfmtSetup + partitioner + installer));
|
||||
} (binfmtSetup + partitioner + installer)
|
||||
);
|
||||
|
||||
system.build.diskoImagesScript = diskoLib.writeCheckedBash { inherit checked pkgs; } cfg.name ''
|
||||
set -efu
|
||||
@@ -209,32 +231,34 @@ in
|
||||
shift
|
||||
done
|
||||
|
||||
export preVM=${diskoLib.writeCheckedBash { inherit pkgs checked; } "preVM.sh" ''
|
||||
set -efu
|
||||
mv copy_before_disko copy_after_disko xchg/
|
||||
origBuilder=${pkgs.writeScript "disko-builder" ''
|
||||
set -eu
|
||||
export PATH=${lib.makeBinPath dependencies}
|
||||
for src in /tmp/xchg/copy_before_disko/*; do
|
||||
[ -e "$src" ] || continue
|
||||
dst=$(basename "$src" | base64 -d)
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
cp -r "$src" "$dst"
|
||||
done
|
||||
set -f
|
||||
${partitioner}
|
||||
set +f
|
||||
for src in /tmp/xchg/copy_after_disko/*; do
|
||||
[ -e "$src" ] || continue
|
||||
dst=/mnt/$(basename "$src" | base64 -d)
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
cp -r "$src" "$dst"
|
||||
done
|
||||
${installer}
|
||||
''}
|
||||
echo "export origBuilder=$origBuilder" >> xchg/saved-env
|
||||
${preVM}
|
||||
''}
|
||||
export preVM=${
|
||||
diskoLib.writeCheckedBash { inherit pkgs checked; } "preVM.sh" ''
|
||||
set -efu
|
||||
mv copy_before_disko copy_after_disko xchg/
|
||||
origBuilder=${pkgs.writeScript "disko-builder" ''
|
||||
set -eu
|
||||
export PATH=${lib.makeBinPath dependencies}
|
||||
for src in /tmp/xchg/copy_before_disko/*; do
|
||||
[ -e "$src" ] || continue
|
||||
dst=$(basename "$src" | base64 -d)
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
cp -r "$src" "$dst"
|
||||
done
|
||||
set -f
|
||||
${partitioner}
|
||||
set +f
|
||||
for src in /tmp/xchg/copy_after_disko/*; do
|
||||
[ -e "$src" ] || continue
|
||||
dst=/mnt/$(basename "$src" | base64 -d)
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
cp -r "$src" "$dst"
|
||||
done
|
||||
${installer}
|
||||
''}
|
||||
echo "export origBuilder=$origBuilder" >> xchg/saved-env
|
||||
${preVM}
|
||||
''
|
||||
}
|
||||
export postVM=${diskoLib.writeCheckedBash { inherit pkgs checked; } "postVM.sh" cfg.extraPostVM}
|
||||
|
||||
build_memory=''${build_memory:-${builtins.toString diskoCfg.memSize}}
|
||||
|
527
lib/tests.nix
527
lib/tests.nix
@@ -1,37 +1,48 @@
|
||||
{ lib
|
||||
, makeTest
|
||||
, eval-config
|
||||
, ...
|
||||
{
|
||||
lib,
|
||||
makeTest,
|
||||
eval-config,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
testLib = {
|
||||
# this takes a nixos config and changes the disk devices so we can run them inside the qemu test runner
|
||||
# basically changes all the disk.*.devices to something like /dev/vda or /dev/vdb etc.
|
||||
prepareDiskoConfig = cfg: devices:
|
||||
prepareDiskoConfig =
|
||||
cfg: devices:
|
||||
let
|
||||
cleanedTopLevel = lib.filterAttrsRecursive (n: _: !lib.hasPrefix "_" n) cfg;
|
||||
|
||||
preparedDisks = lib.foldlAttrs
|
||||
(acc: n: v: {
|
||||
devices = lib.tail acc.devices;
|
||||
grub-devices = acc.grub-devices ++ (lib.optional (lib.any (part: (part.type or "") == "EF02") (lib.attrValues (v.content.partitions or { }))) (lib.head acc.devices));
|
||||
disks = acc.disks // {
|
||||
"${n}" = v // {
|
||||
device = lib.head acc.devices;
|
||||
content = v.content // { device = lib.head acc.devices; };
|
||||
preparedDisks =
|
||||
lib.foldlAttrs
|
||||
(acc: n: v: {
|
||||
devices = lib.tail acc.devices;
|
||||
grub-devices =
|
||||
acc.grub-devices
|
||||
++ (lib.optional (lib.any (part: (part.type or "") == "EF02") (
|
||||
lib.attrValues (v.content.partitions or { })
|
||||
)) (lib.head acc.devices));
|
||||
disks = acc.disks // {
|
||||
"${n}" = v // {
|
||||
device = lib.head acc.devices;
|
||||
content = v.content // {
|
||||
device = lib.head acc.devices;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
{
|
||||
inherit devices;
|
||||
grub-devices = [ ];
|
||||
disks = { };
|
||||
}
|
||||
cleanedTopLevel.disko.devices.disk;
|
||||
})
|
||||
{
|
||||
inherit devices;
|
||||
grub-devices = [ ];
|
||||
disks = { };
|
||||
}
|
||||
cleanedTopLevel.disko.devices.disk;
|
||||
in
|
||||
cleanedTopLevel // {
|
||||
boot.loader.grub.devices = if (preparedDisks.grub-devices != [ ]) then preparedDisks.grub-devices else [ "nodev" ];
|
||||
cleanedTopLevel
|
||||
// {
|
||||
boot.loader.grub.devices =
|
||||
if (preparedDisks.grub-devices != [ ]) then preparedDisks.grub-devices else [ "nodev" ];
|
||||
disko.devices = cleanedTopLevel.disko.devices // {
|
||||
disk = preparedDisks.disks;
|
||||
};
|
||||
@@ -58,33 +69,31 @@ let
|
||||
|
||||
# This is the test generator for a disko test
|
||||
makeDiskoTest =
|
||||
{ name
|
||||
, disko-config
|
||||
, extendModules ? null
|
||||
, pkgs ? import <nixpkgs> { }
|
||||
, extraTestScript ? ""
|
||||
, bootCommands ? ""
|
||||
, extraInstallerConfig ? { }
|
||||
, extraSystemConfig ? { }
|
||||
, efi ? !pkgs.stdenv.hostPlatform.isRiscV64
|
||||
, postDisko ? ""
|
||||
, testMode ? "module" # can be one of direct module cli
|
||||
, testBoot ? true # if we actually want to test booting or just create/mount
|
||||
, enableOCR ? false
|
||||
{
|
||||
name,
|
||||
disko-config,
|
||||
extendModules ? null,
|
||||
pkgs ? import <nixpkgs> { },
|
||||
extraTestScript ? "",
|
||||
bootCommands ? "",
|
||||
extraInstallerConfig ? { },
|
||||
extraSystemConfig ? { },
|
||||
efi ? !pkgs.stdenv.hostPlatform.isRiscV64,
|
||||
postDisko ? "",
|
||||
testMode ? "module", # can be one of direct module cli
|
||||
testBoot ? true, # if we actually want to test booting or just create/mount
|
||||
enableOCR ? false,
|
||||
}:
|
||||
let
|
||||
makeTest' = args:
|
||||
makeTest' =
|
||||
args:
|
||||
makeTest args {
|
||||
inherit pkgs;
|
||||
inherit (pkgs) system;
|
||||
};
|
||||
# for installation we skip /dev/vda because it is the test runner disk
|
||||
|
||||
importedDiskoConfig =
|
||||
if builtins.isPath disko-config then
|
||||
import disko-config
|
||||
else
|
||||
disko-config;
|
||||
importedDiskoConfig = if builtins.isPath disko-config then import disko-config else disko-config;
|
||||
|
||||
diskoConfigWithArgs =
|
||||
if builtins.isFunction importedDiskoConfig then
|
||||
@@ -104,79 +113,93 @@ let
|
||||
tsp-config = tsp-generator.config testConfigBooted;
|
||||
num-disks = builtins.length (lib.attrNames testConfigBooted.disko.devices.disk);
|
||||
|
||||
installed-system = { config, ... }: {
|
||||
imports = [
|
||||
(lib.optionalAttrs (testMode == "direct") tsp-config)
|
||||
(lib.optionalAttrs (testMode == "module") {
|
||||
disko.enableConfig = true;
|
||||
imports = [
|
||||
../module.nix
|
||||
testConfigBooted
|
||||
];
|
||||
})
|
||||
];
|
||||
installed-system =
|
||||
{ config, ... }:
|
||||
{
|
||||
imports = [
|
||||
(lib.optionalAttrs (testMode == "direct") tsp-config)
|
||||
(lib.optionalAttrs (testMode == "module") {
|
||||
disko.enableConfig = true;
|
||||
imports = [
|
||||
../module.nix
|
||||
testConfigBooted
|
||||
];
|
||||
})
|
||||
];
|
||||
|
||||
# config for tests to make them run faster or work at all
|
||||
documentation.enable = false;
|
||||
hardware.enableAllFirmware = lib.mkForce false;
|
||||
# FIXME: we don't have an systemd in stage-1 equialvent for this
|
||||
boot.initrd.preDeviceCommands = lib.mkIf (!config.boot.initrd.systemd.enable) ''
|
||||
echo -n 'secretsecret' > /tmp/secret.key
|
||||
'';
|
||||
boot.consoleLogLevel = lib.mkForce 100;
|
||||
boot.loader.systemd-boot.enable = lib.mkDefault efi;
|
||||
};
|
||||
# config for tests to make them run faster or work at all
|
||||
documentation.enable = false;
|
||||
hardware.enableAllFirmware = lib.mkForce false;
|
||||
# FIXME: we don't have an systemd in stage-1 equialvent for this
|
||||
boot.initrd.preDeviceCommands = lib.mkIf (!config.boot.initrd.systemd.enable) ''
|
||||
echo -n 'secretsecret' > /tmp/secret.key
|
||||
'';
|
||||
boot.consoleLogLevel = lib.mkForce 100;
|
||||
boot.loader.systemd-boot.enable = lib.mkDefault efi;
|
||||
};
|
||||
|
||||
installed-system-eval = eval-config {
|
||||
modules = [ installed-system ];
|
||||
inherit (pkgs) system;
|
||||
};
|
||||
|
||||
installedTopLevel = ((if extendModules != null then extendModules else installed-system-eval.extendModules) {
|
||||
modules = [
|
||||
({ config, ... }: {
|
||||
imports = [
|
||||
extraSystemConfig
|
||||
({ modulesPath, ... }: {
|
||||
imports = [
|
||||
(modulesPath + "/testing/test-instrumentation.nix") # we need these 2 modules always to be able to run the tests
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
disko.devices = lib.mkForce testConfigBooted.disko.devices;
|
||||
})
|
||||
];
|
||||
|
||||
# since we boot on a different machine, the efi payload needs to be portable
|
||||
boot.loader.grub.efiInstallAsRemovable = efi;
|
||||
boot.loader.grub.efiSupport = efi;
|
||||
boot.loader.systemd-boot.graceful = true;
|
||||
|
||||
# we always want the bind-mounted nix store. otherwise tests take forever
|
||||
fileSystems."/nix/store" = lib.mkForce {
|
||||
device = "nix-store";
|
||||
fsType = "9p";
|
||||
neededForBoot = true;
|
||||
options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ];
|
||||
};
|
||||
boot.zfs.devNodes = "/dev/disk/by-uuid"; # needed because /dev/disk/by-id is empty in qemu-vms
|
||||
|
||||
# grub will install to these devices, we need to force those or we are offset by 1
|
||||
# we use mkOveride 70, so that users can override this with mkForce in case they are testing grub mirrored boots
|
||||
boot.loader.grub.devices = lib.mkOverride 70 testConfigInstall.boot.loader.grub.devices;
|
||||
|
||||
assertions = [
|
||||
installedTopLevel =
|
||||
((if extendModules != null then extendModules else installed-system-eval.extendModules) {
|
||||
modules = [
|
||||
(
|
||||
{ config, ... }:
|
||||
{
|
||||
assertion = builtins.length config.boot.loader.grub.mirroredBoots > 1 -> config.boot.loader.grub.devices == [ ];
|
||||
message = ''
|
||||
When using `--vm-test` in combination with `mirroredBoots`,
|
||||
it is necessary to configure `boot.loader.grub.devices` as an empty list by setting `boot.loader.grub.devices = lib.mkForce [];`.
|
||||
This adjustment is crucial because the `--vm-test` mechanism automatically overrides the grub boot devices as part of the virtual machine test.
|
||||
'';
|
||||
imports = [
|
||||
extraSystemConfig
|
||||
(
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/testing/test-instrumentation.nix") # we need these 2 modules always to be able to run the tests
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
disko.devices = lib.mkForce testConfigBooted.disko.devices;
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
# since we boot on a different machine, the efi payload needs to be portable
|
||||
boot.loader.grub.efiInstallAsRemovable = efi;
|
||||
boot.loader.grub.efiSupport = efi;
|
||||
boot.loader.systemd-boot.graceful = true;
|
||||
|
||||
# we always want the bind-mounted nix store. otherwise tests take forever
|
||||
fileSystems."/nix/store" = lib.mkForce {
|
||||
device = "nix-store";
|
||||
fsType = "9p";
|
||||
neededForBoot = true;
|
||||
options = [
|
||||
"trans=virtio"
|
||||
"version=9p2000.L"
|
||||
"cache=loose"
|
||||
];
|
||||
};
|
||||
boot.zfs.devNodes = "/dev/disk/by-uuid"; # needed because /dev/disk/by-id is empty in qemu-vms
|
||||
|
||||
# grub will install to these devices, we need to force those or we are offset by 1
|
||||
# we use mkOveride 70, so that users can override this with mkForce in case they are testing grub mirrored boots
|
||||
boot.loader.grub.devices = lib.mkOverride 70 testConfigInstall.boot.loader.grub.devices;
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
builtins.length config.boot.loader.grub.mirroredBoots > 1 -> config.boot.loader.grub.devices == [ ];
|
||||
message = ''
|
||||
When using `--vm-test` in combination with `mirroredBoots`,
|
||||
it is necessary to configure `boot.loader.grub.devices` as an empty list by setting `boot.loader.grub.devices = lib.mkForce [];`.
|
||||
This adjustment is crucial because the `--vm-test` mechanism automatically overrides the grub boot devices as part of the virtual machine test.
|
||||
'';
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
})
|
||||
];
|
||||
}).config.system.build.toplevel;
|
||||
)
|
||||
];
|
||||
}).config.system.build.toplevel;
|
||||
|
||||
in
|
||||
makeTest' {
|
||||
@@ -184,153 +207,177 @@ let
|
||||
meta.timeout = 600; # 10 minutes
|
||||
inherit enableOCR;
|
||||
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
imports = [
|
||||
(lib.optionalAttrs (testMode == "module") {
|
||||
imports = [
|
||||
../module.nix
|
||||
];
|
||||
disko = {
|
||||
enableConfig = false;
|
||||
checkScripts = true;
|
||||
devices = testConfigInstall.disko.devices;
|
||||
};
|
||||
})
|
||||
extraInstallerConfig
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
(lib.optionalAttrs (testMode == "module") {
|
||||
imports = [
|
||||
../module.nix
|
||||
];
|
||||
disko = {
|
||||
enableConfig = false;
|
||||
checkScripts = true;
|
||||
devices = testConfigInstall.disko.devices;
|
||||
};
|
||||
})
|
||||
extraInstallerConfig
|
||||
|
||||
# from base.nix
|
||||
({ config, ... }: {
|
||||
boot.supportedFilesystems =
|
||||
[ "btrfs" "cifs" "f2fs" "jfs" "ntfs" "reiserfs" "vfat" "xfs" ] ++
|
||||
lib.optional (config.networking.hostId != null && lib.meta.availableOn pkgs.stdenv.hostPlatform config.boot.zfs.package) "zfs";
|
||||
})
|
||||
# from base.nix
|
||||
(
|
||||
{ config, ... }:
|
||||
{
|
||||
boot.supportedFilesystems =
|
||||
[
|
||||
"btrfs"
|
||||
"cifs"
|
||||
"f2fs"
|
||||
"jfs"
|
||||
"ntfs"
|
||||
"reiserfs"
|
||||
"vfat"
|
||||
"xfs"
|
||||
]
|
||||
++ lib.optional (
|
||||
config.networking.hostId != null
|
||||
&& lib.meta.availableOn pkgs.stdenv.hostPlatform config.boot.zfs.package
|
||||
) "zfs";
|
||||
}
|
||||
)
|
||||
|
||||
(if lib.versionAtLeast (lib.versions.majorMinor lib.version) "23.11" then {
|
||||
boot.swraid.enable = true;
|
||||
} else {
|
||||
boot.initrd.services.swraid.enable = true;
|
||||
})
|
||||
];
|
||||
(
|
||||
if lib.versionAtLeast (lib.versions.majorMinor lib.version) "23.11" then
|
||||
{
|
||||
boot.swraid.enable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
boot.initrd.services.swraid.enable = true;
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
systemd.services.mdmonitor.enable = false; # silence some weird warnings
|
||||
systemd.services.mdmonitor.enable = false; # silence some weird warnings
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.jq
|
||||
];
|
||||
environment.systemPackages = [
|
||||
pkgs.jq
|
||||
];
|
||||
|
||||
# speed-up eval
|
||||
documentation.enable = false;
|
||||
# speed-up eval
|
||||
documentation.enable = false;
|
||||
|
||||
nix.settings = {
|
||||
substituters = lib.mkForce [ ];
|
||||
hashed-mirrors = null;
|
||||
connect-timeout = 1;
|
||||
nix.settings = {
|
||||
substituters = lib.mkForce [ ];
|
||||
hashed-mirrors = null;
|
||||
connect-timeout = 1;
|
||||
};
|
||||
|
||||
networking.hostId = lib.mkIf (
|
||||
(testConfigInstall ? networking.hostId) && (testConfigInstall.networking.hostId != null)
|
||||
) testConfigInstall.networking.hostId;
|
||||
|
||||
virtualisation.emptyDiskImages = builtins.genList (_: 4096) num-disks;
|
||||
|
||||
# useful for debugging via repl
|
||||
system.build.systemToInstall = installed-system-eval;
|
||||
};
|
||||
|
||||
networking.hostId = lib.mkIf
|
||||
(
|
||||
(testConfigInstall ? networking.hostId) && (testConfigInstall.networking.hostId != null)
|
||||
)
|
||||
testConfigInstall.networking.hostId;
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
''
|
||||
def disks(oldmachine, num_disks):
|
||||
disk_flags = []
|
||||
for i in range(num_disks):
|
||||
disk_flags += [
|
||||
'-drive',
|
||||
f"file={oldmachine.state_dir}/empty{i}.qcow2,id=drive{i + 1},if=none,index={i + 1},werror=report",
|
||||
'-device',
|
||||
f"virtio-blk-pci,drive=drive{i + 1}"
|
||||
]
|
||||
return disk_flags
|
||||
|
||||
virtualisation.emptyDiskImages = builtins.genList (_: 4096) num-disks;
|
||||
|
||||
# useful for debugging via repl
|
||||
system.build.systemToInstall = installed-system-eval;
|
||||
};
|
||||
|
||||
testScript = { nodes, ... }: ''
|
||||
def disks(oldmachine, num_disks):
|
||||
disk_flags = []
|
||||
for i in range(num_disks):
|
||||
disk_flags += [
|
||||
'-drive',
|
||||
f"file={oldmachine.state_dir}/empty{i}.qcow2,id=drive{i + 1},if=none,index={i + 1},werror=report",
|
||||
'-device',
|
||||
f"virtio-blk-pci,drive=drive{i + 1}"
|
||||
]
|
||||
return disk_flags
|
||||
|
||||
def create_test_machine(
|
||||
oldmachine=None, **kwargs
|
||||
): # taken from <nixpkgs/nixos/tests/installer.nix>
|
||||
start_command = [
|
||||
"${pkgs.qemu_test}/bin/qemu-kvm",
|
||||
"-cpu",
|
||||
"max",
|
||||
"-m",
|
||||
"1024",
|
||||
"-virtfs",
|
||||
"local,path=/nix/store,security_model=none,mount_tag=nix-store",
|
||||
*disks(oldmachine, ${toString num-disks})
|
||||
]
|
||||
${lib.optionalString efi ''
|
||||
start_command += ["-drive",
|
||||
"if=pflash,format=raw,unit=0,readonly=on,file=${pkgs.OVMF.firmware}",
|
||||
"-drive",
|
||||
"if=pflash,format=raw,unit=1,readonly=on,file=${pkgs.OVMF.variables}"
|
||||
def create_test_machine(
|
||||
oldmachine=None, **kwargs
|
||||
): # taken from <nixpkgs/nixos/tests/installer.nix>
|
||||
start_command = [
|
||||
"${pkgs.qemu_test}/bin/qemu-kvm",
|
||||
"-cpu",
|
||||
"max",
|
||||
"-m",
|
||||
"1024",
|
||||
"-virtfs",
|
||||
"local,path=/nix/store,security_model=none,mount_tag=nix-store",
|
||||
*disks(oldmachine, ${toString num-disks})
|
||||
]
|
||||
''}
|
||||
machine = create_machine(start_command=" ".join(start_command), **kwargs)
|
||||
driver.machines.append(machine)
|
||||
return machine
|
||||
${lib.optionalString efi ''
|
||||
start_command += ["-drive",
|
||||
"if=pflash,format=raw,unit=0,readonly=on,file=${pkgs.OVMF.firmware}",
|
||||
"-drive",
|
||||
"if=pflash,format=raw,unit=1,readonly=on,file=${pkgs.OVMF.variables}"
|
||||
]
|
||||
''}
|
||||
machine = create_machine(start_command=" ".join(start_command), **kwargs)
|
||||
driver.machines.append(machine)
|
||||
return machine
|
||||
|
||||
machine.start()
|
||||
machine.succeed("echo -n 'additionalSecret' > /tmp/additionalSecret.key")
|
||||
machine.succeed("echo -n 'secretsecret' > /tmp/secret.key")
|
||||
${lib.optionalString (testMode == "direct") ''
|
||||
# running direct mode
|
||||
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-unmount}")
|
||||
machine.succeed("${lib.getExe tsp-unmount}") # verify that umount is idempotent
|
||||
machine.succeed("${lib.getExe tsp-mount}") # verify that mount is idempotent
|
||||
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
|
||||
machine.succeed("test -e /mnt/home/testfile")
|
||||
''}
|
||||
${lib.optionalString (testMode == "module") ''
|
||||
# running module mode
|
||||
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} --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
|
||||
machine.succeed("test -e /mnt/home/testfile")
|
||||
''}
|
||||
|
||||
${postDisko}
|
||||
|
||||
${lib.optionalString testBoot ''
|
||||
# mount nix-store in /mnt
|
||||
machine.succeed("mkdir -p /mnt/nix/store")
|
||||
machine.succeed("mount --bind /nix/store /mnt/nix/store")
|
||||
|
||||
machine.succeed("nix-store --load-db < ${pkgs.closureInfo {rootPaths = [installedTopLevel];}}/registration")
|
||||
|
||||
# fix "this is not a NixOS installation"
|
||||
machine.succeed("mkdir -p /mnt/etc")
|
||||
machine.succeed("touch /mnt/etc/NIXOS")
|
||||
|
||||
machine.succeed("mkdir -p /mnt/nix/var/nix/profiles")
|
||||
machine.succeed("nix-env -p /mnt/nix/var/nix/profiles/system --set ${installedTopLevel}")
|
||||
machine.succeed("NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root /mnt -- ${installedTopLevel}/bin/switch-to-configuration boot")
|
||||
machine.succeed("sync")
|
||||
machine.shutdown()
|
||||
|
||||
machine = create_test_machine(oldmachine=machine, name="booted_machine")
|
||||
machine.start()
|
||||
${bootCommands}
|
||||
machine.wait_for_unit("local-fs.target")
|
||||
''}
|
||||
machine.succeed("echo -n 'additionalSecret' > /tmp/additionalSecret.key")
|
||||
machine.succeed("echo -n 'secretsecret' > /tmp/secret.key")
|
||||
${lib.optionalString (testMode == "direct") ''
|
||||
# running direct mode
|
||||
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-unmount}")
|
||||
machine.succeed("${lib.getExe tsp-unmount}") # verify that umount is idempotent
|
||||
machine.succeed("${lib.getExe tsp-mount}") # verify that mount is idempotent
|
||||
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
|
||||
machine.succeed("test -e /mnt/home/testfile")
|
||||
''}
|
||||
${lib.optionalString (testMode == "module") ''
|
||||
# running module mode
|
||||
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} --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
|
||||
machine.succeed("test -e /mnt/home/testfile")
|
||||
''}
|
||||
|
||||
${extraTestScript}
|
||||
'';
|
||||
${postDisko}
|
||||
|
||||
${lib.optionalString testBoot ''
|
||||
# mount nix-store in /mnt
|
||||
machine.succeed("mkdir -p /mnt/nix/store")
|
||||
machine.succeed("mount --bind /nix/store /mnt/nix/store")
|
||||
|
||||
machine.succeed("nix-store --load-db < ${
|
||||
pkgs.closureInfo { rootPaths = [ installedTopLevel ]; }
|
||||
}/registration")
|
||||
|
||||
# fix "this is not a NixOS installation"
|
||||
machine.succeed("mkdir -p /mnt/etc")
|
||||
machine.succeed("touch /mnt/etc/NIXOS")
|
||||
|
||||
machine.succeed("mkdir -p /mnt/nix/var/nix/profiles")
|
||||
machine.succeed("nix-env -p /mnt/nix/var/nix/profiles/system --set ${installedTopLevel}")
|
||||
machine.succeed("NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root /mnt -- ${installedTopLevel}/bin/switch-to-configuration boot")
|
||||
machine.succeed("sync")
|
||||
machine.shutdown()
|
||||
|
||||
machine = create_test_machine(oldmachine=machine, name="booted_machine")
|
||||
machine.start()
|
||||
${bootCommands}
|
||||
machine.wait_for_unit("local-fs.target")
|
||||
''}
|
||||
|
||||
${extraTestScript}
|
||||
'';
|
||||
};
|
||||
};
|
||||
in
|
||||
|
@@ -1,60 +1,71 @@
|
||||
{ config, options, diskoLib, lib, rootMountPoint, parent, device, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
diskoLib,
|
||||
lib,
|
||||
rootMountPoint,
|
||||
parent,
|
||||
device,
|
||||
...
|
||||
}:
|
||||
let
|
||||
swapType = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
size = lib.mkOption {
|
||||
type = lib.types.strMatching "^([0-9]+[KMGTP])?$";
|
||||
description = "Size of the swap file (e.g. 2G)";
|
||||
};
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
size = lib.mkOption {
|
||||
type = lib.types.strMatching "^([0-9]+[KMGTP])?$";
|
||||
description = "Size of the swap file (e.g. 2G)";
|
||||
};
|
||||
|
||||
path = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "Path to the swap file (relative to the mountpoint)";
|
||||
};
|
||||
path = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "Path to the swap file (relative to the mountpoint)";
|
||||
};
|
||||
|
||||
priority = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = null;
|
||||
description = ''
|
||||
Specify the priority of the swap file. Priority is a value between 0 and 32767.
|
||||
Higher numbers indicate higher priority.
|
||||
null lets the kernel choose a priority, which will show up as a negative value.
|
||||
'';
|
||||
};
|
||||
priority = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = null;
|
||||
description = ''
|
||||
Specify the priority of the swap file. Priority is a value between 0 and 32767.
|
||||
Higher numbers indicate higher priority.
|
||||
null lets the kernel choose a priority, which will show up as a negative value.
|
||||
'';
|
||||
};
|
||||
|
||||
options = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.nonEmptyStr;
|
||||
default = [ "defaults" ];
|
||||
example = [ "nofail" ];
|
||||
description = "Options used to mount the swap.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
options = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.nonEmptyStr;
|
||||
default = [ "defaults" ];
|
||||
example = [ "nofail" ];
|
||||
description = "Options used to mount the swap.";
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
description = "Swap files";
|
||||
};
|
||||
|
||||
swapConfig = { mountpoint, swap }:
|
||||
swapConfig =
|
||||
{ mountpoint, swap }:
|
||||
{
|
||||
swapDevices = builtins.map
|
||||
(file: {
|
||||
device = "${mountpoint}/${file.path}";
|
||||
inherit (file) priority options;
|
||||
})
|
||||
(lib.attrValues swap);
|
||||
swapDevices = builtins.map (file: {
|
||||
device = "${mountpoint}/${file.path}";
|
||||
inherit (file) priority options;
|
||||
}) (lib.attrValues swap);
|
||||
};
|
||||
|
||||
swapCreate = mountpoint: swap:
|
||||
lib.concatMapStringsSep
|
||||
"\n"
|
||||
(file: ''
|
||||
if ! test -e "${mountpoint}/${file.path}"; then
|
||||
btrfs filesystem mkswapfile --size ${file.size} "${mountpoint}/${file.path}"
|
||||
fi
|
||||
'')
|
||||
(lib.attrValues swap);
|
||||
swapCreate =
|
||||
mountpoint: swap:
|
||||
lib.concatMapStringsSep "\n" (file: ''
|
||||
if ! test -e "${mountpoint}/${file.path}"; then
|
||||
btrfs filesystem mkswapfile --size ${file.size} "${mountpoint}/${file.path}"
|
||||
fi
|
||||
'') (lib.attrValues swap);
|
||||
|
||||
in
|
||||
{
|
||||
@@ -80,37 +91,42 @@ in
|
||||
description = "A list of options to pass to mount.";
|
||||
};
|
||||
subvolumes = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = config._module.args.name;
|
||||
description = "Name of the BTRFS subvolume.";
|
||||
};
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [ "btrfs_subvol" ];
|
||||
default = "btrfs_subvol";
|
||||
internal = true;
|
||||
description = "Type";
|
||||
};
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra arguments";
|
||||
};
|
||||
mountOptions = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "defaults" ];
|
||||
description = "Options to pass to mount";
|
||||
};
|
||||
mountpoint = lib.mkOption {
|
||||
type = lib.types.nullOr diskoLib.optionTypes.absolute-pathname;
|
||||
default = null;
|
||||
description = "Location to mount the subvolume to.";
|
||||
};
|
||||
swap = swapType;
|
||||
};
|
||||
}));
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ config, ... }:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = config._module.args.name;
|
||||
description = "Name of the BTRFS subvolume.";
|
||||
};
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [ "btrfs_subvol" ];
|
||||
default = "btrfs_subvol";
|
||||
internal = true;
|
||||
description = "Type";
|
||||
};
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra arguments";
|
||||
};
|
||||
mountOptions = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "defaults" ];
|
||||
description = "Options to pass to mount";
|
||||
};
|
||||
mountpoint = lib.mkOption {
|
||||
type = lib.types.nullOr diskoLib.optionTypes.absolute-pathname;
|
||||
default = null;
|
||||
description = "Location to mount the subvolume to.";
|
||||
};
|
||||
swap = swapType;
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
description = "Subvolumes to define for BTRFS.";
|
||||
};
|
||||
@@ -138,9 +154,9 @@ in
|
||||
if ! (blkid "${config.device}" -o export | grep -q '^TYPE='); then
|
||||
mkfs.btrfs "${config.device}" ${toString config.extraArgs}
|
||||
fi
|
||||
${lib.optionalString (config.swap != {} || config.subvolumes != {}) ''
|
||||
${lib.optionalString (config.swap != { } || config.subvolumes != { }) ''
|
||||
if (blkid "${config.device}" -o export | grep -q '^TYPE=btrfs$'); then
|
||||
${lib.optionalString (config.swap != {}) ''
|
||||
${lib.optionalString (config.swap != { }) ''
|
||||
(
|
||||
MNTPOINT=$(mktemp -d)
|
||||
mount ${device} "$MNTPOINT" -o subvol=/
|
||||
@@ -169,79 +185,84 @@ in
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
subvolMounts = lib.concatMapAttrs
|
||||
(_: subvol:
|
||||
lib.warnIf (subvol.mountOptions != (options.subvolumes.type.getSubOptions [ ]).mountOptions.default && subvol.mountpoint == null)
|
||||
"Subvolume ${subvol.name} has mountOptions but no mountpoint. See upgrade guide (2023-07-09 121df48)."
|
||||
lib.optionalAttrs
|
||||
(subvol.mountpoint != null)
|
||||
{
|
||||
${subvol.mountpoint} = ''
|
||||
if ! findmnt "${config.device}" "${rootMountPoint}${subvol.mountpoint}" > /dev/null 2>&1; then
|
||||
mount "${config.device}" "${rootMountPoint}${subvol.mountpoint}" \
|
||||
${lib.concatMapStringsSep " " (opt: "-o ${opt}") (subvol.mountOptions ++ [ "subvol=${subvol.name}" ])} \
|
||||
-o X-mount.mkdir
|
||||
fi
|
||||
'';
|
||||
}
|
||||
)
|
||||
config.subvolumes;
|
||||
subvolMounts = lib.concatMapAttrs (
|
||||
_: subvol:
|
||||
lib.warnIf
|
||||
(
|
||||
subvol.mountOptions != (options.subvolumes.type.getSubOptions [ ]).mountOptions.default
|
||||
&& subvol.mountpoint == null
|
||||
)
|
||||
"Subvolume ${subvol.name} has mountOptions but no mountpoint. See upgrade guide (2023-07-09 121df48)."
|
||||
lib.optionalAttrs
|
||||
(subvol.mountpoint != null)
|
||||
{
|
||||
${subvol.mountpoint} = ''
|
||||
if ! findmnt "${config.device}" "${rootMountPoint}${subvol.mountpoint}" > /dev/null 2>&1; then
|
||||
mount "${config.device}" "${rootMountPoint}${subvol.mountpoint}" \
|
||||
${
|
||||
lib.concatMapStringsSep " " (opt: "-o ${opt}") (subvol.mountOptions ++ [ "subvol=${subvol.name}" ])
|
||||
} \
|
||||
-o X-mount.mkdir
|
||||
fi
|
||||
'';
|
||||
}
|
||||
) config.subvolumes;
|
||||
in
|
||||
{
|
||||
fs = subvolMounts // lib.optionalAttrs (config.mountpoint != null) {
|
||||
${config.mountpoint} = ''
|
||||
if ! findmnt "${config.device}" "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then
|
||||
mount "${config.device}" "${rootMountPoint}${config.mountpoint}" \
|
||||
${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \
|
||||
-o X-mount.mkdir
|
||||
fi
|
||||
'';
|
||||
};
|
||||
fs =
|
||||
subvolMounts
|
||||
// lib.optionalAttrs (config.mountpoint != null) {
|
||||
${config.mountpoint} = ''
|
||||
if ! findmnt "${config.device}" "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then
|
||||
mount "${config.device}" "${rootMountPoint}${config.mountpoint}" \
|
||||
${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \
|
||||
-o X-mount.mkdir
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
subvolMounts = lib.concatMapAttrs
|
||||
(_: subvol:
|
||||
lib.optionalAttrs
|
||||
(subvol.mountpoint != null)
|
||||
{
|
||||
${subvol.mountpoint} = ''
|
||||
if findmnt "${config.device}" "${rootMountPoint}${subvol.mountpoint}" > /dev/null 2>&1; then
|
||||
umount "${rootMountPoint}${subvol.mountpoint}"
|
||||
fi
|
||||
'';
|
||||
}
|
||||
)
|
||||
config.subvolumes;
|
||||
subvolMounts = lib.concatMapAttrs (
|
||||
_: subvol:
|
||||
lib.optionalAttrs (subvol.mountpoint != null) {
|
||||
${subvol.mountpoint} = ''
|
||||
if findmnt "${config.device}" "${rootMountPoint}${subvol.mountpoint}" > /dev/null 2>&1; then
|
||||
umount "${rootMountPoint}${subvol.mountpoint}"
|
||||
fi
|
||||
'';
|
||||
}
|
||||
) config.subvolumes;
|
||||
in
|
||||
{
|
||||
fs = subvolMounts // lib.optionalAttrs (config.mountpoint != null) {
|
||||
${config.mountpoint} = ''
|
||||
if findmnt "${config.device}" "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then
|
||||
umount "${rootMountPoint}${config.mountpoint}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
fs =
|
||||
subvolMounts
|
||||
// lib.optionalAttrs (config.mountpoint != null) {
|
||||
${config.mountpoint} = ''
|
||||
if findmnt "${config.device}" "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then
|
||||
umount "${rootMountPoint}${config.mountpoint}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = [
|
||||
(map
|
||||
(subvol:
|
||||
lib.optional (subvol.mountpoint != null) {
|
||||
fileSystems.${subvol.mountpoint} = {
|
||||
device = config.device;
|
||||
fsType = "btrfs";
|
||||
options = subvol.mountOptions ++ [ "subvol=${subvol.name}" ];
|
||||
};
|
||||
}
|
||||
)
|
||||
(lib.attrValues config.subvolumes))
|
||||
(map (
|
||||
subvol:
|
||||
lib.optional (subvol.mountpoint != null) {
|
||||
fileSystems.${subvol.mountpoint} = {
|
||||
device = config.device;
|
||||
fsType = "btrfs";
|
||||
options = subvol.mountOptions ++ [ "subvol=${subvol.name}" ];
|
||||
};
|
||||
}
|
||||
) (lib.attrValues config.subvolumes))
|
||||
(lib.optional (config.mountpoint != null) {
|
||||
fileSystems.${config.mountpoint} = {
|
||||
device = config.device;
|
||||
@@ -249,11 +270,12 @@ in
|
||||
options = config.mountOptions;
|
||||
};
|
||||
})
|
||||
(map
|
||||
(subvol: swapConfig {
|
||||
(map (
|
||||
subvol:
|
||||
swapConfig {
|
||||
inherit (subvol) mountpoint swap;
|
||||
})
|
||||
(lib.attrValues config.subvolumes))
|
||||
}
|
||||
) (lib.attrValues config.subvolumes))
|
||||
(swapConfig {
|
||||
inherit (config) mountpoint swap;
|
||||
})
|
||||
@@ -264,8 +286,10 @@ in
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs:
|
||||
[ pkgs.btrfs-progs pkgs.gnugrep ];
|
||||
default = pkgs: [
|
||||
pkgs.btrfs-progs
|
||||
pkgs.gnugrep
|
||||
];
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
|
@@ -1,4 +1,10 @@
|
||||
{ config, options, lib, diskoLib, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
@@ -32,13 +38,20 @@
|
||||
'';
|
||||
default = "2G";
|
||||
};
|
||||
content = diskoLib.deviceType { parent = config; device = config.device; };
|
||||
content = diskoLib.deviceType {
|
||||
parent = config;
|
||||
device = config.device;
|
||||
};
|
||||
_meta = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = diskoLib.jsonType;
|
||||
default =
|
||||
lib.optionalAttrs (config.content != null) (config.content._meta [ "disk" config.device ]);
|
||||
default = lib.optionalAttrs (config.content != null) (
|
||||
config.content._meta [
|
||||
"disk"
|
||||
config.device
|
||||
]
|
||||
);
|
||||
description = "Metadata";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
@@ -56,8 +69,7 @@
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default =
|
||||
lib.optional (config.content != null) config.content._config;
|
||||
default = lib.optional (config.content != null) config.content._config;
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
_pkgs = lib.mkOption {
|
||||
|
@@ -1,4 +1,13 @@
|
||||
{ config, options, lib, diskoLib, rootMountPoint, parent, device, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
rootMountPoint,
|
||||
parent,
|
||||
device,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
@@ -90,18 +99,32 @@
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
# type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs:
|
||||
[ pkgs.util-linux pkgs.gnugrep ] ++ (
|
||||
default =
|
||||
pkgs:
|
||||
[
|
||||
pkgs.util-linux
|
||||
pkgs.gnugrep
|
||||
]
|
||||
++ (
|
||||
# TODO add many more
|
||||
if (config.format == "xfs") then [ pkgs.xfsprogs ]
|
||||
else if (config.format == "btrfs") then [ pkgs.btrfs-progs ]
|
||||
else if (config.format == "vfat") then [ pkgs.dosfstools ]
|
||||
else if (config.format == "ext2") then [ pkgs.e2fsprogs ]
|
||||
else if (config.format == "ext3") then [ pkgs.e2fsprogs ]
|
||||
else if (config.format == "ext4") then [ pkgs.e2fsprogs ]
|
||||
else if (config.format == "bcachefs") then [ pkgs.bcachefs-tools ]
|
||||
else if (config.format == "f2fs") then [ pkgs.f2fs-tools ]
|
||||
else [ ]
|
||||
if (config.format == "xfs") then
|
||||
[ pkgs.xfsprogs ]
|
||||
else if (config.format == "btrfs") then
|
||||
[ pkgs.btrfs-progs ]
|
||||
else if (config.format == "vfat") then
|
||||
[ pkgs.dosfstools ]
|
||||
else if (config.format == "ext2") then
|
||||
[ pkgs.e2fsprogs ]
|
||||
else if (config.format == "ext3") then
|
||||
[ pkgs.e2fsprogs ]
|
||||
else if (config.format == "ext4") then
|
||||
[ pkgs.e2fsprogs ]
|
||||
else if (config.format == "bcachefs") then
|
||||
[ pkgs.bcachefs-tools ]
|
||||
else if (config.format == "f2fs") then
|
||||
[ pkgs.f2fs-tools ]
|
||||
else
|
||||
[ ]
|
||||
);
|
||||
description = "Packages";
|
||||
};
|
||||
|
@@ -1,4 +1,12 @@
|
||||
{ config, options, lib, diskoLib, parent, device, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
parent,
|
||||
device,
|
||||
...
|
||||
}:
|
||||
let
|
||||
sortedPartitions = lib.sort (x: y: x.priority < y.priority) (lib.attrValues config.partitions);
|
||||
sortedHybridPartitions = lib.filter (p: p.hybrid != null) sortedPartitions;
|
||||
@@ -16,171 +24,210 @@ in
|
||||
description = "Device to use for the partition table";
|
||||
};
|
||||
partitions = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }@partition: {
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
type =
|
||||
let
|
||||
hexPattern = len: "[A-Fa-f0-9]{${toString len}}";
|
||||
in
|
||||
lib.types.either
|
||||
(lib.types.strMatching (hexPattern 4))
|
||||
(lib.types.strMatching (lib.concatMapStringsSep "-" hexPattern [ 8 4 4 4 12 ]));
|
||||
default = if partition.config.content != null && partition.config.content.type == "swap" then "8200" else "8300";
|
||||
defaultText = ''8300 (Linux filesystem) normally, 8200 (Linux swap) if content.type is "swap"'';
|
||||
description = ''
|
||||
Filesystem type to use.
|
||||
This can either be an sgdisk-specific short code (run sgdisk -L to see what is available),
|
||||
or a fully specified GUID (see https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs).
|
||||
'';
|
||||
};
|
||||
device = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default =
|
||||
if partition.config.uuid != null then
|
||||
"/dev/disk/by-partuuid/${partition.config.uuid}"
|
||||
else if config._parent.type == "mdadm" then
|
||||
# workaround because mdadm partlabel do not appear in /dev/disk/by-partlabel
|
||||
"/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 `uuid` is provided:
|
||||
/dev/disk/by-partuuid/''${partition.config.uuid}
|
||||
|
||||
otherwise, 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 {
|
||||
type = lib.types.int;
|
||||
default =
|
||||
if partition.config.size or "" == "100%" then
|
||||
9001
|
||||
else if partition.config.type == "EF02" then
|
||||
# Boot partition should be created first, because some BIOS implementations require it.
|
||||
# Priority defaults to 100 here to support any potential use-case for placing partitions prior to EF02
|
||||
100
|
||||
else
|
||||
1000;
|
||||
defaultText = ''
|
||||
1000: normal partitions
|
||||
9001: partitions with 100% size
|
||||
100: boot partitions (EF02)
|
||||
'';
|
||||
description = "Priority of the partition, smaller values are created first";
|
||||
};
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Name of the partition";
|
||||
default = name;
|
||||
};
|
||||
uuid = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.strMatching "[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}");
|
||||
default = null;
|
||||
defaultText = "`null` - generate a UUID when creating the partition";
|
||||
example = "809b3a2b-828a-4730-95e1-75b6343e415a";
|
||||
description = ''
|
||||
The UUID (also known as GUID) of the partition. Note that this is distinct from the UUID of the filesystem.
|
||||
|
||||
You can generate a UUID with the command `uuidgen -r`.
|
||||
'';
|
||||
};
|
||||
label = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default =
|
||||
let
|
||||
# 72 bytes is the maximum length of a GPT partition name
|
||||
# the labels seem to be in UTF-16, so 2 bytes per character
|
||||
limit = 36;
|
||||
label = "${config._parent.type}-${config._parent.name}-${partition.config.name}";
|
||||
in
|
||||
if (lib.stringLength label) > limit then
|
||||
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]?");
|
||||
default = "0";
|
||||
description = ''
|
||||
Size of the partition, in sgdisk format.
|
||||
sets end automatically with the + prefix
|
||||
can be 100% for the whole remaining disk, will be done last in that case.
|
||||
'';
|
||||
};
|
||||
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 {
|
||||
type = lib.types.str;
|
||||
default = "0";
|
||||
description = "Start of the partition, in sgdisk format, use 0 for next available range";
|
||||
};
|
||||
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
|
||||
or - for relative sizes from the disks end
|
||||
'';
|
||||
};
|
||||
content = diskoLib.partitionType { parent = config; device = partition.config.device; };
|
||||
hybrid = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.submodule ({ ... } @ hp: {
|
||||
options = {
|
||||
mbrPartitionType = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "MBR type code";
|
||||
};
|
||||
mbrBootableFlag = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Set the bootable flag (aka the active flag) on any or all of your hybridized partitions";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
inherit config options;
|
||||
default = ''
|
||||
${lib.optionalString (hp.config.mbrPartitionType != null) ''
|
||||
sfdisk --label-nested dos --part-type "${parent.device}" ${(toString partition.config._index)} ${hp.config.mbrPartitionType}
|
||||
udevadm trigger --subsystem-match=block
|
||||
udevadm settle
|
||||
''}
|
||||
${lib.optionalString hp.config.mbrBootableFlag ''
|
||||
sfdisk --label-nested dos --activate "${parent.device}" ${(toString partition.config._index)}
|
||||
''}
|
||||
'';
|
||||
};
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }@partition:
|
||||
{
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
type =
|
||||
let
|
||||
hexPattern = len: "[A-Fa-f0-9]{${toString len}}";
|
||||
in
|
||||
lib.types.either (lib.types.strMatching (hexPattern 4)) (
|
||||
lib.types.strMatching (
|
||||
lib.concatMapStringsSep "-" hexPattern [
|
||||
8
|
||||
4
|
||||
4
|
||||
4
|
||||
12
|
||||
]
|
||||
)
|
||||
);
|
||||
default =
|
||||
if partition.config.content != null && partition.config.content.type == "swap" then
|
||||
"8200"
|
||||
else
|
||||
"8300";
|
||||
defaultText = ''8300 (Linux filesystem) normally, 8200 (Linux swap) if content.type is "swap"'';
|
||||
description = ''
|
||||
Filesystem type to use.
|
||||
This can either be an sgdisk-specific short code (run sgdisk -L to see what is available),
|
||||
or a fully specified GUID (see https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs).
|
||||
'';
|
||||
};
|
||||
}));
|
||||
default = null;
|
||||
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;
|
||||
};
|
||||
};
|
||||
}));
|
||||
device = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default =
|
||||
if partition.config.uuid != null then
|
||||
"/dev/disk/by-partuuid/${partition.config.uuid}"
|
||||
else if config._parent.type == "mdadm" then
|
||||
# workaround because mdadm partlabel do not appear in /dev/disk/by-partlabel
|
||||
"/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 `uuid` is provided:
|
||||
/dev/disk/by-partuuid/''${partition.config.uuid}
|
||||
|
||||
otherwise, 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 {
|
||||
type = lib.types.int;
|
||||
default =
|
||||
if partition.config.size or "" == "100%" then
|
||||
9001
|
||||
else if partition.config.type == "EF02" then
|
||||
# Boot partition should be created first, because some BIOS implementations require it.
|
||||
# Priority defaults to 100 here to support any potential use-case for placing partitions prior to EF02
|
||||
100
|
||||
else
|
||||
1000;
|
||||
defaultText = ''
|
||||
1000: normal partitions
|
||||
9001: partitions with 100% size
|
||||
100: boot partitions (EF02)
|
||||
'';
|
||||
description = "Priority of the partition, smaller values are created first";
|
||||
};
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Name of the partition";
|
||||
default = name;
|
||||
};
|
||||
uuid = lib.mkOption {
|
||||
type = lib.types.nullOr (
|
||||
lib.types.strMatching "[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}"
|
||||
);
|
||||
default = null;
|
||||
defaultText = "`null` - generate a UUID when creating the partition";
|
||||
example = "809b3a2b-828a-4730-95e1-75b6343e415a";
|
||||
description = ''
|
||||
The UUID (also known as GUID) of the partition. Note that this is distinct from the UUID of the filesystem.
|
||||
|
||||
You can generate a UUID with the command `uuidgen -r`.
|
||||
'';
|
||||
};
|
||||
label = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default =
|
||||
let
|
||||
# 72 bytes is the maximum length of a GPT partition name
|
||||
# the labels seem to be in UTF-16, so 2 bytes per character
|
||||
limit = 36;
|
||||
label = "${config._parent.type}-${config._parent.name}-${partition.config.name}";
|
||||
in
|
||||
if (lib.stringLength label) > limit then
|
||||
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]?");
|
||||
default = "0";
|
||||
description = ''
|
||||
Size of the partition, in sgdisk format.
|
||||
sets end automatically with the + prefix
|
||||
can be 100% for the whole remaining disk, will be done last in that case.
|
||||
'';
|
||||
};
|
||||
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 {
|
||||
type = lib.types.str;
|
||||
default = "0";
|
||||
description = "Start of the partition, in sgdisk format, use 0 for next available range";
|
||||
};
|
||||
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
|
||||
or - for relative sizes from the disks end
|
||||
'';
|
||||
};
|
||||
content = diskoLib.partitionType {
|
||||
parent = config;
|
||||
device = partition.config.device;
|
||||
};
|
||||
hybrid = lib.mkOption {
|
||||
type = lib.types.nullOr (
|
||||
lib.types.submodule (
|
||||
{ ... }@hp:
|
||||
{
|
||||
options = {
|
||||
mbrPartitionType = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "MBR type code";
|
||||
};
|
||||
mbrBootableFlag = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Set the bootable flag (aka the active flag) on any or all of your hybridized partitions";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
inherit config options;
|
||||
default = ''
|
||||
${lib.optionalString (hp.config.mbrPartitionType != null) ''
|
||||
sfdisk --label-nested dos --part-type "${parent.device}" ${(toString partition.config._index)} ${hp.config.mbrPartitionType}
|
||||
udevadm trigger --subsystem-match=block
|
||||
udevadm settle
|
||||
''}
|
||||
${lib.optionalString hp.config.mbrBootableFlag ''
|
||||
sfdisk --label-nested dos --activate "${parent.device}" ${(toString partition.config._index)}
|
||||
''}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = null;
|
||||
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;
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
description = "Attrs of partitions to add to the partition table";
|
||||
};
|
||||
@@ -197,12 +244,13 @@ in
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo diskoLib.jsonType;
|
||||
default = dev:
|
||||
lib.foldr lib.recursiveUpdate { } (map
|
||||
(partition:
|
||||
lib.optionalAttrs (partition.content != null) (partition.content._meta dev)
|
||||
default =
|
||||
dev:
|
||||
lib.foldr lib.recursiveUpdate { } (
|
||||
map (partition: lib.optionalAttrs (partition.content != null) (partition.content._meta dev)) (
|
||||
lib.attrValues config.partitions
|
||||
)
|
||||
(lib.attrValues config.partitions));
|
||||
);
|
||||
description = "Metadata";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
@@ -211,61 +259,63 @@ in
|
||||
if ! blkid "${config.device}" >&2; then
|
||||
sgdisk --clear "${config.device}"
|
||||
fi
|
||||
${lib.concatMapStrings (partition:
|
||||
${lib.concatMapStrings (
|
||||
partition:
|
||||
let
|
||||
args = ''
|
||||
--partition-guid="${toString partition._index}:${if partition.uuid == null then "R" else partition.uuid}" \
|
||||
--partition-guid="${toString partition._index}:${
|
||||
if partition.uuid == null then "R" else partition.uuid
|
||||
}" \
|
||||
--change-name="${toString partition._index}:${partition.label}" \
|
||||
--typecode=${toString partition._index}:${partition.type} \
|
||||
"${config.device}" \
|
||||
'';
|
||||
createArgs = ''
|
||||
--align-end ${lib.optionalString (partition.alignment != 0) ''--set-alignment=${builtins.toString partition.alignment}''} \
|
||||
--align-end ${
|
||||
lib.optionalString (
|
||||
partition.alignment != 0
|
||||
) ''--set-alignment=${builtins.toString partition.alignment}''
|
||||
} \
|
||||
--new=${toString partition._index}:${partition.start}:${partition.end} \
|
||||
'';
|
||||
in
|
||||
''
|
||||
# try to create the partition, if it fails, try to change the type and name
|
||||
if ! sgdisk ${createArgs} ${args}
|
||||
then
|
||||
sgdisk ${args}
|
||||
fi
|
||||
# ensure /dev/disk/by-path/..-partN exists before continuing
|
||||
partprobe "${config.device}" || : # sometimes partprobe fails, but the partitions are still up2date
|
||||
udevadm trigger --subsystem-match=block
|
||||
udevadm settle
|
||||
''
|
||||
''
|
||||
# try to create the partition, if it fails, try to change the type and name
|
||||
if ! sgdisk ${createArgs} ${args}
|
||||
then
|
||||
sgdisk ${args}
|
||||
fi
|
||||
# ensure /dev/disk/by-path/..-partN exists before continuing
|
||||
partprobe "${config.device}" || : # sometimes partprobe fails, but the partitions are still up2date
|
||||
udevadm trigger --subsystem-match=block
|
||||
udevadm settle
|
||||
''
|
||||
) sortedPartitions}
|
||||
|
||||
${
|
||||
lib.optionalString (sortedHybridPartitions != [])
|
||||
("sgdisk -h "
|
||||
+ (lib.concatStringsSep ":" (map (p: (toString p._index)) sortedHybridPartitions))
|
||||
+ (
|
||||
lib.optionalString (!config.efiGptPartitionFirst) ":EE "
|
||||
)
|
||||
+ ''"${parent.device}"'')
|
||||
}
|
||||
${lib.concatMapStrings (p:
|
||||
p.hybrid._create
|
||||
)
|
||||
sortedHybridPartitions
|
||||
}
|
||||
${lib.optionalString (sortedHybridPartitions != [ ]) (
|
||||
"sgdisk -h "
|
||||
+ (lib.concatStringsSep ":" (map (p: (toString p._index)) sortedHybridPartitions))
|
||||
+ (lib.optionalString (!config.efiGptPartitionFirst) ":EE ")
|
||||
+ ''"${parent.device}"''
|
||||
)}
|
||||
${lib.concatMapStrings (p: p.hybrid._create) sortedHybridPartitions}
|
||||
|
||||
${lib.concatStrings (map (partition: ''
|
||||
${lib.optionalString (partition.content != null) partition.content._create}
|
||||
'') sortedPartitions)}
|
||||
${lib.concatStrings (
|
||||
map (partition: ''
|
||||
${lib.optionalString (partition.content != null) partition.content._create}
|
||||
'') sortedPartitions
|
||||
)}
|
||||
'';
|
||||
};
|
||||
_mount = diskoLib.mkMountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (map
|
||||
(partition:
|
||||
lib.optionalAttrs (partition.content != null) partition.content._mount
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (
|
||||
map (partition: lib.optionalAttrs (partition.content != null) partition.content._mount) (
|
||||
lib.attrValues config.partitions
|
||||
)
|
||||
(lib.attrValues config.partitions));
|
||||
);
|
||||
in
|
||||
{
|
||||
dev = partMounts.dev or "";
|
||||
@@ -276,11 +326,11 @@ in
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (map
|
||||
(partition:
|
||||
lib.optionalAttrs (partition.content != null) partition.content._unmount
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (
|
||||
map (partition: lib.optionalAttrs (partition.content != null) partition.content._unmount) (
|
||||
lib.attrValues config.partitions
|
||||
)
|
||||
(lib.attrValues config.partitions));
|
||||
);
|
||||
in
|
||||
{
|
||||
dev = partMounts.dev or "";
|
||||
@@ -290,30 +340,31 @@ in
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = (map
|
||||
(partition:
|
||||
lib.optional (partition.content != null) partition.content._config
|
||||
)
|
||||
(lib.attrValues config.partitions))
|
||||
++ (lib.optional (lib.any (part: part.type == "EF02") (lib.attrValues config.partitions)) {
|
||||
boot.loader.grub.devices = [ config.device ];
|
||||
});
|
||||
default =
|
||||
(map (partition: lib.optional (partition.content != null) partition.content._config) (
|
||||
lib.attrValues config.partitions
|
||||
))
|
||||
++ (lib.optional (lib.any (part: part.type == "EF02") (lib.attrValues config.partitions)) {
|
||||
boot.loader.grub.devices = [ config.device ];
|
||||
});
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
_pkgs = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs:
|
||||
default =
|
||||
pkgs:
|
||||
[
|
||||
pkgs.gptfdisk
|
||||
pkgs.systemdMinimal
|
||||
pkgs.parted # for partprobe
|
||||
] ++ lib.flatten (map
|
||||
(partition:
|
||||
lib.optional (partition.content != null) (partition.content._pkgs pkgs)
|
||||
]
|
||||
++ lib.flatten (
|
||||
map (partition: lib.optional (partition.content != null) (partition.content._pkgs pkgs)) (
|
||||
lib.attrValues config.partitions
|
||||
)
|
||||
(lib.attrValues config.partitions));
|
||||
);
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
|
@@ -1,20 +1,30 @@
|
||||
{ config, options, lib, diskoLib, parent, device, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
parent,
|
||||
device,
|
||||
...
|
||||
}:
|
||||
let
|
||||
keyFile =
|
||||
if config.settings ? "keyFile"
|
||||
then config.settings.keyFile
|
||||
else if config.askPassword
|
||||
then ''<(set +x; echo -n "$password"; set -x)''
|
||||
else if config.passwordFile != null
|
||||
if config.settings ? "keyFile" then
|
||||
config.settings.keyFile
|
||||
else if config.askPassword then
|
||||
''<(set +x; echo -n "$password"; set -x)''
|
||||
else if
|
||||
config.passwordFile != null
|
||||
# do not print the password to the console
|
||||
then ''<(set +x; echo -n "$(cat ${config.passwordFile})"; set -x)''
|
||||
else if config.keyFile != null
|
||||
then
|
||||
lib.warn
|
||||
("The option `keyFile` is deprecated."
|
||||
+ "Use passwordFile instead if you want to use interactive login or settings.keyFile if you want to use key file login")
|
||||
config.keyFile
|
||||
else null;
|
||||
''<(set +x; echo -n "$(cat ${config.passwordFile})"; set -x)''
|
||||
else if config.keyFile != null then
|
||||
lib.warn (
|
||||
"The option `keyFile` is deprecated."
|
||||
+ "Use passwordFile instead if you want to use interactive login or settings.keyFile if you want to use key file login"
|
||||
) config.keyFile
|
||||
else
|
||||
null;
|
||||
keyFileArgs = ''
|
||||
${lib.optionalString (keyFile != null) "--key-file ${keyFile}"} \
|
||||
${lib.optionalString (lib.hasAttr "keyFileSize" config.settings) "--keyfile-size ${builtins.toString config.settings.keyFileSize}"} \
|
||||
@@ -23,7 +33,10 @@ let
|
||||
cryptsetupOpen = ''
|
||||
cryptsetup open "${config.device}" "${config.name}" \
|
||||
${lib.optionalString (config.settings.allowDiscards or false) "--allow-discards"} \
|
||||
${lib.optionalString (config.settings.bypassWorkqueues or false) "--perf-no_read_workqueue --perf-no_write_workqueue"} \
|
||||
${
|
||||
lib.optionalString (config.settings.bypassWorkqueues or false
|
||||
) "--perf-no_read_workqueue --perf-no_write_workqueue"
|
||||
} \
|
||||
${toString config.extraOpenArgs} \
|
||||
${keyFileArgs} \
|
||||
'';
|
||||
@@ -58,7 +71,7 @@ in
|
||||
};
|
||||
askPassword = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = config.keyFile == null && config.passwordFile == null && (! config.settings ? "keyFile");
|
||||
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";
|
||||
};
|
||||
@@ -66,13 +79,14 @@ in
|
||||
type = lib.types.attrsOf lib.types.anything;
|
||||
default = { };
|
||||
description = "LUKS settings (as defined in configuration.nix in boot.initrd.luks.devices.<name>)";
|
||||
example = ''{
|
||||
keyFile = "/tmp/disk.key";
|
||||
keyFileSize = 2048;
|
||||
keyFileOffset = 1024;
|
||||
fallbackToPassword = true;
|
||||
allowDiscards = true;
|
||||
};
|
||||
example = ''
|
||||
{
|
||||
keyFile = "/tmp/disk.key";
|
||||
keyFileSize = 2048;
|
||||
keyFileOffset = 1024;
|
||||
fallbackToPassword = true;
|
||||
allowDiscards = true;
|
||||
};
|
||||
'';
|
||||
};
|
||||
additionalKeyFiles = lib.mkOption {
|
||||
@@ -98,7 +112,10 @@ in
|
||||
description = "Extra arguments to pass to `cryptsetup luksOpen` when opening";
|
||||
example = [ "--timeout 10" ];
|
||||
};
|
||||
content = diskoLib.deviceType { parent = config; device = "/dev/mapper/${config.name}"; };
|
||||
content = diskoLib.deviceType {
|
||||
parent = config;
|
||||
device = "/dev/mapper/${config.name}";
|
||||
};
|
||||
_parent = lib.mkOption {
|
||||
internal = true;
|
||||
default = parent;
|
||||
@@ -107,8 +124,7 @@ in
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo diskoLib.jsonType;
|
||||
default = dev:
|
||||
lib.optionalAttrs (config.content != null) (config.content._meta dev);
|
||||
default = dev: lib.optionalAttrs (config.content != null) (config.content._meta dev);
|
||||
description = "Metadata";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
@@ -136,9 +152,11 @@ in
|
||||
''}
|
||||
cryptsetup -q luksFormat "${config.device}" ${toString config.extraFormatArgs} ${keyFileArgs}
|
||||
${cryptsetupOpen} --persistent
|
||||
${toString (lib.forEach config.additionalKeyFiles (keyFile: ''
|
||||
cryptsetup luksAddKey "${config.device}" ${keyFile} ${keyFileArgs}
|
||||
''))}
|
||||
${toString (
|
||||
lib.forEach config.additionalKeyFiles (keyFile: ''
|
||||
cryptsetup luksAddKey "${config.device}" ${keyFile} ${keyFileArgs}
|
||||
'')
|
||||
)}
|
||||
fi
|
||||
${lib.optionalString (config.content != null) config.content._create}
|
||||
'';
|
||||
@@ -176,34 +194,42 @@ in
|
||||
let
|
||||
contentUnmount = config.content._unmount;
|
||||
in
|
||||
{
|
||||
dev = ''
|
||||
${lib.optionalString (config.content != null) contentUnmount.dev or ""}
|
||||
if cryptsetup status "${config.name}" >/dev/null 2>/dev/null; then
|
||||
cryptsetup close "${config.name}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
{
|
||||
dev = ''
|
||||
${lib.optionalString (config.content != null) contentUnmount.dev or ""}
|
||||
if cryptsetup status "${config.name}" >/dev/null 2>/dev/null; then
|
||||
cryptsetup close "${config.name}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = [ ]
|
||||
default =
|
||||
[ ]
|
||||
# If initrdUnlock is true, then add a device entry to the initrd.luks.devices config.
|
||||
++ (lib.optional config.initrdUnlock [
|
||||
{
|
||||
boot.initrd.luks.devices.${config.name} = {
|
||||
inherit (config) device;
|
||||
} // config.settings;
|
||||
}
|
||||
]) ++ (lib.optional (config.content != null) config.content._config);
|
||||
{
|
||||
boot.initrd.luks.devices.${config.name} = {
|
||||
inherit (config) device;
|
||||
} // config.settings;
|
||||
}
|
||||
])
|
||||
++ (lib.optional (config.content != null) config.content._config);
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
_pkgs = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs: [ pkgs.gnugrep pkgs.cryptsetup ] ++ (lib.optionals (config.content != null) (config.content._pkgs pkgs));
|
||||
default =
|
||||
pkgs:
|
||||
[
|
||||
pkgs.gnugrep
|
||||
pkgs.cryptsetup
|
||||
]
|
||||
++ (lib.optionals (config.content != null) (config.content._pkgs pkgs));
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
|
@@ -1,4 +1,12 @@
|
||||
{ config, options, lib, diskoLib, parent, device, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
parent,
|
||||
device,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
@@ -55,7 +63,10 @@
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs: [ pkgs.gnugrep pkgs.lvm2 ];
|
||||
default = pkgs: [
|
||||
pkgs.gnugrep
|
||||
pkgs.lvm2
|
||||
];
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
|
@@ -1,14 +1,22 @@
|
||||
{ config, options, lib, diskoLib, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# Load kernel modules to ensure device mapper types are available
|
||||
kernelModules =
|
||||
[
|
||||
# Prevent unbootable systems if LVM snapshots are present at boot time.
|
||||
"dm-snapshot"
|
||||
] ++
|
||||
lib.filter (x: x != "") (map
|
||||
(lv: lib.optionalString (lv.lvm_type != null && lv.lvm_type != "thinlv") "dm-${lv.lvm_type}")
|
||||
(lib.attrValues config.lvs));
|
||||
]
|
||||
++ lib.filter (x: x != "") (
|
||||
map (lv: lib.optionalString (lv.lvm_type != null && lv.lvm_type != "thinlv") "dm-${lv.lvm_type}") (
|
||||
lib.attrValues config.lvs
|
||||
)
|
||||
);
|
||||
in
|
||||
{
|
||||
options = {
|
||||
@@ -23,44 +31,65 @@ in
|
||||
description = "Type";
|
||||
};
|
||||
lvs = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }@lv: {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "Name of the logical volume";
|
||||
};
|
||||
priority = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = (if lv.config.lvm_type == "thin-pool" then 501 else 1000) + (if lib.hasInfix "100%" lv.config.size then 251 else 0);
|
||||
defaultText = lib.literalExpression ''
|
||||
if (lib.hasInfix "100%" lv.config.size) then 9001 else 1000
|
||||
'';
|
||||
description = "Priority of the logical volume, smaller values are created first";
|
||||
};
|
||||
size = lib.mkOption {
|
||||
type = lib.types.str; # TODO lvm size type
|
||||
description = "Size of the logical volume";
|
||||
};
|
||||
lvm_type = lib.mkOption {
|
||||
# TODO: add raid10
|
||||
type = lib.types.nullOr (lib.types.enum [ "mirror" "raid0" "raid1" "raid4" "raid5" "raid6" "thin-pool" "thinlv" ]); # TODO add all lib.types
|
||||
default = null; # maybe there is always a default type?
|
||||
description = "LVM type";
|
||||
};
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra arguments";
|
||||
};
|
||||
pool = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "Name of pool LV that this LV belongs to";
|
||||
};
|
||||
content = diskoLib.partitionType { parent = config; device = "/dev/${config.name}/${lv.config.name}"; };
|
||||
};
|
||||
}));
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }@lv:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "Name of the logical volume";
|
||||
};
|
||||
priority = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default =
|
||||
(if lv.config.lvm_type == "thin-pool" then 501 else 1000)
|
||||
+ (if lib.hasInfix "100%" lv.config.size then 251 else 0);
|
||||
defaultText = lib.literalExpression ''
|
||||
if (lib.hasInfix "100%" lv.config.size) then 9001 else 1000
|
||||
'';
|
||||
description = "Priority of the logical volume, smaller values are created first";
|
||||
};
|
||||
size = lib.mkOption {
|
||||
type = lib.types.str; # TODO lvm size type
|
||||
description = "Size of the logical volume";
|
||||
};
|
||||
lvm_type = lib.mkOption {
|
||||
# TODO: add raid10
|
||||
type = lib.types.nullOr (
|
||||
lib.types.enum [
|
||||
"mirror"
|
||||
"raid0"
|
||||
"raid1"
|
||||
"raid4"
|
||||
"raid5"
|
||||
"raid6"
|
||||
"thin-pool"
|
||||
"thinlv"
|
||||
]
|
||||
); # TODO add all lib.types
|
||||
default = null; # maybe there is always a default type?
|
||||
description = "LVM type";
|
||||
};
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra arguments";
|
||||
};
|
||||
pool = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "Name of pool LV that this LV belongs to";
|
||||
};
|
||||
content = diskoLib.partitionType {
|
||||
parent = config;
|
||||
device = "/dev/${config.name}/${lv.config.name}";
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
description = "LVS for the volume group";
|
||||
};
|
||||
@@ -68,12 +97,15 @@ in
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = diskoLib.jsonType;
|
||||
default =
|
||||
diskoLib.deepMergeMap
|
||||
(lv:
|
||||
lib.optionalAttrs (lv.content != null) (lv.content._meta [ "lvm_vg" config.name ])
|
||||
)
|
||||
(lib.attrValues config.lvs);
|
||||
default = diskoLib.deepMergeMap (
|
||||
lv:
|
||||
lib.optionalAttrs (lv.content != null) (
|
||||
lv.content._meta [
|
||||
"lvm_vg"
|
||||
config.name
|
||||
]
|
||||
)
|
||||
) (lib.attrValues config.lvs);
|
||||
description = "Metadata";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
@@ -93,8 +125,14 @@ in
|
||||
if ! lvdisplay "${config.name}/${lv.name}"; then
|
||||
lvcreate \
|
||||
--yes \
|
||||
${if (lv.lvm_type == "thinlv") then "-V"
|
||||
else if lib.hasInfix "%" lv.size then "-l" else "-L"} \
|
||||
${
|
||||
if (lv.lvm_type == "thinlv") then
|
||||
"-V"
|
||||
else if lib.hasInfix "%" lv.size then
|
||||
"-l"
|
||||
else
|
||||
"-L"
|
||||
} \
|
||||
${if lib.hasSuffix "%" lv.size then "${lv.size}FREE" else lv.size} \
|
||||
-n "${lv.name}" \
|
||||
${lib.optionalString (lv.lvm_type == "thinlv") "--thinpool=${lv.pool}"} \
|
||||
@@ -113,11 +151,9 @@ in
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
lvMounts = diskoLib.deepMergeMap
|
||||
(lv:
|
||||
lib.optionalAttrs (lv.content != null) lv.content._mount
|
||||
)
|
||||
(lib.attrValues config.lvs);
|
||||
lvMounts = diskoLib.deepMergeMap (lv: lib.optionalAttrs (lv.content != null) lv.content._mount) (
|
||||
lib.attrValues config.lvs
|
||||
);
|
||||
in
|
||||
{
|
||||
dev = ''
|
||||
@@ -131,12 +167,11 @@ in
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
lvMounts = diskoLib.deepMergeMap
|
||||
(lv:
|
||||
lib.optionalAttrs (lv.content != null) lv.content._unmount
|
||||
)
|
||||
(lib.attrValues config.lvs);
|
||||
in {
|
||||
lvMounts = diskoLib.deepMergeMap (lv: lib.optionalAttrs (lv.content != null) lv.content._unmount) (
|
||||
lib.attrValues config.lvs
|
||||
);
|
||||
in
|
||||
{
|
||||
dev = ''
|
||||
${lib.concatMapStrings (x: x.dev or "") (lib.attrValues lvMounts)}
|
||||
vgchange -a n
|
||||
@@ -147,36 +182,35 @@ in
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = [{ boot.initrd.kernelModules = kernelModules; }] ++
|
||||
map
|
||||
(lv: [
|
||||
(lib.optional (lv.content != null) lv.content._config)
|
||||
(lib.optional (lv.lvm_type != null) {
|
||||
boot.initrd.kernelModules = [
|
||||
default =
|
||||
[ { boot.initrd.kernelModules = kernelModules; } ]
|
||||
++ map (lv: [
|
||||
(lib.optional (lv.content != null) lv.content._config)
|
||||
(lib.optional (lv.lvm_type != null) {
|
||||
boot.initrd.kernelModules =
|
||||
[
|
||||
(if lv.lvm_type == "mirror" then "dm-mirror" else "dm-raid")
|
||||
]
|
||||
++ lib.optional (lv.lvm_type == "raid0") "raid0"
|
||||
++ lib.optional (lv.lvm_type == "raid1") "raid1"
|
||||
# ++ lib.optional (lv.lvm_type == "raid10") "raid10"
|
||||
++ lib.optional
|
||||
(lv.lvm_type == "raid4" ||
|
||||
lv.lvm_type == "raid5" ||
|
||||
lv.lvm_type == "raid6") "raid456";
|
||||
++ lib.optional (
|
||||
lv.lvm_type == "raid4" || lv.lvm_type == "raid5" || lv.lvm_type == "raid6"
|
||||
) "raid456";
|
||||
|
||||
})
|
||||
])
|
||||
(lib.attrValues config.lvs);
|
||||
})
|
||||
]) (lib.attrValues config.lvs);
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
_pkgs = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs: lib.flatten (map
|
||||
(lv:
|
||||
lib.optional (lv.content != null) (lv.content._pkgs pkgs)
|
||||
)
|
||||
(lib.attrValues config.lvs));
|
||||
default =
|
||||
pkgs:
|
||||
lib.flatten (
|
||||
map (lv: lib.optional (lv.content != null) (lv.content._pkgs pkgs)) (lib.attrValues config.lvs)
|
||||
);
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
|
@@ -1,4 +1,10 @@
|
||||
{ config, options, lib, diskoLib, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
@@ -18,17 +24,32 @@
|
||||
description = "mdadm level";
|
||||
};
|
||||
metadata = lib.mkOption {
|
||||
type = lib.types.enum [ "1" "1.0" "1.1" "1.2" "default" "ddf" "imsm" ];
|
||||
type = lib.types.enum [
|
||||
"1"
|
||||
"1.0"
|
||||
"1.1"
|
||||
"1.2"
|
||||
"default"
|
||||
"ddf"
|
||||
"imsm"
|
||||
];
|
||||
default = "default";
|
||||
description = "Metadata";
|
||||
};
|
||||
content = diskoLib.deviceType { parent = config; device = "/dev/md/${config.name}"; };
|
||||
content = diskoLib.deviceType {
|
||||
parent = config;
|
||||
device = "/dev/md/${config.name}";
|
||||
};
|
||||
_meta = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = diskoLib.jsonType;
|
||||
default =
|
||||
lib.optionalAttrs (config.content != null) (config.content._meta [ "mdadm" config.name ]);
|
||||
default = lib.optionalAttrs (config.content != null) (
|
||||
config.content._meta [
|
||||
"mdadm"
|
||||
config.name
|
||||
]
|
||||
);
|
||||
description = "Metadata";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
@@ -54,45 +75,52 @@
|
||||
};
|
||||
_mount = diskoLib.mkMountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
lib.optionalAttrs (config.content != null) config.content._mount;
|
||||
default = lib.optionalAttrs (config.content != null) config.content._mount;
|
||||
# TODO we probably need to assemble the mdadm somehow
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default = let
|
||||
content = lib.optionalAttrs (config.content != null) config.content._unmount;
|
||||
in {
|
||||
fs = content.fs;
|
||||
dev = ''
|
||||
${content.dev or ""}
|
||||
if [ -e "/dev/md/${config.name}" ]; then
|
||||
mdadm --stop "/dev/md/${config.name}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
default =
|
||||
let
|
||||
content = lib.optionalAttrs (config.content != null) config.content._unmount;
|
||||
in
|
||||
{
|
||||
fs = content.fs;
|
||||
dev = ''
|
||||
${content.dev or ""}
|
||||
if [ -e "/dev/md/${config.name}" ]; then
|
||||
mdadm --stop "/dev/md/${config.name}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default =
|
||||
[
|
||||
(if lib.versionAtLeast (lib.versions.majorMinor lib.version) "23.11" then {
|
||||
boot.swraid.enable = true;
|
||||
} else {
|
||||
boot.initrd.services.swraid.enable = true;
|
||||
})
|
||||
] ++
|
||||
lib.optional (config.content != null) config.content._config;
|
||||
default = [
|
||||
(
|
||||
if lib.versionAtLeast (lib.versions.majorMinor lib.version) "23.11" then
|
||||
{
|
||||
boot.swraid.enable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
boot.initrd.services.swraid.enable = true;
|
||||
}
|
||||
)
|
||||
] ++ lib.optional (config.content != null) config.content._config;
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
_pkgs = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs: [
|
||||
pkgs.parted # for partprobe
|
||||
] ++ (lib.optionals (config.content != null) (config.content._pkgs pkgs));
|
||||
default =
|
||||
pkgs:
|
||||
[
|
||||
pkgs.parted # for partprobe
|
||||
]
|
||||
++ (lib.optionals (config.content != null) (config.content._pkgs pkgs));
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
|
@@ -1,4 +1,12 @@
|
||||
{ config, options, lib, diskoLib, parent, device, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
parent,
|
||||
device,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
|
@@ -1,4 +1,11 @@
|
||||
{ lib, config, options, diskoLib, rootMountPoint, ... }:
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
options,
|
||||
diskoLib,
|
||||
rootMountPoint,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
|
@@ -1,4 +1,12 @@
|
||||
{ diskoLib, config, options, lib, parent, device, ... }:
|
||||
{
|
||||
diskoLib,
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
parent,
|
||||
device,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
@@ -14,7 +22,13 @@
|
||||
discardPolicy = lib.mkOption {
|
||||
default = null;
|
||||
example = "once";
|
||||
type = lib.types.nullOr (lib.types.enum [ "once" "pages" "both" ]);
|
||||
type = lib.types.nullOr (
|
||||
lib.types.enum [
|
||||
"once"
|
||||
"pages"
|
||||
"both"
|
||||
]
|
||||
);
|
||||
description = ''
|
||||
Specify the discard policy for the swap device. If "once", then the
|
||||
whole swap space is discarded at swapon invocation. If "pages",
|
||||
@@ -83,12 +97,8 @@
|
||||
if test "''${DISKO_SKIP_SWAP:-}" != 1 && ! swapon --show | grep -q "^$(readlink -f "${config.device}") "; then
|
||||
swapon ${
|
||||
lib.optionalString (config.discardPolicy != null)
|
||||
"--discard${lib.optionalString (config.discardPolicy != "both")
|
||||
"=${config.discardPolicy}"
|
||||
}"} ${
|
||||
lib.optionalString (config.priority != null)
|
||||
"--priority=${toString config.priority}"
|
||||
} \
|
||||
"--discard${lib.optionalString (config.discardPolicy != "both") "=${config.discardPolicy}"}"
|
||||
} ${lib.optionalString (config.priority != null) "--priority=${toString config.priority}"} \
|
||||
--options=${lib.concatStringsSep "," config.mountOptions} \
|
||||
"${config.device}"
|
||||
fi
|
||||
@@ -108,26 +118,33 @@
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = [{
|
||||
swapDevices = [{
|
||||
device = config.device;
|
||||
inherit (config) discardPolicy priority;
|
||||
randomEncryption = {
|
||||
enable = config.randomEncryption;
|
||||
# forward discard/TRIM attempts through dm-crypt
|
||||
allowDiscards = config.discardPolicy != null;
|
||||
};
|
||||
options = config.mountOptions;
|
||||
}];
|
||||
boot.resumeDevice = lib.mkIf config.resumeDevice config.device;
|
||||
}];
|
||||
default = [
|
||||
{
|
||||
swapDevices = [
|
||||
{
|
||||
device = config.device;
|
||||
inherit (config) discardPolicy priority;
|
||||
randomEncryption = {
|
||||
enable = config.randomEncryption;
|
||||
# forward discard/TRIM attempts through dm-crypt
|
||||
allowDiscards = config.discardPolicy != null;
|
||||
};
|
||||
options = config.mountOptions;
|
||||
}
|
||||
];
|
||||
boot.resumeDevice = lib.mkIf config.resumeDevice config.device;
|
||||
}
|
||||
];
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
_pkgs = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs: [ pkgs.gnugrep pkgs.util-linux ];
|
||||
default = pkgs: [
|
||||
pkgs.gnugrep
|
||||
pkgs.util-linux
|
||||
];
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
|
@@ -1,179 +1,227 @@
|
||||
{ config, options, lib, diskoLib, parent, device, ... }:
|
||||
{
|
||||
options = lib.warn ''
|
||||
The legacy table is outdated and should not be used. We recommend using the gpt type instead.
|
||||
Please note that certain features, such as the test framework, may not function properly with the legacy table type.
|
||||
If you encounter errors similar to:
|
||||
"error: The option `disko.devices.disk.disk1.content.partitions."[definition 1-entry 1]".content._config` is read-only, but it's set multiple times,"
|
||||
this is likely due to the use of the legacy table type.
|
||||
for a migration you can follow the guide at https://github.com/nix-community/disko/blob/master/docs/table-to-gpt.md
|
||||
''
|
||||
{
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [ "table" ];
|
||||
internal = true;
|
||||
description = "Partition table";
|
||||
};
|
||||
device = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = device;
|
||||
description = "Device to partition";
|
||||
};
|
||||
format = lib.mkOption {
|
||||
type = lib.types.enum [ "gpt" "msdos" ];
|
||||
default = "gpt";
|
||||
description = "The kind of partition table";
|
||||
};
|
||||
partitions = lib.mkOption {
|
||||
type = lib.types.listOf (lib.types.submodule ({ name, ... }@partition: {
|
||||
options = {
|
||||
part-type = lib.mkOption {
|
||||
type = lib.types.enum [ "primary" "logical" "extended" ];
|
||||
default = "primary";
|
||||
description = "Partition type";
|
||||
};
|
||||
fs-type = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.enum [ "btrfs" "ext2" "ext3" "ext4" "fat16" "fat32" "hfs" "hfs+" "linux-swap" "ntfs" "reiserfs" "udf" "xfs" ]);
|
||||
default = null;
|
||||
description = "Filesystem type to use";
|
||||
};
|
||||
name = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = "Name of the partition";
|
||||
};
|
||||
start = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0%";
|
||||
description = "Start of the partition";
|
||||
};
|
||||
end = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "100%";
|
||||
description = "End of the partition";
|
||||
};
|
||||
flags = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Partition flags";
|
||||
};
|
||||
bootable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to make the partition bootable";
|
||||
};
|
||||
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;
|
||||
};
|
||||
};
|
||||
}));
|
||||
default = [ ];
|
||||
description = "List of partitions to add to the partition table";
|
||||
};
|
||||
_parent = lib.mkOption {
|
||||
internal = true;
|
||||
default = parent;
|
||||
};
|
||||
_meta = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo diskoLib.jsonType;
|
||||
default = dev:
|
||||
lib.foldr lib.recursiveUpdate { } (lib.imap
|
||||
(_index: partition:
|
||||
lib.optionalAttrs (partition.content != null) (partition.content._meta dev)
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
parent,
|
||||
device,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options =
|
||||
lib.warn
|
||||
''
|
||||
The legacy table is outdated and should not be used. We recommend using the gpt type instead.
|
||||
Please note that certain features, such as the test framework, may not function properly with the legacy table type.
|
||||
If you encounter errors similar to:
|
||||
"error: The option `disko.devices.disk.disk1.content.partitions."[definition 1-entry 1]".content._config` is read-only, but it's set multiple times,"
|
||||
this is likely due to the use of the legacy table type.
|
||||
for a migration you can follow the guide at https://github.com/nix-community/disko/blob/master/docs/table-to-gpt.md
|
||||
''
|
||||
{
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [ "table" ];
|
||||
internal = true;
|
||||
description = "Partition table";
|
||||
};
|
||||
device = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = device;
|
||||
description = "Device to partition";
|
||||
};
|
||||
format = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"gpt"
|
||||
"msdos"
|
||||
];
|
||||
default = "gpt";
|
||||
description = "The kind of partition table";
|
||||
};
|
||||
partitions = lib.mkOption {
|
||||
type = lib.types.listOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }@partition:
|
||||
{
|
||||
options = {
|
||||
part-type = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"primary"
|
||||
"logical"
|
||||
"extended"
|
||||
];
|
||||
default = "primary";
|
||||
description = "Partition type";
|
||||
};
|
||||
fs-type = lib.mkOption {
|
||||
type = lib.types.nullOr (
|
||||
lib.types.enum [
|
||||
"btrfs"
|
||||
"ext2"
|
||||
"ext3"
|
||||
"ext4"
|
||||
"fat16"
|
||||
"fat32"
|
||||
"hfs"
|
||||
"hfs+"
|
||||
"linux-swap"
|
||||
"ntfs"
|
||||
"reiserfs"
|
||||
"udf"
|
||||
"xfs"
|
||||
]
|
||||
);
|
||||
default = null;
|
||||
description = "Filesystem type to use";
|
||||
};
|
||||
name = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = "Name of the partition";
|
||||
};
|
||||
start = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0%";
|
||||
description = "Start of the partition";
|
||||
};
|
||||
end = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "100%";
|
||||
description = "End of the partition";
|
||||
};
|
||||
flags = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Partition flags";
|
||||
};
|
||||
bootable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to make the partition bootable";
|
||||
};
|
||||
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;
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
config.partitions);
|
||||
description = "Metadata";
|
||||
);
|
||||
default = [ ];
|
||||
description = "List of partitions to add to the partition table";
|
||||
};
|
||||
_parent = lib.mkOption {
|
||||
internal = true;
|
||||
default = parent;
|
||||
};
|
||||
_meta = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo diskoLib.jsonType;
|
||||
default =
|
||||
dev:
|
||||
lib.foldr lib.recursiveUpdate { } (
|
||||
lib.imap (
|
||||
_index: partition: lib.optionalAttrs (partition.content != null) (partition.content._meta dev)
|
||||
) config.partitions
|
||||
);
|
||||
description = "Metadata";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
inherit config options;
|
||||
default = ''
|
||||
if ! blkid "${config.device}" >/dev/null; then
|
||||
parted -s "${config.device}" -- mklabel ${config.format}
|
||||
${lib.concatStrings (
|
||||
map (partition: ''
|
||||
${lib.optionalString (config.format == "gpt") ''
|
||||
parted -s "${config.device}" -- mkpart "${diskoLib.hexEscapeUdevSymlink partition.name}" ${diskoLib.maybeStr partition.fs-type} ${partition.start} ${partition.end}
|
||||
''}
|
||||
${lib.optionalString (config.format == "msdos") ''
|
||||
parted -s "${config.device}" -- mkpart ${partition.part-type} ${diskoLib.maybeStr partition.fs-type} ${partition.start} ${partition.end}
|
||||
''}
|
||||
# ensure /dev/disk/by-path/..-partN exists before continuing
|
||||
partprobe "${config.device}"
|
||||
udevadm trigger --subsystem-match=block
|
||||
udevadm settle
|
||||
${lib.optionalString partition.bootable ''
|
||||
parted -s "${config.device}" -- set ${toString partition._index} boot on
|
||||
''}
|
||||
${lib.concatMapStringsSep "" (flag: ''
|
||||
parted -s "${config.device}" -- set ${toString partition._index} ${flag} on
|
||||
'') partition.flags}
|
||||
# ensure further operations can detect new partitions
|
||||
partprobe "${config.device}"
|
||||
udevadm trigger --subsystem-match=block
|
||||
udevadm settle
|
||||
'') config.partitions
|
||||
)}
|
||||
fi
|
||||
${lib.concatStrings (
|
||||
map (partition: ''
|
||||
${lib.optionalString (partition.content != null) partition.content._create}
|
||||
'') config.partitions
|
||||
)}
|
||||
'';
|
||||
};
|
||||
_mount = diskoLib.mkMountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (
|
||||
map (
|
||||
partition: lib.optionalAttrs (partition.content != null) partition.content._mount
|
||||
) config.partitions
|
||||
);
|
||||
in
|
||||
{
|
||||
dev = partMounts.dev or "";
|
||||
fs = partMounts.fs or { };
|
||||
};
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (
|
||||
map (
|
||||
partition: lib.optionalAttrs (partition.content != null) partition.content._unmount
|
||||
) config.partitions
|
||||
);
|
||||
in
|
||||
{
|
||||
dev = partMounts.dev or "";
|
||||
fs = partMounts.fs or { };
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = map (
|
||||
partition: lib.optional (partition.content != null) partition.content._config
|
||||
) config.partitions;
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
_pkgs = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default =
|
||||
pkgs:
|
||||
[
|
||||
pkgs.parted
|
||||
pkgs.systemdMinimal
|
||||
]
|
||||
++ lib.flatten (
|
||||
map (
|
||||
partition: lib.optional (partition.content != null) (partition.content._pkgs pkgs)
|
||||
) config.partitions
|
||||
);
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
inherit config options;
|
||||
default = ''
|
||||
if ! blkid "${config.device}" >/dev/null; then
|
||||
parted -s "${config.device}" -- mklabel ${config.format}
|
||||
${lib.concatStrings (map (partition: ''
|
||||
${lib.optionalString (config.format == "gpt") ''
|
||||
parted -s "${config.device}" -- mkpart "${diskoLib.hexEscapeUdevSymlink partition.name}" ${diskoLib.maybeStr partition.fs-type} ${partition.start} ${partition.end}
|
||||
''}
|
||||
${lib.optionalString (config.format == "msdos") ''
|
||||
parted -s "${config.device}" -- mkpart ${partition.part-type} ${diskoLib.maybeStr partition.fs-type} ${partition.start} ${partition.end}
|
||||
''}
|
||||
# ensure /dev/disk/by-path/..-partN exists before continuing
|
||||
partprobe "${config.device}"
|
||||
udevadm trigger --subsystem-match=block
|
||||
udevadm settle
|
||||
${lib.optionalString partition.bootable ''
|
||||
parted -s "${config.device}" -- set ${toString partition._index} boot on
|
||||
''}
|
||||
${lib.concatMapStringsSep "" (flag: ''
|
||||
parted -s "${config.device}" -- set ${toString partition._index} ${flag} on
|
||||
'') partition.flags}
|
||||
# ensure further operations can detect new partitions
|
||||
partprobe "${config.device}"
|
||||
udevadm trigger --subsystem-match=block
|
||||
udevadm settle
|
||||
'') config.partitions)}
|
||||
fi
|
||||
${lib.concatStrings (map (partition: ''
|
||||
${lib.optionalString (partition.content != null) partition.content._create}
|
||||
'') config.partitions)}
|
||||
'';
|
||||
};
|
||||
_mount = diskoLib.mkMountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (map
|
||||
(partition:
|
||||
lib.optionalAttrs (partition.content != null) partition.content._mount
|
||||
)
|
||||
config.partitions);
|
||||
in
|
||||
{
|
||||
dev = partMounts.dev or "";
|
||||
fs = partMounts.fs or { };
|
||||
};
|
||||
};
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (map
|
||||
(partition:
|
||||
lib.optionalAttrs (partition.content != null) partition.content._unmount
|
||||
)
|
||||
config.partitions);
|
||||
in
|
||||
{
|
||||
dev = partMounts.dev or "";
|
||||
fs = partMounts.fs or { };
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default =
|
||||
map
|
||||
(partition:
|
||||
lib.optional (partition.content != null) partition.content._config
|
||||
)
|
||||
config.partitions;
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
_pkgs = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs:
|
||||
[ pkgs.parted pkgs.systemdMinimal ] ++ lib.flatten (map
|
||||
(partition:
|
||||
lib.optional (partition.content != null) (partition.content._pkgs pkgs)
|
||||
)
|
||||
config.partitions);
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@@ -1,4 +1,12 @@
|
||||
{ config, options, lib, diskoLib, parent, device, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
parent,
|
||||
device,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
|
@@ -1,4 +1,12 @@
|
||||
{ config, options, lib, diskoLib, rootMountPoint, parent, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
rootMountPoint,
|
||||
parent,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
@@ -58,45 +66,53 @@
|
||||
default = true;
|
||||
};
|
||||
|
||||
_create = diskoLib.mkCreateOption
|
||||
{
|
||||
inherit config options;
|
||||
# -u prevents mounting newly created datasets, which is
|
||||
# important to prevent accidental shadowing of mount points
|
||||
# since (create order != mount order)
|
||||
# -p creates parents automatically
|
||||
default =
|
||||
let
|
||||
createOptions = (lib.optionalAttrs (config.mountpoint != null) { mountpoint = config.mountpoint; }) // config.options;
|
||||
# All options defined as PROP_ONETIME or PROP_ONETIME_DEFAULT in https://github.com/openzfs/zfs/blob/master/module/zcommon/zfs_prop.c
|
||||
onetimeProperties = [
|
||||
"encryption"
|
||||
"casesensitivity"
|
||||
"utf8only"
|
||||
"normalization"
|
||||
"volblocksize"
|
||||
"pbkdf2iters"
|
||||
"pbkdf2salt"
|
||||
"keyformat"
|
||||
];
|
||||
updateOptions = builtins.removeAttrs createOptions onetimeProperties;
|
||||
in
|
||||
''
|
||||
if ! zfs get type ${config._name} >/dev/null 2>&1; then
|
||||
${if config._createFilesystem then ''
|
||||
zfs create -up ${config._name} \
|
||||
${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "-o ${n}=${v}") (createOptions))}
|
||||
'' else ''
|
||||
# don't create anything for root dataset of zpools
|
||||
true
|
||||
''}
|
||||
${lib.optionalString (updateOptions != {}) ''
|
||||
_create = diskoLib.mkCreateOption {
|
||||
inherit config options;
|
||||
# -u prevents mounting newly created datasets, which is
|
||||
# important to prevent accidental shadowing of mount points
|
||||
# since (create order != mount order)
|
||||
# -p creates parents automatically
|
||||
default =
|
||||
let
|
||||
createOptions =
|
||||
(lib.optionalAttrs (config.mountpoint != null) { mountpoint = config.mountpoint; })
|
||||
// config.options;
|
||||
# All options defined as PROP_ONETIME or PROP_ONETIME_DEFAULT in https://github.com/openzfs/zfs/blob/master/module/zcommon/zfs_prop.c
|
||||
onetimeProperties = [
|
||||
"encryption"
|
||||
"casesensitivity"
|
||||
"utf8only"
|
||||
"normalization"
|
||||
"volblocksize"
|
||||
"pbkdf2iters"
|
||||
"pbkdf2salt"
|
||||
"keyformat"
|
||||
];
|
||||
updateOptions = builtins.removeAttrs createOptions onetimeProperties;
|
||||
in
|
||||
''
|
||||
if ! zfs get type ${config._name} >/dev/null 2>&1; then
|
||||
${
|
||||
if config._createFilesystem then
|
||||
''
|
||||
zfs create -up ${config._name} \
|
||||
${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "-o ${n}=${v}") (createOptions))}
|
||||
''
|
||||
else
|
||||
''
|
||||
# don't create anything for root dataset of zpools
|
||||
true
|
||||
''
|
||||
}
|
||||
${lib.optionalString (updateOptions != { }) ''
|
||||
else
|
||||
zfs set -u ${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${v}") updateOptions)} ${config._name}
|
||||
''}
|
||||
fi
|
||||
'';
|
||||
};
|
||||
zfs set -u ${
|
||||
lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${v}") updateOptions)
|
||||
} ${config._name}
|
||||
''}
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
_mount = diskoLib.mkMountOption {
|
||||
inherit config options;
|
||||
@@ -107,17 +123,20 @@
|
||||
zfs load-key ${config._name}
|
||||
fi
|
||||
'';
|
||||
}) // lib.optionalAttrs (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
|
||||
fs.${config.mountpoint} = ''
|
||||
if ! findmnt ${config._name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
|
||||
mount ${config._name} "${rootMountPoint}${config.mountpoint}" \
|
||||
-o X-mount.mkdir \
|
||||
${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \
|
||||
${lib.optionalString ((config.options.mountpoint or "") != "legacy") "-o zfsutil"} \
|
||||
-t zfs
|
||||
fi
|
||||
'';
|
||||
};
|
||||
})
|
||||
// lib.optionalAttrs
|
||||
(config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off")
|
||||
{
|
||||
fs.${config.mountpoint} = ''
|
||||
if ! findmnt ${config._name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
|
||||
mount ${config._name} "${rootMountPoint}${config.mountpoint}" \
|
||||
-o X-mount.mkdir \
|
||||
${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \
|
||||
${lib.optionalString ((config.options.mountpoint or "") != "legacy") "-o zfsutil"} \
|
||||
-t zfs
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
_unmount = diskoLib.mkUnmountOption {
|
||||
@@ -125,26 +144,32 @@
|
||||
default =
|
||||
(lib.optionalAttrs (config.options.keylocation or "none" != "none") {
|
||||
dev = "zfs unload-key ${config.name}";
|
||||
}) // lib.optionalAttrs (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
|
||||
fs.${config.mountpoint} = ''
|
||||
if findmnt ${config._name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
|
||||
umount "${rootMountPoint}${config.mountpoint}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
})
|
||||
// lib.optionalAttrs
|
||||
(config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off")
|
||||
{
|
||||
fs.${config.mountpoint} = ''
|
||||
if findmnt ${config._name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
|
||||
umount "${rootMountPoint}${config.mountpoint}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default =
|
||||
lib.optional (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
|
||||
fileSystems.${config.mountpoint} = {
|
||||
device = "${config._name}";
|
||||
fsType = "zfs";
|
||||
options = config.mountOptions ++ lib.optional ((config.options.mountpoint or "") != "legacy") "zfsutil";
|
||||
lib.optional (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off")
|
||||
{
|
||||
fileSystems.${config.mountpoint} = {
|
||||
device = "${config._name}";
|
||||
fsType = "zfs";
|
||||
options =
|
||||
config.mountOptions
|
||||
++ lib.optional ((config.options.mountpoint or "") != "legacy") "zfsutil";
|
||||
};
|
||||
};
|
||||
};
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
|
||||
@@ -157,4 +182,3 @@
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,11 @@
|
||||
{ config, options, lib, diskoLib, parent, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
parent,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
@@ -35,7 +42,10 @@
|
||||
description = "Size of the dataset";
|
||||
};
|
||||
|
||||
content = diskoLib.partitionType { parent = config; device = "/dev/zvol/${config._parent.name}/${config.name}"; };
|
||||
content = diskoLib.partitionType {
|
||||
parent = config;
|
||||
device = "/dev/zvol/${config._parent.name}/${config.name}";
|
||||
};
|
||||
|
||||
_parent = lib.mkOption {
|
||||
internal = true;
|
||||
@@ -45,8 +55,7 @@
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo diskoLib.jsonType;
|
||||
default = dev:
|
||||
lib.optionalAttrs (config.content != null) (config.content._meta dev);
|
||||
default = dev: lib.optionalAttrs (config.content != null) (config.content._meta dev);
|
||||
description = "Metadata";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
@@ -83,31 +92,34 @@
|
||||
inherit config options;
|
||||
default = {
|
||||
dev = ''
|
||||
${lib.optionalString (config.options.keylocation or "none" != "none") "zfs unload-key ${config.name}"}
|
||||
${lib.optionalString (
|
||||
config.options.keylocation or "none" != "none"
|
||||
) "zfs unload-key ${config.name}"}
|
||||
|
||||
${config.content._unmount.dev or ""}
|
||||
'';
|
||||
|
||||
fs = config.content._unmount.fs or {};
|
||||
fs = config.content._unmount.fs or { };
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default =
|
||||
lib.optional (config.content != null) config.content._config;
|
||||
default = lib.optional (config.content != null) config.content._config;
|
||||
description = "NixOS configuration";
|
||||
};
|
||||
_pkgs = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs: [
|
||||
pkgs.util-linux
|
||||
pkgs.parted # for partprobe
|
||||
] ++ lib.optionals (config.content != null) (config.content._pkgs pkgs);
|
||||
default =
|
||||
pkgs:
|
||||
[
|
||||
pkgs.util-linux
|
||||
pkgs.parted # for partprobe
|
||||
]
|
||||
++ lib.optionals (config.content != null) (config.content._pkgs pkgs);
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,11 @@
|
||||
{ config, options, lib, diskoLib, rootMountPoint, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
diskoLib,
|
||||
rootMountPoint,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# TODO: Consider expanding to handle `file` and `draid` mode options.
|
||||
modeOptions = [
|
||||
@@ -63,134 +70,161 @@ in
|
||||
};
|
||||
};
|
||||
};
|
||||
type = (lib.types.oneOf [
|
||||
(lib.types.enum modeOptions)
|
||||
(lib.types.attrsOf (diskoLib.subType {
|
||||
types = {
|
||||
topology =
|
||||
let
|
||||
vdev = lib.types.submodule ({ ... }: {
|
||||
options = {
|
||||
mode = lib.mkOption {
|
||||
type = lib.types.enum modeOptions;
|
||||
default = "";
|
||||
description = "Mode of the zfs vdev";
|
||||
};
|
||||
members = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = "Members of the vdev";
|
||||
};
|
||||
};
|
||||
});
|
||||
in
|
||||
lib.types.submodule
|
||||
({ ... }: {
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [ "topology" ];
|
||||
default = "topology";
|
||||
internal = true;
|
||||
description = "Type";
|
||||
};
|
||||
# zfs device types
|
||||
vdev = lib.mkOption {
|
||||
type = lib.types.listOf vdev;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of storage vdevs. See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Virtual_Devices_(vdevs)
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "x" "y" ];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
spare = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of devices to use as hot spares. See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Hot_Spares
|
||||
for details.
|
||||
'';
|
||||
example = [ "x" "y" ];
|
||||
};
|
||||
log = lib.mkOption {
|
||||
type = lib.types.listOf vdev;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of vdevs used for the zfs intent log (ZIL). See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Intent_Log
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "x" "y" ];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
dedup = lib.mkOption {
|
||||
type = lib.types.listOf vdev;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of vdevs used for the deduplication table. See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#dedup
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "x" "y" ];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
special = lib.mkOption {
|
||||
type = lib.types.either (lib.types.listOf vdev) (lib.types.nullOr vdev);
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of vdevs used as special devices. See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#special
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "x" "y" ];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
cache = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A dedicated zfs cache device (L2ARC). See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Cache_Devices
|
||||
for details.
|
||||
'';
|
||||
example = [ "x" "y" ];
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
extraArgs.parent = config;
|
||||
}))
|
||||
]);
|
||||
type = (
|
||||
lib.types.oneOf [
|
||||
(lib.types.enum modeOptions)
|
||||
(lib.types.attrsOf (
|
||||
diskoLib.subType {
|
||||
types = {
|
||||
topology =
|
||||
let
|
||||
vdev = lib.types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
mode = lib.mkOption {
|
||||
type = lib.types.enum modeOptions;
|
||||
default = "";
|
||||
description = "Mode of the zfs vdev";
|
||||
};
|
||||
members = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = "Members of the vdev";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
in
|
||||
lib.types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [ "topology" ];
|
||||
default = "topology";
|
||||
internal = true;
|
||||
description = "Type";
|
||||
};
|
||||
# zfs device types
|
||||
vdev = lib.mkOption {
|
||||
type = lib.types.listOf vdev;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of storage vdevs. See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Virtual_Devices_(vdevs)
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
spare = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of devices to use as hot spares. See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Hot_Spares
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
};
|
||||
log = lib.mkOption {
|
||||
type = lib.types.listOf vdev;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of vdevs used for the zfs intent log (ZIL). See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Intent_Log
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
dedup = lib.mkOption {
|
||||
type = lib.types.listOf vdev;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of vdevs used for the deduplication table. See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#dedup
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
special = lib.mkOption {
|
||||
type = lib.types.either (lib.types.listOf vdev) (lib.types.nullOr vdev);
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of vdevs used as special devices. See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#special
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
cache = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A dedicated zfs cache device (L2ARC). See
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Cache_Devices
|
||||
for details.
|
||||
'';
|
||||
example = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
extraArgs.parent = config;
|
||||
}
|
||||
))
|
||||
]
|
||||
);
|
||||
description = "Mode of the ZFS pool";
|
||||
};
|
||||
options = lib.mkOption {
|
||||
@@ -214,18 +248,25 @@ in
|
||||
description = "Options to pass to mount";
|
||||
};
|
||||
datasets = lib.mkOption {
|
||||
type = lib.types.attrsOf (diskoLib.subType {
|
||||
types = { inherit (diskoLib.types) zfs_fs zfs_volume; };
|
||||
extraArgs.parent = config;
|
||||
});
|
||||
type = lib.types.attrsOf (
|
||||
diskoLib.subType {
|
||||
types = { inherit (diskoLib.types) zfs_fs zfs_volume; };
|
||||
extraArgs.parent = config;
|
||||
}
|
||||
);
|
||||
description = "List of datasets to define";
|
||||
};
|
||||
_meta = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = diskoLib.jsonType;
|
||||
default =
|
||||
diskoLib.deepMergeMap (dataset: dataset._meta [ "zpool" config.name ]) (lib.attrValues config.datasets);
|
||||
default = diskoLib.deepMergeMap (
|
||||
dataset:
|
||||
dataset._meta [
|
||||
"zpool"
|
||||
config.name
|
||||
]
|
||||
) (lib.attrValues config.datasets);
|
||||
description = "Metadata";
|
||||
};
|
||||
_create = diskoLib.mkCreateOption {
|
||||
@@ -234,14 +275,14 @@ in
|
||||
let
|
||||
formatOutput = type: mode: members: ''
|
||||
entries+=("${type} ${mode}=${
|
||||
lib.concatMapStringsSep " "
|
||||
(d: if lib.strings.hasPrefix "/" d then d else "/dev/disk/by-partlabel/disk-${d}-zfs") members
|
||||
lib.concatMapStringsSep " " (
|
||||
d: if lib.strings.hasPrefix "/" d then d else "/dev/disk/by-partlabel/disk-${d}-zfs"
|
||||
) members
|
||||
}")
|
||||
'';
|
||||
formatVdev = type: vdev: formatOutput type vdev.mode vdev.members;
|
||||
formatVdevList = type: vdevs: lib.concatMapStrings
|
||||
(formatVdev type)
|
||||
(builtins.sort (a: _: a.mode == "") vdevs);
|
||||
formatVdevList =
|
||||
type: vdevs: lib.concatMapStrings (formatVdev type) (builtins.sort (a: _: a.mode == "") vdevs);
|
||||
hasTopology = !(builtins.isString config.mode);
|
||||
mode = if hasTopology then "prescribed" else config.mode;
|
||||
topology = lib.optionalAttrs hasTopology config.mode.topology;
|
||||
@@ -281,18 +322,20 @@ in
|
||||
topology="${mode} ''${zfs_devices[*]}"
|
||||
else
|
||||
entries=()
|
||||
${lib.optionalString (hasTopology && topology.vdev != null)
|
||||
(formatVdevList "" topology.vdev)}
|
||||
${lib.optionalString (hasTopology && topology.spare != [])
|
||||
(formatOutput "spare" "" topology.spare)}
|
||||
${lib.optionalString (hasTopology && topology.log != [])
|
||||
(formatVdevList "log" topology.log)}
|
||||
${lib.optionalString (hasTopology && topology.dedup != [])
|
||||
(formatVdevList "dedup" topology.dedup)}
|
||||
${lib.optionalString (hasTopology && topology.special != null && topology.special != [])
|
||||
(formatVdevList "special" (lib.lists.toList topology.special))}
|
||||
${lib.optionalString (hasTopology && topology.cache != [])
|
||||
(formatOutput "cache" "" topology.cache)}
|
||||
${lib.optionalString (hasTopology && topology.vdev != null) (formatVdevList "" topology.vdev)}
|
||||
${lib.optionalString (hasTopology && topology.spare != [ ]) (
|
||||
formatOutput "spare" "" topology.spare
|
||||
)}
|
||||
${lib.optionalString (hasTopology && topology.log != [ ]) (formatVdevList "log" topology.log)}
|
||||
${lib.optionalString (hasTopology && topology.dedup != [ ]) (
|
||||
formatVdevList "dedup" topology.dedup
|
||||
)}
|
||||
${lib.optionalString (hasTopology && topology.special != null && topology.special != [ ]) (
|
||||
formatVdevList "special" (lib.lists.toList topology.special)
|
||||
)}
|
||||
${lib.optionalString (hasTopology && topology.cache != [ ]) (
|
||||
formatOutput "cache" "" topology.cache
|
||||
)}
|
||||
all_devices=()
|
||||
last_type=
|
||||
for line in "''${entries[@]}"; do
|
||||
@@ -337,7 +380,9 @@ in
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
datasetFilesystemsMounts = diskoLib.deepMergeMap (dataset: dataset._mount.fs or {}) (lib.attrValues config.datasets);
|
||||
datasetFilesystemsMounts = diskoLib.deepMergeMap (dataset: dataset._mount.fs or { }) (
|
||||
lib.attrValues config.datasets
|
||||
);
|
||||
in
|
||||
{
|
||||
dev = ''
|
||||
@@ -359,7 +404,7 @@ in
|
||||
zpool export "${config.name}"
|
||||
fi
|
||||
'';
|
||||
fs = diskoLib.deepMergeMap (dataset: dataset._unmount.fs or {}) (lib.attrValues config.datasets);
|
||||
fs = diskoLib.deepMergeMap (dataset: dataset._unmount.fs or { }) (lib.attrValues config.datasets);
|
||||
};
|
||||
};
|
||||
_config = lib.mkOption {
|
||||
@@ -372,7 +417,13 @@ in
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.functionTo (lib.types.listOf lib.types.package);
|
||||
default = pkgs: [ pkgs.gnugrep pkgs.util-linux ] ++ lib.flatten (map (dataset: dataset._pkgs pkgs) (lib.attrValues config.datasets));
|
||||
default =
|
||||
pkgs:
|
||||
[
|
||||
pkgs.gnugrep
|
||||
pkgs.util-linux
|
||||
]
|
||||
++ lib.flatten (map (dataset: dataset._pkgs pkgs) (lib.attrValues config.datasets));
|
||||
description = "Packages";
|
||||
};
|
||||
};
|
||||
|
81
module.nix
81
module.nix
@@ -1,4 +1,11 @@
|
||||
{ config, lib, pkgs, extendModules, diskoLib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
extendModules,
|
||||
diskoLib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.disko;
|
||||
|
||||
@@ -107,7 +114,10 @@ in
|
||||
};
|
||||
|
||||
imageFormat = lib.mkOption {
|
||||
type = lib.types.enum [ "raw" "qcow2" ];
|
||||
type = lib.types.enum [
|
||||
"raw"
|
||||
"qcow2"
|
||||
];
|
||||
description = "QEMU image format to use for the disk images";
|
||||
default = "raw";
|
||||
};
|
||||
@@ -239,38 +249,49 @@ in
|
||||
eval-config = import (pkgs.path + "/nixos/lib/eval-config.nix");
|
||||
};
|
||||
|
||||
system.build = (cfg.devices._scripts { inherit pkgs; checked = cfg.checkScripts; }) // (
|
||||
let
|
||||
throwIfNoDisksDetected = _: v: if cfg.devices.disk == { } then throw "No disks defined, did you forget to import your disko config?" else v;
|
||||
in
|
||||
lib.mapAttrs throwIfNoDisksDetected {
|
||||
# we keep these old outputs for compatibility
|
||||
disko = builtins.trace "the .disko output is deprecated, please use .diskoScript instead" (cfg.devices._scripts { inherit pkgs; }).diskoScript;
|
||||
diskoNoDeps = builtins.trace "the .diskoNoDeps output is deprecated, please use .diskoScriptNoDeps instead" (cfg.devices._scripts { inherit pkgs; }).diskoScriptNoDeps;
|
||||
system.build =
|
||||
(cfg.devices._scripts {
|
||||
inherit pkgs;
|
||||
checked = cfg.checkScripts;
|
||||
})
|
||||
// (
|
||||
let
|
||||
throwIfNoDisksDetected =
|
||||
_: v:
|
||||
if cfg.devices.disk == { } then
|
||||
throw "No disks defined, did you forget to import your disko config?"
|
||||
else
|
||||
v;
|
||||
in
|
||||
lib.mapAttrs throwIfNoDisksDetected {
|
||||
# we keep these old outputs for compatibility
|
||||
disko =
|
||||
builtins.trace "the .disko output is deprecated, please use .diskoScript instead"
|
||||
(cfg.devices._scripts { inherit pkgs; }).diskoScript;
|
||||
diskoNoDeps =
|
||||
builtins.trace "the .diskoNoDeps output is deprecated, please use .diskoScriptNoDeps instead"
|
||||
(cfg.devices._scripts { inherit pkgs; }).diskoScriptNoDeps;
|
||||
|
||||
installTest = diskoLib.testLib.makeDiskoTest {
|
||||
inherit extendModules pkgs;
|
||||
name = "${config.networking.hostName}-disko";
|
||||
disko-config = builtins.removeAttrs config [ "_module" ];
|
||||
testMode = "direct";
|
||||
bootCommands = cfg.tests.bootCommands;
|
||||
efi = cfg.tests.efi;
|
||||
enableOCR = cfg.tests.enableOCR;
|
||||
extraSystemConfig = cfg.tests.extraConfig;
|
||||
extraTestScript = cfg.tests.extraChecks;
|
||||
};
|
||||
installTest = diskoLib.testLib.makeDiskoTest {
|
||||
inherit extendModules pkgs;
|
||||
name = "${config.networking.hostName}-disko";
|
||||
disko-config = builtins.removeAttrs config [ "_module" ];
|
||||
testMode = "direct";
|
||||
bootCommands = cfg.tests.bootCommands;
|
||||
efi = cfg.tests.efi;
|
||||
enableOCR = cfg.tests.enableOCR;
|
||||
extraSystemConfig = cfg.tests.extraConfig;
|
||||
extraTestScript = cfg.tests.extraChecks;
|
||||
};
|
||||
|
||||
vmWithDisko = lib.mkDefault config.virtualisation.vmVariantWithDisko.system.build.vmWithDisko;
|
||||
}
|
||||
);
|
||||
vmWithDisko = lib.mkDefault config.virtualisation.vmVariantWithDisko.system.build.vmWithDisko;
|
||||
}
|
||||
);
|
||||
|
||||
# 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
|
||||
fileSystems = lib.mkIf
|
||||
cfg.enableConfig cfg.devices._config.fileSystems or { };
|
||||
boot = lib.mkIf
|
||||
cfg.enableConfig cfg.devices._config.boot or { };
|
||||
swapDevices = lib.mkIf
|
||||
cfg.enableConfig cfg.devices._config.swapDevices or [ ];
|
||||
fileSystems = lib.mkIf cfg.enableConfig cfg.devices._config.fileSystems or { };
|
||||
boot = lib.mkIf cfg.enableConfig cfg.devices._config.boot or { };
|
||||
swapDevices = lib.mkIf cfg.enableConfig cfg.devices._config.swapDevices or [ ];
|
||||
};
|
||||
}
|
||||
|
20
package.nix
20
package.nix
@@ -1,4 +1,14 @@
|
||||
{ stdenvNoCC, makeWrapper, lib, path, nix, coreutils, nixos-install-tools, binlore, diskoVersion }:
|
||||
{
|
||||
stdenvNoCC,
|
||||
makeWrapper,
|
||||
lib,
|
||||
path,
|
||||
nix,
|
||||
coreutils,
|
||||
nixos-install-tools,
|
||||
binlore,
|
||||
diskoVersion,
|
||||
}:
|
||||
|
||||
let
|
||||
self = stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
@@ -16,7 +26,13 @@ let
|
||||
chmod 755 "$out/bin/$i"
|
||||
wrapProgram "$out/bin/$i" \
|
||||
--set DISKO_VERSION "${diskoVersion}" \
|
||||
--prefix PATH : ${lib.makeBinPath [ nix coreutils nixos-install-tools ]} \
|
||||
--prefix PATH : ${
|
||||
lib.makeBinPath [
|
||||
nix
|
||||
coreutils
|
||||
nixos-install-tools
|
||||
]
|
||||
} \
|
||||
--prefix NIX_PATH : "nixpkgs=${path}"
|
||||
done
|
||||
'';
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
# Don't run directly! Instead, use
|
||||
# nix run .#create-release
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
@@ -17,4 +18,3 @@ diskoLib.testLib.makeDiskoTest {
|
||||
machine.succeed("test -e /partition-root/swapfile1");
|
||||
'';
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
@@ -26,7 +27,10 @@ diskoLib.testLib.makeDiskoTest {
|
||||
];
|
||||
};
|
||||
extraInstallerConfig = {
|
||||
boot.kernelModules = [ "dm-raid" "dm-mirror" ];
|
||||
boot.kernelModules = [
|
||||
"dm-raid"
|
||||
"dm-mirror"
|
||||
];
|
||||
imports = [
|
||||
../module.nix
|
||||
];
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
@@ -24,6 +25,9 @@ diskoLib.testLib.makeDiskoTest {
|
||||
machine.succeed("test -e /ext4_on_lvm/file-from-postMountHook");
|
||||
'';
|
||||
extraInstallerConfig = {
|
||||
boot.kernelModules = [ "dm-raid" "dm-mirror" ];
|
||||
boot.kernelModules = [
|
||||
"dm-raid"
|
||||
"dm-mirror"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
@@ -1,20 +1,28 @@
|
||||
{ makeTest ? import <nixpkgs/nixos/tests/make-test-python.nix>
|
||||
, eval-config ? import <nixpkgs/nixos/lib/eval-config.nix>
|
||||
, pkgs ? import <nixpkgs> { }
|
||||
{
|
||||
makeTest ? import <nixpkgs/nixos/tests/make-test-python.nix>,
|
||||
eval-config ? import <nixpkgs/nixos/lib/eval-config.nix>,
|
||||
pkgs ? import <nixpkgs> { },
|
||||
}:
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
diskoLib = import ../lib { inherit lib makeTest eval-config; };
|
||||
|
||||
allTestFilenames =
|
||||
builtins.map (lib.removeSuffix ".nix") (
|
||||
builtins.filter
|
||||
(x: lib.hasSuffix ".nix" x && x != "default.nix")
|
||||
(lib.attrNames (builtins.readDir ./.))
|
||||
);
|
||||
incompatibleTests = lib.optionals pkgs.stdenv.buildPlatform.isRiscV64 [ "zfs" "zfs-over-legacy" "cli" "module" "complex" ];
|
||||
allTestFilenames = builtins.map (lib.removeSuffix ".nix") (
|
||||
builtins.filter (x: lib.hasSuffix ".nix" x && x != "default.nix") (
|
||||
lib.attrNames (builtins.readDir ./.)
|
||||
)
|
||||
);
|
||||
incompatibleTests = lib.optionals pkgs.stdenv.buildPlatform.isRiscV64 [
|
||||
"zfs"
|
||||
"zfs-over-legacy"
|
||||
"cli"
|
||||
"module"
|
||||
"complex"
|
||||
];
|
||||
allCompatibleFilenames = lib.subtractLists incompatibleTests allTestFilenames;
|
||||
|
||||
allTests = lib.genAttrs allCompatibleFilenames (test: import (./. + "/${test}.nix") { inherit diskoLib pkgs; });
|
||||
allTests = lib.genAttrs allCompatibleFilenames (
|
||||
test: import (./. + "/${test}.nix") { inherit diskoLib pkgs; }
|
||||
);
|
||||
in
|
||||
allTests
|
||||
|
@@ -1,4 +1,10 @@
|
||||
{ lib, pkgs, modulesPath, ... }: {
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/testing/test-instrumentation.nix")
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
@@ -13,11 +19,15 @@
|
||||
hashed-mirrors = null;
|
||||
connect-timeout = 3;
|
||||
flake-registry = pkgs.writeText "flake-registry" ''{"flakes":[],"version":2}'';
|
||||
experimental-features = [ "nix-command" "flakes" ];
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
};
|
||||
services.openssh.enable = true;
|
||||
boot.kernelParams = [ "console=tty0" ] ++
|
||||
(lib.optional (pkgs.stdenv.hostPlatform.isAarch) "ttyAMA0,115200") ++
|
||||
(lib.optional (pkgs.stdenv.hostPlatform.isRiscV64) "ttySIF0,115200") ++
|
||||
[ "console=ttyS0,115200" ];
|
||||
boot.kernelParams =
|
||||
[ "console=tty0" ]
|
||||
++ (lib.optional (pkgs.stdenv.hostPlatform.isAarch) "ttyAMA0,115200")
|
||||
++ (lib.optional (pkgs.stdenv.hostPlatform.isRiscV64) "ttySIF0,115200")
|
||||
++ [ "console=ttyS0,115200" ];
|
||||
}
|
||||
|
@@ -1,4 +1,8 @@
|
||||
{ pkgs ? import <nixpkgs> { }, self, diskoVersion }:
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
self,
|
||||
diskoVersion,
|
||||
}:
|
||||
let
|
||||
disko = pkgs.callPackage ../../package.nix { inherit diskoVersion; };
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
@@ -9,7 +10,11 @@ diskoLib.testLib.makeDiskoTest {
|
||||
machine.succeed("mountpoint /home");
|
||||
'';
|
||||
extraInstallerConfig = {
|
||||
boot.kernelModules = [ "dm-raid" "raid0" "dm-mirror" ];
|
||||
boot.kernelModules = [
|
||||
"dm-raid"
|
||||
"raid0"
|
||||
"dm-mirror"
|
||||
];
|
||||
};
|
||||
extraSystemConfig = {
|
||||
# sadly systemd-boot fails to install to a raid /boot device
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,13 +1,17 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, ...
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
...
|
||||
}:
|
||||
|
||||
(pkgs.nixos [
|
||||
../module.nix
|
||||
../example/simple-efi.nix
|
||||
({ config, ... }: {
|
||||
documentation.enable = false;
|
||||
system.stateVersion = config.system.nixos.version;
|
||||
disko.checkScripts = true;
|
||||
})
|
||||
(
|
||||
{ config, ... }:
|
||||
{
|
||||
documentation.enable = false;
|
||||
system.stateVersion = config.system.nixos.version;
|
||||
disko.checkScripts = true;
|
||||
}
|
||||
)
|
||||
]).config.system.build.diskoImagesScript
|
||||
|
@@ -1,14 +1,18 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, ...
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
...
|
||||
}:
|
||||
|
||||
(pkgs.nixos [
|
||||
../module.nix
|
||||
../example/simple-efi.nix
|
||||
({ config, ... }: {
|
||||
documentation.enable = false;
|
||||
system.stateVersion = config.system.nixos.version;
|
||||
disko.memSize = 2048;
|
||||
disko.checkScripts = true;
|
||||
})
|
||||
(
|
||||
{ config, ... }:
|
||||
{
|
||||
documentation.enable = false;
|
||||
system.stateVersion = config.system.nixos.version;
|
||||
disko.memSize = 2048;
|
||||
disko.checkScripts = true;
|
||||
}
|
||||
)
|
||||
]).config.system.build.diskoImages
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
@@ -21,6 +22,9 @@ diskoLib.testLib.makeDiskoTest {
|
||||
machine.succeed("mountpoint /ext4_on_lvm");
|
||||
'';
|
||||
extraInstallerConfig = {
|
||||
boot.kernelModules = [ "dm-raid" "dm-mirror" ];
|
||||
boot.kernelModules = [
|
||||
"dm-raid"
|
||||
"dm-mirror"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
# this is a regression test for https://github.com/nix-community/disko/issues/52
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
# this is a regression test for https://github.com/nix-community/disko/issues/52
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,4 +1,7 @@
|
||||
{ pkgs ? import <nixpkgs> { }, ... }:
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
...
|
||||
}:
|
||||
(pkgs.nixos [
|
||||
../example/stand-alone/configuration.nix
|
||||
{ documentation.enable = false; }
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,18 +1,17 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
name = "zfs-encrypted-root";
|
||||
extraInstallerConfig.networking.hostId = "8425e349";
|
||||
extraSystemConfig.networking.hostId = "8425e349";
|
||||
disko-config =
|
||||
pkgs.lib.recursiveUpdate (import ../example/zfs-encrypted-root.nix) {
|
||||
disko.devices.zpool.zroot.datasets.root.options.keylocation = "file:///tmp/secret.key";
|
||||
};
|
||||
disko-config = pkgs.lib.recursiveUpdate (import ../example/zfs-encrypted-root.nix) {
|
||||
disko.devices.zpool.zroot.datasets.root.options.keylocation = "file:///tmp/secret.key";
|
||||
};
|
||||
extraTestScript = ''
|
||||
machine.succeed("mountpoint /");
|
||||
machine.succeed("mountpoint /nix");
|
||||
'';
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
@@ -12,4 +13,3 @@ diskoLib.testLib.makeDiskoTest {
|
||||
machine.succeed("mountpoint /zfs_fs");
|
||||
'';
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, diskoLib ? pkgs.callPackage ../lib { }
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
diskoLib ? pkgs.callPackage ../lib { },
|
||||
}:
|
||||
diskoLib.testLib.makeDiskoTest {
|
||||
inherit pkgs;
|
||||
|
@@ -1 +1,4 @@
|
||||
{ version = "1.10.0"; released = false; }
|
||||
{
|
||||
version = "1.10.0";
|
||||
released = false;
|
||||
}
|
||||
|
Reference in New Issue
Block a user