remove nofail mount option, import/export things

This commit is contained in:
Niklas Gollenstede 2023-09-01 17:01:13 +02:00
parent b2cbacc21e
commit e6dff14d73
8 changed files with 14 additions and 53 deletions

View File

@ -24,7 +24,7 @@ nix run .'#'hostname -- --help
```
[`config.installer.commands.*`](./modules/installer.nix.md) can be used to run host-specific commands at various points of the installation, and additional `config.installer.scripts` can [add or replace](./lib/setup-scripts/README.md) new and existing setup commands or functions.
<!-- This mechanism has been used to, for example, [automatically restore of ZFS backups](#TODO) during the installation, or to [automatically deploy](#TODO) locally built system images tp Hetzner VPSes. -->
This mechanism has been used to, for example, <!-- [automatically restore of ZFS backups]() during the installation, or to --> [automatically deploy](https://github.com/NiklasGollenstede/nix-wiplib/blob/master/modules/hardware/hetzner-vps.nix.md#installation--testing) locally built system images tp Hetzner VPSes.
## Repo Layout/Contents

View File

@ -21,7 +21,7 @@ in [ # Run »nix flake show --allow-import-from-derivation« to see what this me
(lib.self.mkSystemsFlake { inherit inputs; buildPlatform = "aarch64-linux"; renameOutputs = name: "arm:${name}"; }) # nixosConfigurations.arm:* apps.*-linux.arm:* devShells.*-linux.arm:* packages.*-linux.arm:all-systems
# Any packages touched by the ./overlays/:
(lib.fun.forEachSystem [ "aarch64-linux" "x86_64-linux" ] (localSystem: let # packages.*-linux.*
packages = lib.fun.getModifiedPackages (lib.fun.importPkgs inputs { system = localSystem; }) overlays;
packages = builtins.removeAttrs (lib.fun.getModifiedPackages (lib.fun.importPkgs inputs { system = localSystem; }) overlays) [ "libblockdev" ];
in { packages = packages // { default = self.packages.${localSystem}.all-systems; }; }))
]); }

View File

@ -117,6 +117,8 @@ in rec {
nixosSystem ? inputs.nixpkgs.lib.nixosSystem,
# If provided, this will be set as »config.nixpkgs.buildPlatform« for all hosts, which in turn enables cross-compilation for all hosts whose »config.nixpkgs.hostPlatform« (the architecture they will run on) does not expand to the same value. Without this, building for other platforms may still work (slowly) if »boot.binfmt.emulatedSystems« on the building system is configured for the respective target(s).
buildPlatform ? null,
## The platforms for which the setup scripts (installation & maintenance/debugging) will be defined. SHould include the ».buildPlatform« and/or the target system's »config.nixpkgs.hostPlatform«.
setupPlatforms ? if inputs?systems then import inputs.systems else [ "aarch64-linux" "x86_64-linux" ],
## If provided, then change the name of each output attribute by passing it through this function. Allows exporting of multiple variants of a repo's hosts from a single flake (by then merging the results):
renameOutputs ? false,
... }: let
@ -130,7 +132,7 @@ in rec {
nixosConfigurations = if builtins.isList systems then mergeAttrsUnique (map (systems: mkNixosConfigurations (otherArgs // systems)) systems) else mkNixosConfigurations (otherArgs // systems);
in let outputs = {
inherit nixosConfigurations;
} // (forEachSystem [ "aarch64-linux" "x86_64-linux" ] (buildSystem: let
} // (forEachSystem setupPlatforms (buildSystem: let
pkgs = (import inputs.nixpkgs { inherit overlays; system = buildSystem; });
tools = lib.unique (map (p: p.outPath) (lib.filter lib.isDerivation pkgs.stdenv.allowedRequisites));
in rec {
@ -156,7 +158,7 @@ in rec {
})); in if renameOutputs == false then outputs else {
nixosConfigurations = mapMergeUnique (k: v: { ${renameOutputs k} = v; }) outputs.nixosConfigurations;
} // (forEachSystem [ "aarch64-linux" "x86_64-linux" ] (buildSystem: {
} // (forEachSystem setupPlatforms (buildSystem: {
apps = mapMergeUnique (k: v: { ${renameOutputs k} = v; }) outputs.apps.${buildSystem};
packages.${renameOutputs "all-systems"} = outputs.packages.${buildSystem}.all-systems;
checks.${renameOutputs "all-systems"} = outputs.checks.${buildSystem}.all-systems;

View File

@ -148,7 +148,7 @@ function run-qemu {
fi
# TODO: network bridging:
#[[ @{config.networking.hostId} =~ ^(.)(.)(.)(.)(.)(.)(.)(.)$ ]] ; mac=$( printf "52:54:%s%s:%s%s:%s%s:%s%s" "${BASH_REMATCH[@]:1}" )
#[[ @{config.networking.hostId} =~ ^(.)(.)(.)(.)(.)(.)(.)(.)$ ]] && mac=$( printf "52:54:%s%s:%s%s:%s%s:%s%s" "${BASH_REMATCH[@]:1}" ) || { echo 'Invalid hostId' &>2 ; return; }
#qemu+=( -netdev bridge,id=enp0s3,macaddr=$mac -device virtio-net-pci,netdev=hn0,id=nic1 )
# To pass a USB device (e.g. a YubiKey for unlocking), add pass »--usb-port=${bus}-${port}«, where bus and port refer to the physical USB port »/sys/bus/usb/devices/${bus}-${port}« (see »lsusb -tvv«). E.g.: »--usb-port=3-1.1.1.4«

View File

@ -1,43 +0,0 @@
# NixOS Modules
A NixOS module is a collection of any number of NixOS option definitions and value assignments to those or other options.
While the set of imported modules, and thereby that of the defined options, is static (in this case starting with the modules passed to `mkNixosSystem` in `../flake.nix`), the value assignments can generally be contingent on other values (as long as there are no logical loops), making for highly flexible system constructions.
Since modules can't be imported (or excluded) dynamically, most modules have an `enable` option, which, if false, effectively disables whatever that module does.
Ultimately, the goal of a NixOS configuration is to build an operating system, which is basically a structured collection of program and configuration files.
To that end, there are a number of pre-defined options (in `nixpkgs`) that collect programs, create and write configuration files (primarily in `/etc`), compose a boot loader, etc.
Other modules use those options to manipulate how the system is built.
## Template
Here is a skeleton structure for writing a new `<module>.nix.md`:
````md
/*
# TODO: title
TODO: documentation
## Implementation
```nix
#*/# end of MarkDown, beginning of NixOS module:
dirname: inputs: { config, pkgs, lib, ... }: let lib = inputs.self.lib.__internal__; in let
prefix = inputs.config.prefix;
cfg = config.${prefix}.${TODO: name};
in {
options.${prefix} = { ${TODO: name} = {
enable = lib.mkEnableOption "TODO: what";
# TODO: more options
}; };
config = lib.mkIf cfg.enable (lib.mkMerge [ ({
# TODO: implementation
}) ]);
}
````

