Initial import
This commit is contained in:
commit
25a131eba5
18 changed files with 947 additions and 0 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Hidden files
|
||||||
|
.*
|
||||||
|
!.git*
|
||||||
|
|
||||||
|
# Nix
|
||||||
|
/result
|
111
flake.lock
Normal file
111
flake.lock
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1710146030,
|
||||||
|
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flakey-profile": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1712898590,
|
||||||
|
"narHash": "sha256-FhGIEU93VHAChKEXx905TSiPZKga69bWl1VB37FK//I=",
|
||||||
|
"owner": "lf-",
|
||||||
|
"repo": "flakey-profile",
|
||||||
|
"rev": "243c903fd8eadc0f63d205665a92d4df91d42d9d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "lf-",
|
||||||
|
"repo": "flakey-profile",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lix": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1720626042,
|
||||||
|
"narHash": "sha256-f8k+BezKdJfmE+k7zgBJiohtS3VkkriycdXYsKOm3sc=",
|
||||||
|
"rev": "2a4376be20d70feaa2b0e640c5041fb66ddc67ed",
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/2a4376be20d70feaa2b0e640c5041fb66ddc67ed.tar.gz"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://git.lix.systems/lix-project/lix/archive/2.90.0.tar.gz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lix-module": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"flakey-profile": "flakey-profile",
|
||||||
|
"lix": "lix",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1720641669,
|
||||||
|
"narHash": "sha256-yEO2cGNgzm9x/XxiDQI+WckSWnZX63R8aJLBRSXtYNE=",
|
||||||
|
"rev": "5c48c833c15bb80d127a398a8c2484d42fdd8257",
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/5c48c833c15bb80d127a398a8c2484d42fdd8257.tar.gz"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://git.lix.systems/lix-project/nixos-module/archive/2.90.0.tar.gz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1721379653,
|
||||||
|
"narHash": "sha256-8MUgifkJ7lkZs3u99UDZMB4kbOxvMEXQZ31FO3SopZ0=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "1d9c2c9b3e71b9ee663d11c5d298727dace8d374",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"lix-module": "lix-module",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
62
flake.nix
Normal file
62
flake.nix
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
||||||
|
|
||||||
|
lix-module = {
|
||||||
|
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.90.0.tar.gz";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixConfig = {
|
||||||
|
extra-substituters = [
|
||||||
|
"https://cache.kyouma.net"
|
||||||
|
"https://cache.cyberchaos.dev/musl"
|
||||||
|
];
|
||||||
|
|
||||||
|
extra-trusted-public-keys = [
|
||||||
|
"cache.kyouma.net:Frjwu4q1rnwE/MnSTmX9yx86GNA/z3p/oElGvucLiZg="
|
||||||
|
"musl:6lUuur6Gv7UwNit/ywRRUl+lElUnLmUJEgUTZLGCI2s="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, lix-module, ... }@inputs:
|
||||||
|
let
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
|
||||||
|
platforms = builtins.mapAttrs
|
||||||
|
(_: platform: lib.systems.elaborate platform)
|
||||||
|
(import ./platforms.nix);
|
||||||
|
|
||||||
|
modules = lib.attrNames (builtins.readDir ./modules);
|
||||||
|
modName = lib.removeSuffix ".nix";
|
||||||
|
in {
|
||||||
|
overlays.default = import ./overlay.nix;
|
||||||
|
legacyPackages = builtins.mapAttrs (name: platform:
|
||||||
|
import nixpkgs {
|
||||||
|
localSystem = builtins.currentSystem or platform.system;
|
||||||
|
crossSystem = platform;
|
||||||
|
overlays = [
|
||||||
|
self.overlays.default
|
||||||
|
lix-module.overlays.default
|
||||||
|
];
|
||||||
|
|
||||||
|
config.allowUnfree = true;
|
||||||
|
}) platforms;
|
||||||
|
|
||||||
|
nixosModules = builtins.listToAttrs
|
||||||
|
(builtins.map (mod: { name = modName mod; value = import ./modules/${mod}; }) modules)
|
||||||
|
// { default = { ... }: { imports = map (mod: self.nixosModules.${modName mod}) modules; }; };
|
||||||
|
|
||||||
|
nixosConfigurations = builtins.mapAttrs (_: platform: lib.nixosSystem {
|
||||||
|
specialArgs = { pkgs = self.legacyPackages.${platform.system}; };
|
||||||
|
modules = [ self.nixosModules.default ./nixos.nix ];
|
||||||
|
}) platforms;
|
||||||
|
|
||||||
|
hydraJobs = {
|
||||||
|
nixosConfigurations = builtins.mapAttrs
|
||||||
|
(_: host: host.config.system.build.vm)
|
||||||
|
self.nixosConfigurations;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
94
modules/btrfs.nix
Normal file
94
modules/btrfs.nix
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
optionalString
|
||||||
|
|
||||||
|
mkOption
|
||||||
|
types;
|
||||||
|
|
||||||
|
cfg = config.idiosyn.btrfs;
|
||||||
|
|
||||||
|
btrfs-scrub = pkgs.writeShellApplication {
|
||||||
|
name = "btrfs-scrub";
|
||||||
|
runtimeInputs = with pkgs; [ util-linux btrfs-progs ];
|
||||||
|
text = ''
|
||||||
|
findmnt --noheadings --output "SOURCE" --types btrfs --nofsroot | sort -u \
|
||||||
|
| xargs -n 1 -P "$(nproc)" -r btrfs scrub start -B
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
btrfs-balance = pkgs.writeShellApplication {
|
||||||
|
name = "btrfs-balance";
|
||||||
|
runtimeInputs = with pkgs; [ util-linux btrfs-progs ];
|
||||||
|
text = ''
|
||||||
|
findmnt --types btrfs --output "SOURCE" --nofsroot --noheading | sort -u \
|
||||||
|
| xargs -n 1 -r findmnt --first-only --noheadings --output "TARGET" --types btrfs --source \
|
||||||
|
| xargs -n 1 -P "$(nproc)" -r btrfs balance start${optionalString (cfg.balance.dataUsage != null) " -dusage=${toString cfg.balance.dataUsage}"}${optionalString (cfg.balance.metadataUsage != null) " -musage=${toString cfg.balance.metadataUsage}"}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
idiosyn.btrfs = {
|
||||||
|
scrub.timer = mkOption {
|
||||||
|
type = with types; nullOr nonEmptyStr;
|
||||||
|
default = null;
|
||||||
|
example = "weekly";
|
||||||
|
description = ''
|
||||||
|
Realtime (wallclock) timer for regular scrubs
|
||||||
|
|
||||||
|
See {manpage}systemd.time(7).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
balance = {
|
||||||
|
timer = mkOption {
|
||||||
|
type = with types; nullOr nonEmptyStr;
|
||||||
|
default = null;
|
||||||
|
example = "weekly";
|
||||||
|
description = ''
|
||||||
|
Realtime (wallclock) timer for regular balances.
|
||||||
|
|
||||||
|
See {manpage}systemd.time(7).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataUsage = mkOption {
|
||||||
|
type = with types; nullOr (ints.between 0 100);
|
||||||
|
default = 10;
|
||||||
|
description = ''
|
||||||
|
Balance only data block groups with usage below the given percentage.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
metadataUsage = mkOption {
|
||||||
|
type = with types; nullOr (ints.between 0 100);
|
||||||
|
default = 5;
|
||||||
|
description = ''
|
||||||
|
Balance only metadata block groups with usage below the given percentage.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
systemd.services.btrfs-scrub = lib.mkIf (cfg.scrub.timer != null) {
|
||||||
|
startAt = cfg.scrub.timer;
|
||||||
|
unitConfig.ConditionACPower = true;
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "exec";
|
||||||
|
ExecStart = "${btrfs-scrub}/bin/btrfs-scrub";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.btrfs-balance = lib.mkIf (cfg.balance.timer != null) {
|
||||||
|
startAt = cfg.balance.timer;
|
||||||
|
unitConfig.ConditionACPower = true;
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "exec";
|
||||||
|
ExecStart = "${btrfs-balance}/bin/btrfs-balance";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
16
modules/datacow.nix
Normal file
16
modules/datacow.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.services;
|
||||||
|
|
||||||
|
noDataCow = dir: ''
|
||||||
|
mkdir -p ${lib.escapeShellArg dir}
|
||||||
|
${pkgs.e2fsprogs}/bin/chattr +C ${lib.escapeShellArg dir}
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
config = {
|
||||||
|
systemd.services.mysql.preStart = lib.mkIf cfg.mysql.enable
|
||||||
|
(lib.mkBefore (noDataCow cfg.mysql.dataDir));
|
||||||
|
systemd.services.postgresql.preStart = lib.mkIf cfg.postgresql.enable
|
||||||
|
(lib.mkBefore (noDataCow cfg.postgresql.dataDir));
|
||||||
|
};
|
||||||
|
}
|
210
modules/ephemeral.nix
Normal file
210
modules/ephemeral.nix
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
{ config, pkgs, lib, ...}:
|
||||||
|
|
||||||
|
with lib; let
|
||||||
|
cfg = config.local.ephemeral;
|
||||||
|
|
||||||
|
device = mkOption {
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
description = mdDoc "Device to mount.";
|
||||||
|
};
|
||||||
|
|
||||||
|
options = mkOption {
|
||||||
|
type = with types; listOf nonEmptyStr;
|
||||||
|
readOnly = true;
|
||||||
|
description = mdDoc "Options used to mount the file system.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraOptions = mkOption {
|
||||||
|
type = with types; listOf nonEmptyStr;
|
||||||
|
default = [ ];
|
||||||
|
description = mdDoc "Additional options used to mount the file system.";
|
||||||
|
};
|
||||||
|
|
||||||
|
filesystem = {
|
||||||
|
options = {
|
||||||
|
inherit device options extraOptions;
|
||||||
|
fsType = mkOption {
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
description = mdDoc "Type of the file system.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
tmpfs = {
|
||||||
|
options = {
|
||||||
|
inherit options extraOptions;
|
||||||
|
name = mkOption {
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
default = "none";
|
||||||
|
description = mdDoc "Name of the file system.";
|
||||||
|
};
|
||||||
|
|
||||||
|
size = mkOption {
|
||||||
|
type = with types; either nonEmptyStr ints.positive;
|
||||||
|
description = mdDoc "Size of the file system.";
|
||||||
|
};
|
||||||
|
|
||||||
|
mode = mkOption {
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
description = mdDoc "Initial permissions of the root directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
uid = mkOption {
|
||||||
|
type = with types; either nonEmptyStr ints.unsigned;
|
||||||
|
default = 0;
|
||||||
|
description = mdDom "Initial user ID of the root directory";
|
||||||
|
};
|
||||||
|
|
||||||
|
gid = mkOption {
|
||||||
|
type = with types; either nonEmptyStr ints.unsigned;
|
||||||
|
default = 0;
|
||||||
|
description = mdDom "Initial group ID of the root directory";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
subvol = {
|
||||||
|
options = {
|
||||||
|
inherit options extraOptions;
|
||||||
|
subvolume = mkOption {
|
||||||
|
type = with types; nullOr nonEmptyStr;
|
||||||
|
default = null;
|
||||||
|
description = mdDoc "Source path of the subvolume.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ephemeralDefaults = {
|
||||||
|
"/" = {
|
||||||
|
size = "256m";
|
||||||
|
mode = "755";
|
||||||
|
uid = 0;
|
||||||
|
gid = 0;
|
||||||
|
options = [ "nodev" "noexec" "nosuid" ];
|
||||||
|
extraOptions = [ ];
|
||||||
|
};
|
||||||
|
"/run/nix" = {
|
||||||
|
size = "80%";
|
||||||
|
mode = "1775";
|
||||||
|
uid = 0;
|
||||||
|
gid = "nixbld";
|
||||||
|
options = [ "nodev" "nosuid" ];
|
||||||
|
extraOptions = [ ];
|
||||||
|
};
|
||||||
|
"/tmp" = {
|
||||||
|
size = "256m";
|
||||||
|
mode = "1777";
|
||||||
|
uid = 0;
|
||||||
|
gid = 0;
|
||||||
|
options = [ "nodev" "noexec" "nosuid" ];
|
||||||
|
extraOptions = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
subvolumeDefaults = {
|
||||||
|
"/etc/keys" = {
|
||||||
|
options = [ "nodev" "noexec" "nosuid" ];
|
||||||
|
extraOptions = [ "noatime" "compress=zstd" ];
|
||||||
|
};
|
||||||
|
"/nix" = {
|
||||||
|
options = [ "nodev" "nosuid" ];
|
||||||
|
extraOptions = [ "noatime" "compress=zstd" ];
|
||||||
|
};
|
||||||
|
"/var" = {
|
||||||
|
options = [ "nodev" "noexec" "nosuid" ];
|
||||||
|
extraOptions = [ "noatime" "compress=zstd" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
local.ephemeral = {
|
||||||
|
enable = mkEnableOption "ephemeral filesystem";
|
||||||
|
|
||||||
|
device = mkOption {
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
description = mdDoc "Persistent btrfs device.";
|
||||||
|
};
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
inherit device;
|
||||||
|
|
||||||
|
fsType = mkOption {
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
options = mkOption {
|
||||||
|
inherit (options) type readOnly description;
|
||||||
|
default = [ "nodev" "noexec" "nosuid" ]
|
||||||
|
++ optionals (cfg.boot.fsType == "vfat") [ "fmask=0137" "dmask=022" ]
|
||||||
|
++ optionals (builtins.match "ext[34]" cfg.boot.fsType != null) [ "data=journal" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
extraOptions = mkOption {
|
||||||
|
inherit (extraOptions) type description;
|
||||||
|
default = [ "noatime" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ephemeral = mkOption {
|
||||||
|
type = with types; attrsOf (submodule tmpfs);
|
||||||
|
description = mdDoc "Ephemeral filesystems.";
|
||||||
|
default = ephemeralDefaults;
|
||||||
|
};
|
||||||
|
|
||||||
|
subvolumes = mkOption {
|
||||||
|
type = with types; attrsOf (submodule subvol);
|
||||||
|
description = mdDoc "Persistent subvolumes.";
|
||||||
|
default = subvolumeDefaults;
|
||||||
|
example = {
|
||||||
|
"/home" = {
|
||||||
|
options = [ "nodev" "noexec" "nosuid" ];
|
||||||
|
extraOptions = [ "noatime" "compress=zstd" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
boot.initrd.availableKernelModules = [ "zstd" ];
|
||||||
|
boot.supportedFilesystems = [ "btrfs" ];
|
||||||
|
|
||||||
|
environment.etc.machine-id.source = mkDefault "/etc/keys/machine-id";
|
||||||
|
environment.etc.secureboot.source = mkDefault "/etc/keys/secureboot";
|
||||||
|
|
||||||
|
fileSystems = {
|
||||||
|
"/boot" = mkOverride 99 {
|
||||||
|
device = cfg.boot.device;
|
||||||
|
fsType = cfg.boot.fsType;
|
||||||
|
options = cfg.boot.options ++ cfg.boot.extraOptions;
|
||||||
|
};
|
||||||
|
} //
|
||||||
|
(mapAttrs (key: val: mkOverride 99 {
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = val.options ++ val.extraOptions
|
||||||
|
++ [
|
||||||
|
"strictatime"
|
||||||
|
"size=${toString val.size}"
|
||||||
|
"mode=${val.mode}"
|
||||||
|
"uid=${toString val.uid}"
|
||||||
|
"gid=${toString val.gid}"
|
||||||
|
"huge=within_size"
|
||||||
|
];
|
||||||
|
}) (ephemeralDefaults // cfg.ephemeral)) //
|
||||||
|
(mapAttrs (key: val: mkOverride 99 {
|
||||||
|
device = cfg.device;
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = val.options ++ val.extraOptions
|
||||||
|
++ [ "subvol=${if (val ? subvolume && val.subvolume != null) then val.subvolume else key}" ];
|
||||||
|
neededForBoot = true;
|
||||||
|
}) (subvolumeDefaults // cfg.subvolumes));
|
||||||
|
|
||||||
|
#nix.settings.build-dir = mkDefault "/run/nix";
|
||||||
|
systemd.services.nix-daemon.environment.TMPDIR = mkDefault "/run/nix";
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /etc/keys 0751 root root"
|
||||||
|
"D /run/nix 1775 root nixbld 1d"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
118
modules/iosched.nix
Normal file
118
modules/iosched.nix
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.hardware.block;
|
||||||
|
escape = lib.strings.escape [ ''"'' ];
|
||||||
|
|
||||||
|
inherit (lib)
|
||||||
|
mkIf
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
|
|
||||||
|
concatStrings
|
||||||
|
mapAttrsToList
|
||||||
|
optionalString;
|
||||||
|
in {
|
||||||
|
options.hardware.block = {
|
||||||
|
defaultScheduler = mkOption {
|
||||||
|
type = with types; nullOr nonEmptyStr;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Default block I/O scheduler.
|
||||||
|
|
||||||
|
Unless `null`, the value is assigned through a udev rule matching all
|
||||||
|
block devices.
|
||||||
|
'';
|
||||||
|
example = "kyber";
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultSchedulerRotational = mkOption {
|
||||||
|
type = with types; nullOr nonEmptyStr;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Default block I/O scheduler for rotational drives (e.g. hard disks).
|
||||||
|
|
||||||
|
Unless `null`, the value is assigned through a udev rule matching all
|
||||||
|
rotational block devices.
|
||||||
|
|
||||||
|
This option takes precedence over
|
||||||
|
{option}`config.hardware.block.defaultScheduler`.
|
||||||
|
'';
|
||||||
|
example = "bfq";
|
||||||
|
};
|
||||||
|
|
||||||
|
scheduler = mkOption {
|
||||||
|
type = with types; attrsOf nonEmptyStr;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Assign block I/O scheduler by device name pattern.
|
||||||
|
|
||||||
|
Names are matched using the {manpage}`udev(7)` pattern syntax:
|
||||||
|
|
||||||
|
`*`
|
||||||
|
: Matches zero or more characters.
|
||||||
|
|
||||||
|
`?`
|
||||||
|
: Matches any single character.
|
||||||
|
|
||||||
|
`[]`
|
||||||
|
: Matches any single character specified in the brackets. Ranges are
|
||||||
|
supported via the `-` character.
|
||||||
|
|
||||||
|
`|`
|
||||||
|
: Separates alternative patterns.
|
||||||
|
|
||||||
|
|
||||||
|
Please note that overlapping patterns may produce unexpected results.
|
||||||
|
More complex configurations requiring these should instead be specified
|
||||||
|
directly through custom udev rules, for example via
|
||||||
|
[{option}`config.services.udev.extraRules`](#opt-services.udev.extraRules),
|
||||||
|
to ensure correct ordering.
|
||||||
|
|
||||||
|
Available schedulers depend on the kernel configuration but modern
|
||||||
|
Linux systems typically support:
|
||||||
|
|
||||||
|
`none`
|
||||||
|
: No‐operation scheduler with no re‐ordering of requests. Suitable
|
||||||
|
for devices with fast random I/O such as NVMe SSDs.
|
||||||
|
|
||||||
|
[`mq-deadline`](https://www.kernel.org/doc/html/latest/block/deadline-iosched.html)
|
||||||
|
: Simple latency‐oriented general‐purpose scheduler.
|
||||||
|
|
||||||
|
[`kyber`](https://www.kernel.org/doc/html/latest/block/kyber-iosched.html)
|
||||||
|
: Simple latency‐oriented scheduler for fast multi‐queue devices
|
||||||
|
like NVMe SSDs.
|
||||||
|
|
||||||
|
[`bfq`](https://www.kernel.org/doc/html/latest/block/bfq-iosched.html)
|
||||||
|
: Complex fairness‐oriented scheduler. Higher processing overhead,
|
||||||
|
but good interactive response, especially with slower devices.
|
||||||
|
|
||||||
|
|
||||||
|
Schedulers assigned through this option take precedence over
|
||||||
|
{option}`config.hardware.block.defaultScheduler` and
|
||||||
|
{option}`config.hardware.block.defaultSchedulerRotational` but may be
|
||||||
|
overridden by other udev rules.
|
||||||
|
'';
|
||||||
|
example = {
|
||||||
|
"mmcblk[0-9]*" = "bfq";
|
||||||
|
"nvme[0-9]*" = "kyber";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.defaultScheduler != null ||
|
||||||
|
cfg.defaultSchedulerRotational != null || cfg.scheduler != { }) {
|
||||||
|
services.udev.packages = [
|
||||||
|
(pkgs.writeTextDir "etc/udev/rules.d/98-block-io-scheduler.rules"
|
||||||
|
(optionalString (cfg.defaultScheduler != null) ''
|
||||||
|
SUBSYSTEM=="block", ACTION=="add|change", TEST=="queue/scheduler", ATTR{queue/scheduler}="${escape cfg.defaultScheduler}"
|
||||||
|
'' + optionalString (cfg.defaultSchedulerRotational != null) ''
|
||||||
|
SUBSYSTEM=="block", ACTION=="add|change", ATTR{queue/rotational}=="1", TEST=="queue/scheduler", ATTR{queue/scheduler}="${escape cfg.defaultSchedulerRotational}"
|
||||||
|
'' + concatStrings (mapAttrsToList (name: sched: ''
|
||||||
|
SUBSYSTEM=="block", ACTION=="add|change", KERNEL=="${escape name}", ATTR{queue/scheduler}="${escape sched}"
|
||||||
|
'') cfg.scheduler)))
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [ mvs ];
|
||||||
|
}
|
24
modules/musl.nix
Normal file
24
modules/musl.nix
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }: {
|
||||||
|
disabledModules = [
|
||||||
|
(modulesPath + "/config/ldso.nix")
|
||||||
|
(modulesPath + "/config/stub-ld.nix")
|
||||||
|
(modulesPath + "/programs/nix-ld.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
config = lib.mkIf pkgs.stdenv.hostPlatform.isMusl {
|
||||||
|
i18n = {
|
||||||
|
glibcLocales = lib.mkDefault (pkgs.runCommandNoCC "locale-archive" {
|
||||||
|
preferLocalBuild = true;
|
||||||
|
} ''
|
||||||
|
mkdir -p $out/lib/locale
|
||||||
|
touch $out/lib/locale/locale-archive
|
||||||
|
'');
|
||||||
|
|
||||||
|
supportedLocales = lib.mkDefault [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
security.pam.services.login.updateWtmp = lib.mkForce false;
|
||||||
|
services.nscd.enable = lib.mkForce false;
|
||||||
|
system.nssModules = lib.mkForce [ ];
|
||||||
|
};
|
||||||
|
}
|
48
modules/network.nix
Normal file
48
modules/network.nix
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
networking.nameservers = lib.mkDefault [
|
||||||
|
"[2a05:f480:1800:d2e::1]:853#resolve.solitary.social"
|
||||||
|
"80.240.30.163:853#resolve.solitary.social"
|
||||||
|
"[2a01:4f8:1c0c:6c89::1]:853#resolve.nyantec.com"
|
||||||
|
"116.203.220.161:853#resolve.nyantec.com"
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.nftables.enable = lib.mkDefault true;
|
||||||
|
networking.useNetworkd = lib.mkDefault true;
|
||||||
|
|
||||||
|
services.resolved = {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
dnsovertls = lib.mkDefault "true";
|
||||||
|
dnssec = lib.mkDefault "true";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.network.networks."98-ethernet-default-dhcp" = {
|
||||||
|
matchConfig.Type = "ether";
|
||||||
|
matchConfig.Name = "en*";
|
||||||
|
|
||||||
|
DHCP = lib.mkDefault "yes";
|
||||||
|
dhcpV4Config.UseDNS = lib.mkDefault false;
|
||||||
|
dhcpV6Config.UseDNS = lib.mkDefault false;
|
||||||
|
ipv6AcceptRAConfig.Token = lib.mkDefault "prefixstable";
|
||||||
|
|
||||||
|
fairQueueingConfig.Pacing = lib.mkDefault true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.network.networks."98-wireless-client-dhcp" = {
|
||||||
|
matchConfig.Type = "wlan";
|
||||||
|
matchConfig.WLANInterfaceType = "station";
|
||||||
|
|
||||||
|
DHCP = lib.mkDefault "yes";
|
||||||
|
dhcpV4Config.UseDNS = lib.mkDefault false;
|
||||||
|
dhcpV4Config.RouteMetric = lib.mkDefault 1025;
|
||||||
|
dhcpV6Config.UseDNS = lib.mkDefault false;
|
||||||
|
ipv6AcceptRAConfig.Token = lib.mkDefault "prefixstable";
|
||||||
|
ipv6AcceptRAConfig.RouteMetric = lib.mkDefault 1025;
|
||||||
|
|
||||||
|
cakeConfig = {
|
||||||
|
Bandwidth = lib.mkDefault "100M";
|
||||||
|
AutoRateIngress = lib.mkDefault true;
|
||||||
|
UseRawPacketSize = lib.mkDefault false;
|
||||||
|
PriorityQueueingPreset = lib.mkDefault "diffserv4";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
31
modules/nix.nix
Normal file
31
modules/nix.nix
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
config = {
|
||||||
|
nix = {
|
||||||
|
channel.enable = lib.mkDefault false;
|
||||||
|
|
||||||
|
daemonCPUSchedPolicy = lib.mkDefault "batch";
|
||||||
|
daemonIOSchedClass = lib.mkDefault "best-effort";
|
||||||
|
daemonIOSchedPriority = lib.mkDefault 7;
|
||||||
|
|
||||||
|
gc = {
|
||||||
|
automatic = lib.mkDefault true;
|
||||||
|
dates = lib.mkDefault "weekly";
|
||||||
|
options = lib.mkDefault "--delete-older-than 14d";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
experimental-features = lib.mkDefault [
|
||||||
|
"cgroups"
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
"repl-flake"
|
||||||
|
];
|
||||||
|
|
||||||
|
allowed-users = lib.mkDefault [ "@users" ];
|
||||||
|
trusted-users = lib.mkDefault [ "@wheel" ];
|
||||||
|
use-groups = lib.mkDefault true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
85
modules/ocsp.nix
Normal file
85
modules/ocsp.nix
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
{ config, pkgs, lib, ...}:
|
||||||
|
|
||||||
|
with lib; let
|
||||||
|
cfg = config.security.acme;
|
||||||
|
|
||||||
|
script = pkgs.writeShellApplication {
|
||||||
|
name = "ocsp-query";
|
||||||
|
runtimeInputs = with pkgs; [ openssl ];
|
||||||
|
text = ''
|
||||||
|
cd "$1"
|
||||||
|
|
||||||
|
tmp="$(mktemp ocsp.der.XXXXXXXXXX)"
|
||||||
|
trap 'rm -f "$tmp"' EXIT TERM
|
||||||
|
|
||||||
|
url="$(openssl x509 -in cert.pem -noout -ocsp_uri)"
|
||||||
|
openssl ocsp -issuer chain.pem -cert cert.pem -url "$url" -respout "$tmp"
|
||||||
|
|
||||||
|
chown "$(id -u):$(id -g)" "$tmp"
|
||||||
|
chmod 644 "$tmp"
|
||||||
|
mv "$tmp" ocsp.der
|
||||||
|
|
||||||
|
ln -s -f ocsp.der full.ocsp
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options.security.acme.ocspTimer = mkOption {
|
||||||
|
type = with types; nullOr nonEmptyStr;
|
||||||
|
default = "daily";
|
||||||
|
description = mdDoc "Realtime (wall clock) timer for regular OCSP queries.";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.ocspTimer != null) {
|
||||||
|
systemd.services = mapAttrs' (cert: conf: nameValuePair "ocsp-${cert}" {
|
||||||
|
description = "Query OCSP endpoint for ${cert}";
|
||||||
|
after = [ "network.target" "network-online.target" "acme-${cert}.service" ];
|
||||||
|
wants = [ "network.target" "network-online.target" "acme-${cert}.service" ];
|
||||||
|
|
||||||
|
confinement.enable = true;
|
||||||
|
confinement.packages = with pkgs; [ openssl ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
|
||||||
|
User = "acme";
|
||||||
|
Group = conf.group;
|
||||||
|
UMask = "0022";
|
||||||
|
|
||||||
|
BindPaths = [ conf.directory ];
|
||||||
|
|
||||||
|
ExecStart = "${script}/bin/ocsp-query ${escapeShellArg conf.directory}";
|
||||||
|
|
||||||
|
ProtectProc = "noaccess";
|
||||||
|
ProcSubset = "pid";
|
||||||
|
ProtectHome = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateIPC = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
RestrictAddressFamilies = ["AF_INET" "AF_INET6" ];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
LockPersonality = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
RemoveIPC = true;
|
||||||
|
CapabilityBoundingSet = null;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
SystemCallFilter = [ "@system-service" "~@privileged" "@chown" ];
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
DeviceAllow = null;
|
||||||
|
DevicePolicy = "closed";
|
||||||
|
SocketBindDeny = "any";
|
||||||
|
};
|
||||||
|
}) cfg.certs;
|
||||||
|
|
||||||
|
systemd.timers = mapAttrs' (cert: conf: nameValuePair "ocsp-${cert}" {
|
||||||
|
description = "Query OCSP endpoint for ${cert} regularly";
|
||||||
|
timerConfig.OnCalendar = cfg.ocspTimer;
|
||||||
|
}) cfg.certs;
|
||||||
|
};
|
||||||
|
}
|
57
modules/openssh.nix
Normal file
57
modules/openssh.nix
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{ lib, ...}:
|
||||||
|
|
||||||
|
let
|
||||||
|
ciphers = [
|
||||||
|
"chacha20-poly1305@openssh.com"
|
||||||
|
"aes256-gcm@openssh.com"
|
||||||
|
"aes128-gcm@openssh.com"
|
||||||
|
];
|
||||||
|
|
||||||
|
sigAlgorithms = [
|
||||||
|
"ssh-ed25519-cert-v01@openssh.com"
|
||||||
|
"ssh-ed25519"
|
||||||
|
];
|
||||||
|
|
||||||
|
kexAlgorithms = [
|
||||||
|
"sntrup761x25519-sha512@openssh.com"
|
||||||
|
"curve25519-sha256"
|
||||||
|
"curve25519-sha256@libssh.org"
|
||||||
|
];
|
||||||
|
|
||||||
|
macs = [
|
||||||
|
"umac-128-etm@openssh.com"
|
||||||
|
"hmac-sha2-512-etm@openssh.com"
|
||||||
|
"hmac-sha2-256-etm@openssh.com"
|
||||||
|
];
|
||||||
|
in {
|
||||||
|
programs.ssh = {
|
||||||
|
ciphers = lib.mkDefault ciphers;
|
||||||
|
kexAlgorithms = lib.mkDefault ciphers;
|
||||||
|
macs = lib.mkDefault macs;
|
||||||
|
hostKeyAlgorithms = lib.mkDefault sigAlgorithms;
|
||||||
|
pubkeyAcceptedKeyTypes = lib.mkDefault sigAlgorithms;
|
||||||
|
setXAuthLocation = lib.mkDefault false;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
settings = {
|
||||||
|
PermitRootLogin = lib.mkDefault "no";
|
||||||
|
|
||||||
|
PasswordAuthentication = lib.mkDefault false;
|
||||||
|
KbdInteractiveAuthentication = lib.mkDefault false;
|
||||||
|
AuthenticationMethods = lib.mkDefault "publickey";
|
||||||
|
|
||||||
|
Ciphers = lib.mkDefault ciphers;
|
||||||
|
Macs = lib.mkDefault macs;
|
||||||
|
|
||||||
|
KexAlgorithms = lib.mkDefault kexAlgorithms;
|
||||||
|
HostKeyAlgorithms = lib.mkDefault (lib.concatStringsSep "," sigAlgorithms);
|
||||||
|
PubkeyAcceptedAlgorithms = lib.mkDefault (lib.concatStringsSep "," sigAlgorithms);
|
||||||
|
|
||||||
|
# Remove stale Unix sockets when forwarding
|
||||||
|
StreamLocalBindUnlink = lib.mkDefault true;
|
||||||
|
|
||||||
|
ClientAliveInterval = lib.mkDefault 900;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
5
modules/prefs.nix
Normal file
5
modules/prefs.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
config = {
|
||||||
|
services.dbus.implementation = lib.mkDefault "broker";
|
||||||
|
};
|
||||||
|
}
|
22
nixos.nix
Normal file
22
nixos.nix
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{ pkgs, ... }: {
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
fileSystems."/".label = "nixos";
|
||||||
|
|
||||||
|
nixpkgs = { inherit pkgs; };
|
||||||
|
|
||||||
|
security.sudo.wheelNeedsPassword = false;
|
||||||
|
services.getty.autologinUser = "nixos";
|
||||||
|
|
||||||
|
users.users.nixos = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "24.11";
|
||||||
|
|
||||||
|
virtualisation.vmVariant.virtualisation.diskImage = null;
|
||||||
|
|
||||||
|
hardware.block.defaultScheduler = "kyber";
|
||||||
|
}
|
27
overlay.nix
Normal file
27
overlay.nix
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
final: prev:
|
||||||
|
let
|
||||||
|
inherit (final) lib callPackage;
|
||||||
|
|
||||||
|
alpine-patches = callPackage ./pkgs/alpine-patches.nix { };
|
||||||
|
gentoo-patches = callPackage ./pkgs/gentoo-patches.nix { };
|
||||||
|
in {
|
||||||
|
keyutils = prev.keyutils.overrideAttrs (base: {
|
||||||
|
buildFlags = base.buildFlags or [ ]
|
||||||
|
++ lib.optional final.keyutils.stdenv.cc.bintools.isLLVM
|
||||||
|
"LDFLAGS=-Wl,--undefined-version";
|
||||||
|
});
|
||||||
|
|
||||||
|
cpp-utilities = prev.cpp-utilities.overrideAttrs (base: {
|
||||||
|
buildInputs = [ final.boost ];
|
||||||
|
});
|
||||||
|
|
||||||
|
jemalloc = prev.jemalloc.override {
|
||||||
|
stdenv = final.gccStdenv;
|
||||||
|
};
|
||||||
|
|
||||||
|
time = prev.time.overrideAttrs (base: {
|
||||||
|
patches = base.patches or [ ]
|
||||||
|
++ lib.optional final.time.stdenv.cc.isClang
|
||||||
|
"${gentoo-patches}/sys-process/time/files/time-1.9-implicit-func-decl-clang.patch";
|
||||||
|
});
|
||||||
|
}
|
14
pkgs/alpine-patches.nix
Normal file
14
pkgs/alpine-patches.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{ fetchGitLab, lib }:
|
||||||
|
|
||||||
|
fetchgit {
|
||||||
|
url = "https://anongit.gentoo.org/git/repo/gentoo.git";
|
||||||
|
domain = "gitlab.alpineline.org";
|
||||||
|
owner = "alpine";
|
||||||
|
repo = "aports";
|
||||||
|
rev = "3.20-stable";
|
||||||
|
|
||||||
|
useFetchGit = true;
|
||||||
|
sparseCheckout = [ "*.patch" ];
|
||||||
|
nonConeMode = true;
|
||||||
|
hash = lib.fakeFash;
|
||||||
|
}
|
9
pkgs/gentoo-patches.nix
Normal file
9
pkgs/gentoo-patches.nix
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{ fetchgit }:
|
||||||
|
|
||||||
|
fetchgit {
|
||||||
|
url = "https://anongit.gentoo.org/git/repo/gentoo.git";
|
||||||
|
rev = "fa77d52a7ff39464c50707ca024725deab08b534";
|
||||||
|
sparseCheckout = [ "*.patch" ];
|
||||||
|
nonConeMode = true;
|
||||||
|
hash = "sha256-ZTrPeo8TjKSDAUyeJyWq1C8O9EXd9uhClHlphPsFXCA=";
|
||||||
|
}
|
8
platforms.nix
Normal file
8
platforms.nix
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"x86_64-linux" = {
|
||||||
|
config = "x86_64-unknown-linux-musl";
|
||||||
|
gcc.arch = "x86-64-v3";
|
||||||
|
#useLLVM = true;
|
||||||
|
#linker = "lld";
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue