mirror of
https://github.com/nix-community/disko
synced 2024-11-14 16:17:06 +00:00
disko2: Add basic config evaluation via nushell
You can call it like so: ./disko.nu mount example/simple-efi.nix ./disko.nu mount -f .#testmachine and it will output a JSON representation of the evaluated disko configuration. eval-config.nix is based on cli.nix The test script is a first attempt.
This commit is contained in:
parent
d7d57edb72
commit
3d67130ff3
4 changed files with 421 additions and 0 deletions
|
@ -17,6 +17,7 @@ let
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
inherit eval;
|
||||||
lib = lib.warn "the .lib.lib output is deprecated" diskoLib;
|
lib = lib.warn "the .lib.lib output is deprecated" diskoLib;
|
||||||
|
|
||||||
# legacy alias
|
# legacy alias
|
||||||
|
|
96
disko.nu
Executable file
96
disko.nu
Executable file
|
@ -0,0 +1,96 @@
|
||||||
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
|
use std log
|
||||||
|
|
||||||
|
alias nix = ^nix --extra-experimental-features nix-command --extra-experimental-features flakes
|
||||||
|
alias nix-eval-expr = nix eval --impure --json --expr
|
||||||
|
|
||||||
|
def eval-config [args: record]: nothing -> record {
|
||||||
|
do { nix-eval-expr $"import ./eval-config.nix \(builtins.fromJSON ''($args | to json -r)'')" }
|
||||||
|
| complete
|
||||||
|
| if $in.exit_code != 0 {
|
||||||
|
{
|
||||||
|
success: false
|
||||||
|
messages: [
|
||||||
|
$"Failed to evaluate disko config with args ($args)!"
|
||||||
|
$"Error from nix eval: ($in.stderr)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$in.stdout
|
||||||
|
| from json
|
||||||
|
| {
|
||||||
|
success: true
|
||||||
|
value: $in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export def eval-disko-file []: path -> record {
|
||||||
|
let config = $in
|
||||||
|
# If the file is valid JSON, parse and return it
|
||||||
|
open $config | try { into record } | if $in != null {
|
||||||
|
return {
|
||||||
|
success: true
|
||||||
|
value: $in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eval-config { diskoFile: $config }
|
||||||
|
}
|
||||||
|
|
||||||
|
export def eval-flake []: string -> record {
|
||||||
|
let flakeUri = $in
|
||||||
|
let parseResult = $flakeUri | parse "{flake}#{flakeAttr}" | if not ( $in | is-empty ) {
|
||||||
|
$in
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
success: false
|
||||||
|
messages: [
|
||||||
|
$"Flake-uri ($flakeUri) does not contain an attribute."
|
||||||
|
"Please append an attribute like \"#foo\" to the flake-uri."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let flake = $parseResult.0.flake | if ($in | path exists) { $in | path expand } else { $in }
|
||||||
|
let flakeAttr = $parseResult.0.flakeAttr
|
||||||
|
|
||||||
|
eval-config { flake: $flake, flakeAttr: $flakeAttr }
|
||||||
|
}
|
||||||
|
|
||||||
|
def exit-on-error [context: string] {
|
||||||
|
if $in.success {
|
||||||
|
log debug $"Success: ($context)"
|
||||||
|
log debug $"Return value: ($in.value)"
|
||||||
|
return $in.value
|
||||||
|
}
|
||||||
|
|
||||||
|
log error $"Failed: ($context)"
|
||||||
|
for msg in $in.messages {
|
||||||
|
log error $msg
|
||||||
|
}
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
def modes [] { ["destroy", "format", "mount", "format,mount", "destroy,format,mount"]}
|
||||||
|
|
||||||
|
def main [
|
||||||
|
mode: string@modes, # Mode to use. Allowed values are 'destroy', 'format', 'mount', 'format,mount', 'destroy,format,mount'
|
||||||
|
disko_file?: path, # File to read the disko configuration from. Can be a .nix file or a .json file
|
||||||
|
--flake (-f): string # Flake URI to search for the disko configuration
|
||||||
|
] {
|
||||||
|
|
||||||
|
if not ($flake != null xor $disko_file != null) {
|
||||||
|
log error "Either --flake or disko_file must be provided"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
let config = if $disko_file != null {
|
||||||
|
$disko_file | eval-disko-file | exit-on-error "eval-config"
|
||||||
|
} else {
|
||||||
|
$flake | eval-flake | exit-on-error "eval-flake"
|
||||||
|
}
|
||||||
|
|
||||||
|
$config | to json | print
|
||||||
|
}
|
275
disko.test.nu
Executable file
275
disko.test.nu
Executable file
|
@ -0,0 +1,275 @@
|
||||||
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
|
use disko.nu
|
||||||
|
|
||||||
|
use std assert
|
||||||
|
|
||||||
|
assert equal ("example/simple-efi.nix" | path expand | disko eval-disko-file) {
|
||||||
|
success: true,
|
||||||
|
value: {
|
||||||
|
"disk": {
|
||||||
|
"main": {
|
||||||
|
"content": {
|
||||||
|
"device": "/dev/disk/by-id/some-disk-id",
|
||||||
|
"efiGptPartitionFirst": true,
|
||||||
|
"partitions": {
|
||||||
|
"ESP": {
|
||||||
|
"alignment": 0,
|
||||||
|
"content": {
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-main-ESP",
|
||||||
|
"extraArgs": [],
|
||||||
|
"format": "vfat",
|
||||||
|
"mountOptions": [
|
||||||
|
"umask=0077"
|
||||||
|
],
|
||||||
|
"mountpoint": "/boot",
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "filesystem"
|
||||||
|
},
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-main-ESP",
|
||||||
|
"end": "+500M",
|
||||||
|
"hybrid": null,
|
||||||
|
"label": "disk-main-ESP",
|
||||||
|
"name": "ESP",
|
||||||
|
"priority": 1000,
|
||||||
|
"size": "500M",
|
||||||
|
"start": "0",
|
||||||
|
"type": "EF00"
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"alignment": 0,
|
||||||
|
"content": {
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-main-root",
|
||||||
|
"extraArgs": [],
|
||||||
|
"format": "ext4",
|
||||||
|
"mountOptions": [
|
||||||
|
"defaults"
|
||||||
|
],
|
||||||
|
"mountpoint": "/",
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "filesystem"
|
||||||
|
},
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-main-root",
|
||||||
|
"end": "-0",
|
||||||
|
"hybrid": null,
|
||||||
|
"label": "disk-main-root",
|
||||||
|
"name": "root",
|
||||||
|
"priority": 9001,
|
||||||
|
"size": "100%",
|
||||||
|
"start": "0",
|
||||||
|
"type": "8300"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "gpt"
|
||||||
|
},
|
||||||
|
"device": "/dev/disk/by-id/some-disk-id",
|
||||||
|
"imageName": "main",
|
||||||
|
"imageSize": "2G",
|
||||||
|
"name": "main",
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "disk"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lvm_vg": {},
|
||||||
|
"mdadm": {},
|
||||||
|
"nodev": {},
|
||||||
|
"zpool": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert equal ("example/with-lib.nix" | path expand | disko eval-disko-file) {
|
||||||
|
success: true,
|
||||||
|
value: {
|
||||||
|
"disk": {
|
||||||
|
"/dev/vdb": {
|
||||||
|
"content": {
|
||||||
|
"device": "/dev/vdb",
|
||||||
|
"efiGptPartitionFirst": true,
|
||||||
|
"partitions": {
|
||||||
|
"boot": {
|
||||||
|
"alignment": 0,
|
||||||
|
"content": null,
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-_dev_vdb-boot",
|
||||||
|
"end": "+1M",
|
||||||
|
"hybrid": null,
|
||||||
|
"label": "disk-_dev_vdb-boot",
|
||||||
|
"name": "boot",
|
||||||
|
"priority": 100,
|
||||||
|
"size": "1M",
|
||||||
|
"start": "0",
|
||||||
|
"type": "EF02"
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"alignment": 0,
|
||||||
|
"content": {
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-_dev_vdb-root",
|
||||||
|
"extraArgs": [],
|
||||||
|
"format": "ext4",
|
||||||
|
"mountOptions": [
|
||||||
|
"defaults"
|
||||||
|
],
|
||||||
|
"mountpoint": "/",
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "filesystem"
|
||||||
|
},
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-_dev_vdb-root",
|
||||||
|
"end": "-0",
|
||||||
|
"hybrid": null,
|
||||||
|
"label": "disk-_dev_vdb-root",
|
||||||
|
"name": "root",
|
||||||
|
"priority": 9001,
|
||||||
|
"size": "100%",
|
||||||
|
"start": "0",
|
||||||
|
"type": "8300"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "gpt"
|
||||||
|
},
|
||||||
|
"device": "/dev/vdb",
|
||||||
|
"imageName": "_dev_vdb",
|
||||||
|
"imageSize": "2G",
|
||||||
|
"name": "_dev_vdb",
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "disk"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lvm_vg": {},
|
||||||
|
"mdadm": {},
|
||||||
|
"nodev": {},
|
||||||
|
"zpool": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert equal (".#testmachine" | disko eval-flake) {
|
||||||
|
success: true,
|
||||||
|
value: {
|
||||||
|
"disk": {
|
||||||
|
"main": {
|
||||||
|
"content": {
|
||||||
|
"device": "/dev/disk/by-id/ata-Samsung_SSD_850_EVO_250GB_S21PNXAGB12345",
|
||||||
|
"efiGptPartitionFirst": true,
|
||||||
|
"partitions": {
|
||||||
|
"ESP": {
|
||||||
|
"alignment": 0,
|
||||||
|
"content": {
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-main-ESP",
|
||||||
|
"extraArgs": [],
|
||||||
|
"format": "vfat",
|
||||||
|
"mountOptions": [
|
||||||
|
"umask=0077"
|
||||||
|
],
|
||||||
|
"mountpoint": "/boot",
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "filesystem"
|
||||||
|
},
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-main-ESP",
|
||||||
|
"end": "+512M",
|
||||||
|
"hybrid": null,
|
||||||
|
"label": "disk-main-ESP",
|
||||||
|
"name": "ESP",
|
||||||
|
"priority": 1000,
|
||||||
|
"size": "512M",
|
||||||
|
"start": "0",
|
||||||
|
"type": "EF00"
|
||||||
|
},
|
||||||
|
"boot": {
|
||||||
|
"alignment": 0,
|
||||||
|
"content": null,
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-main-boot",
|
||||||
|
"end": "+1M",
|
||||||
|
"hybrid": null,
|
||||||
|
"label": "disk-main-boot",
|
||||||
|
"name": "boot",
|
||||||
|
"priority": 100,
|
||||||
|
"size": "1M",
|
||||||
|
"start": "0",
|
||||||
|
"type": "EF02"
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"alignment": 0,
|
||||||
|
"content": {
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-main-root",
|
||||||
|
"extraArgs": [],
|
||||||
|
"format": "ext4",
|
||||||
|
"mountOptions": [
|
||||||
|
"defaults"
|
||||||
|
],
|
||||||
|
"mountpoint": "/",
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "filesystem"
|
||||||
|
},
|
||||||
|
"device": "/dev/disk/by-partlabel/disk-main-root",
|
||||||
|
"end": "-0",
|
||||||
|
"hybrid": null,
|
||||||
|
"label": "disk-main-root",
|
||||||
|
"name": "root",
|
||||||
|
"priority": 9001,
|
||||||
|
"size": "100%",
|
||||||
|
"start": "0",
|
||||||
|
"type": "8300"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "gpt"
|
||||||
|
},
|
||||||
|
"device": "/dev/disk/by-id/ata-Samsung_SSD_850_EVO_250GB_S21PNXAGB12345",
|
||||||
|
"imageName": "main",
|
||||||
|
"imageSize": "2G",
|
||||||
|
"name": "main",
|
||||||
|
"postCreateHook": "",
|
||||||
|
"postMountHook": "",
|
||||||
|
"preCreateHook": "",
|
||||||
|
"preMountHook": "",
|
||||||
|
"type": "disk"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lvm_vg": {},
|
||||||
|
"mdadm": {},
|
||||||
|
"nodev": {},
|
||||||
|
"zpool": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert equal ("." | disko eval-flake) {
|
||||||
|
success: false,
|
||||||
|
messages: [
|
||||||
|
"Flake-uri . does not contain an attribute.",
|
||||||
|
"Please append an attribute like \"#foo\" to the flake-uri."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
def main [] {
|
||||||
|
echo "All tests passed"
|
||||||
|
}
|
49
eval-config.nix
Normal file
49
eval-config.nix
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{ pkgs ? import <nixpkgs> { }
|
||||||
|
, lib ? pkgs.lib
|
||||||
|
, flake ? null
|
||||||
|
, flakeAttr ? null
|
||||||
|
, diskoFile ? null
|
||||||
|
, rootMountPoint ? "/mnt"
|
||||||
|
, ...
|
||||||
|
}@args:
|
||||||
|
let
|
||||||
|
disko = import ./. {
|
||||||
|
inherit rootMountPoint;
|
||||||
|
inherit lib;
|
||||||
|
};
|
||||||
|
|
||||||
|
flake' = (builtins.getFlake flake);
|
||||||
|
|
||||||
|
hasDiskoFile = diskoFile != null;
|
||||||
|
|
||||||
|
hasFlakeDiskoConfig = lib.hasAttrByPath [ "diskoConfigurations" flakeAttr ] flake';
|
||||||
|
|
||||||
|
hasFlakeDiskoModule =
|
||||||
|
lib.hasAttrByPath [ "nixosConfigurations" flakeAttr "config" "disko" "devices" ] flake';
|
||||||
|
|
||||||
|
diskFormat =
|
||||||
|
let
|
||||||
|
diskoConfig =
|
||||||
|
if hasDiskoFile then
|
||||||
|
import diskoFile
|
||||||
|
else
|
||||||
|
flake'.diskoConfigurations.${flakeAttr};
|
||||||
|
in
|
||||||
|
if builtins.isFunction diskoConfig then
|
||||||
|
diskoConfig ({ inherit lib; } // args)
|
||||||
|
else
|
||||||
|
diskoConfig;
|
||||||
|
|
||||||
|
evaluatedConfig =
|
||||||
|
if hasDiskoFile || hasFlakeDiskoConfig then
|
||||||
|
disko.eval diskFormat
|
||||||
|
else if (lib.traceValSeq hasFlakeDiskoModule) then
|
||||||
|
flake'.nixosConfigurations.${flakeAttr}
|
||||||
|
else
|
||||||
|
(builtins.abort "couldn't find `diskoConfigurations.${flakeAttr}` or `nixosConfigurations.${flakeAttr}.config.disko.devices`");
|
||||||
|
|
||||||
|
diskoConfig = evaluatedConfig.config.disko.devices;
|
||||||
|
|
||||||
|
finalConfig = lib.filterAttrsRecursive (name: value: !lib.hasPrefix "_" name) diskoConfig;
|
||||||
|
in
|
||||||
|
finalConfig
|
Loading…
Reference in a new issue