View File

@ -16,11 +16,13 @@ in {
options = {
fileSystems = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule [ { options = {
${preMountCommands} = lib.mkOption { description = ''
Commands to be run as root every time before mounting this filesystem, but after all its dependents were mounted (TODO: or does this run just once per boot?).
Commands to be run as root every time before mounting this filesystem **via systemd**, but after all its dependents were mounted.
This does not order itself before or after `systemd-fsck@''${utils.escapeSystemdPath device}.service`.
This is not implemented for mounts in the initrd (those that are `neededForBoot`) yet.
Note that if a symlink exists at a mount point when systemd's fstab-generator runs, it will read/resolve the symlink and use that as the mount point, resulting in mismatching unit names for that mount, effectively disabling its `${preMountCommands}`.
Note that if a symlink exists at a mount point when systemd's fstab-generator runs, it will read/resolve the symlink and use the link's target as the mount point, resulting in mismatching unit names for that mount, effectively disabling its `.${preMountCommands}`.
This does not (apparently and unfortunately) run when mounting via the `mount` command (and probably not with the `mount` system call either).
''; type = lib.types.lines; default = ""; };
#Also, trying to create the "device" of a "nofail" mount will not work with `mount`, as it will not even attempt to mount anything (and thus not run the `.${preMountCommands}`) if the "device" is missing.
}; } ]);
}; };

View File

@ -18,7 +18,7 @@ The attribute value in the `.keys` keys specification dictates how the key is ac
The format of the key specification is `method[=args]`, where `method` is the suffix of a bash function call `gen-key-<method>` (the default functions are in [`add-key.sh`](../../lib/setup-scripts/add-key.sh), but others could be added to the installer), and `args` is the second argument to the respective function (often a `:` separated list of arguments, but some methods don't need any arguments at all).
Most key generation methods only make sense in some key usage contexts. A `random` key is impossible to provide to unlock the keystore (which it is stored in), but is well suited to unlock other devices (if the keystore has backups); conversely a USB-partition can be used to headlessly unlock the keystore, but would be redundant for any further devices, as it would also be copied into the keystore.
If the module is `enable`d, a partition and LUKS device `keystore-...` gets configured and the contents of the installation time keystore is copied to it (in its entirety, including intermediate or derived keys and those unlocking the keystore itself (TODO: this could be optimized)).
If the module is `enable`d, a partition and LUKS device `keystore-...` gets configured and the contents of the installation time keystore is copied to it (in its entirety, including intermediate or derived keys and those unlocking the keystore itself).
This LUKS device is then configured to be unlocked (using any of the key methods specified for it -- by default, key slot 0 is set to the `hostname`) before anything else during boot, and closed before leaving the initramfs phase.
Any number of other devices may thus specify paths in the keystore as keylocation to be unlocked during boot without needing to prompt for further secrets, and without exposing the keys to the running system.

View File

@ -229,9 +229,9 @@ in {
fileSystems = { # this does get applied early
# (on systems without hardware clock, this allows systemd to provide an at least monolithic time after restarts)
"/var/lib/systemd/timesync" = { device = "/local/var/lib/systemd/timesync"; options = [ "bind" "nofail" ]; }; # TODO: add »neededForBoot = true«?
"/var/lib/systemd/timesync" = { device = "/local/var/lib/systemd/timesync"; options = [ "bind" ]; }; # TODO: add »neededForBoot = true«?
# save persistent timer states
"/var/lib/systemd/timers" = { device = "/local/var/lib/systemd/timers"; options = [ "bind" "nofail" ]; }; # TODO: add »neededForBoot = true«?
"/var/lib/systemd/timers" = { device = "/local/var/lib/systemd/timers"; options = [ "bind" ]; }; # TODO: add »neededForBoot = true«?
};
security.sudo.extraConfig = "Defaults lecture=never"; # default is »once«, but we'd forget that we did that