treewide: format all files
This commit is contained in:
61
cli.nix
61
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,8 +18,10 @@ let
|
||||
hasDiskoFile = diskoFile != null;
|
||||
|
||||
diskoAttr =
|
||||
(if noDeps then
|
||||
(if hasDiskoFile then
|
||||
(
|
||||
if noDeps then
|
||||
(
|
||||
if hasDiskoFile then
|
||||
{
|
||||
destroy = "_cliDestroyNoDeps";
|
||||
format = "_cliFormatNoDeps";
|
||||
@@ -37,14 +40,17 @@ let
|
||||
|
||||
"format,mount" = "formatMountNoDeps";
|
||||
"destroy,format,mount" = "destroyFormatMountNoDeps";
|
||||
}) // {
|
||||
}
|
||||
)
|
||||
// {
|
||||
# legacy aliases
|
||||
disko = "diskoScriptNoDeps";
|
||||
create = "createScriptNoDeps";
|
||||
zap_create_mount = "diskoScriptNoDeps";
|
||||
}
|
||||
else
|
||||
(if hasDiskoFile then
|
||||
(
|
||||
if hasDiskoFile then
|
||||
{
|
||||
destroy = "_cliDestroy";
|
||||
format = "_cliFormat";
|
||||
@@ -63,7 +69,9 @@ let
|
||||
|
||||
"format,mount" = "formatMount";
|
||||
"destroy,format,mount" = "destroyFormatMount";
|
||||
}) // {
|
||||
}
|
||||
)
|
||||
// {
|
||||
# legacy aliases
|
||||
disko = "diskoScript";
|
||||
create = "createScript";
|
||||
@@ -74,9 +82,13 @@ let
|
||||
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`");
|
||||
|
||||
|
93
default.nix
93
default.nix
@@ -1,10 +1,13 @@
|
||||
{ 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 {
|
||||
eval =
|
||||
cfg:
|
||||
lib.evalModules {
|
||||
modules = lib.singleton {
|
||||
# _file = toString input;
|
||||
imports = lib.singleton { disko.devices = cfg.disko.devices; };
|
||||
@@ -17,48 +20,88 @@ let
|
||||
};
|
||||
# We might instead reuse some of the deprecated output names to refer to the values the _cli* outputs currently do,
|
||||
# but this warning allows us to get feedback from users early in case they have a use case we haven't considered.
|
||||
warnDeprecated = name: lib.warn "the ${name} output is deprecated and will be removed, please open an issue if you're using it!";
|
||||
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;
|
||||
|
14
doc.nix
14
doc.nix
@@ -1,4 +1,10 @@
|
||||
{ lib, nixosOptionsDoc, runCommand, fetchurl, pandoc }:
|
||||
{
|
||||
lib,
|
||||
nixosOptionsDoc,
|
||||
runCommand,
|
||||
fetchurl,
|
||||
pandoc,
|
||||
}:
|
||||
|
||||
let
|
||||
diskoLib = import ./lib {
|
||||
@@ -21,13 +27,15 @@ let
|
||||
options = nixosOptionsDoc {
|
||||
options = eval.options;
|
||||
};
|
||||
md = (runCommand "disko-options.md" { } ''
|
||||
md =
|
||||
(runCommand "disko-options.md" { } ''
|
||||
cat >$out <<EOF
|
||||
# Disko options
|
||||
|
||||
EOF
|
||||
cat ${options.optionsCommonMark} >>$out
|
||||
'').overrideAttrs (_o: {
|
||||
'').overrideAttrs
|
||||
(_o: {
|
||||
# Work around https://github.com/hercules-ci/hercules-ci-agent/issues/168
|
||||
allowSubstitutes = true;
|
||||
});
|
||||
|
@@ -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" ];
|
||||
|
38
flake.nix
38
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 {
|
||||
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) {
|
||||
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
|
||||
|
@@ -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,8 +17,7 @@ let
|
||||
else
|
||||
throw "No device passed for disk '${name}'. Pass `--disk ${name} /dev/name` via commandline";
|
||||
|
||||
modifiedDisks = builtins.mapAttrs
|
||||
(
|
||||
modifiedDisks = builtins.mapAttrs (
|
||||
name: value:
|
||||
let
|
||||
dev = deviceName name;
|
||||
@@ -30,8 +29,7 @@ let
|
||||
device = dev;
|
||||
};
|
||||
}
|
||||
)
|
||||
originalSystem.config.disko.devices.disk;
|
||||
) 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
|
||||
@@ -153,7 +161,8 @@ in
|
||||
|
||||
inherit (elaborated) qemuArch;
|
||||
isQemu = "qemu-${qemuArch}" == baseNameOf interpreter;
|
||||
in makeBinfmtLine (
|
||||
in
|
||||
makeBinfmtLine (
|
||||
{
|
||||
name = system;
|
||||
inherit interpreter;
|
||||
|
585
lib/default.nix
585
lib/default.nix
@@ -1,7 +1,8 @@
|
||||
{ lib ? import <nixpkgs/lib>
|
||||
, rootMountPoint ? "/mnt"
|
||||
, makeTest ? import <nixpkgs/nixos/tests/make-test-python.nix>
|
||||
, eval-config ? import <nixpkgs/nixos/lib/eval-config.nix>
|
||||
{
|
||||
lib ? import <nixpkgs/lib>,
|
||||
rootMountPoint ? "/mnt",
|
||||
makeTest ? import <nixpkgs/nixos/tests/make-test-python.nix>,
|
||||
eval-config ? import <nixpkgs/nixos/lib/eval-config.nix>,
|
||||
}:
|
||||
let
|
||||
outputs = import ../default.nix { inherit lib diskoLib; };
|
||||
@@ -9,42 +10,89 @@ let
|
||||
testLib = import ./tests.nix { inherit lib makeTest eval-config; };
|
||||
# like lib.types.oneOf but instead of a list takes an attrset
|
||||
# uses the field "type" to find the correct type in the attrset
|
||||
subType = { types, extraArgs ? { parent = { type = "rootNode"; name = "root"; }; } }: lib.mkOptionType {
|
||||
subType =
|
||||
{
|
||||
types,
|
||||
extraArgs ? {
|
||||
parent = {
|
||||
type = "rootNode";
|
||||
name = "root";
|
||||
};
|
||||
},
|
||||
}:
|
||||
lib.mkOptionType {
|
||||
name = "subType";
|
||||
description = "one of ${lib.concatStringsSep "," (lib.attrNames types)}";
|
||||
check = x: if x ? type then types.${x.type}.check x else throw "No type option set in:\n${lib.generators.toPretty {} x}";
|
||||
merge = loc: lib.foldl'
|
||||
(_res: def: types.${def.value.type}.merge loc [
|
||||
check =
|
||||
x:
|
||||
if x ? type then
|
||||
types.${x.type}.check x
|
||||
else
|
||||
throw "No type option set in:\n${lib.generators.toPretty { } x}";
|
||||
merge =
|
||||
loc:
|
||||
lib.foldl' (
|
||||
_res: def:
|
||||
types.${def.value.type}.merge loc [
|
||||
# we add a dummy root parent node to render documentation
|
||||
(lib.recursiveUpdate { value._module.args = extraArgs; } def)
|
||||
])
|
||||
{ };
|
||||
]
|
||||
) { };
|
||||
nestedTypes = types;
|
||||
};
|
||||
|
||||
# option for valid contents of partitions (basically like devices, but without tables)
|
||||
_partitionTypes = { inherit (diskoLib.types) btrfs filesystem zfs mdraid luks lvm_pv swap; };
|
||||
partitionType = extraArgs: lib.mkOption {
|
||||
type = lib.types.nullOr (diskoLib.subType {
|
||||
_partitionTypes = {
|
||||
inherit (diskoLib.types)
|
||||
btrfs
|
||||
filesystem
|
||||
zfs
|
||||
mdraid
|
||||
luks
|
||||
lvm_pv
|
||||
swap
|
||||
;
|
||||
};
|
||||
partitionType =
|
||||
extraArgs:
|
||||
lib.mkOption {
|
||||
type = lib.types.nullOr (
|
||||
diskoLib.subType {
|
||||
types = diskoLib._partitionTypes;
|
||||
inherit extraArgs;
|
||||
});
|
||||
}
|
||||
);
|
||||
default = null;
|
||||
description = "The type of partition";
|
||||
};
|
||||
|
||||
# option for valid contents of devices
|
||||
_deviceTypes = { inherit (diskoLib.types) table gpt btrfs filesystem zfs mdraid luks lvm_pv swap; };
|
||||
deviceType = extraArgs: lib.mkOption {
|
||||
type = lib.types.nullOr (diskoLib.subType {
|
||||
_deviceTypes = {
|
||||
inherit (diskoLib.types)
|
||||
table
|
||||
gpt
|
||||
btrfs
|
||||
filesystem
|
||||
zfs
|
||||
mdraid
|
||||
luks
|
||||
lvm_pv
|
||||
swap
|
||||
;
|
||||
};
|
||||
deviceType =
|
||||
extraArgs:
|
||||
lib.mkOption {
|
||||
type = lib.types.nullOr (
|
||||
diskoLib.subType {
|
||||
types = diskoLib._deviceTypes;
|
||||
inherit extraArgs;
|
||||
});
|
||||
}
|
||||
);
|
||||
default = null;
|
||||
description = "The type of device";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
like lib.recursiveUpdate but supports merging of lists
|
||||
|
||||
@@ -75,25 +123,35 @@ let
|
||||
boot.loader.grub.devices = [ "/dev/hda" "/dev/hdb" ];
|
||||
}
|
||||
```
|
||||
**/
|
||||
recursiveUpdate = left: right:
|
||||
*
|
||||
*/
|
||||
recursiveUpdate =
|
||||
left: right:
|
||||
let
|
||||
inherit (lib) zipAttrsWith length elemAt head isAttrs isList concatLists all reverseList;
|
||||
inherit (lib)
|
||||
zipAttrsWith
|
||||
length
|
||||
elemAt
|
||||
head
|
||||
isAttrs
|
||||
isList
|
||||
concatLists
|
||||
all
|
||||
reverseList
|
||||
;
|
||||
|
||||
recursiveMergeUntil =
|
||||
pred:
|
||||
lhs:
|
||||
rhs:
|
||||
pred: lhs: rhs:
|
||||
let
|
||||
f = attrPath:
|
||||
zipAttrsWith (n: values:
|
||||
let here = attrPath ++ [ n ]; in
|
||||
if length values == 1
|
||||
|| pred here (elemAt values 1) (head values) then
|
||||
(
|
||||
if all isList values then concatLists (reverseList values)
|
||||
else head values
|
||||
)
|
||||
f =
|
||||
attrPath:
|
||||
zipAttrsWith (
|
||||
n: values:
|
||||
let
|
||||
here = attrPath ++ [ n ];
|
||||
in
|
||||
if length values == 1 || pred here (elemAt values 1) (head values) then
|
||||
(if all isList values then concatLists (reverseList values) else head values)
|
||||
else
|
||||
f here values
|
||||
);
|
||||
@@ -101,19 +159,17 @@ let
|
||||
f [ ] [ rhs lhs ];
|
||||
|
||||
recursiveMerge =
|
||||
lhs:
|
||||
rhs:
|
||||
recursiveMergeUntil
|
||||
(_path: lhs: rhs:
|
||||
!(isAttrs lhs && isAttrs rhs))
|
||||
lhs
|
||||
rhs;
|
||||
|
||||
lhs: rhs:
|
||||
recursiveMergeUntil (
|
||||
_path: lhs: rhs:
|
||||
!(isAttrs lhs && isAttrs rhs)
|
||||
) lhs rhs;
|
||||
|
||||
in
|
||||
recursiveMerge left right;
|
||||
|
||||
/* deepMergeMap takes a function and a list of attrsets and deep merges them
|
||||
/*
|
||||
deepMergeMap takes a function and a list of attrsets and deep merges them
|
||||
|
||||
deepMergeMap :: (AttrSet -> AttrSet ) -> [ AttrSet ] -> Attrset
|
||||
|
||||
@@ -123,7 +179,8 @@ let
|
||||
*/
|
||||
deepMergeMap = f: lib.foldr (attr: acc: (diskoLib.recursiveUpdate acc (f attr))) { };
|
||||
|
||||
/* get a device and an index to get the matching device name
|
||||
/*
|
||||
get a device and an index to get the matching device name
|
||||
|
||||
deviceNumbering :: str -> int -> str
|
||||
|
||||
@@ -134,8 +191,11 @@ let
|
||||
deviceNumbering "/dev/disk/by-id/xxx" 2
|
||||
=> "/dev/disk/by-id/xxx-part2"
|
||||
*/
|
||||
deviceNumbering = dev: index:
|
||||
let inherit (lib) match; in
|
||||
deviceNumbering =
|
||||
dev: index:
|
||||
let
|
||||
inherit (lib) match;
|
||||
in
|
||||
if match "/dev/([vs]|(xv)d).+" dev != null then
|
||||
dev + toString index # /dev/{s,v,xv}da style
|
||||
else if match "/dev/(disk|zvol)/.+" dev != null then
|
||||
@@ -146,14 +206,15 @@ let
|
||||
"${dev}${toString index}" # /dev/md/raid1 style
|
||||
else if match "/dev/mapper/.+" dev != null then
|
||||
"${dev}${toString index}" # /dev/mapper/vg-lv1 style
|
||||
else if match "/dev/loop[[:digit:]]+" dev != null
|
||||
then "${dev}p${toString index}" # /dev/mapper/vg-lv1 style
|
||||
else if match "/dev/loop[[:digit:]]+" dev != null then
|
||||
"${dev}p${toString index}" # /dev/mapper/vg-lv1 style
|
||||
else
|
||||
abort ''
|
||||
${dev} seems not to be a supported disk format. Please add this to disko in https://github.com/nix-community/disko/blob/master/lib/default.nix
|
||||
'';
|
||||
|
||||
/* Escape a string as required to be used in udev symlinks
|
||||
/*
|
||||
Escape a string as required to be used in udev symlinks
|
||||
|
||||
The allowed characters are "0-9A-Za-z#+-.:=@_/", valid UTF-8 character sequences, and "\x00" hex encoding.
|
||||
Everything else is escaped as "\xXX" where XX is the hex value of the character.
|
||||
@@ -181,10 +242,12 @@ let
|
||||
allowedChars = "[0-9A-Za-z#+-.:=@_/]";
|
||||
charToHex = c: lib.toHexString (lib.strings.charToInt c);
|
||||
in
|
||||
lib.stringAsChars
|
||||
(c: if lib.match allowedChars c != null || c == "" then c else "\\x" + charToHex c);
|
||||
lib.stringAsChars (
|
||||
c: if lib.match allowedChars c != null || c == "" then c else "\\x" + charToHex c
|
||||
);
|
||||
|
||||
/* get the index an item in a list
|
||||
/*
|
||||
get the index an item in a list
|
||||
|
||||
indexOf :: (a -> bool) -> [a] -> int -> int
|
||||
|
||||
@@ -195,9 +258,11 @@ let
|
||||
indexOf (x: x == "x") [ 1 2 3 ] 0
|
||||
=> 0
|
||||
*/
|
||||
indexOf = f: list: fallback:
|
||||
indexOf =
|
||||
f: list: fallback:
|
||||
let
|
||||
iter = index: list:
|
||||
iter =
|
||||
index: list:
|
||||
if list == [ ] then
|
||||
fallback
|
||||
else if f (lib.head list) then
|
||||
@@ -207,8 +272,8 @@ let
|
||||
in
|
||||
iter 1 list;
|
||||
|
||||
|
||||
/* indent takes a multiline string and indents it by 2 spaces starting on the second line
|
||||
/*
|
||||
indent takes a multiline string and indents it by 2 spaces starting on the second line
|
||||
|
||||
indent :: str -> str
|
||||
|
||||
@@ -218,11 +283,12 @@ let
|
||||
*/
|
||||
indent = lib.replaceStrings [ "\n" ] [ "\n " ];
|
||||
|
||||
/* A nix option type representing a json datastructure, vendored from nixpkgs to avoid dependency on pkgs */
|
||||
# A nix option type representing a json datastructure, vendored from nixpkgs to avoid dependency on pkgs
|
||||
jsonType =
|
||||
let
|
||||
valueType = lib.types.nullOr
|
||||
(lib.types.oneOf [
|
||||
valueType =
|
||||
lib.types.nullOr (
|
||||
lib.types.oneOf [
|
||||
lib.types.bool
|
||||
lib.types.int
|
||||
lib.types.float
|
||||
@@ -230,21 +296,24 @@ let
|
||||
lib.types.path
|
||||
(lib.types.attrsOf valueType)
|
||||
(lib.types.listOf valueType)
|
||||
]) // {
|
||||
]
|
||||
)
|
||||
// {
|
||||
description = "JSON value";
|
||||
};
|
||||
in
|
||||
valueType;
|
||||
|
||||
/* Given a attrset of deviceDependencies and a devices attrset
|
||||
/*
|
||||
Given a attrset of deviceDependencies and a devices attrset
|
||||
returns a sorted list by deviceDependencies. aborts if a loop is found
|
||||
|
||||
sortDevicesByDependencies :: AttrSet -> AttrSet -> [ [ str str ] ]
|
||||
*/
|
||||
sortDevicesByDependencies = deviceDependencies: devices:
|
||||
sortDevicesByDependencies =
|
||||
deviceDependencies: devices:
|
||||
let
|
||||
dependsOn = a: b:
|
||||
lib.elem a (lib.attrByPath b [ ] deviceDependencies);
|
||||
dependsOn = a: b: lib.elem a (lib.attrByPath b [ ] deviceDependencies);
|
||||
maybeSortedDevices = lib.toposort dependsOn (diskoLib.deviceList devices);
|
||||
in
|
||||
if (lib.hasAttr "cycle" maybeSortedDevices) then
|
||||
@@ -252,7 +321,8 @@ let
|
||||
else
|
||||
maybeSortedDevices.result;
|
||||
|
||||
/* Takes a devices attrSet and returns it as a list
|
||||
/*
|
||||
Takes a devices attrSet and returns it as a list
|
||||
|
||||
deviceList :: AttrSet -> [ [ str str ] ]
|
||||
|
||||
@@ -260,10 +330,20 @@ let
|
||||
deviceList { zfs.pool1 = {}; zfs.pool2 = {}; mdadm.raid1 = {}; }
|
||||
=> [ [ "zfs" "pool1" ] [ "zfs" "pool2" ] [ "mdadm" "raid1" ] ]
|
||||
*/
|
||||
deviceList = devices:
|
||||
lib.concatLists (lib.mapAttrsToList (n: v: (map (x: [ n x ]) (lib.attrNames v))) devices);
|
||||
deviceList =
|
||||
devices:
|
||||
lib.concatLists (
|
||||
lib.mapAttrsToList (
|
||||
n: v:
|
||||
(map (x: [
|
||||
n
|
||||
x
|
||||
]) (lib.attrNames v))
|
||||
) devices
|
||||
);
|
||||
|
||||
/* Takes either a string or null and returns the string or an empty string
|
||||
/*
|
||||
Takes either a string or null and returns the string or an empty string
|
||||
|
||||
maybeStr :: Either (str null) -> str
|
||||
|
||||
@@ -275,34 +355,46 @@ let
|
||||
*/
|
||||
maybeStr = x: lib.optionalString (x != null) x;
|
||||
|
||||
/* Takes a Submodules config and options argument and returns a serializable
|
||||
/*
|
||||
Takes a Submodules config and options argument and returns a serializable
|
||||
subset of config variables as a shell script snippet.
|
||||
*/
|
||||
defineHookVariables = { options }:
|
||||
defineHookVariables =
|
||||
{ options }:
|
||||
let
|
||||
sanitizeName = lib.replaceStrings [ "-" ] [ "_" ];
|
||||
isAttrsOfSubmodule = o: o.type.name == "attrsOf" && o.type.nestedTypes.elemType.name == "submodule";
|
||||
isSerializable = n: o: !(
|
||||
isSerializable =
|
||||
n: o:
|
||||
!(
|
||||
lib.hasPrefix "_" n
|
||||
|| lib.hasSuffix "Hook" n
|
||||
|| isAttrsOfSubmodule o
|
||||
# TODO don't hardcode diskoLib.subType options.
|
||||
|| n == "content" || n == "partitions" || n == "datasets" || n == "swap"
|
||||
|| n == "content"
|
||||
|| n == "partitions"
|
||||
|| n == "datasets"
|
||||
|| n == "swap"
|
||||
|| n == "mode"
|
||||
);
|
||||
in
|
||||
lib.toShellVars
|
||||
(lib.mapAttrs'
|
||||
(n: o: lib.nameValuePair (sanitizeName n) o.value)
|
||||
(lib.filterAttrs isSerializable options));
|
||||
lib.toShellVars (
|
||||
lib.mapAttrs' (n: o: lib.nameValuePair (sanitizeName n) o.value) (
|
||||
lib.filterAttrs isSerializable options
|
||||
)
|
||||
);
|
||||
|
||||
mkHook = description: lib.mkOption {
|
||||
mkHook =
|
||||
description:
|
||||
lib.mkOption {
|
||||
inherit description;
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
};
|
||||
|
||||
mkSubType = module: lib.types.submodule [
|
||||
mkSubType =
|
||||
module:
|
||||
lib.types.submodule [
|
||||
module
|
||||
|
||||
{
|
||||
@@ -320,13 +412,25 @@ let
|
||||
}
|
||||
];
|
||||
|
||||
mkCreateOption = { config, options, default }@attrs:
|
||||
mkCreateOption =
|
||||
{
|
||||
config,
|
||||
options,
|
||||
default,
|
||||
}@attrs:
|
||||
lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.str;
|
||||
default = ''
|
||||
( # ${config.type} ${lib.concatMapStringsSep " " (n: toString (config.${n} or "")) ["name" "device" "format" "mountpoint"]} #
|
||||
( # ${config.type} ${
|
||||
lib.concatMapStringsSep " " (n: toString (config.${n} or "")) [
|
||||
"name"
|
||||
"device"
|
||||
"format"
|
||||
"mountpoint"
|
||||
]
|
||||
} #
|
||||
${diskoLib.indent (diskoLib.defineHookVariables { inherit options; })}
|
||||
${diskoLib.indent config.preCreateHook}
|
||||
${diskoLib.indent attrs.default}
|
||||
@@ -336,98 +440,131 @@ let
|
||||
description = "Creation script";
|
||||
};
|
||||
|
||||
mkMountOption = { config, options, default }@attrs:
|
||||
mkMountOption =
|
||||
{
|
||||
config,
|
||||
options,
|
||||
default,
|
||||
}@attrs:
|
||||
lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = diskoLib.jsonType;
|
||||
default = lib.mapAttrsRecursive
|
||||
(_name: value:
|
||||
if builtins.isString value then ''
|
||||
default = lib.mapAttrsRecursive (
|
||||
_name: value:
|
||||
if builtins.isString value then
|
||||
''
|
||||
(
|
||||
${diskoLib.indent (diskoLib.defineHookVariables { inherit options; })}
|
||||
${diskoLib.indent config.preMountHook}
|
||||
${diskoLib.indent value}
|
||||
${diskoLib.indent config.postMountHook}
|
||||
)
|
||||
'' else value)
|
||||
attrs.default;
|
||||
''
|
||||
else
|
||||
value
|
||||
) attrs.default;
|
||||
description = "Mount script";
|
||||
};
|
||||
|
||||
mkUnmountOption = { config, options, default }@attrs:
|
||||
mkUnmountOption =
|
||||
{
|
||||
config,
|
||||
options,
|
||||
default,
|
||||
}@attrs:
|
||||
lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = diskoLib.jsonType;
|
||||
default = lib.mapAttrsRecursive
|
||||
(_name: value:
|
||||
if builtins.isString value then ''
|
||||
default = lib.mapAttrsRecursive (
|
||||
_name: value:
|
||||
if builtins.isString value then
|
||||
''
|
||||
(
|
||||
${diskoLib.indent (diskoLib.defineHookVariables { inherit options; })}
|
||||
${diskoLib.indent config.preUnmountHook}
|
||||
${diskoLib.indent value}
|
||||
${diskoLib.indent config.postUnmountHook}
|
||||
)
|
||||
'' else value)
|
||||
attrs.default;
|
||||
''
|
||||
else
|
||||
value
|
||||
) attrs.default;
|
||||
description = "Unmount script";
|
||||
};
|
||||
|
||||
/* Writer for optionally checking bash scripts before writing them to the store
|
||||
/*
|
||||
Writer for optionally checking bash scripts before writing them to the store
|
||||
|
||||
writeCheckedBash :: AttrSet -> str -> str -> derivation
|
||||
*/
|
||||
writeCheckedBash = { pkgs, checked ? false, noDeps ? false }: pkgs.writers.makeScriptWriter {
|
||||
writeCheckedBash =
|
||||
{
|
||||
pkgs,
|
||||
checked ? false,
|
||||
noDeps ? false,
|
||||
}:
|
||||
pkgs.writers.makeScriptWriter {
|
||||
interpreter = if noDeps then "/usr/bin/env bash" else "${pkgs.bash}/bin/bash";
|
||||
check = lib.optionalString (checked && !pkgs.stdenv.hostPlatform.isRiscV64 && !pkgs.stdenv.hostPlatform.isx86_32) (pkgs.writeScript "check" ''
|
||||
check =
|
||||
lib.optionalString
|
||||
(checked && !pkgs.stdenv.hostPlatform.isRiscV64 && !pkgs.stdenv.hostPlatform.isx86_32)
|
||||
(
|
||||
pkgs.writeScript "check" ''
|
||||
set -efu
|
||||
# SC2054: our toShellVars function doesn't quote list elements with commas
|
||||
# SC2034: We don't use all variables exported by hooks.
|
||||
${pkgs.shellcheck}/bin/shellcheck -e SC2034,SC2054 "$1"
|
||||
'');
|
||||
''
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
/* Takes a disko device specification, returns an attrset with metadata
|
||||
/*
|
||||
Takes a disko device specification, returns an attrset with metadata
|
||||
|
||||
meta :: lib.types.devices -> AttrSet
|
||||
*/
|
||||
meta = toplevel: toplevel._meta;
|
||||
|
||||
/* Takes a disko device specification and returns a string which formats the disks
|
||||
/*
|
||||
Takes a disko device specification and returns a string which formats the disks
|
||||
|
||||
create :: lib.types.devices -> str
|
||||
*/
|
||||
create = toplevel: toplevel._create;
|
||||
/* Takes a disko device specification and returns a string which mounts the disks
|
||||
/*
|
||||
Takes a disko device specification and returns a string which mounts the disks
|
||||
|
||||
mount :: lib.types.devices -> str
|
||||
*/
|
||||
mount = toplevel: toplevel._mount;
|
||||
|
||||
/* takes a disko device specification and returns a string which unmounts, destroys all disks and then runs create and mount
|
||||
/*
|
||||
takes a disko device specification and returns a string which unmounts, destroys all disks and then runs create and mount
|
||||
|
||||
zapCreateMount :: lib.types.devices -> str
|
||||
*/
|
||||
zapCreateMount = toplevel:
|
||||
''
|
||||
zapCreateMount = toplevel: ''
|
||||
set -efux
|
||||
${toplevel._disko}
|
||||
'';
|
||||
/* Takes a disko device specification and returns a nixos configuration
|
||||
/*
|
||||
Takes a disko device specification and returns a nixos configuration
|
||||
|
||||
config :: lib.types.devices -> nixosConfig
|
||||
*/
|
||||
config = toplevel: toplevel._config;
|
||||
|
||||
/* Takes a disko device specification and returns a function to get the needed packages to format/mount the disks
|
||||
/*
|
||||
Takes a disko device specification and returns a function to get the needed packages to format/mount the disks
|
||||
|
||||
packages :: lib.types.devices -> pkgs -> [ derivation ]
|
||||
*/
|
||||
packages = toplevel: toplevel._packages;
|
||||
|
||||
/* Checks whether nixpkgs is recent enough for vmTools to support the customQemu argument.
|
||||
/*
|
||||
Checks whether nixpkgs is recent enough for vmTools to support the customQemu argument.
|
||||
|
||||
Returns false, which is technically incorrect, for a few commits on 2024-07-08, but we can't be more accurate.
|
||||
Make sure to pass lib, not pkgs.lib! See https://github.com/nix-community/disko/issues/904
|
||||
@@ -453,8 +590,10 @@ let
|
||||
|
||||
pathname = lib.mkOptionType {
|
||||
name = "pathname";
|
||||
check = x:
|
||||
with lib; let
|
||||
check =
|
||||
x:
|
||||
with lib;
|
||||
let
|
||||
# The filter is used to normalize paths, i.e. to remove duplicated and
|
||||
# trailing slashes. It also removes leading slashes, thus we have to
|
||||
# check for "/" explicitly below.
|
||||
@@ -466,11 +605,19 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
/* topLevel type of the disko config, takes attrsets of disks, mdadms, zpools, nodevs, and lvm vgs.
|
||||
*/
|
||||
toplevel = lib.types.submodule (cfg:
|
||||
# topLevel type of the disko config, takes attrsets of disks, mdadms, zpools, nodevs, and lvm vgs.
|
||||
toplevel = lib.types.submodule (
|
||||
cfg:
|
||||
let
|
||||
devices = { inherit (cfg.config) disk mdadm zpool lvm_vg nodev; };
|
||||
devices = {
|
||||
inherit (cfg.config)
|
||||
disk
|
||||
mdadm
|
||||
zpool
|
||||
lvm_vg
|
||||
nodev
|
||||
;
|
||||
};
|
||||
in
|
||||
{
|
||||
options = {
|
||||
@@ -505,7 +652,9 @@ let
|
||||
meta informationen generated by disko
|
||||
currently used for building a dependency list so we know in which order to create the devices
|
||||
'';
|
||||
default = diskoLib.deepMergeMap (dev: dev._meta) (lib.flatten (map lib.attrValues (lib.attrValues devices)));
|
||||
default = diskoLib.deepMergeMap (dev: dev._meta) (
|
||||
lib.flatten (map lib.attrValues (lib.attrValues devices))
|
||||
);
|
||||
};
|
||||
_packages = lib.mkOption {
|
||||
internal = true;
|
||||
@@ -513,16 +662,31 @@ let
|
||||
packages required by the disko configuration
|
||||
coreutils is always included
|
||||
'';
|
||||
default = pkgs: with lib; unique ((flatten (map (dev: dev._pkgs pkgs) (flatten (map attrValues (attrValues devices))))) ++ [ pkgs.coreutils-full ]);
|
||||
default =
|
||||
pkgs:
|
||||
with lib;
|
||||
unique (
|
||||
(flatten (map (dev: dev._pkgs pkgs) (flatten (map attrValues (attrValues devices)))))
|
||||
++ [ pkgs.coreutils-full ]
|
||||
);
|
||||
};
|
||||
_scripts = lib.mkOption {
|
||||
internal = true;
|
||||
description = ''
|
||||
The scripts generated by disko
|
||||
'';
|
||||
default = { pkgs, checked ? false }:
|
||||
default =
|
||||
{
|
||||
pkgs,
|
||||
checked ? false,
|
||||
}:
|
||||
let
|
||||
throwIfNoDisksDetected = _: v: if devices.disk == { } then throw "No disks defined, did you forget to import your disko config?" else v;
|
||||
throwIfNoDisksDetected =
|
||||
_: v:
|
||||
if devices.disk == { } then
|
||||
throw "No disks defined, did you forget to import your disko config?"
|
||||
else
|
||||
v;
|
||||
destroyDependencies = with pkgs; [
|
||||
util-linux
|
||||
e2fsprogs
|
||||
@@ -557,32 +721,71 @@ let
|
||||
export PATH=${lib.makeBinPath ((cfg.config._packages pkgs) ++ [ pkgs.bash ])}:$PATH
|
||||
${cfg.config._formatMount}
|
||||
'';
|
||||
destroyFormatMount = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "/bin/disko-destroy-format-mount" ''
|
||||
export PATH=${lib.makeBinPath ((cfg.config._packages pkgs) ++ [ pkgs.bash ] ++ destroyDependencies)}:$PATH
|
||||
destroyFormatMount =
|
||||
(diskoLib.writeCheckedBash { inherit pkgs checked; }) "/bin/disko-destroy-format-mount"
|
||||
''
|
||||
export PATH=${
|
||||
lib.makeBinPath ((cfg.config._packages pkgs) ++ [ pkgs.bash ] ++ destroyDependencies)
|
||||
}:$PATH
|
||||
${cfg.config._destroyFormatMount}
|
||||
'';
|
||||
|
||||
# These are useful to skip copying executables uploading a script to an in-memory installer
|
||||
destroyNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-destroy" ''
|
||||
destroyNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"/bin/disko-destroy"
|
||||
''
|
||||
${cfg.config._destroy}
|
||||
'';
|
||||
formatNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-format" ''
|
||||
formatNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"/bin/disko-format"
|
||||
''
|
||||
${cfg.config._create}
|
||||
'';
|
||||
mountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-mount" ''
|
||||
mountNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"/bin/disko-mount"
|
||||
''
|
||||
${cfg.config._mount}
|
||||
'';
|
||||
unmountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-unmount" ''
|
||||
unmountNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"/bin/disko-unmount"
|
||||
''
|
||||
${cfg.config._unmount}
|
||||
'';
|
||||
formatMountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-format-mount" ''
|
||||
formatMountNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"/bin/disko-format-mount"
|
||||
''
|
||||
${cfg.config._formatMount}
|
||||
'';
|
||||
destroyFormatMountNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "/bin/disko-destroy-format-mount" ''
|
||||
destroyFormatMountNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"/bin/disko-destroy-format-mount"
|
||||
''
|
||||
${cfg.config._destroyFormatMount}
|
||||
'';
|
||||
|
||||
|
||||
# Legacy scripts, to be removed in version 2.0.0
|
||||
# They are generally less useful, because the scripts are directly written to their $out path instead of
|
||||
# into the $out/bin directory, which makes them incompatible with `nix run`
|
||||
@@ -604,24 +807,50 @@ let
|
||||
'';
|
||||
|
||||
diskoScript = (diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko" ''
|
||||
export PATH=${lib.makeBinPath ((cfg.config._packages pkgs) ++ [ pkgs.bash ] ++ destroyDependencies)}:$PATH
|
||||
export PATH=${
|
||||
lib.makeBinPath ((cfg.config._packages pkgs) ++ [ pkgs.bash ] ++ destroyDependencies)
|
||||
}:$PATH
|
||||
${cfg.config._disko}
|
||||
'';
|
||||
|
||||
# These are useful to skip copying executables uploading a script to an in-memory installer
|
||||
destroyScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-destroy" ''
|
||||
destroyScriptNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"disko-destroy"
|
||||
''
|
||||
${cfg.config._legacyDestroy}
|
||||
'';
|
||||
|
||||
formatScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-format" ''
|
||||
formatScriptNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"disko-format"
|
||||
''
|
||||
${cfg.config._create}
|
||||
'';
|
||||
|
||||
mountScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-mount" ''
|
||||
mountScriptNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"disko-mount"
|
||||
''
|
||||
${cfg.config._mount}
|
||||
'';
|
||||
|
||||
diskoScriptNoDeps = (diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko" ''
|
||||
diskoScriptNoDeps =
|
||||
(diskoLib.writeCheckedBash {
|
||||
inherit pkgs checked;
|
||||
noDeps = true;
|
||||
})
|
||||
"disko"
|
||||
''
|
||||
${cfg.config._disko}
|
||||
'';
|
||||
};
|
||||
@@ -687,8 +916,10 @@ let
|
||||
The script to create all devices defined by disko.devices
|
||||
'';
|
||||
default =
|
||||
with lib; let
|
||||
sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }) devices;
|
||||
with lib;
|
||||
let
|
||||
sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }
|
||||
) devices;
|
||||
in
|
||||
''
|
||||
set -efux
|
||||
@@ -697,7 +928,7 @@ let
|
||||
trap 'rm -rf "$disko_devices_dir"' EXIT
|
||||
mkdir -p "$disko_devices_dir"
|
||||
|
||||
${concatMapStrings (dev: (attrByPath (dev ++ [ "_create" ]) {} devices)) sortedDeviceList}
|
||||
${concatMapStrings (dev: (attrByPath (dev ++ [ "_create" ]) { } devices)) sortedDeviceList}
|
||||
'';
|
||||
};
|
||||
_mount = lib.mkOption {
|
||||
@@ -707,14 +938,18 @@ let
|
||||
The script to mount all devices defined by disko.devices
|
||||
'';
|
||||
default =
|
||||
with lib; let
|
||||
fsMounts = diskoLib.deepMergeMap (dev: dev._mount.fs or { }) (flatten (map attrValues (attrValues devices)));
|
||||
sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }) devices;
|
||||
with lib;
|
||||
let
|
||||
fsMounts = diskoLib.deepMergeMap (dev: dev._mount.fs or { }) (
|
||||
flatten (map attrValues (attrValues devices))
|
||||
);
|
||||
sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }
|
||||
) devices;
|
||||
in
|
||||
''
|
||||
set -efux
|
||||
# first create the necessary devices
|
||||
${concatMapStrings (dev: (attrByPath (dev ++ [ "_mount" ]) {} devices).dev or "") sortedDeviceList}
|
||||
${concatMapStrings (dev: (attrByPath (dev ++ [ "_mount" ]) { } devices).dev or "") sortedDeviceList}
|
||||
|
||||
# and then mount the filesystems in alphabetical order
|
||||
${concatStrings (attrValues fsMounts)}
|
||||
@@ -727,9 +962,13 @@ let
|
||||
The script to unmount all devices defined by disko.devices
|
||||
'';
|
||||
default =
|
||||
with lib; let
|
||||
fsMounts = diskoLib.deepMergeMap (dev: dev._unmount.fs or { }) (flatten (map attrValues (attrValues devices)));
|
||||
sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }) devices;
|
||||
with lib;
|
||||
let
|
||||
fsMounts = diskoLib.deepMergeMap (dev: dev._unmount.fs or { }) (
|
||||
flatten (map attrValues (attrValues devices))
|
||||
);
|
||||
sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }
|
||||
) devices;
|
||||
in
|
||||
''
|
||||
set -efux
|
||||
@@ -737,7 +976,9 @@ let
|
||||
${concatStrings (lib.reverseList (attrValues fsMounts))}
|
||||
|
||||
# Than close the devices
|
||||
${concatMapStrings (dev: (attrByPath (dev ++ [ "_unmount" ]) {} devices).dev or "") (lib.reverseList sortedDeviceList)}
|
||||
${concatMapStrings (dev: (attrByPath (dev ++ [ "_unmount" ]) { } devices).dev or "") (
|
||||
lib.reverseList sortedDeviceList
|
||||
)}
|
||||
'';
|
||||
};
|
||||
_disko = lib.mkOption {
|
||||
@@ -782,39 +1023,33 @@ let
|
||||
The NixOS config generated by disko
|
||||
'';
|
||||
default =
|
||||
with lib; let
|
||||
configKeys = flatten (map attrNames (flatten (map (dev: dev._config) (flatten (map attrValues (attrValues devices))))));
|
||||
with lib;
|
||||
let
|
||||
configKeys = flatten (
|
||||
map attrNames (flatten (map (dev: dev._config) (flatten (map attrValues (attrValues devices)))))
|
||||
);
|
||||
collectedConfigs = flatten (map (dev: dev._config) (flatten (map attrValues (attrValues devices))));
|
||||
in
|
||||
genAttrs configKeys (key: mkMerge (catAttrs key collectedConfigs));
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
# import all the types from the types directory
|
||||
types = lib.listToAttrs (
|
||||
map
|
||||
(file: lib.nameValuePair
|
||||
(lib.removeSuffix ".nix" file)
|
||||
(diskoLib.mkSubType (./types + "/${file}"))
|
||||
)
|
||||
(lib.attrNames (builtins.readDir ./types))
|
||||
map (
|
||||
file: lib.nameValuePair (lib.removeSuffix ".nix" file) (diskoLib.mkSubType (./types + "/${file}"))
|
||||
) (lib.attrNames (builtins.readDir ./types))
|
||||
);
|
||||
|
||||
|
||||
# render types into an json serializable format
|
||||
serializeType = type:
|
||||
serializeType =
|
||||
type:
|
||||
let
|
||||
options = lib.filter (x: !lib.hasPrefix "_" x) (lib.attrNames type.options);
|
||||
in
|
||||
lib.listToAttrs (
|
||||
map
|
||||
(option: lib.nameValuePair
|
||||
option
|
||||
type.options.${option}
|
||||
)
|
||||
options
|
||||
);
|
||||
lib.listToAttrs (map (option: lib.nameValuePair option type.options.${option}) options);
|
||||
|
||||
typesSerializerLib = {
|
||||
rootMountPoint = "";
|
||||
@@ -855,7 +1090,10 @@ let
|
||||
};
|
||||
either = t1: t2: {
|
||||
type = "oneOf";
|
||||
types = [ t1 t2 ];
|
||||
types = [
|
||||
t1
|
||||
t2
|
||||
];
|
||||
};
|
||||
enum = choices: {
|
||||
type = "enum";
|
||||
@@ -867,7 +1105,9 @@ let
|
||||
str = "str";
|
||||
bool = "bool";
|
||||
int = "int";
|
||||
submodule = x: x {
|
||||
submodule =
|
||||
x:
|
||||
x {
|
||||
inherit (diskoLib.typesSerializerLib) lib config options;
|
||||
name = "<self.name>";
|
||||
};
|
||||
@@ -878,7 +1118,9 @@ let
|
||||
# Spoof these types to avoid infinite recursion
|
||||
deviceType = _: "<deviceType>";
|
||||
partitionType = _: "<partitionType>";
|
||||
subType = { types, ... }: {
|
||||
subType =
|
||||
{ types, ... }:
|
||||
{
|
||||
type = "oneOf";
|
||||
types = lib.attrNames types;
|
||||
};
|
||||
@@ -886,15 +1128,16 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
jsonTypes = lib.listToAttrs
|
||||
(
|
||||
map
|
||||
(file: lib.nameValuePair
|
||||
(lib.removeSuffix ".nix" file)
|
||||
(diskoLib.serializeType (import (./types + "/${file}") diskoLib.typesSerializerLib))
|
||||
jsonTypes =
|
||||
lib.listToAttrs (
|
||||
map (
|
||||
file:
|
||||
lib.nameValuePair (lib.removeSuffix ".nix" file) (
|
||||
diskoLib.serializeType (import (./types + "/${file}") diskoLib.typesSerializerLib)
|
||||
)
|
||||
(lib.filter (name: lib.hasSuffix ".nix" name) (lib.attrNames (builtins.readDir ./types)))
|
||||
) // {
|
||||
) (lib.filter (name: lib.hasSuffix ".nix" name) (lib.attrNames (builtins.readDir ./types)))
|
||||
)
|
||||
// {
|
||||
partitionType = {
|
||||
type = "oneOf";
|
||||
types = lib.attrNames diskoLib._partitionTypes;
|
||||
|
@@ -1,8 +1,16 @@
|
||||
{ diskoLib, modulesPath, config, pkgs, lib, ... }:
|
||||
{
|
||||
diskoLib,
|
||||
modulesPath,
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
vm_disko = (diskoLib.testLib.prepareDiskoConfig config diskoLib.testLib.devices).disko;
|
||||
cfg_ = (lib.evalModules {
|
||||
cfg_ =
|
||||
(lib.evalModules {
|
||||
modules = lib.singleton {
|
||||
# _file = toString input;
|
||||
imports = lib.singleton { disko.devices = vm_disko.devices; };
|
||||
@@ -26,13 +34,11 @@ let
|
||||
deviceExtraOpts.bootindex = "1";
|
||||
deviceExtraOpts.serial = "root";
|
||||
};
|
||||
otherDisks = map
|
||||
(disk: {
|
||||
otherDisks = map (disk: {
|
||||
name = disk.name;
|
||||
file = ''"$tmp"/${lib.escapeShellArg disk.name}.qcow2'';
|
||||
driveExtraOpts.werror = "report";
|
||||
})
|
||||
(builtins.tail disks);
|
||||
}) (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,16 +14,25 @@ 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"
|
||||
@@ -32,14 +42,17 @@ let
|
||||
]
|
||||
++ (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,7 +64,9 @@ let
|
||||
}
|
||||
];
|
||||
};
|
||||
systemToInstallNative = if binfmt.systemsAreDifferent then extendModules {
|
||||
systemToInstallNative =
|
||||
if binfmt.systemsAreDifferent then
|
||||
extendModules {
|
||||
modules = [
|
||||
cfg.extraConfig
|
||||
{
|
||||
@@ -62,8 +77,11 @@ let
|
||||
}
|
||||
];
|
||||
}
|
||||
else systemToInstall;
|
||||
dependencies = with pkgs; [
|
||||
else
|
||||
systemToInstall;
|
||||
dependencies =
|
||||
with pkgs;
|
||||
[
|
||||
bash
|
||||
coreutils
|
||||
gnused
|
||||
@@ -73,11 +91,13 @@ let
|
||||
util-linux
|
||||
findutils
|
||||
kmod
|
||||
] ++ cfg.extraDependencies;
|
||||
]
|
||||
++ cfg.extraDependencies;
|
||||
preVM = ''
|
||||
# shellcheck disable=SC2154
|
||||
mkdir -p "$out"
|
||||
${lib.concatMapStringsSep "\n" (disk:
|
||||
${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)}
|
||||
@@ -127,24 +147,26 @@ let
|
||||
umount -Rv ${systemToInstall.config.disko.rootMountPoint}
|
||||
'';
|
||||
|
||||
QEMU_OPTS = lib.concatStringsSep " " ([
|
||||
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:
|
||||
]
|
||||
++ 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,7 +231,8 @@ in
|
||||
shift
|
||||
done
|
||||
|
||||
export preVM=${diskoLib.writeCheckedBash { inherit pkgs checked; } "preVM.sh" ''
|
||||
export preVM=${
|
||||
diskoLib.writeCheckedBash { inherit pkgs checked; } "preVM.sh" ''
|
||||
set -efu
|
||||
mv copy_before_disko copy_after_disko xchg/
|
||||
origBuilder=${pkgs.writeScript "disko-builder" ''
|
||||
@@ -234,7 +257,8 @@ in
|
||||
''}
|
||||
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}}
|
||||
|
149
lib/tests.nix
149
lib/tests.nix
@@ -1,25 +1,34 @@
|
||||
{ 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
|
||||
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));
|
||||
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; };
|
||||
content = v.content // {
|
||||
device = lib.head acc.devices;
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
@@ -30,8 +39,10 @@ let
|
||||
}
|
||||
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,7 +113,9 @@ let
|
||||
tsp-config = tsp-generator.config testConfigBooted;
|
||||
num-disks = builtins.length (lib.attrNames testConfigBooted.disko.devices.disk);
|
||||
|
||||
installed-system = { config, ... }: {
|
||||
installed-system =
|
||||
{ config, ... }:
|
||||
{
|
||||
imports = [
|
||||
(lib.optionalAttrs (testMode == "direct") tsp-config)
|
||||
(lib.optionalAttrs (testMode == "module") {
|
||||
@@ -132,18 +143,24 @@ let
|
||||
inherit (pkgs) system;
|
||||
};
|
||||
|
||||
installedTopLevel = ((if extendModules != null then extendModules else installed-system-eval.extendModules) {
|
||||
installedTopLevel =
|
||||
((if extendModules != null then extendModules else installed-system-eval.extendModules) {
|
||||
modules = [
|
||||
({ config, ... }: {
|
||||
(
|
||||
{ config, ... }:
|
||||
{
|
||||
imports = [
|
||||
extraSystemConfig
|
||||
({ modulesPath, ... }: {
|
||||
(
|
||||
{ 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
|
||||
@@ -156,7 +173,11 @@ let
|
||||
device = "nix-store";
|
||||
fsType = "9p";
|
||||
neededForBoot = true;
|
||||
options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ];
|
||||
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
|
||||
|
||||
@@ -166,7 +187,8 @@ let
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = builtins.length config.boot.loader.grub.mirroredBoots > 1 -> config.boot.loader.grub.devices == [ ];
|
||||
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 [];`.
|
||||
@@ -174,7 +196,8 @@ let
|
||||
'';
|
||||
}
|
||||
];
|
||||
})
|
||||
}
|
||||
)
|
||||
];
|
||||
}).config.system.build.toplevel;
|
||||
|
||||
@@ -184,7 +207,9 @@ let
|
||||
meta.timeout = 600; # 10 minutes
|
||||
inherit enableOCR;
|
||||
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
(lib.optionalAttrs (testMode == "module") {
|
||||
imports = [
|
||||
@@ -199,17 +224,37 @@ let
|
||||
extraInstallerConfig
|
||||
|
||||
# from base.nix
|
||||
({ config, ... }: {
|
||||
(
|
||||
{ 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";
|
||||
})
|
||||
[
|
||||
"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 {
|
||||
(
|
||||
if lib.versionAtLeast (lib.versions.majorMinor lib.version) "23.11" then
|
||||
{
|
||||
boot.swraid.enable = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
boot.initrd.services.swraid.enable = true;
|
||||
})
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
systemd.services.mdmonitor.enable = false; # silence some weird warnings
|
||||
@@ -227,11 +272,9 @@ let
|
||||
connect-timeout = 1;
|
||||
};
|
||||
|
||||
networking.hostId = lib.mkIf
|
||||
(
|
||||
networking.hostId = lib.mkIf (
|
||||
(testConfigInstall ? networking.hostId) && (testConfigInstall.networking.hostId != null)
|
||||
)
|
||||
testConfigInstall.networking.hostId;
|
||||
) testConfigInstall.networking.hostId;
|
||||
|
||||
virtualisation.emptyDiskImages = builtins.genList (_: 4096) num-disks;
|
||||
|
||||
@@ -239,7 +282,9 @@ let
|
||||
system.build.systemToInstall = installed-system-eval;
|
||||
};
|
||||
|
||||
testScript = { nodes, ... }: ''
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
''
|
||||
def disks(oldmachine, num_disks):
|
||||
disk_flags = []
|
||||
for i in range(num_disks):
|
||||
@@ -311,7 +356,9 @@ let
|
||||
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")
|
||||
machine.succeed("nix-store --load-db < ${
|
||||
pkgs.closureInfo { rootPaths = [ installedTopLevel ]; }
|
||||
}/registration")
|
||||
|
||||
# fix "this is not a NixOS installation"
|
||||
machine.succeed("mkdir -p /mnt/etc")
|
||||
|
@@ -1,7 +1,19 @@
|
||||
{ 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, ... }: {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
size = lib.mkOption {
|
||||
type = lib.types.strMatching "^([0-9]+[KMGTP])?$";
|
||||
@@ -31,30 +43,29 @@ let
|
||||
description = "Options used to mount the swap.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
description = "Swap files";
|
||||
};
|
||||
|
||||
swapConfig = { mountpoint, swap }:
|
||||
swapConfig =
|
||||
{ mountpoint, swap }:
|
||||
{
|
||||
swapDevices = builtins.map
|
||||
(file: {
|
||||
swapDevices = builtins.map (file: {
|
||||
device = "${mountpoint}/${file.path}";
|
||||
inherit (file) priority options;
|
||||
})
|
||||
(lib.attrValues swap);
|
||||
}) (lib.attrValues swap);
|
||||
};
|
||||
|
||||
swapCreate = mountpoint: swap:
|
||||
lib.concatMapStringsSep
|
||||
"\n"
|
||||
(file: ''
|
||||
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);
|
||||
'') (lib.attrValues swap);
|
||||
|
||||
in
|
||||
{
|
||||
@@ -80,7 +91,10 @@ in
|
||||
description = "A list of options to pass to mount.";
|
||||
};
|
||||
subvolumes = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ config, ... }: {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ config, ... }:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
@@ -110,7 +124,9 @@ in
|
||||
};
|
||||
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,9 +185,13 @@ in
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
subvolMounts = lib.concatMapAttrs
|
||||
(_: subvol:
|
||||
lib.warnIf (subvol.mountOptions != (options.subvolumes.type.getSubOptions [ ]).mountOptions.default && subvol.mountpoint == null)
|
||||
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)
|
||||
@@ -179,16 +199,19 @@ in
|
||||
${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}" ])} \
|
||||
${
|
||||
lib.concatMapStringsSep " " (opt: "-o ${opt}") (subvol.mountOptions ++ [ "subvol=${subvol.name}" ])
|
||||
} \
|
||||
-o X-mount.mkdir
|
||||
fi
|
||||
'';
|
||||
}
|
||||
)
|
||||
config.subvolumes;
|
||||
) config.subvolumes;
|
||||
in
|
||||
{
|
||||
fs = subvolMounts // lib.optionalAttrs (config.mountpoint != null) {
|
||||
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}" \
|
||||
@@ -203,22 +226,21 @@ in
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
subvolMounts = lib.concatMapAttrs
|
||||
(_: subvol:
|
||||
lib.optionalAttrs
|
||||
(subvol.mountpoint != null)
|
||||
{
|
||||
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;
|
||||
) config.subvolumes;
|
||||
in
|
||||
{
|
||||
fs = subvolMounts // lib.optionalAttrs (config.mountpoint != null) {
|
||||
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}"
|
||||
@@ -231,8 +253,8 @@ in
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = [
|
||||
(map
|
||||
(subvol:
|
||||
(map (
|
||||
subvol:
|
||||
lib.optional (subvol.mountpoint != null) {
|
||||
fileSystems.${subvol.mountpoint} = {
|
||||
device = config.device;
|
||||
@@ -240,8 +262,7 @@ in
|
||||
options = subvol.mountOptions ++ [ "subvol=${subvol.name}" ];
|
||||
};
|
||||
}
|
||||
)
|
||||
(lib.attrValues config.subvolumes))
|
||||
) (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,17 +24,32 @@ in
|
||||
description = "Device to use for the partition table";
|
||||
};
|
||||
partitions = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }@partition: {
|
||||
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";
|
||||
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.
|
||||
@@ -80,7 +103,9 @@ in
|
||||
default = name;
|
||||
};
|
||||
uuid = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.strMatching "[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}");
|
||||
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";
|
||||
@@ -120,7 +145,19 @@ in
|
||||
};
|
||||
alignment = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = if (builtins.substring (builtins.stringLength partition.config.start - 1) 1 partition.config.start == "s" || (builtins.substring (builtins.stringLength partition.config.end - 1) 1 partition.config.end == "s")) then 1 else 0;
|
||||
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";
|
||||
};
|
||||
@@ -141,9 +178,15 @@ in
|
||||
or - for relative sizes from the disks end
|
||||
'';
|
||||
};
|
||||
content = diskoLib.partitionType { parent = config; device = partition.config.device; };
|
||||
content = diskoLib.partitionType {
|
||||
parent = config;
|
||||
device = partition.config.device;
|
||||
};
|
||||
hybrid = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.submodule ({ ... } @ hp: {
|
||||
type = lib.types.nullOr (
|
||||
lib.types.submodule (
|
||||
{ ... }@hp:
|
||||
{
|
||||
options = {
|
||||
mbrPartitionType = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
@@ -169,7 +212,9 @@ in
|
||||
'';
|
||||
};
|
||||
};
|
||||
}));
|
||||
}
|
||||
)
|
||||
);
|
||||
default = null;
|
||||
description = "Entry to add to the Hybrid MBR table";
|
||||
};
|
||||
@@ -180,7 +225,9 @@ in
|
||||
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,16 +259,23 @@ 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
|
||||
@@ -237,35 +292,30 @@ in
|
||||
''
|
||||
) sortedPartitions}
|
||||
|
||||
${
|
||||
lib.optionalString (sortedHybridPartitions != [])
|
||||
("sgdisk -h "
|
||||
${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 (!config.efiGptPartitionFirst) ":EE ")
|
||||
+ ''"${parent.device}"''
|
||||
)}
|
||||
${lib.concatMapStrings (p: p.hybrid._create) sortedHybridPartitions}
|
||||
|
||||
${lib.concatStrings (map (partition: ''
|
||||
${lib.concatStrings (
|
||||
map (partition: ''
|
||||
${lib.optionalString (partition.content != null) partition.content._create}
|
||||
'') sortedPartitions)}
|
||||
'') 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,11 +340,10 @@ in
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = (map
|
||||
(partition:
|
||||
lib.optional (partition.content != null) partition.content._config
|
||||
)
|
||||
(lib.attrValues config.partitions))
|
||||
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 ];
|
||||
});
|
||||
@@ -304,16 +353,18 @@ in
|
||||
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,7 +79,8 @@ in
|
||||
type = lib.types.attrsOf lib.types.anything;
|
||||
default = { };
|
||||
description = "LUKS settings (as defined in configuration.nix in boot.initrd.luks.devices.<name>)";
|
||||
example = ''{
|
||||
example = ''
|
||||
{
|
||||
keyFile = "/tmp/disk.key";
|
||||
keyFileSize = 2048;
|
||||
keyFileOffset = 1024;
|
||||
@@ -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: ''
|
||||
${toString (
|
||||
lib.forEach config.additionalKeyFiles (keyFile: ''
|
||||
cryptsetup luksAddKey "${config.device}" ${keyFile} ${keyFileArgs}
|
||||
''))}
|
||||
'')
|
||||
)}
|
||||
fi
|
||||
${lib.optionalString (config.content != null) config.content._create}
|
||||
'';
|
||||
@@ -188,7 +206,8 @@ in
|
||||
_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 [
|
||||
{
|
||||
@@ -196,14 +215,21 @@ in
|
||||
inherit (config) device;
|
||||
} // config.settings;
|
||||
}
|
||||
]) ++ (lib.optional (config.content != null) config.content._config);
|
||||
])
|
||||
++ (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,7 +31,10 @@ in
|
||||
description = "Type";
|
||||
};
|
||||
lvs = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }@lv: {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }@lv:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
@@ -32,7 +43,9 @@ in
|
||||
};
|
||||
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);
|
||||
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
|
||||
'';
|
||||
@@ -44,7 +57,18 @@ in
|
||||
};
|
||||
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
|
||||
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";
|
||||
};
|
||||
@@ -58,9 +82,14 @@ in
|
||||
default = null;
|
||||
description = "Name of pool LV that this LV belongs to";
|
||||
};
|
||||
content = diskoLib.partitionType { parent = config; device = "/dev/${config.name}/${lv.config.name}"; };
|
||||
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 ])
|
||||
default = diskoLib.deepMergeMap (
|
||||
lv:
|
||||
lib.optionalAttrs (lv.content != null) (
|
||||
lv.content._meta [
|
||||
"lvm_vg"
|
||||
config.name
|
||||
]
|
||||
)
|
||||
(lib.attrValues config.lvs);
|
||||
) (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: [
|
||||
default =
|
||||
[ { boot.initrd.kernelModules = kernelModules; } ]
|
||||
++ map (lv: [
|
||||
(lib.optional (lv.content != null) lv.content._config)
|
||||
(lib.optional (lv.lvm_type != null) {
|
||||
boot.initrd.kernelModules = [
|
||||
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,15 +75,16 @@
|
||||
};
|
||||
_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
|
||||
default =
|
||||
let
|
||||
content = lib.optionalAttrs (config.content != null) config.content._unmount;
|
||||
in {
|
||||
in
|
||||
{
|
||||
fs = content.fs;
|
||||
dev = ''
|
||||
${content.dev or ""}
|
||||
@@ -75,24 +97,30 @@
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default =
|
||||
[
|
||||
(if lib.versionAtLeast (lib.versions.majorMinor lib.version) "23.11" then {
|
||||
default = [
|
||||
(
|
||||
if lib.versionAtLeast (lib.versions.majorMinor lib.version) "23.11" then
|
||||
{
|
||||
boot.swraid.enable = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
boot.initrd.services.swraid.enable = true;
|
||||
})
|
||||
] ++
|
||||
lib.optional (config.content != null) config.content._config;
|
||||
}
|
||||
)
|
||||
] ++ 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: [
|
||||
default =
|
||||
pkgs:
|
||||
[
|
||||
pkgs.parted # for partprobe
|
||||
] ++ (lib.optionals (config.content != null) (config.content._pkgs pkgs));
|
||||
]
|
||||
++ (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,8 +118,10 @@
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = [{
|
||||
swapDevices = [{
|
||||
default = [
|
||||
{
|
||||
swapDevices = [
|
||||
{
|
||||
device = config.device;
|
||||
inherit (config) discardPolicy priority;
|
||||
randomEncryption = {
|
||||
@@ -118,16 +130,21 @@
|
||||
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,6 +1,16 @@
|
||||
{ config, options, lib, diskoLib, parent, device, ... }:
|
||||
{
|
||||
options = lib.warn ''
|
||||
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:
|
||||
@@ -20,20 +30,46 @@
|
||||
description = "Device to partition";
|
||||
};
|
||||
format = lib.mkOption {
|
||||
type = lib.types.enum [ "gpt" "msdos" ];
|
||||
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: {
|
||||
type = lib.types.listOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }@partition:
|
||||
{
|
||||
options = {
|
||||
part-type = lib.mkOption {
|
||||
type = lib.types.enum [ "primary" "logical" "extended" ];
|
||||
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" ]);
|
||||
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";
|
||||
};
|
||||
@@ -61,7 +97,10 @@
|
||||
default = false;
|
||||
description = "Whether to make the partition bootable";
|
||||
};
|
||||
content = diskoLib.partitionType { parent = config; device = diskoLib.deviceNumbering config.device partition.config._index; };
|
||||
content = diskoLib.partitionType {
|
||||
parent = config;
|
||||
device = diskoLib.deviceNumbering config.device partition.config._index;
|
||||
};
|
||||
_index = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
internal = true;
|
||||
@@ -69,7 +108,9 @@
|
||||
defaultText = null;
|
||||
};
|
||||
};
|
||||
}));
|
||||
}
|
||||
)
|
||||
);
|
||||
default = [ ];
|
||||
description = "List of partitions to add to the partition table";
|
||||
};
|
||||
@@ -81,12 +122,13 @@
|
||||
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);
|
||||
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 {
|
||||
@@ -94,7 +136,8 @@
|
||||
default = ''
|
||||
if ! blkid "${config.device}" >/dev/null; then
|
||||
parted -s "${config.device}" -- mklabel ${config.format}
|
||||
${lib.concatStrings (map (partition: ''
|
||||
${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}
|
||||
''}
|
||||
@@ -115,22 +158,25 @@
|
||||
partprobe "${config.device}"
|
||||
udevadm trigger --subsystem-match=block
|
||||
udevadm settle
|
||||
'') config.partitions)}
|
||||
'') config.partitions
|
||||
)}
|
||||
fi
|
||||
${lib.concatStrings (map (partition: ''
|
||||
${lib.concatStrings (
|
||||
map (partition: ''
|
||||
${lib.optionalString (partition.content != null) partition.content._create}
|
||||
'') config.partitions)}
|
||||
'') 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);
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (
|
||||
map (
|
||||
partition: lib.optionalAttrs (partition.content != null) partition.content._mount
|
||||
) config.partitions
|
||||
);
|
||||
in
|
||||
{
|
||||
dev = partMounts.dev or "";
|
||||
@@ -141,11 +187,11 @@
|
||||
inherit config options;
|
||||
default =
|
||||
let
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (map
|
||||
(partition:
|
||||
lib.optionalAttrs (partition.content != null) partition.content._unmount
|
||||
)
|
||||
config.partitions);
|
||||
partMounts = lib.foldr lib.recursiveUpdate { } (
|
||||
map (
|
||||
partition: lib.optionalAttrs (partition.content != null) partition.content._unmount
|
||||
) config.partitions
|
||||
);
|
||||
in
|
||||
{
|
||||
dev = partMounts.dev or "";
|
||||
@@ -155,24 +201,26 @@
|
||||
_config = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default =
|
||||
map
|
||||
(partition:
|
||||
lib.optional (partition.content != null) partition.content._config
|
||||
)
|
||||
config.partitions;
|
||||
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);
|
||||
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,8 +66,7 @@
|
||||
default = true;
|
||||
};
|
||||
|
||||
_create = diskoLib.mkCreateOption
|
||||
{
|
||||
_create = diskoLib.mkCreateOption {
|
||||
inherit config options;
|
||||
# -u prevents mounting newly created datasets, which is
|
||||
# important to prevent accidental shadowing of mount points
|
||||
@@ -67,7 +74,9 @@
|
||||
# -p creates parents automatically
|
||||
default =
|
||||
let
|
||||
createOptions = (lib.optionalAttrs (config.mountpoint != null) { mountpoint = config.mountpoint; }) // config.options;
|
||||
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"
|
||||
@@ -83,16 +92,23 @@
|
||||
in
|
||||
''
|
||||
if ! zfs get type ${config._name} >/dev/null 2>&1; then
|
||||
${if config._createFilesystem then ''
|
||||
${
|
||||
if config._createFilesystem then
|
||||
''
|
||||
zfs create -up ${config._name} \
|
||||
${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "-o ${n}=${v}") (createOptions))}
|
||||
'' else ''
|
||||
''
|
||||
else
|
||||
''
|
||||
# don't create anything for root dataset of zpools
|
||||
true
|
||||
''}
|
||||
${lib.optionalString (updateOptions != {}) ''
|
||||
''
|
||||
}
|
||||
${lib.optionalString (updateOptions != { }) ''
|
||||
else
|
||||
zfs set -u ${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${v}") updateOptions)} ${config._name}
|
||||
zfs set -u ${
|
||||
lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${v}") updateOptions)
|
||||
} ${config._name}
|
||||
''}
|
||||
fi
|
||||
'';
|
||||
@@ -107,7 +123,10 @@
|
||||
zfs load-key ${config._name}
|
||||
fi
|
||||
'';
|
||||
}) // lib.optionalAttrs (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
|
||||
})
|
||||
// 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}" \
|
||||
@@ -125,7 +144,10 @@
|
||||
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") {
|
||||
})
|
||||
// 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}"
|
||||
@@ -138,11 +160,14 @@
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default =
|
||||
lib.optional (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
|
||||
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";
|
||||
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: [
|
||||
default =
|
||||
pkgs:
|
||||
[
|
||||
pkgs.util-linux
|
||||
pkgs.parted # for partprobe
|
||||
] ++ lib.optionals (config.content != null) (config.content._pkgs pkgs);
|
||||
]
|
||||
++ 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,13 +70,17 @@ in
|
||||
};
|
||||
};
|
||||
};
|
||||
type = (lib.types.oneOf [
|
||||
type = (
|
||||
lib.types.oneOf [
|
||||
(lib.types.enum modeOptions)
|
||||
(lib.types.attrsOf (diskoLib.subType {
|
||||
(lib.types.attrsOf (
|
||||
diskoLib.subType {
|
||||
types = {
|
||||
topology =
|
||||
let
|
||||
vdev = lib.types.submodule ({ ... }: {
|
||||
vdev = lib.types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
mode = lib.mkOption {
|
||||
type = lib.types.enum modeOptions;
|
||||
@@ -81,10 +92,12 @@ in
|
||||
description = "Members of the vdev";
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
in
|
||||
lib.types.submodule
|
||||
({ ... }: {
|
||||
lib.types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [ "topology" ];
|
||||
@@ -104,7 +117,10 @@ in
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "x" "y" ];
|
||||
members = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
@@ -119,7 +135,10 @@ in
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Hot_Spares
|
||||
for details.
|
||||
'';
|
||||
example = [ "x" "y" ];
|
||||
example = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
};
|
||||
log = lib.mkOption {
|
||||
type = lib.types.listOf vdev;
|
||||
@@ -132,7 +151,10 @@ in
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "x" "y" ];
|
||||
members = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
@@ -150,7 +172,10 @@ in
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "x" "y" ];
|
||||
members = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
@@ -168,7 +193,10 @@ in
|
||||
example = [
|
||||
{
|
||||
mode = "mirror";
|
||||
members = [ "x" "y" ];
|
||||
members = [
|
||||
"x"
|
||||
"y"
|
||||
];
|
||||
}
|
||||
{
|
||||
members = [ "z" ];
|
||||
@@ -183,14 +211,20 @@ in
|
||||
https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html#Cache_Devices
|
||||
for details.
|
||||
'';
|
||||
example = [ "x" "y" ];
|
||||
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 {
|
||||
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";
|
||||
};
|
||||
};
|
||||
|
45
module.nix
45
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,14 +249,28 @@ in
|
||||
eval-config = import (pkgs.path + "/nixos/lib/eval-config.nix");
|
||||
};
|
||||
|
||||
system.build = (cfg.devices._scripts { inherit pkgs; checked = cfg.checkScripts; }) // (
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
@@ -266,11 +290,8 @@ in
|
||||
|
||||
# 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 ./.))
|
||||
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" ];
|
||||
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, ... }: {
|
||||
(
|
||||
{ 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, ... }: {
|
||||
(
|
||||
{ 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,13 +1,13 @@
|
||||
{ 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-config = pkgs.lib.recursiveUpdate (import ../example/zfs-encrypted-root.nix) {
|
||||
disko.devices.zpool.zroot.datasets.root.options.keylocation = "file:///tmp/secret.key";
|
||||
};
|
||||
extraTestScript = ''
|
||||
@@ -15,4 +15,3 @@ diskoLib.testLib.makeDiskoTest {
|
||||
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