mirror of
https://github.com/NiklasGollenstede/nixos-installer.git
synced 2024-11-21 23:43:14 +01:00
nixos-23.11: fileSystems.*.format{Options->Args},
other fixes
This commit is contained in:
parent
2bbefc97c3
commit
afc4c9ab9a
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -153,6 +153,7 @@
|
|||||||
"reexec", // option
|
"reexec", // option
|
||||||
"refreservation", // zfs
|
"refreservation", // zfs
|
||||||
"relatime", // mount option
|
"relatime", // mount option
|
||||||
|
"rootfs", // linux
|
||||||
"rpool", // zfs
|
"rpool", // zfs
|
||||||
"sandboxing", // word
|
"sandboxing", // word
|
||||||
"sata", // storage protocol
|
"sata", // storage protocol
|
||||||
|
@ -14,7 +14,5 @@
|
|||||||
installer = "installer"; # config.${installer}
|
installer = "installer"; # config.${installer}
|
||||||
setup = "setup"; # config.${setup}
|
setup = "setup"; # config.${setup}
|
||||||
preface = "preface"; # config.${preface}
|
preface = "preface"; # config.${preface}
|
||||||
extlinux = "extlinux"; # config.boot.loader.${extlinux}
|
|
||||||
preMountCommands = "preMountCommands"; # config.fileSystems.*.${preMountCommands}
|
|
||||||
};
|
};
|
||||||
}; }
|
}; }
|
||||||
|
BIN
flake.lock
BIN
flake.lock
Binary file not shown.
@ -2,7 +2,7 @@
|
|||||||
"Fully automated NixOS CLI installer"
|
"Fully automated NixOS CLI installer"
|
||||||
); inputs = {
|
); inputs = {
|
||||||
|
|
||||||
nixpkgs = { url = "github:NixOS/nixpkgs/nixos-23.05"; };
|
nixpkgs = { url = "github:NixOS/nixpkgs/nixos-23.11"; };
|
||||||
functions = { url = "github:NiklasGollenstede/nix-functions"; inputs.nixpkgs.follows = "nixpkgs"; };
|
functions = { url = "github:NiklasGollenstede/nix-functions"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
config.url = "path:./example/defaultConfig";
|
config.url = "path:./example/defaultConfig";
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ in { preface = { # (any »preface« options have to be defined here)
|
|||||||
|
|
||||||
# Put everything except for /boot and /nix/store on a tmpfs. This is the absolute minimum, most usable systems require some more paths that are persistent (e.g. all of /nix and /home).
|
# Put everything except for /boot and /nix/store on a tmpfs. This is the absolute minimum, most usable systems require some more paths that are persistent (e.g. all of /nix and /home).
|
||||||
fileSystems."/" = { fsType = "tmpfs"; device = "tmpfs"; neededForBoot = true; options = [ "mode=755" ]; };
|
fileSystems."/" = { fsType = "tmpfs"; device = "tmpfs"; neededForBoot = true; options = [ "mode=755" ]; };
|
||||||
fileSystems."/boot" = { fsType = "vfat"; device = "/dev/disk/by-partlabel/boot-${hash}"; neededForBoot = true; options = [ "noatime" ]; formatOptions = "-F 32"; };
|
fileSystems."/boot" = { fsType = "vfat"; device = "/dev/disk/by-partlabel/boot-${hash}"; neededForBoot = true; options = [ "noatime" ]; formatArgs = [ "-F" "32" ]; };
|
||||||
fileSystems."/system" = { fsType = "ext4"; device = "/dev/disk/by-partlabel/system-${hash}"; neededForBoot = true; options = [ "noatime" ]; formatOptions = "-O inline_data -E nodiscard -F"; };
|
fileSystems."/system" = { fsType = "ext4"; device = "/dev/disk/by-partlabel/system-${hash}"; neededForBoot = true; options = [ "noatime" ]; formatArgs = [ "-O" "inline_data" "-E" "nodiscard" "-F" ]; };
|
||||||
fileSystems."/nix/store" = { options = ["bind,ro"]; device = "/system/nix/store"; neededForBoot = true; };
|
fileSystems."/nix/store" = { options = ["bind,ro"]; device = "/system/nix/store"; neededForBoot = true; };
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ in rec {
|
|||||||
# An attrset of imported Nix flakes, for example the argument(s) passed to the flake »outputs« function. All other arguments are optional (and have reasonable defaults) if this is provided and contains »self« and the standard »nixpkgs«. This is also the second argument passed to the individual host's top level config files.
|
# An attrset of imported Nix flakes, for example the argument(s) passed to the flake »outputs« function. All other arguments are optional (and have reasonable defaults) if this is provided and contains »self« and the standard »nixpkgs«. This is also the second argument passed to the individual host's top level config files.
|
||||||
inputs ? { },
|
inputs ? { },
|
||||||
# Arguments »{ files, dir, exclude, }« to »mkNixosConfigurations«, see there for details. May also be a list of those attrsets, in which case those multiple sets of hosts will be built separately by »mkNixosConfigurations«, allowing for separate sets of »peers« passed to »mkNixosConfiguration«. Each call will receive all other arguments, and the resulting sets of hosts will be merged.
|
# Arguments »{ files, dir, exclude, }« to »mkNixosConfigurations«, see there for details. May also be a list of those attrsets, in which case those multiple sets of hosts will be built separately by »mkNixosConfigurations«, allowing for separate sets of »peers« passed to »mkNixosConfiguration«. Each call will receive all other arguments, and the resulting sets of hosts will be merged.
|
||||||
systems ? ({ dir = "${inputs.self}/hosts"; exclude = [ ]; }),
|
systems ? ({ dir = "${inputs.self}/hosts"; exclude = [ ]; }), # TODO: (before nix 2.14) this is not relative to the flake.nix, but relative to the root of the repo
|
||||||
# List of Modules to import for all hosts, in addition to the default ones in »nixpkgs«. The host-individual module should selectively enable these. Defaults to ».nixosModules.default« of all »moduleInputs«/»inputs« (including »inputs.self«).
|
# List of Modules to import for all hosts, in addition to the default ones in »nixpkgs«. The host-individual module should selectively enable these. Defaults to ».nixosModules.default« of all »moduleInputs«/»inputs« (including »inputs.self«).
|
||||||
modules ? (getModulesFromInputs moduleInputs),
|
modules ? (getModulesFromInputs moduleInputs),
|
||||||
# (Subset of) »inputs« that »modules« will be used from. Example: »{ inherit (inputs) self flakeA flakeB; }«.
|
# (Subset of) »inputs« that »modules« will be used from. Example: »{ inherit (inputs) self flakeA flakeB; }«.
|
||||||
|
@ -197,9 +197,8 @@ function format-partitions {
|
|||||||
elif [[ ${fs[device]} == /dev/mapper/* ]] ; then
|
elif [[ ${fs[device]} == /dev/mapper/* ]] ; then
|
||||||
if [[ ! @{config.boot.initrd.luks.devices!catAttrSets.device[${fs[device]/'/dev/mapper/'/}]:-} ]] ; then echo "LUKS device ${fs[device]} used by mount ${fs[mountPoint]} does not point at one of the device mappings ${!config.boot.initrd.luks.devices!catAttrSets.device[@]}" 1>&2 ; \return 1 ; fi
|
if [[ ! @{config.boot.initrd.luks.devices!catAttrSets.device[${fs[device]/'/dev/mapper/'/}]:-} ]] ; then echo "LUKS device ${fs[device]} used by mount ${fs[mountPoint]} does not point at one of the device mappings ${!config.boot.initrd.luks.devices!catAttrSets.device[@]}" 1>&2 ; \return 1 ; fi
|
||||||
else continue ; fi
|
else continue ; fi
|
||||||
#if [[ ${fs[fsType]} == ext4 && ' '${fs[formatOptions]}' ' != *' -F '* ]] ; then fs[formatOptions]+=' -F' ; fi
|
eval 'declare -a formatArgs='"${fs[formatArgs]}"
|
||||||
#if [[ ${fs[fsType]} == f2fs && ' '${fs[formatOptions]}' ' != *' -f '* ]] ; then fs[formatOptions]+=' -f' ; fi
|
( PATH=@{native.e2fsprogs}/bin:@{native.f2fs-tools}/bin:@{native.xfsprogs}/bin:@{native.dosfstools}/bin:$PATH ; ${_set_x:-:} ; mkfs."${fs[fsType]}" "${formatArgs[@]}" "${fs[device]}" >$beLoud 2>$beSilent ) || return
|
||||||
( PATH=@{native.e2fsprogs}/bin:@{native.f2fs-tools}/bin:@{native.xfsprogs}/bin:@{native.dosfstools}/bin:$PATH ; ${_set_x:-:} ; mkfs.${fs[fsType]} ${fs[formatOptions]} "${fs[device]}" >$beLoud 2>$beSilent ) || return
|
|
||||||
@{native.parted}/bin/partprobe "${fs[device]}" || true
|
@{native.parted}/bin/partprobe "${fs[device]}" || true
|
||||||
done
|
done
|
||||||
for swapDev in "@{config.swapDevices!catAttrs.device[@]}" ; do
|
for swapDev in "@{config.swapDevices!catAttrs.device[@]}" ; do
|
||||||
|
@ -121,8 +121,8 @@ function nixos-install-cmd {( # 1: mnt, 2: topLevel
|
|||||||
#PATH=@{native.nix}/bin:$PATH:@{config.systemd.package}/bin TMPDIR=/tmp LC_ALL=C @{native.nixos-install-tools}/bin/nixos-install --system "$2" --no-root-passwd --no-channel-copy --root "$1" || exit # We did most of this, so just install the bootloader:
|
#PATH=@{native.nix}/bin:$PATH:@{config.systemd.package}/bin TMPDIR=/tmp LC_ALL=C @{native.nixos-install-tools}/bin/nixos-install --system "$2" --no-root-passwd --no-channel-copy --root "$1" || exit # We did most of this, so just install the bootloader:
|
||||||
|
|
||||||
export NIXOS_INSTALL_BOOTLOADER=1 # tells some bootloader installers (systemd & grub) to not skip parts of the installation
|
export NIXOS_INSTALL_BOOTLOADER=1 # tells some bootloader installers (systemd & grub) to not skip parts of the installation
|
||||||
#( export LC_ALL=C ; PATH=$PATH:@{native.util-linux}/bin:@{native.nixos-install-tools}/bin/ ; ${_set_x:-:} ; nixos-enter --silent --root "$1" -- @{config.system.build.installBootLoader} "$2" ) || exit
|
LC_ALL=C PATH=@{native.busybox}/bin:$PATH:@{native.util-linux}/bin @{native.nixos-install-tools}/bin/nixos-enter --silent --root "$1" -c "source /etc/set-environment ; ${_set_x:-:} ; @{config.system.build.installBootLoader} $2" || exit
|
||||||
LC_ALL=C PATH=$PATH:@{native.util-linux}/bin @{native.nixos-install-tools}/bin/nixos-enter --silent --root "$1" -c "${_set_x:-:} ; @{config.system.build.installBootLoader} $2" || exit
|
# (newer versions of »mount« seem to be unable to do »--make-private« on »rootfs« (in the initrd), but busybox's mount still works)
|
||||||
)}
|
)}
|
||||||
|
|
||||||
declare-flag install-system toplevel "store-path" "Optional replacement for the actual »config.system.build.toplevel«."
|
declare-flag install-system toplevel "store-path" "Optional replacement for the actual »config.system.build.toplevel«."
|
||||||
@ -142,7 +142,7 @@ function install-system-to {( set -u # 1: mnt, 2?: topLevel
|
|||||||
mkdir -p -m 755 $mnt/nix/var/nix || exit ; mkdir -p -m 1775 $mnt/nix/store || exit
|
mkdir -p -m 755 $mnt/nix/var/nix || exit ; mkdir -p -m 1775 $mnt/nix/store || exit
|
||||||
mkdir -p $mnt/etc $mnt/run || exit ; mkdir -p -m 1777 $mnt/tmp || exit
|
mkdir -p $mnt/etc $mnt/run || exit ; mkdir -p -m 1777 $mnt/tmp || exit
|
||||||
@{native.util-linux}/bin/mount tmpfs -t tmpfs $mnt/run || exit ; prepend_trap "@{native.util-linux}/bin/umount -l $mnt/run" EXIT || exit # If there isn't anything mounted here, »activate« will mount a tmpfs (inside »nixos-enter«'s private mount namespace). That would hide the additions below.
|
@{native.util-linux}/bin/mount tmpfs -t tmpfs $mnt/run || exit ; prepend_trap "@{native.util-linux}/bin/umount -l $mnt/run" EXIT || exit # If there isn't anything mounted here, »activate« will mount a tmpfs (inside »nixos-enter«'s private mount namespace). That would hide the additions below.
|
||||||
[[ -e $mnt/etc/NIXOS ]] || touch $mnt/etc/NIXOS || exit # for »switch-to-configuration«
|
[[ -e $mnt/etc/NIXOS ]] || touch $mnt/etc/NIXOS || exit # for »nixos-enter«
|
||||||
[[ -e $mnt/etc/mtab ]] || ln -sfn /proc/mounts $mnt/etc/mtab || exit
|
[[ -e $mnt/etc/mtab ]] || ln -sfn /proc/mounts $mnt/etc/mtab || exit
|
||||||
ln -sT $( realpath $targetSystem ) $mnt/run/current-system || exit
|
ln -sT $( realpath $targetSystem ) $mnt/run/current-system || exit
|
||||||
#mkdir -p /nix/var/nix/db # »nixos-containers« requires this but nothing creates it before nix is used. BUT »nixos-enter« screams: »/nix/var/nix/db exists and is not a regular file.«
|
#mkdir -p /nix/var/nix/db # »nixos-containers« requires this but nothing creates it before nix is used. BUT »nixos-enter« screams: »/nix/var/nix/db exists and is not a regular file.«
|
||||||
@ -200,7 +200,7 @@ function install-system-to {( set -u # 1: mnt, 2?: topLevel
|
|||||||
else
|
else
|
||||||
( set +x ; echo "[1;32mInstallation done![0m This shell is in a chroot in the mounted system for inspection. Exiting the shell will unmount the system." 1>&2 )
|
( set +x ; echo "[1;32mInstallation done![0m This shell is in a chroot in the mounted system for inspection. Exiting the shell will unmount the system." 1>&2 )
|
||||||
fi
|
fi
|
||||||
LC_ALL=C PATH=$PATH:@{native.util-linux}/bin @{native.nixos-install-tools}/bin/nixos-enter --root $mnt -- /nix/var/nix/profiles/system/sw/bin/bash -c 'source /etc/set-environment ; NIXOS_INSTALL_BOOTLOADER=1 CHROOT_DIR="'"$mnt"'" mnt=/ exec "'"$self"'" bash' || exit # +o monitor
|
LC_ALL=C PATH=@{native.busybox}/bin:$PATH:@{native.util-linux}/bin @{native.nixos-install-tools}/bin/nixos-enter --root $mnt -- /nix/var/nix/profiles/system/sw/bin/bash -c 'source /etc/set-environment ; NIXOS_INSTALL_BOOTLOADER=1 CHROOT_DIR="'"$mnt"'" mnt=/ exec "'"$self"'" bash' || exit # +o monitor
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p $mnt/var/lib/systemd/timesync && touch $mnt/var/lib/systemd/timesync/clock || true # save current time
|
mkdir -p $mnt/var/lib/systemd/timesync && touch $mnt/var/lib/systemd/timesync/clock || true # save current time
|
||||||
|
@ -16,13 +16,13 @@ This uses the same implementation as `boot.loader.generic-extlinux-compatible` t
|
|||||||
```nix
|
```nix
|
||||||
#*/# end of MarkDown, beginning of NixOS module:
|
#*/# end of MarkDown, beginning of NixOS module:
|
||||||
dirname: inputs: args@{ config, options, pkgs, lib, ... }: let lib = inputs.self.lib.__internal__; in let
|
dirname: inputs: args@{ config, options, pkgs, lib, ... }: let lib = inputs.self.lib.__internal__; in let
|
||||||
inherit (inputs.config.rename) setup extlinux;
|
inherit (inputs.config.rename) setup;
|
||||||
cfg = config.boot.loader.${extlinux};
|
cfg = config.boot.loader.extlinux;
|
||||||
targetMount = let path = lib.findFirst (path: config.fileSystems?${path}) "/" (lib.fun.parentPaths cfg.targetDir); in config.fileSystems.${path};
|
targetMount = let path = lib.findFirst (path: config.fileSystems?${path}) "/" (lib.fun.parentPaths cfg.targetDir); in config.fileSystems.${path};
|
||||||
supportedFSes = [ "vfat" "ntfs" "ext2" "ext3" "ext4" "btrfs" "xfs" "ufs" ]; fsSupported = fs: builtins.elem fs supportedFSes;
|
supportedFSes = [ "vfat" "ntfs" "ext2" "ext3" "ext4" "btrfs" "xfs" "ufs" ]; fsSupported = fs: builtins.elem fs supportedFSes;
|
||||||
in {
|
in {
|
||||||
|
|
||||||
options = { boot.loader.${extlinux} = {
|
options = { boot.loader.extlinux = {
|
||||||
enable = lib.mkEnableOption (lib.mdDoc ''
|
enable = lib.mkEnableOption (lib.mdDoc ''
|
||||||
`extlinux`, a simple bootloader for legacy-BIOS environments, like (by default) Qemu.
|
`extlinux`, a simple bootloader for legacy-BIOS environments, like (by default) Qemu.
|
||||||
This uses the same implementation as `boot.loader.generic-extlinux-compatible` to generate the bootloader configuration, but then actually also installs `extlinux` itself, instead of relying on something else (like an externally installed u-boot) to read and execute the configuration.
|
This uses the same implementation as `boot.loader.generic-extlinux-compatible` to generate the bootloader configuration, but then actually also installs `extlinux` itself, instead of relying on something else (like an externally installed u-boot) to read and execute the configuration.
|
||||||
@ -57,17 +57,17 @@ in {
|
|||||||
assertions = [ {
|
assertions = [ {
|
||||||
assertion = cfg.allowInstableTargetPart || (builtins.match ''^/dev/disk/by-(id|label|partlabel|partuuid|uuid)/.*[^/]$'' cfg.targetPart) != null;
|
assertion = cfg.allowInstableTargetPart || (builtins.match ''^/dev/disk/by-(id|label|partlabel|partuuid|uuid)/.*[^/]$'' cfg.targetPart) != null;
|
||||||
message = ''
|
message = ''
|
||||||
`config.boot.loader.${extlinux}.targetPart` is set to `${cfg.targetPart}`, which is not a stable path in `/dev/disk/by-{id,label,partlabel,partuuid,uuid}/`. Not using a unique identifier (or even using a path that can unexpectedly change) is very risky.
|
`config.boot.loader.extlinux.targetPart` is set to `${cfg.targetPart}`, which is not a stable path in `/dev/disk/by-{id,label,partlabel,partuuid,uuid}/`. Not using a unique identifier (or even using a path that can unexpectedly change) is very risky.
|
||||||
'';
|
'';
|
||||||
} {
|
} {
|
||||||
assertion = fsSupported targetMount.fsType;
|
assertion = fsSupported targetMount.fsType;
|
||||||
message = ''
|
message = ''
|
||||||
`config.boot.loader.${extlinux}.targetPart`'s closest mount (`${targetMount.mountPoint}`) is of type `${targetMount.fsType}`, which is not one of extlinux's supported types (${lib.concatStringsSep ", " supportedFSes}).
|
`config.boot.loader.extlinux.targetPart`'s closest mount (`${targetMount.mountPoint}`) is of type `${targetMount.fsType}`, which is not one of extlinux's supported types (${lib.concatStringsSep ", " supportedFSes}).
|
||||||
'';
|
'';
|
||||||
} ];
|
} ];
|
||||||
|
|
||||||
${setup}.bootpart = { enable = lib.mkDefault true; mountpoint = lib.mkDefault cfg.targetDir; };
|
${setup}.bootpart = { enable = lib.mkDefault true; mountpoint = lib.mkDefault cfg.targetDir; };
|
||||||
boot.loader.${extlinux}.allowInstableTargetPart = lib.mkForce false;
|
boot.loader.extlinux.allowInstableTargetPart = lib.mkForce false;
|
||||||
|
|
||||||
system.boot.loader.id = "extlinux";
|
system.boot.loader.id = "extlinux";
|
||||||
system.build.installBootLoader = "${pkgs.writeShellScript "install-extlinux.sh" ''
|
system.build.installBootLoader = "${pkgs.writeShellScript "install-extlinux.sh" ''
|
||||||
@ -107,7 +107,7 @@ in {
|
|||||||
}) (
|
}) (
|
||||||
|
|
||||||
(lib.mkIf (options.virtualisation?useDefaultFilesystems) { # (»nixos/modules/virtualisation/qemu-vm.nix« is imported, i.e. we are building a "vmVariant")
|
(lib.mkIf (options.virtualisation?useDefaultFilesystems) { # (»nixos/modules/virtualisation/qemu-vm.nix« is imported, i.e. we are building a "vmVariant")
|
||||||
boot.loader.${extlinux} = {
|
boot.loader.extlinux = {
|
||||||
enable = lib.mkIf config.virtualisation.useDefaultFilesystems (lib.mkVMOverride false);
|
enable = lib.mkIf config.virtualisation.useDefaultFilesystems (lib.mkVMOverride false);
|
||||||
allowInstableTargetPart = lib.mkVMOverride true; # (»/dev/sdX« etc in the VM are stable (if the VM is invoked the same way))
|
allowInstableTargetPart = lib.mkVMOverride true; # (»/dev/sdX« etc in the VM are stable (if the VM is invoked the same way))
|
||||||
};
|
};
|
||||||
|
1
modules/filesystems/default.nix
Normal file
1
modules/filesystems/default.nix
Normal file
@ -0,0 +1 @@
|
|||||||
|
dirname: inputs@{ self, nixpkgs, ...}: self.lib.__internal__.fun.importModules inputs dirname { }
|
21
modules/filesystems/format-args.nix.md
Normal file
21
modules/filesystems/format-args.nix.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
# `fileSystems.*.formatArgs`
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
|
```nix
|
||||||
|
#*/# end of MarkDown, beginning of NixOS module:
|
||||||
|
dirname: inputs: moduleArgs@{ config, pkgs, lib, utils, ... }: let lib = inputs.self.lib.__internal__; in let
|
||||||
|
inherit (inputs.config.rename) preMountCommands;
|
||||||
|
in {
|
||||||
|
|
||||||
|
options = {
|
||||||
|
fileSystems = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule [ ({ config, ...}@_: { options = {
|
||||||
|
formatArgs = lib.mkOption { description = "Arguments passed to mkfs for this filesystem during OS installation."; type = lib.types.listOf lib.types.str; default = if (lib.isString config.formatOptions or null) then lib.splitString config.formatOptions else [ ]; };
|
||||||
|
}; }) ]);
|
||||||
|
}; };
|
||||||
|
|
||||||
|
# (These are used in »../../lib/setup-scripts/disk.sh#format-partitions«.)
|
||||||
|
|
||||||
|
}
|
@ -1,28 +1,24 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
# Additions to `fileSystems`
|
# `fileSystems.*.preMountCommands`
|
||||||
|
|
||||||
Currently, this just adds `preMountCommands`.
|
|
||||||
|
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
#*/# end of MarkDown, beginning of NixOS module:
|
#*/# end of MarkDown, beginning of NixOS module:
|
||||||
dirname: inputs: moduleArgs@{ config, pkgs, lib, utils, ... }: let lib = inputs.self.lib.__internal__; in let
|
dirname: inputs: moduleArgs@{ config, pkgs, lib, utils, ... }: let lib = inputs.self.lib.__internal__; in let
|
||||||
inherit (inputs.config.rename) preMountCommands;
|
|
||||||
in {
|
in {
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
fileSystems = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule [ { options = {
|
fileSystems = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule [ { options = {
|
||||||
${preMountCommands} = lib.mkOption { description = ''
|
preMountCommands = lib.mkOption { description = ''
|
||||||
Commands to be run as root every time before mounting this filesystem **via systemd**, but after all its dependents were mounted.
|
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 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.
|
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 the link's target 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).
|
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 = ""; };
|
''; 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.
|
#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.
|
||||||
}; } ]);
|
}; } ]);
|
||||||
}; };
|
}; };
|
||||||
|
|
||||||
@ -30,12 +26,12 @@ in {
|
|||||||
in ({
|
in ({
|
||||||
|
|
||||||
assertions = lib.mapAttrsToList (name: fs: {
|
assertions = lib.mapAttrsToList (name: fs: {
|
||||||
assertion = (fs.${preMountCommands} == "") || (!utils.fsNeededForBoot fs);
|
assertion = (fs.preMountCommands == "") || (!utils.fsNeededForBoot fs);
|
||||||
message = ''The filesystem "${name}" has `.${preMountCommands}` but is also (possibly implicitly) `.neededForBoot`. This is not currently supported.'';
|
message = ''The filesystem "${name}" has `.preMountCommands` but is also (possibly implicitly) `.neededForBoot`. This is not currently supported.'';
|
||||||
}) config.fileSystems;
|
}) config.fileSystems;
|
||||||
|
|
||||||
# The implementation is derived from the "mkfs-${device'}" service in nixpkgs.
|
# The implementation is derived from the "mkfs-${device'}" service in nixpkgs.
|
||||||
systemd.services = lib.fun.mapMergeUnique (_: args@{ mountPoint, device, depends, ... }: if (args.${preMountCommands} != "") then let
|
systemd.services = lib.fun.mapMergeUnique (_: args@{ mountPoint, device, depends, ... }: if (args.preMountCommands != "") then let
|
||||||
isDevice = lib.fun.startsWith "/dev/" device;
|
isDevice = lib.fun.startsWith "/dev/" device;
|
||||||
mountPoint' = utils.escapeSystemdPath mountPoint;
|
mountPoint' = utils.escapeSystemdPath mountPoint;
|
||||||
device' = utils.escapeSystemdPath device;
|
device' = utils.escapeSystemdPath device;
|
||||||
@ -45,7 +41,7 @@ in {
|
|||||||
requires = lib.optional isDevice "${device'}.device"; after = lib.optional isDevice "${device'}.device";
|
requires = lib.optional isDevice "${device'}.device"; after = lib.optional isDevice "${device'}.device";
|
||||||
unitConfig.RequiresMountsFor = depends ++ [ (builtins.dirOf device) (builtins.dirOf mountPoint) ];
|
unitConfig.RequiresMountsFor = depends ++ [ (builtins.dirOf device) (builtins.dirOf mountPoint) ];
|
||||||
unitConfig.DefaultDependencies = false;
|
unitConfig.DefaultDependencies = false;
|
||||||
serviceConfig.Type = "oneshot"; script = args.${preMountCommands};
|
serviceConfig.Type = "oneshot"; script = args.preMountCommands;
|
||||||
}; } else { }) config.fileSystems;
|
}; } else { }) config.fileSystems;
|
||||||
|
|
||||||
});
|
});
|
@ -32,7 +32,7 @@ in {
|
|||||||
a;1 # active/boot ; part1
|
a;1 # active/boot ; part1
|
||||||
''; }; };
|
''; }; };
|
||||||
};
|
};
|
||||||
fileSystems.${cfg.mountpoint} = { fsType = "vfat"; device = "/dev/disk/by-partlabel/boot-${hash}"; neededForBoot = true; options = [ "nosuid" "nodev" "noexec" "noatime" "umask=0027" "discard" ]; formatOptions = "-F 32"; };
|
fileSystems.${cfg.mountpoint} = { fsType = "vfat"; device = "/dev/disk/by-partlabel/boot-${hash}"; neededForBoot = true; options = [ "nosuid" "nodev" "noexec" "noatime" "umask=0027" "discard" ]; formatArgs = [ "-F" "32" ]; };
|
||||||
|
|
||||||
}) ]);
|
}) ]);
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ in let module = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Create and populate keystore during installation:
|
# Create and populate keystore during installation:
|
||||||
fileSystems.${keystore} = { fsType = "vfat"; device = "/dev/mapper/keystore-${hash}"; options = [ "ro" "nosuid" "nodev" "noexec" "noatime" "umask=0277" "noauto" ]; formatOptions = ""; };
|
fileSystems.${keystore} = { fsType = "vfat"; device = "/dev/mapper/keystore-${hash}"; options = [ "ro" "nosuid" "nodev" "noexec" "noatime" "umask=0277" "noauto" ]; formatArgs = [ ]; };
|
||||||
|
|
||||||
${setup}.disks.partitions."keystore-${hash}" = { type = lib.mkDefault "8309"; order = lib.mkDefault 1375; disk = lib.mkDefault "primary"; size = lib.mkDefault "32M"; };
|
${setup}.disks.partitions."keystore-${hash}" = { type = lib.mkDefault "8309"; order = lib.mkDefault 1375; disk = lib.mkDefault "primary"; size = lib.mkDefault "32M"; };
|
||||||
${installer}.commands.postFormat = ''( : 'Copy the live keystore to its primary persistent location:'
|
${installer}.commands.postFormat = ''( : 'Copy the live keystore to its primary persistent location:'
|
||||||
|
@ -296,14 +296,14 @@ in {
|
|||||||
fileSystems.${cfg.local.bind.source} = {
|
fileSystems.${cfg.local.bind.source} = {
|
||||||
fsType = fsType; device = "/dev/${if encrypted then "mapper" else "disk/by-partlabel"}/local-${hash}";
|
fsType = fsType; device = "/dev/${if encrypted then "mapper" else "disk/by-partlabel"}/local-${hash}";
|
||||||
} // (if fsType == "f2fs" then {
|
} // (if fsType == "f2fs" then {
|
||||||
formatOptions = (lib.concatStrings [
|
formatArgs = [
|
||||||
" -O extra_attr" # required by other options
|
"-O" "extra_attr" # required by other options
|
||||||
",inode_checksum" # enable inode checksum
|
"-O" "inode_checksum" # enable inode checksum
|
||||||
",sb_checksum" # enable superblock checksum
|
"-O" "sb_checksum" # enable superblock checksum
|
||||||
",compression" # allow compression
|
"-O" "compression" # allow compression
|
||||||
#"-w ?" # "sector size in bytes"
|
#"-w ?" # "sector size in bytes"
|
||||||
# sector ? segments < section < zone
|
# sector ? segments < section < zone
|
||||||
]);
|
];
|
||||||
options = optionsToList (cfg.local.mountOptions // {
|
options = optionsToList (cfg.local.mountOptions // {
|
||||||
# F2FS compresses only for performance and wear. The whole uncompressed space is still reserved (in case the file content needs to get replaced by incompressible data in-place). To free the gained space, »ioctl(fd, F2FS_IOC_RELEASE_COMPRESS_BLOCKS)« needs to be called per file, making the file immutable. Nix could do that when moving stuff into the store.
|
# F2FS compresses only for performance and wear. The whole uncompressed space is still reserved (in case the file content needs to get replaced by incompressible data in-place). To free the gained space, »ioctl(fd, F2FS_IOC_RELEASE_COMPRESS_BLOCKS)« needs to be called per file, making the file immutable. Nix could do that when moving stuff into the store.
|
||||||
compress_mode = "fs"; # enable compression for all files
|
compress_mode = "fs"; # enable compression for all files
|
||||||
@ -313,16 +313,16 @@ in {
|
|||||||
discard = true;
|
discard = true;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
formatOptions = (lib.concatStrings [
|
formatArgs = [
|
||||||
" -O inline_data" # embed data of small files in the top-level inode
|
"-O" "inline_data" # embed data of small files in the top-level inode
|
||||||
",has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize" # (ext4 default options)
|
#"-O" "has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize" # (ext4 defaults, no need to set again)
|
||||||
#",lazy_journal_init,lazy_itable_init" # speed up creation (but: Invalid filesystem option set)
|
#"-O" "lazy_journal_init,lazy_itable_init" # speed up creation (but: Invalid filesystem option set)
|
||||||
" -I 256" # inode size (ext default, allows for timestamps past 2038)
|
"-I" "256" # inode size (ext default, allows for timestamps past 2038)
|
||||||
" -i 16384" # create one inode per 16k bytes of disk (ext default)
|
"-i" "16384" # create one inode per 16k bytes of disk (ext default)
|
||||||
" -b 4096" # block size (ext default)
|
"-b" "4096" # block size (ext default)
|
||||||
" -E nodiscard" # do not trim the whole blockdev upon formatting
|
"-E" "nodiscard" # do not trim the whole blockdev upon formatting
|
||||||
" -e panic" # when (critical?) FS errors are detected, reset the system
|
"-e" "panic" # when (critical?) FS errors are detected, reset the system
|
||||||
]); options = optionsToList (cfg.local.mountOptions // {
|
]; options = optionsToList (cfg.local.mountOptions // {
|
||||||
discard = true;
|
discard = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -342,7 +342,7 @@ in {
|
|||||||
) ++ [ (rec {
|
) ++ [ (rec {
|
||||||
device = "${cfg.${type}.bind.source}/${source}";
|
device = "${cfg.${type}.bind.source}/${source}";
|
||||||
options = optionsToList (cfg.${type}.mountOptions // args.options // { bind = true; });
|
options = optionsToList (cfg.${type}.mountOptions // args.options // { bind = true; });
|
||||||
${preMountCommands} = lib.mkIf (!extraFsConfig.neededForBoot && !(lib.elem target utils.pathsNeededForBoot)) ''
|
preMountCommands = lib.mkIf (!extraFsConfig.neededForBoot && !(lib.elem target utils.pathsNeededForBoot)) ''
|
||||||
mkdir -pm 000 -- ${lib.escapeShellArg target}
|
mkdir -pm 000 -- ${lib.escapeShellArg target}
|
||||||
mkdir -pm 000 -- ${lib.escapeShellArg device}
|
mkdir -pm 000 -- ${lib.escapeShellArg device}
|
||||||
chown ${toString uid}:${toString gid} -- ${lib.escapeShellArg device}
|
chown ${toString uid}:${toString gid} -- ${lib.escapeShellArg device}
|
||||||
|
Loading…
Reference in New Issue
Block a user