Format project using nixfmt rfc candidate.

This commit is contained in:
Kevin Baensch 2024-11-20 20:32:38 +01:00
parent 1f63817684
commit a9f7fe416f
Signed by: derped
GPG key ID: C0F1D326C7626543
91 changed files with 1347 additions and 1000 deletions

View file

@ -4,11 +4,12 @@
pkgs, pkgs,
... ...
}: }:
with lib; { with lib;
{
environment.etc = mkIf (elem "etcfiles" config.machine.conffiles) { environment.etc = mkIf (elem "etcfiles" config.machine.conffiles) {
"rofi.rasi".source = import ./etc/rofi.rasi.nix {inherit pkgs;}; "rofi.rasi".source = import ./etc/rofi.rasi.nix { inherit pkgs; };
"i3/py3status".source = ./etc/i3/py3status; "i3/py3status".source = ./etc/i3/py3status;
"sway/config".source = mkDefault (import ./etc/sway/config.nix {inherit pkgs;}); "sway/config".source = mkDefault (import ./etc/sway/config.nix { inherit pkgs; });
"mpv/input.conf".source = ./etc/mpv/input.conf; "mpv/input.conf".source = ./etc/mpv/input.conf;
"mpv/mpv.conf".source = ./etc/mpv/mpv.conf; "mpv/mpv.conf".source = ./etc/mpv/mpv.conf;
"youtube-dl.conf".source = ./etc/youtube-dl.conf; "youtube-dl.conf".source = ./etc/youtube-dl.conf;

View file

@ -1,4 +1,5 @@
{pkgs, ...}: (pkgs.writeText "config" '' { pkgs, ... }:
(pkgs.writeText "config" ''
# i3 config file (v4) # i3 config file (v4)
# #
# Please see http://i3wm.org/docs/userguide.html for a complete reference! # Please see http://i3wm.org/docs/userguide.html for a complete reference!

View file

@ -1,26 +1,30 @@
{pkgs}: let { pkgs }:
tabMode = pkgs.writeScript "tab-finder.sh" (with pkgs; /* bash */ '' let
#!/usr/bin/env bash tabMode = pkgs.writeScript "tab-finder.sh" (
if [ -z ''${1} ]; then with pkgs; # bash
${brotab}/bin/bt list; ''
else #!/usr/bin/env bash
TARGET_TAB=$(sed "s/\t.*$//g" <<< ''${1}); if [ -z ''${1} ]; then
# activate window as focused to it is easy to switch to ${brotab}/bin/bt list;
${brotab}/bin/bt activate --focused ''${TARGET_TAB} > /dev/null 2>&1; else
if [ -n ''${SWAYSOCK} ] && which swaymsg; then TARGET_TAB=$(sed "s/\t.*$//g" <<< ''${1});
swaymsg "[urgent=latest] focus" > /dev/null 2>&1; # activate window as focused to it is easy to switch to
${brotab}/bin/bt activate --focused ''${TARGET_TAB} > /dev/null 2>&1;
if [ -n ''${SWAYSOCK} ] && which swaymsg; then
swaymsg "[urgent=latest] focus" > /dev/null 2>&1;
fi
fi fi
fi exit 0;
exit 0; ''
''); );
in in
pkgs.writeText "rofi.rasi" '' pkgs.writeText "rofi.rasi" ''
configuration { configuration {
modi: "combi,window,drun,ssh,tabFinder:${tabMode}"; modi: "combi,window,drun,ssh,tabFinder:${tabMode}";
font: "hack 10"; font: "hack 10";
combi-modi: "window,drun,ssh,tabFinder"; combi-modi: "window,drun,ssh,tabFinder";
icon-theme: "Papirus"; icon-theme: "Papirus";
show-icons: true; show-icons: true;
} }
@theme "DarkBlue" @theme "DarkBlue"
'' ''

View file

@ -1,36 +1,38 @@
{pkgs}: { pkgs }:
let let
# TODO/FIX: pkgs.sway-unwrapped is not the same sway derivation as the one running the desktop # TODO/FIX: pkgs.sway-unwrapped is not the same sway derivation as the one running the desktop
grim-wrapper = pkgs.writeShellScript "grim-wrapper" /* bash */ '' grim-wrapper =
OUTPUT_DIR="$(${pkgs.xdg-user-dirs}/bin/xdg-user-dir PICTURES)" pkgs.writeShellScript "grim-wrapper" # bash
DATE="$(${pkgs.coreutils}/bin/date +'%Y-%m-%d;%H:%M:%S;')"; ''
WINDOW_LIST="$(${pkgs.sway-unwrapped}/bin/swaymsg -t get_tree | ${pkgs.jq}/bin/jq -r '.. | select(.pid? and .visible?) | "\(.rect.x+.window_rect.x),\(.rect.y+.window_rect.y) \(.window_rect.width)x\(.window_rect.height) \(.app_id):\(.name)"' | ${pkgs.coreutils}/bin/tr -d '"/;\\')"; OUTPUT_DIR="$(${pkgs.xdg-user-dirs}/bin/xdg-user-dir PICTURES)"
DATE="$(${pkgs.coreutils}/bin/date +'%Y-%m-%d;%H:%M:%S;')";
WINDOW_LIST="$(${pkgs.sway-unwrapped}/bin/swaymsg -t get_tree | ${pkgs.jq}/bin/jq -r '.. | select(.pid? and .visible?) | "\(.rect.x+.window_rect.x),\(.rect.y+.window_rect.y) \(.window_rect.width)x\(.window_rect.height) \(.app_id):\(.name)"' | ${pkgs.coreutils}/bin/tr -d '"/;\\')";
case "''${1}" in case "''${1}" in
selection) selection)
# split slurp selection result into jseon selectable screen area (for grim) and output name # split slurp selection result into jseon selectable screen area (for grim) and output name
SELECTION_FORMAT='{ "area": "%x,%y %wx%h", "name": "%wx%h;%o;%l" }'; SELECTION_FORMAT='{ "area": "%x,%y %wx%h", "name": "%wx%h;%o;%l" }';
SELECTION="$(${pkgs.slurp}/bin/slurp -d -f "''${SELECTION_FORMAT}" <<< ''${WINDOW_LIST})"; SELECTION="$(${pkgs.slurp}/bin/slurp -d -f "''${SELECTION_FORMAT}" <<< ''${WINDOW_LIST})";
SELECTION_AREA="$(${pkgs.jq}/bin/jq -r '.area' <<< "''${SELECTION}")"; SELECTION_AREA="$(${pkgs.jq}/bin/jq -r '.area' <<< "''${SELECTION}")";
SELECTION_NAME="$(${pkgs.jq}/bin/jq -r '.name' <<< "''${SELECTION}"| ${pkgs.coreutils}/bin/tr ' ' '_')"; SELECTION_NAME="$(${pkgs.jq}/bin/jq -r '.name' <<< "''${SELECTION}"| ${pkgs.coreutils}/bin/tr ' ' '_')";
OUTNAME="''${OUTPUT_DIR}/''${DATE}''${SELECTION_NAME}.png"; OUTNAME="''${OUTPUT_DIR}/''${DATE}''${SELECTION_NAME}.png";
${pkgs.grim}/bin/grim -g "''${SELECTION_AREA}" "''${OUTNAME}"; ${pkgs.grim}/bin/grim -g "''${SELECTION_AREA}" "''${OUTNAME}";
;; ;;
clip) clip)
SELECTION="$(${pkgs.slurp}/bin/slurp -d <<< ''${WINDOW_LIST})"; SELECTION="$(${pkgs.slurp}/bin/slurp -d <<< ''${WINDOW_LIST})";
${pkgs.grim}/bin/grim - | ${pkgs.wl-clipboard}/bin/wl-copy; ${pkgs.grim}/bin/grim - | ${pkgs.wl-clipboard}/bin/wl-copy;
;; ;;
*) *)
DISPLAY="$(${pkgs.sway-unwrapped}/bin/swaymsg -t get_outputs | ${pkgs.jq}/bin/jq -r '.[] | select(.focused) | .name')"; DISPLAY="$(${pkgs.sway-unwrapped}/bin/swaymsg -t get_outputs | ${pkgs.jq}/bin/jq -r '.[] | select(.focused) | .name')";
DISPLAY_RES="$(${pkgs.sway-unwrapped}/bin/swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .current_mode | "\(.width)x\(.height)"')"; DISPLAY_RES="$(${pkgs.sway-unwrapped}/bin/swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .current_mode | "\(.width)x\(.height)"')";
OUTNAME="''${OUTPUT_DIR}/''${DATE}''${DISPLAY_RES};''${DISPLAY};.png" OUTNAME="''${OUTPUT_DIR}/''${DATE}''${DISPLAY_RES};''${DISPLAY};.png"
${pkgs.grim}/bin/grim -o "''${DISPLAY}" "''${OUTNAME}"; ${pkgs.grim}/bin/grim -o "''${DISPLAY}" "''${OUTNAME}";
;; ;;
esac; esac;
''; '';
in pkgs.writeText "config" in
'' pkgs.writeText "config" ''
include /etc/sway/config.d/* include /etc/sway/config.d/*
# Read `man 5 sway` for a complete reference. # Read `man 5 sway` for a complete reference.

View file

@ -5,20 +5,20 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "fonts" config.machine.conffiles) { mkIf (elem "fonts" config.machine.conffiles) {
fonts = { fonts = {
fontDir.enable = true; fontDir.enable = true;
enableGhostscriptFonts = true; enableGhostscriptFonts = true;
fontconfig = { fontconfig = {
enable = true; enable = true;
includeUserConf = false; includeUserConf = false;
};
packages = with pkgs; [
(nerdfonts.override {
fonts = [
"JetBrainsMono"
];
})
];
}; };
} packages = with pkgs; [
(nerdfonts.override {
fonts = [
"JetBrainsMono"
];
})
];
};
}

View file

@ -3,17 +3,22 @@
lib, lib,
pkgs, pkgs,
... ...
}: { }:
{
console.keyMap = "de"; console.keyMap = "de";
i18n = { i18n = {
defaultLocale = "en_US.UTF-8"; defaultLocale = "en_US.UTF-8";
supportedLocales = ["all"]; supportedLocales = [ "all" ];
inputMethod = { inputMethod = {
enable = (lib.elem "desktop" config.machine.services); enable = (lib.elem "desktop" config.machine.services);
type = "fcitx5"; type = "fcitx5";
fcitx5 = { fcitx5 = {
waylandFrontend = true; waylandFrontend = true;
addons = with pkgs; [fcitx5-chinese-addons fcitx5-mozc fcitx5-table-extra]; addons = with pkgs; [
fcitx5-chinese-addons
fcitx5-mozc
fcitx5-table-extra
];
}; };
}; };
}; };

View file

@ -3,9 +3,11 @@
lib, lib,
... ...
}: }:
with lib; let with lib;
let
inherit (config.machine) networkD; inherit (config.machine) networkD;
in { in
{
networking = { networking = {
inherit (config.machine) hostName; inherit (config.machine) hostName;
useNetworkd = networkD.enable; useNetworkd = networkD.enable;
@ -16,44 +18,49 @@ in {
# https://github.com/NixOS/nixpkgs/issues/10001#issuecomment-905532069 # https://github.com/NixOS/nixpkgs/issues/10001#issuecomment-905532069
systemd.network = mkIf networkD.enable { systemd.network = mkIf networkD.enable {
enable = true; enable = true;
networks = let networks =
networkConfig = { let
DHCP = "yes";
DNSSEC = "yes";
DNSOverTLS = "yes";
DNS = ["1.1.1.1" "1.0.0.1"];
};
in {
"40-wired" = {
enable = true;
name = "en*";
dhcpV4Config.RouteMetric = 2048;
inherit networkConfig;
};
"40-wireless" = {
enable = true;
name = "wl*";
dhcpV4Config.RouteMetric = 1024;
inherit networkConfig;
};
"50-vlan" = {
enable = true;
matchConfig = {
Name = "br0";
};
networkConfig = { networkConfig = {
DNS = "10.0.0.1"; DHCP = "yes";
Address = "10.0.0.100/16"; DNSSEC = "yes";
# DHCPServer = true; DNSOverTLS = "yes";
# IPMasquerade = true; DNS = [
"1.1.1.1"
"1.0.0.1"
];
};
in
{
"40-wired" = {
enable = true;
name = "en*";
dhcpV4Config.RouteMetric = 2048;
inherit networkConfig;
};
"40-wireless" = {
enable = true;
name = "wl*";
dhcpV4Config.RouteMetric = 1024;
inherit networkConfig;
};
"50-vlan" = {
enable = true;
matchConfig = {
Name = "br0";
};
networkConfig = {
DNS = "10.0.0.1";
Address = "10.0.0.100/16";
# DHCPServer = true;
# IPMasquerade = true;
};
# dhcpServerConfig = {
# ServerAddress = "172.16.9.1/12";
# PoolOffset = 100;
# EmitDNS = false;
# };
}; };
# dhcpServerConfig = {
# ServerAddress = "172.16.9.1/12";
# PoolOffset = 100;
# EmitDNS = false;
# };
}; };
};
}; };
# Wait for any interface to become available, not for all # Wait for any interface to become available, not for all
systemd.services."systemd-networkd-wait-online" = { systemd.services."systemd-networkd-wait-online" = {

View file

@ -6,10 +6,12 @@
config, config,
lib, lib,
... ...
}: let }:
let
cfg = config.machine; cfg = config.machine;
emptyGlobalRegistry = pkgs.writeText "registry.json" ''{ "flakes": [], "version": 2 }''; emptyGlobalRegistry = pkgs.writeText "registry.json" ''{ "flakes": [], "version": 2 }'';
in { in
{
nix = { nix = {
package = pkgs.nix; package = pkgs.nix;
registry = { registry = {
@ -22,19 +24,15 @@ in {
cores = 1; cores = 1;
sandbox = true; sandbox = true;
auto-optimise-store = true; auto-optimise-store = true;
trusted-substituters = trusted-substituters = [
[ "https://cache.nixos.org"
"https://cache.nixos.org" ] ++ cfg.binaryCaches;
]
++ cfg.binaryCaches;
# TODO: integrate into sops # TODO: integrate into sops
# trusted-public-keys = [ (lib.fileContents "${cfg.secretPath}/hydra_cache.pub") ]; # trusted-public-keys = [ (lib.fileContents "${cfg.secretPath}/hydra_cache.pub") ];
substituters = substituters = [
[ "https://cache.nixos.org"
"https://cache.nixos.org" ] ++ cfg.binaryCaches;
] allowed-users = [ "root" ] ++ (map (n: n.name) cfg.administrators);
++ cfg.binaryCaches;
allowed-users = ["root"] ++ (map (n: n.name) cfg.administrators);
}; };
extraOptions = '' extraOptions = ''
build-timeout = 86400 # 24 hours build-timeout = 86400 # 24 hours

View file

@ -4,9 +4,9 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "security" config.machine.conffiles) { mkIf (elem "security" config.machine.conffiles) {
security = { security = {
audit.enable = true; audit.enable = true;
auditd.enable = true; auditd.enable = true;
}; };
} }

View file

@ -5,39 +5,52 @@
pkgs, pkgs,
... ...
}: }:
with lib; let with lib;
let
withDocker = config.virtualisation.docker.enable; withDocker = config.virtualisation.docker.enable;
withPodman = config.virtualisation.podman.enable; withPodman = config.virtualisation.podman.enable;
administrators = user: { administrators = user: {
inherit (user) name; inherit (user) name;
value = let value =
cfg = config.services; let
passPath = config.sops.secrets."users/${user.name}/password".path; cfg = config.services;
in { passPath = config.sops.secrets."users/${user.name}/password".path;
isNormalUser = true; in
inherit (user) name; {
uid = user.id; isNormalUser = true;
subUidRanges = optional withPodman { inherit (user) name;
startUid = 100000; uid = user.id;
count = 65536; subUidRanges = optional withPodman {
startUid = 100000;
count = 65536;
};
subGidRanges = optional withPodman {
startGid = 100000;
count = 65536;
};
home = builtins.toPath "/home/${user.name}";
createHome = true;
description = "Administrative user ${user.name}.";
group = user.name;
extraGroups =
[
"audio"
"wheel"
"network"
]
++ (optionals (lib.elem "desktop" config.machine.services) [
"input"
"video"
])
++ (optionals cfg.printing.enable [
"cups"
"lp"
])
++ (optional (withDocker && !withPodman) "docker")
++ (optional withPodman "podman");
shell = "${pkgs.zsh}/bin/zsh";
hashedPasswordFile = passPath;
}; };
subGidRanges = optional withPodman {
startGid = 100000;
count = 65536;
};
home = builtins.toPath "/home/${user.name}";
createHome = true;
description = "Administrative user ${user.name}.";
group = user.name;
extraGroups =
["audio" "wheel" "network"]
++ (optionals (lib.elem "desktop" config.machine.services) ["input" "video"])
++ (optionals cfg.printing.enable ["cups" "lp"])
++ (optional (withDocker && !withPodman) "docker")
++ (optional withPodman "podman");
shell = "${pkgs.zsh}/bin/zsh";
hashedPasswordFile = passPath;
};
}; };
mkusergroup = user: { mkusergroup = user: {
@ -45,15 +58,14 @@ with lib; let
value = { value = {
inherit (user) name; inherit (user) name;
gid = user.id; gid = user.id;
members = [user.name]; members = [ user.name ];
}; };
}; };
in { in
sops.secrets = {
fn.sopsHelper sops.secrets = fn.sopsHelper (user: "users/${user.name}/password") config.machine.administrators {
(user: "users/${user.name}/password") neededForUsers = true;
config.machine.administrators };
{neededForUsers = true;};
users = { users = {
mutableUsers = false; mutableUsers = false;
users = listToAttrs (map administrators config.machine.administrators); users = listToAttrs (map administrators config.machine.administrators);

View file

@ -4,35 +4,44 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "zsh" config.machine.conffiles) { mkIf (elem "zsh" config.machine.conffiles) {
programs.zsh = { programs.zsh = {
enable = true; enable = true;
autosuggestions.enable = true; autosuggestions.enable = true;
syntaxHighlighting.enable = true; syntaxHighlighting.enable = true;
shellAliases = { shellAliases = {
cat = ''bat --paging=never --theme="Solarized (dark)"''; cat = ''bat --paging=never --theme="Solarized (dark)"'';
less = ''bat --paging=always --style=changes --color=always --theme="Solarized (dark)"''; less = ''bat --paging=always --style=changes --color=always --theme="Solarized (dark)"'';
ls = "eza"; ls = "eza";
l = "eza -abgHhl@ --git --color=always --group-directories-first"; l = "eza -abgHhl@ --git --color=always --group-directories-first";
tree = "exa --tree --color=always"; tree = "exa --tree --color=always";
ustrip = "sed -e '/\.service\|\.timer\|\.target\|\.socket\|\.slice\|\.scope\|\.path\|\.mount\|\.device)/!d' -e 's/loaded.*$//g' -e 's/^ \|^ //g'"; ustrip = "sed -e '/\.service\|\.timer\|\.target\|\.socket\|\.slice\|\.scope\|\.path\|\.mount\|\.device)/!d' -e 's/loaded.*$//g' -e 's/^ \|^ //g'";
lsunits = "systemctl list-units | ustrip"; lsunits = "systemctl list-units | ustrip";
};
shellInit = ''
function ll() { eza -abgHhl@ --git --color=always --group-directories-first $@ | bat --paging=always --style=changes --color=always --theme="Solarized (dark)" }
function lln() { eza -abgHhl@ --git --color=always --group-directories-first $@ | bat --paging=always --style=changes --color=always --theme="Solarized (dark)" -n }
function lszip() { unzip -l $@ 2>&1 | sed -e "1,3d" -e "s/^.*:.. *//g" | head --lines=-2 }
function rwhich() { realpath $(which $@) }
function cdf() { cd $(rwhich $@ | sed "s/$@$//") }
function sfu() { lsunits | rg -i $@ }
function map() { for f in "$\{@:2\}"; do; eval $1 \"$f\"; done }
'';
ohMyZsh = {
enable = true;
plugins = ["cabal" "docker" "gitfast" "python" "pip" "sudo" "systemd" "man"];
theme = "gentoo";
};
}; };
}
shellInit = ''
function ll() { eza -abgHhl@ --git --color=always --group-directories-first $@ | bat --paging=always --style=changes --color=always --theme="Solarized (dark)" }
function lln() { eza -abgHhl@ --git --color=always --group-directories-first $@ | bat --paging=always --style=changes --color=always --theme="Solarized (dark)" -n }
function lszip() { unzip -l $@ 2>&1 | sed -e "1,3d" -e "s/^.*:.. *//g" | head --lines=-2 }
function rwhich() { realpath $(which $@) }
function cdf() { cd $(rwhich $@ | sed "s/$@$//") }
function sfu() { lsunits | rg -i $@ }
function map() { for f in "$\{@:2\}"; do; eval $1 \"$f\"; done }
'';
ohMyZsh = {
enable = true;
plugins = [
"cabal"
"docker"
"gitfast"
"python"
"pip"
"sudo"
"systemd"
"man"
];
theme = "gentoo";
};
};
}

102
flake.nix
View file

@ -18,19 +18,21 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
}; };
outputs = { outputs =
self, {
nixpkgs, self,
flake-utils, nixpkgs,
nixpkgs-wayland, flake-utils,
mailserver, nixpkgs-wayland,
sops-nix, mailserver,
... sops-nix,
} @ attrs: ...
}@attrs:
flake-utils.lib.eachDefaultSystem ( flake-utils.lib.eachDefaultSystem (
system: let system:
let
inherit (nixpkgs) lib; inherit (nixpkgs) lib;
fn = import ./fn.nix {inherit lib;}; fn = import ./fn.nix { inherit lib; };
pkgs = nixpkgs.legacyPackages."${system}"; pkgs = nixpkgs.legacyPackages."${system}";
machineList = fn.lst { machineList = fn.lst {
p = toString ./machines; p = toString ./machines;
@ -39,46 +41,52 @@
}; };
nixosSystemFor = machine: { nixosSystemFor = machine: {
name = machine; name = machine;
value = let value =
configFiles = fn.lst { let
p = toString ./config; configFiles = fn.lst {
b = true; p = toString ./config;
}; b = true;
pkgsFiles = fn.lst { };
p = toString ./pkgs; pkgsFiles = fn.lst {
b = true; p = toString ./pkgs;
}; b = true;
serviceFiles = fn.lst { };
p = toString ./services; serviceFiles = fn.lst {
b = true; p = toString ./services;
}; b = true;
machinePath = lib.concatStringsSep "/" [(toString ./.) "machines" machine]; };
machineFiles = lib.filter (lib.strings.hasSuffix ".nix") (fn.lst { machinePath = lib.concatStringsSep "/" [
p = machinePath; (toString ./.)
b = true; "machines"
}); machine
in ];
machineFiles = lib.filter (lib.strings.hasSuffix ".nix") (
fn.lst {
p = machinePath;
b = true;
}
);
in
nixpkgs.lib.nixosSystem { nixpkgs.lib.nixosSystem {
inherit system; inherit system;
specialArgs = specialArgs = attrs // {
attrs inherit system;
// { inherit fn;
inherit system; };
inherit fn; modules = [
}; (
modules = { config, ... }:
[ {
({config, ...}: {config.nixpkgs.overlays = [nixpkgs-wayland.overlay];}) config.nixpkgs.overlays = [ nixpkgs-wayland.overlay ];
(toString ./options/machine.nix) }
sops-nix.nixosModules.sops )
] (toString ./options/machine.nix)
++ machineFiles sops-nix.nixosModules.sops
++ configFiles ] ++ machineFiles ++ configFiles ++ pkgsFiles ++ serviceFiles;
++ pkgsFiles
++ serviceFiles;
}; };
}; };
in { in
{
apps = { apps = {
"lint" = { "lint" = {
type = "app"; type = "app";

187
fn.nix
View file

@ -1,85 +1,94 @@
{lib}: { lib }:
with builtins; with builtins;
with lib; rec { with lib;
ifelse = a: b: c: rec {
if a ifelse =
then b a: b: c:
else c; if a then b else c;
fileContentsOr = a: b: (ifelse fileContentsOr = a: b: (ifelse (pathIsRegularFile a) a b);
(pathIsRegularFile a)
a
b);
cwd = builtins.getEnv "PWD"; cwd = builtins.getEnv "PWD";
# lst (string PATH) (string FILETYPE) (bool RETURNFULLPATH) # lst (string PATH) (string FILETYPE) (bool RETURNFULLPATH)
lst = { lst =
p ? cwd, {
t ? "regular", p ? cwd,
b ? false, t ? "regular",
}: (lists.forEach b ? false,
(attrNames }:
(filterAttrs (n: v: v == t) (lists.forEach (attrNames (filterAttrs (n: v: v == t) (readDir p))) (
(readDir p))) v: ((optionalString b "${p}/") + v)
(v: ((optionalString b "${p}/") + v))); ));
lsf = p: (lst {inherit p;}); lsf = p: (lst { inherit p; });
lsd = p: (lst { lsd =
inherit p; p:
t = "directory"; (lst {
b = true; inherit p;
}); t = "directory";
lsfRec = p: b: b = true;
flatten ((map (np: lsfRec np b) (lsd p)) });
lsfRec =
p: b:
flatten (
(map (np: lsfRec np b) (lsd p))
++ (lst { ++ (lst {
inherit p; inherit p;
inherit b; inherit b;
})); })
hasAttrs = aList: d: (map );
(a: (ifelse (isList a) hasAttrs = aList: d: (map (a: (ifelse (isList a) (hasAttrByPath a d) (hasAttr a d))) aList);
(hasAttrByPath a d)
(hasAttr a d)))
aList);
# Not sure how list operations are implemented in Nix # Not sure how list operations are implemented in Nix
# This might be a tad bit inefficient. # This might be a tad bit inefficient.
# TODO: look for better implementation (map is a builtin function so checking that probably won't help) # TODO: look for better implementation (map is a builtin function so checking that probably won't help)
# Sequentially checks elements of list (l) for condition (cond) and executes do on first match. # Sequentially checks elements of list (l) for condition (cond) and executes do on first match.
meetsConDo = cond: do: l: meetsConDo =
ifelse (l == []) false cond: do: l:
(let ifelse (l == [ ]) false (
h = head l; let
t = tail l; h = head l;
in t = tail l;
ifelse (cond h) (do h) in
(meetsConDo cond do t)); ifelse (cond h) (do h) (meetsConDo cond do t)
deps = p: );
ifelse (isAttrs p) ( deps =
filter isAttrs p:
(p.buildInputs ++ p.nativeBuildInputs ++ p.propagatedBuildInputs ++ p.propagatedNativeBuildInputs) ifelse (isAttrs p) (filter isAttrs (
) []; p.buildInputs ++ p.nativeBuildInputs ++ p.propagatedBuildInputs ++ p.propagatedNativeBuildInputs
)) [ ];
importFilter = l: filter (n: elem (nameFromURL (toString n) ".") l); importFilter = l: filter (n: elem (nameFromURL (toString n) ".") l);
depsRec = ld: ifelse (ld == []) [] ((toList ld) ++ (depsRec (lists.unique (lists.flatten (map deps (toList ld)))))); depsRec =
isBroken = p: ld:
meetsConDo (s: ((hasAttrByPath s.path p) && (s.check (getAttrFromPath s.path p)))) (s: s.msg) ifelse (ld == [ ]) [ ] (
[ (toList ld) ++ (depsRec (lists.unique (lists.flatten (map deps (toList ld)))))
);
isBroken =
p:
meetsConDo (s: ((hasAttrByPath s.path p) && (s.check (getAttrFromPath s.path p)))) (s: s.msg) [
{ {
path = ["meta" "broken"]; path = [
"meta"
"broken"
];
msg = warn "Package ${p.name} is marked as broken." true; msg = warn "Package ${p.name} is marked as broken." true;
check = m: m; check = m: m;
} }
{ {
path = ["meta" "knownVulnerabilities"]; path = [
"meta"
"knownVulnerabilities"
];
msg = warn "Package ${p.name} has known Vulnerabilities.." true; msg = warn "Package ${p.name} has known Vulnerabilities.." true;
check = m: m != []; check = m: m != [ ];
} }
{ {
path = ["name"]; path = [ "name" ];
msg = warn "${p.name}: python2 is depricated." false; msg = warn "${p.name}: python2 is depricated." false;
check = m: (strings.hasInfix "python2" m) || (strings.hasInfix "python-2" m); check = m: (strings.hasInfix "python2" m) || (strings.hasInfix "python-2" m);
} }
# not sure if the following test creates false positives (AFAIK every derivation/package needs to have an outPath) # not sure if the following test creates false positives (AFAIK every derivation/package needs to have an outPath)
# , definitely should catch all corner cases/everything that fails to evaluate. # , definitely should catch all corner cases/everything that fails to evaluate.
{ {
path = ["outPath"]; path = [ "outPath" ];
msg = warn "Package ${p.name} has no outPath" true; msg = warn "Package ${p.name} has no outPath" true;
check = m: !(tryEval m).success; check = m: !(tryEval m).success;
} }
@ -87,35 +96,45 @@ with lib; rec {
depsBroken = p: lists.any (p: (isBroken p)) (deps p); depsBroken = p: lists.any (p: (isBroken p)) (deps p);
# No more magic 🧙 here 😢 # No more magic 🧙 here 😢
# But at least it now (hopefully) checks ONLY dependencies (and all of them at that). # But at least it now (hopefully) checks ONLY dependencies (and all of them at that).
depsBrokenRec = p: ( depsBrokenRec =
meetsConDo p: (meetsConDo (p: ifelse (depsBroken p) true (depsBrokenRec (deps p))) (p: true) (deps p));
(p: ifelse (depsBroken p) true (depsBrokenRec (deps p))) sopsHelper =
(p: true) (deps p) template: names: options:
); let
sopsHelper = template: names: options: let optionsIsFunction = (typeOf options) == "lambda";
optionsIsFunction = (typeOf options) == "lambda"; in
in listToAttrs (
listToAttrs (map map (name: {
(name: {
name = template name; name = template name;
value = ifelse optionsIsFunction (options name) options; value = ifelse optionsIsFunction (options name) options;
}) }) names
names); );
pkgFilter = ld: (filter pkgFilter =
(p: ( ld:
ifelse (isBroken p) (filter (
false p:
(ifelse (depsBrokenRec p) (ifelse (isBroken p) false (
(warn "Dependency of ${p.name} is marked as broken." false) ifelse (depsBrokenRec p) (warn "Dependency of ${p.name} is marked as broken." false) true
true) ))
)) ) ld);
ld); makeOptionTypeList =
makeOptionTypeList = path: ( path:
lists.forEach (lists.forEach
# get a list of all files ending in .nix in path # get a list of all files ending in .nix in path
(filter (hasSuffix ".nix") (filter (hasSuffix ".nix") (lsfRec path true))
(lsfRec path true)) # remove leading path and trailing ".nix", replace every slash with "::"
# remove leading path and trailing ".nix", replace every slash with "::" (
(replaceStrings ["${path}/" "/" ".nix"] ["" "::" ""]) replaceStrings
); [
"${path}/"
"/"
".nix"
]
[
""
"::"
""
]
)
);
} }

View file

@ -2,7 +2,8 @@
pkgs, pkgs,
lib, lib,
... ...
}: { }:
{
services.cron.enable = false; services.cron.enable = false;
networking.dhcpcd.extraConfig = "noarp"; networking.dhcpcd.extraConfig = "noarp";
@ -56,7 +57,7 @@
}; };
joycond.enable = true; joycond.enable = true;
udev = { udev = {
packages = []; packages = [ ];
extraRules = '' extraRules = ''
KERNEL=="rtc0", GROUP="audio" KERNEL=="rtc0", GROUP="audio"
KERNEL=="hpet", GROUP="audio" KERNEL=="hpet", GROUP="audio"
@ -64,8 +65,13 @@
}; };
}; };
boot = { boot = {
kernelModules = ["snd-usb-audio" "snd-aloop" "snd-seq" "snd-rawmidi"]; kernelModules = [
kernelParams = ["threadirq"]; "snd-usb-audio"
"snd-aloop"
"snd-seq"
"snd-rawmidi"
];
kernelParams = [ "threadirq" ];
extraModprobeConfig = '' extraModprobeConfig = ''
options snd-usb-audio nrpacks=1 options snd-usb-audio nrpacks=1
''; '';

View file

@ -3,10 +3,12 @@
config, config,
pkgs, pkgs,
... ...
}: let }:
let
cfg = config.machine; cfg = config.machine;
in { in
imports = ["${nixpkgs}/nixos/modules/installer/scan/not-detected.nix"]; {
imports = [ "${nixpkgs}/nixos/modules/installer/scan/not-detected.nix" ];
boot = { boot = {
loader.systemd-boot = { loader.systemd-boot = {
@ -22,14 +24,24 @@ in {
}; };
kernelPackages = pkgs.linuxPackages_latest; kernelPackages = pkgs.linuxPackages_latest;
initrd.availableKernelModules = ["xhci_pci" "ahci" "sd_mod" "rtsx_pci_sdmmc"]; initrd.availableKernelModules = [
kernelModules = ["acpi_call" "i915" "kvm-intel" "uinput"]; "xhci_pci"
"ahci"
"sd_mod"
"rtsx_pci_sdmmc"
];
kernelModules = [
"acpi_call"
"i915"
"kvm-intel"
"uinput"
];
# 5_10 breaks my touchpad/mouse buttons # 5_10 breaks my touchpad/mouse buttons
# https://bbs.archlinux.org/viewtopic.php?id=254885 # https://bbs.archlinux.org/viewtopic.php?id=254885
# maybe modprobe hid_rmi or i2c_i801 # maybe modprobe hid_rmi or i2c_i801
# blacklistedKernelModules = [ "i2c_i801" ]; # blacklistedKernelModules = [ "i2c_i801" ];
extraModulePackages = with config.boot.kernelPackages; [acpi_call]; #pkgs.gitpkgs.linuxPackages_latest.hid-nintendo ]; extraModulePackages = with config.boot.kernelPackages; [ acpi_call ]; # pkgs.gitpkgs.linuxPackages_latest.hid-nintendo ];
kernelParams = ["intel_iommu=on"]; kernelParams = [ "intel_iommu=on" ];
extraModprobeConfig = '' extraModprobeConfig = ''
options i915 enable_fbc=1 enable_guc=3 options i915 enable_fbc=1 enable_guc=3
''; '';
@ -51,13 +63,15 @@ in {
}; };
hardware = { hardware = {
firmware = with pkgs; [firmwareLinuxNonfree]; firmware = with pkgs; [ firmwareLinuxNonfree ];
cpu.intel.updateMicrocode = true; cpu.intel.updateMicrocode = true;
enableAllFirmware = false; enableAllFirmware = false;
ksm.enable = true; ksm.enable = true;
graphics = { graphics = {
extraPackages = with pkgs; [ (intel-vaapi-driver.override { enableHybridCodec = true; }) ]; extraPackages = with pkgs; [ (intel-vaapi-driver.override { enableHybridCodec = true; }) ];
extraPackages32 = with pkgs.pkgsi686Linux; [ (intel-vaapi-driver.override { enableHybridCodec = true; }) ]; extraPackages32 = with pkgs.pkgsi686Linux; [
(intel-vaapi-driver.override { enableHybridCodec = true; })
];
}; };
pulseaudio = { pulseaudio = {
@ -82,7 +96,7 @@ in {
}; };
services = { services = {
upower.enable = true; upower.enable = true;
xserver.videoDrivers = ["intel"]; xserver.videoDrivers = [ "intel" ];
}; };
environment.variables.LIBVA_DRIVER_NAME = "i915"; environment.variables.LIBVA_DRIVER_NAME = "i915";
time.timeZone = "Europe/Berlin"; time.timeZone = "Europe/Berlin";

View file

@ -3,7 +3,8 @@
lib, lib,
... ...
}: }:
with lib; { with lib;
{
imports = [ imports = [
../../options/copySysConf.nix ../../options/copySysConf.nix
]; ];
@ -51,8 +52,8 @@ with lib; {
firewall = { firewall = {
enable = true; enable = true;
allowPing = true; allowPing = true;
allowedUDPPorts = [24642]; allowedUDPPorts = [ 24642 ];
allowedTCPPorts = [24642]; allowedTCPPorts = [ 24642 ];
allowedUDPPortRanges = [ allowedUDPPortRanges = [
{ {
from = 1714; from = 1714;

View file

@ -2,7 +2,8 @@
config, config,
lib, lib,
... ...
}: { }:
{
sops = { sops = {
defaultSopsFile = ./secrets.yaml; defaultSopsFile = ./secrets.yaml;
age = { age = {

View file

@ -1,4 +1,5 @@
{pkgs, ...}: { { pkgs, ... }:
{
services.cron.enable = false; services.cron.enable = false;
security.pki.certificateFiles = [ security.pki.certificateFiles = [
./certs/proxy ./certs/proxy

View file

@ -3,10 +3,12 @@
pkgs, pkgs,
modulesPath, modulesPath,
... ...
}: let }:
let
cfg = config.machine; cfg = config.machine;
in { in
imports = [(modulesPath + "/installer/scan/not-detected.nix")]; {
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot = { boot = {
loader.systemd-boot = { loader.systemd-boot = {
@ -19,8 +21,14 @@ in {
}; };
kernelPackages = pkgs.linuxPackages_latest; kernelPackages = pkgs.linuxPackages_latest;
initrd.availableKernelModules = ["nvme" "xhci_pci" "usb_storage" "sd_mod" "rtsx_pci_sdmmc"]; initrd.availableKernelModules = [
kernelModules = ["kvm-amd"]; "nvme"
"xhci_pci"
"usb_storage"
"sd_mod"
"rtsx_pci_sdmmc"
];
kernelModules = [ "kvm-amd" ];
kernelParams = [ kernelParams = [
# get backlight service to work part one (fixes systemd backlight service) # get backlight service to work part one (fixes systemd backlight service)
"acpi_backlight=native" "acpi_backlight=native"
@ -43,7 +51,7 @@ in {
}; };
hardware = { hardware = {
firmware = with pkgs; [firmwareLinuxNonfree]; firmware = with pkgs; [ firmwareLinuxNonfree ];
enableAllFirmware = true; enableAllFirmware = true;
ksm.enable = true; ksm.enable = true;
opengl = { opengl = {

View file

@ -3,7 +3,8 @@
lib, lib,
... ...
}: }:
with lib; { with lib;
{
imports = [ imports = [
../../options/copySysConf.nix ../../options/copySysConf.nix
]; ];
@ -41,10 +42,10 @@ with lib; {
firewall = { firewall = {
enable = true; enable = true;
allowPing = true; allowPing = true;
allowedUDPPorts = []; allowedUDPPorts = [ ];
allowedTCPPorts = []; allowedTCPPorts = [ ];
allowedUDPPortRanges = []; allowedUDPPortRanges = [ ];
allowedTCPPortRanges = []; allowedTCPPortRanges = [ ];
}; };
}; };

View file

@ -2,7 +2,8 @@
config, config,
lib, lib,
... ...
}: { }:
{
sops = { sops = {
defaultSopsFile = ./secrets.yaml; defaultSopsFile = ./secrets.yaml;
age = { age = {

View file

@ -2,16 +2,23 @@
nixpkgs, nixpkgs,
pkgs, pkgs,
... ...
}: { }:
{
imports = [ imports = [
"${nixpkgs}/nixos/modules/profiles/qemu-guest.nix" "${nixpkgs}/nixos/modules/profiles/qemu-guest.nix"
]; ];
boot = { boot = {
initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "sd_mod" "sr_mod"]; initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"virtio_pci"
"sd_mod"
"sr_mod"
];
kernelPackages = pkgs.linuxPackages_latest; kernelPackages = pkgs.linuxPackages_latest;
kernelModules = []; kernelModules = [ ];
extraModulePackages = []; extraModulePackages = [ ];
loader.grub = { loader.grub = {
enable = true; enable = true;
device = "/dev/sda"; # or "nodev" for efi only device = "/dev/sda"; # or "nodev" for efi only
@ -25,5 +32,5 @@
fsType = "ext4"; fsType = "ext4";
}; };
swapDevices = []; swapDevices = [ ];
} }

View file

@ -3,9 +3,11 @@
lib, lib,
... ...
}: }:
with lib; let with lib;
let
cfg = config.machine; cfg = config.machine;
in { in
{
config.machine = rec { config.machine = rec {
hostName = "Ophanim"; hostName = "Ophanim";
domain = "ophanim.de"; domain = "ophanim.de";
@ -18,7 +20,10 @@ in {
mailAccounts = [ mailAccounts = [
{ {
name = "derped"; name = "derped";
aliases = ["postmaster" "baensch"]; aliases = [
"postmaster"
"baensch"
];
} }
]; ];
allowUnfree = true; allowUnfree = true;
@ -42,37 +47,48 @@ in {
"nginx" "nginx"
"openssh" "openssh"
]; ];
vHosts = let vHosts =
base = domain; let
in [ base = domain;
{ in
domain = base; [
service = "simple"; {
} domain = base;
# { domain = "builder.${base}"; service = "hydra"; } service = "simple";
# { domain = "cache.${base}"; service = "cache"; } }
{ # { domain = "builder.${base}"; service = "hydra"; }
domain = "storage.${base}"; # { domain = "cache.${base}"; service = "cache"; }
service = "nextcloud"; {
} domain = "storage.${base}";
{ service = "nextcloud";
domain = "mail.${base}"; }
service = "mail"; {
} domain = "mail.${base}";
{ service = "mail";
domain = "git.${base}"; }
service = "forgejo"; {
} domain = "git.${base}";
{ service = "forgejo";
domain = "food.${base}"; }
service = "tandoor"; {
} domain = "food.${base}";
]; service = "tandoor";
}
];
firewall = { firewall = {
enable = true; enable = true;
allowPing = false; allowPing = false;
allowedUDPPorts = [22 80 443 7776]; allowedUDPPorts = [
allowedTCPPorts = [80 443 7776]; 22
80
443
7776
];
allowedTCPPorts = [
80
443
7776
];
}; };
}; };
} }

View file

@ -2,7 +2,8 @@
config, config,
lib, lib,
... ...
}: { }:
{
sops = { sops = {
defaultSopsFile = ./secrets.yaml; defaultSopsFile = ./secrets.yaml;
age = { age = {

View file

@ -18,7 +18,11 @@
}; };
fileSystems."/home/august/Videos" = { fileSystems."/home/august/Videos" = {
device = "/mnt/WD/Videos/Movies/"; device = "/mnt/WD/Videos/Movies/";
options = [ "nofail" "bind" "x-systemd.automount" ]; options = [
"nofail"
"bind"
"x-systemd.automount"
];
neededForBoot = false; neededForBoot = false;
}; };
} }

View file

@ -1,4 +1,5 @@
{...}: { { ... }:
{
services = { services = {
avahi = { avahi = {
enable = true; enable = true;
@ -13,16 +14,18 @@
}; };
# udp5353 1024-65535 # udp5353 1024-65535
networking.firewall = let networking.firewall =
range = { let
from = 1024; range = {
to = 65535; from = 1024;
to = 65535;
};
in
{
allowedUDPPorts = [ 5353 ];
allowedUDPPortRanges = [ range ];
allowedTCPPortRanges = [ range ];
}; };
in {
allowedUDPPorts = [ 5353 ];
allowedUDPPortRanges = [ range ];
allowedTCPPortRanges = [ range ];
};
networking.dhcpcd.extraConfig = "noarp"; networking.dhcpcd.extraConfig = "noarp";
system.stateVersion = "24.05"; system.stateVersion = "24.05";
} }

View file

@ -1,11 +1,16 @@
{nixos-hardware, ...}: { { nixos-hardware, ... }:
{
imports = [ imports = [
nixos-hardware.nixosModules.raspberry-pi-5 nixos-hardware.nixosModules.raspberry-pi-5
]; ];
boot = { boot = {
kernelParams = [ "8250.nr_uarts=11" "console=ttyAMA10,9600" "console=tty0" ]; kernelParams = [
supportedFilesystems = ["btrfs"]; "8250.nr_uarts=11"
"console=ttyAMA10,9600"
"console=tty0"
];
supportedFilesystems = [ "btrfs" ];
initrd.systemd.enableTpm2 = false; initrd.systemd.enableTpm2 = false;
loader.systemd-boot.enable = true; loader.systemd-boot.enable = true;
loader.efi.canTouchEfiVariables = false; loader.efi.canTouchEfiVariables = false;
@ -14,7 +19,12 @@
"/" = { "/" = {
device = "none"; device = "none";
fsType = "tmpfs"; fsType = "tmpfs";
options = ["defaults" "size=2G" "mode=755" "noexec"]; options = [
"defaults"
"size=2G"
"mode=755"
"noexec"
];
}; };
"/boot" = { "/boot" = {
device = "/dev/disk/by-uuid/F8BB-8019"; device = "/dev/disk/by-uuid/F8BB-8019";
@ -23,25 +33,40 @@
"/nix" = { "/nix" = {
device = "/dev/disk/by-uuid/7741fa2e-ce5d-4aef-bf3c-8e283e973409"; device = "/dev/disk/by-uuid/7741fa2e-ce5d-4aef-bf3c-8e283e973409";
fsType = "btrfs"; fsType = "btrfs";
options = ["subvol=nix" "compress=zstd" "noatime"]; options = [
"subvol=nix"
"compress=zstd"
"noatime"
];
neededForBoot = true; neededForBoot = true;
}; };
"/persist" = { "/persist" = {
device = "/dev/disk/by-uuid/7741fa2e-ce5d-4aef-bf3c-8e283e973409"; device = "/dev/disk/by-uuid/7741fa2e-ce5d-4aef-bf3c-8e283e973409";
fsType = "btrfs"; fsType = "btrfs";
options = ["subvol=persist" "compress=zstd" "noexec"]; options = [
"subvol=persist"
"compress=zstd"
"noexec"
];
neededForBoot = true; neededForBoot = true;
}; };
"/snapshots" = { "/snapshots" = {
device = "/dev/disk/by-uuid/7741fa2e-ce5d-4aef-bf3c-8e283e973409"; device = "/dev/disk/by-uuid/7741fa2e-ce5d-4aef-bf3c-8e283e973409";
fsType = "btrfs"; fsType = "btrfs";
options = ["subvol=snapshots" "compress=zstd" "noexec"]; options = [
"subvol=snapshots"
"compress=zstd"
"noexec"
];
neededForBoot = false; neededForBoot = false;
}; };
"/mnt/WD" = { "/mnt/WD" = {
device = "/dev/disk/by-uuid/EA2866C92866947B"; device = "/dev/disk/by-uuid/EA2866C92866947B";
fsType = "ntfs"; fsType = "ntfs";
options = ["nofail" "x-systemd.automount"]; options = [
"nofail"
"x-systemd.automount"
];
neededForBoot = false; neededForBoot = false;
}; };
}; };

View file

@ -1,4 +1,5 @@
{impermanence, ...}: { { impermanence, ... }:
{
imports = [ imports = [
impermanence.nixosModules.impermanence impermanence.nixosModules.impermanence
]; ];

View file

@ -1,4 +1,5 @@
{...}: { { ... }:
{
imports = [ imports = [
../../options/copySysConf.nix ../../options/copySysConf.nix
]; ];

View file

@ -2,7 +2,8 @@
config, config,
lib, lib,
... ...
}: { }:
{
sops = { sops = {
defaultSopsFile = ./secrets.yaml; defaultSopsFile = ./secrets.yaml;
age = { age = {

View file

@ -4,12 +4,12 @@
lib, lib,
... ...
}: }:
with lib; let with lib;
let
cfg = config.system.copySysConf; cfg = config.system.copySysConf;
cfgPath = ../.; cfgPath = ../.;
copySysConf = copySysConf =
if !(isStorePath cfgPath) if !(isStorePath cfgPath) then
then
pkgs.stdenv.mkDerivation rec { pkgs.stdenv.mkDerivation rec {
name = "NixOS_Configuration-${version}"; name = "NixOS_Configuration-${version}";
version = commitIdFromGitRepo (cfgPath + "/.git"); version = commitIdFromGitRepo (cfgPath + "/.git");
@ -20,8 +20,10 @@ with lib; let
cp -R ./. $out cp -R ./. $out
''; '';
} }
else (builtins.toPath ../.); else
in { (builtins.toPath ../.);
in
{
options.system.copySysConf = { options.system.copySysConf = {
enable = mkOption { enable = mkOption {
type = types.bool; type = types.bool;

View file

@ -5,7 +5,8 @@
... ...
}: }:
with builtins; with builtins;
with lib; let with lib;
let
cfg = config.machine; cfg = config.machine;
pkgsetList = fn.makeOptionTypeList (toString ../pkgsets); pkgsetList = fn.makeOptionTypeList (toString ../pkgsets);
serviceList = fn.makeOptionTypeList (toString ../services); serviceList = fn.makeOptionTypeList (toString ../services);
@ -13,7 +14,12 @@ with lib; let
name = pname; name = pname;
value = rec { value = rec {
pkgwrap = mkOption { pkgwrap = mkOption {
type = with types; oneOf [package (listOf package)]; type =
with types;
oneOf [
package
(listOf package)
];
default = fn.pkgFilter cfg.pkgsets."${pname}".pkgs; default = fn.pkgFilter cfg.pkgsets."${pname}".pkgs;
description = '' description = ''
Package Wrapper for packages using a wrapper function (like python, haskell, ...) Package Wrapper for packages using a wrapper function (like python, haskell, ...)
@ -21,18 +27,19 @@ with lib; let
}; };
pkgs = mkOption { pkgs = mkOption {
type = types.unspecified; type = types.unspecified;
default = []; default = [ ];
description = '' description = ''
${pname} package list. ${pname} package list.
''; '';
}; };
}; };
}; };
in { in
{
options.machine = { options.machine = {
pkgs = mkOption { pkgs = mkOption {
type = types.listOf (types.enum pkgsetList); type = types.listOf (types.enum pkgsetList);
default = ["base"]; default = [ "base" ];
description = '' description = ''
The list of metapackages to be installed. The list of metapackages to be installed.
''; '';
@ -41,14 +48,14 @@ in {
pkgsets = listToAttrs (map pkgOption (lists.filter (v: !(strings.hasInfix "::" v)) pkgsetList)); pkgsets = listToAttrs (map pkgOption (lists.filter (v: !(strings.hasInfix "::" v)) pkgsetList));
services = mkOption { services = mkOption {
type = types.listOf (types.enum serviceList); type = types.listOf (types.enum serviceList);
default = []; default = [ ];
description = '' description = ''
List of services to be enabled. List of services to be enabled.
''; '';
}; };
conffiles = mkOption { conffiles = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = ["zsh"]; default = [ "zsh" ];
description = '' description = ''
List of configuration files to be enabled. List of configuration files to be enabled.
''; '';
@ -77,7 +84,7 @@ in {
}; };
binaryCaches = mkOption { binaryCaches = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
description = '' description = ''
Adds binary caches to both nix.trustedBinaryCaches and nix.binaryCaches. ("https://cache.nixos.org" is kept by default) Adds binary caches to both nix.trustedBinaryCaches and nix.binaryCaches. ("https://cache.nixos.org" is kept by default)
''; '';
@ -97,28 +104,47 @@ in {
}; };
extraDomains = mkOption { extraDomains = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [ ];
description = '' description = ''
Extra domains used in various services. Extra domains used in various services.
''; '';
}; };
mailAccounts = mkOption { mailAccounts = mkOption {
type = types.listOf types.attrs; type = types.listOf types.attrs;
default = []; default = [ ];
description = '' description = ''
List of mail account user names. List of mail account user names.
''; '';
}; };
vHosts = mkOption { vHosts = mkOption {
type = types.listOf types.attrs; type = types.listOf types.attrs;
default = []; default = [ ];
description = '' description = ''
Domain - Service mappings for nginx vHost config. Domain - Service mappings for nginx vHost config.
''; '';
}; };
}; };
imports = [ imports = [
(mkAliasOptionModule ["machine" "firewall"] ["networking" "firewall"]) (mkAliasOptionModule
(mkAliasOptionModule ["machine" "allowUnfree"] ["nixpkgs" "config" "allowUnfree"]) [
"machine"
"firewall"
]
[
"networking"
"firewall"
]
)
(mkAliasOptionModule
[
"machine"
"allowUnfree"
]
[
"nixpkgs"
"config"
"allowUnfree"
]
)
]; ];
} }

View file

@ -68,7 +68,7 @@ buildPythonPackage rec {
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "GNU Mailman, a mailing list management system"; description = "GNU Mailman, a mailing list management system";
license = licenses.gpl3; license = licenses.gpl3;
maintainers = with maintainers; []; maintainers = with maintainers; [ ];
homepage = "http://list.org/"; homepage = "http://list.org/";
}; };
} }

View file

@ -14,5 +14,5 @@ buildPythonPackage rec {
sha256 = "1xdfk741pjmz1cm8dsi4n5vq4517i175rm94696m3f7kcgk7xsmp"; sha256 = "1xdfk741pjmz1cm8dsi4n5vq4517i175rm94696m3f7kcgk7xsmp";
}; };
doCheck = false; doCheck = false;
propagatedBuildInputs = [atpublic]; propagatedBuildInputs = [ atpublic ];
} }

View file

@ -16,7 +16,10 @@ buildPythonPackage rec {
sha256 = "0k5kjqa3x6gvwwxyzb2vwi1g1i6asm1zw5fivylxz3d583y4kid2"; sha256 = "0k5kjqa3x6gvwwxyzb2vwi1g1i6asm1zw5fivylxz3d583y4kid2";
}; };
propagatedBuildInputs = [atpublic zope_interface]; propagatedBuildInputs = [
atpublic
zope_interface
];
doCheck = false; doCheck = false;
} }

View file

@ -15,7 +15,7 @@ buildPythonPackage rec {
sha256 = "1csgds59nx0ann9v2alqr69lakp1cnc1ikmbgn96l6n23js7c2ah"; sha256 = "1csgds59nx0ann9v2alqr69lakp1cnc1ikmbgn96l6n23js7c2ah";
}; };
propagatedBuildInputs = [atpublic]; propagatedBuildInputs = [ atpublic ];
doCheck = false; doCheck = false;
} }

View file

@ -15,7 +15,7 @@ buildPythonPackage rec {
sha256 = "0nzzd6l30ff6cwsrlrb94xzfja4wkyrqv3ydc6cz0hdbr766mmm8"; sha256 = "0nzzd6l30ff6cwsrlrb94xzfja4wkyrqv3ydc6cz0hdbr766mmm8";
}; };
propagatedBuildInputs = [atpublic]; propagatedBuildInputs = [ atpublic ];
doCheck = false; doCheck = false;
} }

View file

@ -15,7 +15,7 @@ buildPythonPackage rec {
sha256 = "1s7pyvlq06qjrkaw9r6nc290lb095n25ybzgavvy51ygpxkgqxwn"; sha256 = "1s7pyvlq06qjrkaw9r6nc290lb095n25ybzgavvy51ygpxkgqxwn";
}; };
propagatedBuildInputs = [lazr_delegates]; propagatedBuildInputs = [ lazr_delegates ];
doCheck = false; doCheck = false;
} }

View file

@ -16,7 +16,10 @@ buildPythonPackage rec {
sha256 = "1rdnl85j9ayp8n85l0ciip621j9dcziz5qnmv2m7krgwgcn31vfx"; sha256 = "1rdnl85j9ayp8n85l0ciip621j9dcziz5qnmv2m7krgwgcn31vfx";
}; };
propagatedBuildInputs = [nose zope_interface]; propagatedBuildInputs = [
nose
zope_interface
];
doCheck = false; doCheck = false;
} }

View file

@ -4,8 +4,9 @@
config, config,
... ...
}: }:
with lib; let with lib;
mailman3 = import ./release.nix {}; let
mailman3 = import ./release.nix { };
cfg = config.services.mailman3; cfg = config.services.mailman3;
usePostgresql = cfg.database.type == "postgresql"; usePostgresql = cfg.database.type == "postgresql";
useSqlite = cfg.database.type == "sqlite3"; useSqlite = cfg.database.type == "sqlite3";
@ -75,7 +76,8 @@ with lib; let
${cfg.extraConfig} ${cfg.extraConfig}
''; '';
in { in
{
options.services.mailman3 = { options.services.mailman3 = {
enable = mkOption { enable = mkOption {
type = types.bool; type = types.bool;
@ -104,7 +106,11 @@ in {
database = { database = {
type = mkOption { type = mkOption {
type = types.enum ["sqlite3" "mysql" "postgres"]; type = types.enum [
"sqlite3"
"mysql"
"postgres"
];
default = "sqlite3"; default = "sqlite3";
example = "mysql"; example = "mysql";
description = '' description = ''
@ -273,7 +279,10 @@ in {
mta = { mta = {
# TODO: add Sentmail and qmail # TODO: add Sentmail and qmail
type = mkOption { type = mkOption {
type = types.enum ["postfix" "exim4"]; type = types.enum [
"postfix"
"exim4"
];
default = "postfix"; default = "postfix";
example = "exim4"; example = "exim4";
description = '' description = ''
@ -366,42 +375,55 @@ in {
home = cfg.paths.var_dir; home = cfg.paths.var_dir;
createHome = true; createHome = true;
useDefaultShell = true; useDefaultShell = true;
packages = [mailman3.core]; packages = [ mailman3.core ];
}; };
}; };
services.postfix.recipientDelimiter = mkIf usePostfix (mkDefault "+"); services.postfix.recipientDelimiter = mkIf usePostfix (mkDefault "+");
services.postfix.mapFiles."transport_maps" = mkIf usePostfix (mkDefault "${cfg.paths.data_dir}/postfix_lmtp"); services.postfix.mapFiles."transport_maps" = mkIf usePostfix (
services.postfix.mapFiles."local_recipient_maps" = mkIf usePostfix (mkDefault "${cfg.paths.data_dir}/postfix_lmtp"); mkDefault "${cfg.paths.data_dir}/postfix_lmtp"
services.postfix.mapFiles."relay_domains" = mkIf usePostfix (mkDefault "${cfg.paths.data_dir}/postfix_domains"); );
services.postfix.mapFiles."local_recipient_maps" = mkIf usePostfix (
mkDefault "${cfg.paths.data_dir}/postfix_lmtp"
);
services.postfix.mapFiles."relay_domains" = mkIf usePostfix (
mkDefault "${cfg.paths.data_dir}/postfix_domains"
);
warnings = warnings = optional (cfg.database.password != "") ''
optional (cfg.database.password != "") config.services.mailman3.database.password will be stored as plaintext
'' config.services.mailman3.database.password will be stored as plaintext in the Nix store. Use database.passwordFile instead.'';
in the Nix store. Use database.passwordFile instead.'';
# Create database passwordFile default when password is configured. # Create database passwordFile default when password is configured.
services.mailman3.database.passwordFile = mkDefault (toString (pkgs.writeTextFile { services.mailman3.database.passwordFile = mkDefault (
name = "mailman3-database-password"; toString (
text = cfg.database.password; pkgs.writeTextFile {
})); name = "mailman3-database-password";
text = cfg.database.password;
}
)
);
systemd.services.mailman3 = { systemd.services.mailman3 = {
description = "GNU Mailing List Manager"; description = "GNU Mailing List Manager";
after = ["network.target"] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service"; after = [
wantedBy = ["multi-user.target"]; "network.target"
] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service";
wantedBy = [ "multi-user.target" ];
preStart = let preStart =
dbpass = fileContents cfg.database.passwordFile; let
smtppass = fileContents cfg.mta.smtp_passFile; dbpass = fileContents cfg.database.passwordFile;
in '' smtppass = fileContents cfg.mta.smtp_passFile;
mkdir -p ${cfg.paths.etc_dir} in
cp ${configFile} ${cfg.paths.etc_dir}/mailman.cfg ''
${optionalString (useMysql || usePostgresql) '' mkdir -p ${cfg.paths.etc_dir}
sed -e "s/#dbpass#/${dbpass}/g" -e "s/#smtppass#/${smtppass}/g" -i ${cfg.paths.etc_dir}/mailman.cfg cp ${configFile} ${cfg.paths.etc_dir}/mailman.cfg
''} ${optionalString (useMysql || usePostgresql) ''
chmod 640 ${cfg.paths.etc_dir}/mailman.cfg sed -e "s/#dbpass#/${dbpass}/g" -e "s/#smtppass#/${smtppass}/g" -i ${cfg.paths.etc_dir}/mailman.cfg
''; ''}
chmod 640 ${cfg.paths.etc_dir}/mailman.cfg
'';
serviceConfig = { serviceConfig = {
Type = "forking"; Type = "forking";

View file

@ -1,17 +1,28 @@
{ {
pkgs ? import <nixpkgs> {}, pkgs ? import <nixpkgs> { },
python3Packages ? pkgs.python3Packages, python3Packages ? pkgs.python3Packages,
}: let }:
let
mailman3 = { mailman3 = {
core = python3Packages.callPackage ./core.nix (with deps; { core = python3Packages.callPackage ./core.nix (
inherit aiosmtpd atpublic flufl_bounce flufl_i18n flufl_lock lazr_config; with deps;
}); {
inherit
aiosmtpd
atpublic
flufl_bounce
flufl_i18n
flufl_lock
lazr_config
;
}
);
}; };
deps = rec { deps = rec {
aiosmtpd = python3Packages.callPackage ./extraPackages/aiosmtpd.nix { aiosmtpd = python3Packages.callPackage ./extraPackages/aiosmtpd.nix {
inherit atpublic; inherit atpublic;
}; };
atpublic = python3Packages.callPackage ./extraPackages/atpublic.nix {}; atpublic = python3Packages.callPackage ./extraPackages/atpublic.nix { };
flufl_bounce = python3Packages.callPackage ./extraPackages/flufl_bounce.nix { flufl_bounce = python3Packages.callPackage ./extraPackages/flufl_bounce.nix {
inherit atpublic; inherit atpublic;
}; };
@ -24,7 +35,7 @@
lazr_config = python3Packages.callPackage ./extraPackages/lazr_config.nix { lazr_config = python3Packages.callPackage ./extraPackages/lazr_config.nix {
inherit lazr_delegates; inherit lazr_delegates;
}; };
lazr_delegates = python3Packages.callPackage ./extraPackages/lazr_delegates.nix {}; lazr_delegates = python3Packages.callPackage ./extraPackages/lazr_delegates.nix { };
}; };
in in
mailman3 mailman3

View file

@ -13,6 +13,6 @@ stdenv.mkDerivation {
sha256 = "0rfv75w9yr8drc3x9g4iz2cb88ixy1lqbflvmb7farw4dz74fk5f"; sha256 = "0rfv75w9yr8drc3x9g4iz2cb88ixy1lqbflvmb7farw4dz74fk5f";
fetchSubmodules = true; fetchSubmodules = true;
}; };
makeFlags = ["PREFIX=$(out)"]; makeFlags = [ "PREFIX=$(out)" ];
propagatedUserEnvPkgs = [gtk-engine-murrine]; propagatedUserEnvPkgs = [ gtk-engine-murrine ];
} }

View file

@ -15,7 +15,7 @@ stdenv.mkDerivation {
sha256 = "sha256-BZRmjVas8q6zsYbXFk4bCk5Ec/3liy9PQ8fqFGHAXe0="; sha256 = "sha256-BZRmjVas8q6zsYbXFk4bCk5Ec/3liy9PQ8fqFGHAXe0=";
}; };
propagatedUserEnvPkgs = [gtk-engine-murrine]; propagatedUserEnvPkgs = [ gtk-engine-murrine ];
installPhase = '' installPhase = ''
runHook preInstall runHook preInstall

View file

@ -6,20 +6,22 @@
nixpkgs-stable, nixpkgs-stable,
nixpkgs-git, nixpkgs-git,
... ...
}: let }:
let
inherit (pkgs) callPackage; inherit (pkgs) callPackage;
in { in
{
nixpkgs = { nixpkgs = {
config = { config = {
allowUnfree = true; allowUnfree = true;
mpv.vaapiSupport = lib.elem "xserver" config.machine.services; mpv.vaapiSupport = lib.elem "xserver" config.machine.services;
packageOverrides = { packageOverrides = {
pyluxafor = pkgs.python3Packages.callPackage ./pyluxafor {}; pyluxafor = pkgs.python3Packages.callPackage ./pyluxafor { };
theme_flat-remix = callPackage ./flat-remix {}; theme_flat-remix = callPackage ./flat-remix { };
theme_sddm_midnight = callPackage ./sddm_midnight {}; theme_sddm_midnight = callPackage ./sddm_midnight { };
xdiskusage = callPackage ./xdiskusage {}; xdiskusage = callPackage ./xdiskusage { };
kanagawa = callPackage ./kanagawa {}; kanagawa = callPackage ./kanagawa { };
}; };
}; };
overlays = [ overlays = [

View file

@ -18,5 +18,8 @@ buildPythonApplication rec {
substituteInPlace setup.py --replace '"click>=6.0,<=6.7.99",' "" substituteInPlace setup.py --replace '"click>=6.0,<=6.7.99",' ""
substituteInPlace setup.py --replace '"pyusb==1.0.0",' "" substituteInPlace setup.py --replace '"pyusb==1.0.0",' ""
''; '';
propagatedBuildInputs = [click pyusb]; propagatedBuildInputs = [
click
pyusb
];
} }

View file

@ -5,22 +5,20 @@
pkgs, pkgs,
... ...
}: }:
with lib; let with lib;
let
cfg = config.machine; cfg = config.machine;
pkgsets = fn.lst { pkgsets = fn.lst {
p = toString ../pkgsets; p = toString ../pkgsets;
b = true; b = true;
}; };
in { in
{
imports = pkgsets; imports = pkgsets;
environment.systemPackages = environment.systemPackages = flatten (
flatten lists.forEach (attrVals (filter (v: !(strings.hasInfix "::" v)) cfg.pkgs) cfg.pkgsets) (
(lists.forEach v: v.pkgwrap
(attrVals )
(filter );
(v: !(strings.hasInfix "::" v))
cfg.pkgs)
cfg.pkgsets)
(v: v.pkgwrap));
} }

View file

@ -7,7 +7,7 @@ stdenv.mkDerivation rec {
name = "xdiskusage"; name = "xdiskusage";
version = "1.51"; version = "1.51";
buildInputs = [fltk]; buildInputs = [ fltk ];
src = fetchurl { src = fetchurl {
url = "http://xdiskusage.sourceforge.net/${name}-${version}.tgz"; url = "http://xdiskusage.sourceforge.net/${name}-${version}.tgz";

View file

@ -3,7 +3,8 @@
config, config,
pkgs, pkgs,
... ...
}: { }:
{
config.machine.pkgsets.base.pkgs = with pkgs; [ config.machine.pkgsets.base.pkgs = with pkgs; [
age age
sops sops

View file

@ -2,7 +2,8 @@
config, config,
pkgs, pkgs,
... ...
}: { }:
{
config.machine.pkgsets.cpp.pkgs = with pkgs; [ config.machine.pkgsets.cpp.pkgs = with pkgs; [
clang clang
cmake cmake

View file

@ -2,10 +2,24 @@
config, config,
pkgs, pkgs,
... ...
}: { }:
{
config.machine.pkgsets.dict.pkgs = with pkgs; [ config.machine.pkgsets.dict.pkgs = with pkgs; [
translate-shell translate-shell
(hunspellWithDicts (with pkgs.hunspellDicts; [de-de en-us])) (hunspellWithDicts (
(aspellWithDicts (d: with d; [de en en-computers en-science])) with pkgs.hunspellDicts;
[
de-de
en-us
]
))
(aspellWithDicts (
d: with d; [
de
en
en-computers
en-science
]
))
]; ];
} }

View file

@ -2,7 +2,8 @@
config, config,
pkgs, pkgs,
... ...
}: { }:
{
config.machine.pkgsets.extra.pkgs = with pkgs; [ config.machine.pkgsets.extra.pkgs = with pkgs; [
alsaUtils alsaUtils
binutils-unwrapped binutils-unwrapped

View file

@ -2,6 +2,10 @@
config, config,
pkgs, pkgs,
... ...
}: { }:
config.machine.pkgsets.haskell-tools.pkgs = with pkgs; [cabal-install hlint]; # ghcid {
config.machine.pkgsets.haskell-tools.pkgs = with pkgs; [
cabal-install
hlint
]; # ghcid
} }

View file

@ -4,8 +4,11 @@
fn, fn,
pkgs, pkgs,
... ...
}: { }:
config.machine.pkgsets.haskell.pkgwrap = pkgs.haskellPackages.ghcWithPackages (pkgs: (fn.pkgFilter config.machine.pkgsets.haskell.pkgs)); {
config.machine.pkgsets.haskell.pkgwrap = pkgs.haskellPackages.ghcWithPackages (
pkgs: (fn.pkgFilter config.machine.pkgsets.haskell.pkgs)
);
config.machine.pkgsets.haskell.pkgs = with pkgs.haskellPackages; [ config.machine.pkgsets.haskell.pkgs = with pkgs.haskellPackages; [
hindent hindent
mtl mtl

View file

@ -4,7 +4,8 @@
pkgs, pkgs,
... ...
}: }:
with lib; { with lib;
{
config.machine.pkgsets.latex.pkgs = with pkgs; [ config.machine.pkgsets.latex.pkgs = with pkgs; [
texlive.combined.scheme-full texlive.combined.scheme-full
texlab texlab

View file

@ -1,7 +1,8 @@
{ {
pkgs, pkgs,
... ...
}: { }:
{
config.machine.pkgsets.mail_utils.pkgs = with pkgs; [ config.machine.pkgsets.mail_utils.pkgs = with pkgs; [
aerc aerc
abook abook

View file

@ -1,6 +1,11 @@
{pkgs, ...}: { { pkgs, ... }:
{
config.machine.pkgsets.nodejs.pkgs = config.machine.pkgsets.nodejs.pkgs =
(with pkgs; [nodejs yarn deno]) (with pkgs; [
nodejs
yarn
deno
])
++ (with pkgs.nodePackages; [ ++ (with pkgs.nodePackages; [
autoprefixer autoprefixer
mermaid-cli mermaid-cli

View file

@ -4,11 +4,12 @@
fn, fn,
pkgs, pkgs,
... ...
}: { }:
{
config.machine.pkgsets.php.pkgwrap = fn.pkgFilter config.machine.pkgsets.php.pkgs; config.machine.pkgsets.php.pkgwrap = fn.pkgFilter config.machine.pkgsets.php.pkgs;
config.machine.pkgsets.php.pkgs = config.machine.pkgsets.php.pkgs =
(with pkgs.php82Packages; [ (with pkgs.php82Packages; [
composer composer
]) ])
++ (with pkgs; [php82]); ++ (with pkgs; [ php82 ]);
} }

View file

@ -5,8 +5,11 @@
pkgs, pkgs,
... ...
}: }:
with lib; { with lib;
config.machine.pkgsets.python3.pkgwrap = pkgs.python3.withPackages (ps: (fn.pkgFilter config.machine.pkgsets.python3.pkgs)); {
config.machine.pkgsets.python3.pkgwrap = pkgs.python3.withPackages (
ps: (fn.pkgFilter config.machine.pkgsets.python3.pkgs)
);
config.machine.pkgsets.python3.pkgs = with pkgs.python3Packages; [ config.machine.pkgsets.python3.pkgs = with pkgs.python3Packages; [
bpython bpython
flake8 flake8

View file

@ -1,15 +1,22 @@
{config, ...}: let { config, ... }:
mozRust = with builtins; let
(map (p: mozRust =
import ((fetchTarball { with builtins;
(map (
p:
import (
(fetchTarball {
url = "https://github.com/mozilla/nixpkgs-mozilla/archive/e912ed4.tar.gz"; url = "https://github.com/mozilla/nixpkgs-mozilla/archive/e912ed4.tar.gz";
sha256 = "08fvzb8w80bkkabc1iyhzd15f4sm7ra10jn32kfch5klgl0gj3j3"; sha256 = "08fvzb8w80bkkabc1iyhzd15f4sm7ra10jn32kfch5klgl0gj3j3";
}) })
+ p))) [ + p
(toPath "/lib-overlay.nix") )
(toPath "/rust-overlay.nix") ))
]; [
stablepkgs = import <nixos-stable> {overlays = mozRust;}; (toPath "/lib-overlay.nix")
(toPath "/rust-overlay.nix")
];
stablepkgs = import <nixos-stable> { overlays = mozRust; };
# https://rust-lang.github.io/rustup-components-history # https://rust-lang.github.io/rustup-components-history
nightly = stablepkgs.rustChannelOf { nightly = stablepkgs.rustChannelOf {
@ -27,18 +34,26 @@
"rustfmt-preview" "rustfmt-preview"
]; ];
} }
// {src = nightly.rust-src;}; // {
src = nightly.rust-src;
};
inherit (nightly) cargo; inherit (nightly) cargo;
}; };
rustPNightly = stablepkgs.recurseIntoAttrs (stablepkgs.makeRustPlatform { rustPNightly = stablepkgs.recurseIntoAttrs (
inherit (rustNightly) rustc cargo; stablepkgs.makeRustPlatform {
}); inherit (rustNightly) rustc cargo;
in { }
);
in
{
config.machine.pkgsets.rustpkgs.pkgs = config.machine.pkgsets.rustpkgs.pkgs =
(with stablepkgs; [ (with stablepkgs; [
diesel-cli diesel-cli
carnix carnix
rustracer rustracer
]) ])
++ (with rustNightly; [rustc cargo]); ++ (with rustNightly; [
rustc
cargo
]);
} }

View file

@ -2,7 +2,8 @@
config, config,
pkgs, pkgs,
... ...
}: { }:
{
config.machine.pkgsets.server.pkgs = with pkgs; [ config.machine.pkgsets.server.pkgs = with pkgs; [
audit audit
certbot certbot

View file

@ -4,7 +4,8 @@
pkgs, pkgs,
... ...
}: }:
with lib; { with lib;
{
config.machine.pkgsets.tracking.pkgs = with pkgs; [ config.machine.pkgsets.tracking.pkgs = with pkgs; [
aw-qt aw-qt
aw-server-rust aw-server-rust

View file

@ -2,6 +2,7 @@
config, config,
pkgs, pkgs,
... ...
}: { }:
config.machine.pkgsets.uniProgs.pkgs = with pkgs; [qucs]; {
config.machine.pkgsets.uniProgs.pkgs = with pkgs; [ qucs ];
} }

View file

@ -2,9 +2,11 @@
config, config,
pkgs, pkgs,
... ...
}: let }:
let
cfg = config.machine; cfg = config.machine;
in { in
{
config.machine.pkgsets.xpkgs.pkgs = with pkgs; [ config.machine.pkgsets.xpkgs.pkgs = with pkgs; [
acpilight acpilight
feh feh

View file

@ -7,13 +7,14 @@
... ...
}: }:
with builtins; with builtins;
with lib; let with lib;
let
cfg = config.machine; cfg = config.machine;
in in
mkIf (elem "acme" cfg.services) { mkIf (elem "acme" cfg.services) {
security.acme = { security.acme = {
# see https://letsencrypt.org/repository/ # see https://letsencrypt.org/repository/
acceptTerms = true; acceptTerms = true;
defaults.email = "${(elemAt cfg.mailAccounts 0).name}@${cfg.domain}"; defaults.email = "${(elemAt cfg.mailAccounts 0).name}@${cfg.domain}";
}; };
} }

View file

@ -8,29 +8,30 @@
... ...
}: }:
with builtins; with builtins;
with lib; let with lib;
let
cfg = config.machine; cfg = config.machine;
in in
mkIf (elem "bind" cfg.services) { mkIf (elem "bind" cfg.services) {
services.bind = { services.bind = {
enable = true; enable = true;
listenOn = ["127.0.0.1"]; listenOn = [ "127.0.0.1" ];
forwarders = [ forwarders = [
# Cloudflare CDN # Cloudflare CDN
"1.1.1.1" "1.1.1.1"
"1.0.0.1" "1.0.0.1"
#CCC DNS #CCC DNS
"204.152.184.76" "204.152.184.76"
"159.203.38.175" "159.203.38.175"
"207.148.83.241" "207.148.83.241"
]; ];
# TODO: add DNSSEC # TODO: add DNSSEC
extraOptions = '' extraOptions = ''
dnssec-validation auto; dnssec-validation auto;
recursion yes; recursion yes;
allow-recursion { 127.0.0.1; }; allow-recursion { 127.0.0.1; };
version none; version none;
''; '';
}; };
} }

View file

@ -4,21 +4,21 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "containers" config.machine.services) { mkIf (elem "containers" config.machine.services) {
containers.CDServer = { containers.CDServer = {
privateNetwork = true; privateNetwork = true;
hostAddress = "192.168.100.10"; hostAddress = "192.168.100.10";
localAddress = "192.168.100.11"; localAddress = "192.168.100.11";
config = { config = {
imports = [ imports = [
../machines/CDServer/options.nix ../machines/CDServer/options.nix
./default.nix ./default.nix
../config/default.nix ../config/default.nix
../pkgs/nixpkgs.nix ../pkgs/nixpkgs.nix
../pkgs/pkgsets.nix ../pkgs/pkgsets.nix
]; ];
services.nixosManual.showManual = false; services.nixosManual.showManual = false;
services.ntp.enable = false; services.ntp.enable = false;
};
}; };
} };
}

View file

@ -5,11 +5,16 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "cups" config.machine.services) { mkIf (elem "cups" config.machine.services) {
services.printing = { services.printing = {
enable = true; enable = true;
browsed.enable = false; browsed.enable = false;
startWhenNeeded = true; startWhenNeeded = true;
drivers = with pkgs; [gutenprint hplip splix samsung-unified-linux-driver]; drivers = with pkgs; [
}; gutenprint
} hplip
splix
samsung-unified-linux-driver
];
};
}

View file

@ -5,68 +5,69 @@
pkgs, pkgs,
... ...
}: }:
with lib; let with lib;
let
cfg = config.machine; cfg = config.machine;
desktopFiles = fn.lst { desktopFiles = fn.lst {
p = toString ./desktop; p = toString ./desktop;
b = true; b = true;
}; };
in in
{ {
imports = desktopFiles; imports = desktopFiles;
} }
// mkIf (elem "desktop" cfg.services) { // mkIf (elem "desktop" cfg.services) {
xdg.portal = { xdg.portal = {
enable = true;
wlr.enable = true;
extraPortals = with pkgs; [
xdg-desktop-portal-gtk
xdg-desktop-portal-gnome
];
};
services = {
gvfs.enable = true;
libinput = {
enable = true; enable = true;
wlr.enable = true; touchpad = {
extraPortals = with pkgs; [ tapping = true;
xdg-desktop-portal-gtk disableWhileTyping = false;
xdg-desktop-portal-gnome naturalScrolling = false;
]; horizontalScrolling = true;
};
}; };
services = { };
gvfs.enable = true; programs = {
libinput = { dconf.enable = true;
enable = true; regreet = {
touchpad = { enable = true;
tapping = true; settings = {
disableWhileTyping = false; GTK = {
naturalScrolling = false; application_prefer_dark_theme = true;
horizontalScrolling = true; theme_name = lib.mkForce "Kanagawa-BL";
};
};
};
programs = {
dconf.enable = true;
regreet = {
enable = true;
settings = {
GTK = {
application_prefer_dark_theme = true;
theme_name = lib.mkForce "Kanagawa-BL";
};
}; };
}; };
}; };
};
environment = { environment = {
systemPackages = with pkgs; [kanagawa]; systemPackages = with pkgs; [ kanagawa ];
etc."xdg/gtk-2.0/gtkrc".text = '' etc."xdg/gtk-2.0/gtkrc".text = ''
gtk-key-theme-name = "Kanagawa-BL" gtk-key-theme-name = "Kanagawa-BL"
'';
etc."xdg/gtk-3.0/settings.ini".text = ''
[Settings]
gtk-key-theme-name = Kanagawa-BL
'';
# Set keyboard layout for regreet cage
# see man cage or:
# https://man.archlinux.org/man/cage.1.en#ENVIRONMENT
variables.XKB_DEFAULT_LAYOUT = "de";
};
# Allow users in the video group to change the display brightness
services.udev.extraRules = ''
ACTION=="add", SUBSYSTEM=="backlight", RUN+="${pkgs.coreutils}/bin/chgrp video /sys/class/backlight/%k/brightness"
ACTION=="add", SUBSYSTEM=="backlight", RUN+="${pkgs.coreutils}/bin/chmod 664 /sys/class/backlight/%k/brightness"
''; '';
} etc."xdg/gtk-3.0/settings.ini".text = ''
[Settings]
gtk-key-theme-name = Kanagawa-BL
'';
# Set keyboard layout for regreet cage
# see man cage or:
# https://man.archlinux.org/man/cage.1.en#ENVIRONMENT
variables.XKB_DEFAULT_LAYOUT = "de";
};
# Allow users in the video group to change the display brightness
services.udev.extraRules = ''
ACTION=="add", SUBSYSTEM=="backlight", RUN+="${pkgs.coreutils}/bin/chgrp video /sys/class/backlight/%k/brightness"
ACTION=="add", SUBSYSTEM=="backlight", RUN+="${pkgs.coreutils}/bin/chmod 664 /sys/class/backlight/%k/brightness"
'';
}

View file

@ -5,20 +5,24 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "desktop::i3" config.machine.services) { mkIf (elem "desktop::i3" config.machine.services) {
services.xserver = { services.xserver = {
enable = true;
windowManager.i3 = {
enable = true; enable = true;
windowManager.i3 = { configFile = import ../../config/etc/i3/config.nix { inherit pkgs; };
enable = true; extraPackages = with pkgs; [
configFile = import ../../config/etc/i3/config.nix {inherit pkgs;}; dmenu
extraPackages = with pkgs; [ file
dmenu i3lock
file i3status
i3lock xdg-user-dirs
i3status ];
xdg-user-dirs
];
};
}; };
machine.pkgsets.python3.pkgs = with pkgs.python3Packages; [py3status pytz tzlocal]; };
} machine.pkgsets.python3.pkgs = with pkgs.python3Packages; [
py3status
pytz
tzlocal
];
}

View file

@ -5,47 +5,47 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "desktop::sway" config.machine.services) { mkIf (elem "desktop::sway" config.machine.services) {
programs.sway = { programs.sway = {
enable = true; enable = true;
package = pkgs.sway.override { package = pkgs.sway.override {
enableXWayland = true; enableXWayland = true;
};
extraPackages = with pkgs; [
file
gnome.adwaita-icon-theme
grim
gsettings-desktop-schemas
gtk3
i3status
kanagawa
light
mako
qt5.qtwayland
rofi-wayland
slurp
swayidle
swaylock
wf-recorder
wl-clipboard
];
wrapperFeatures = {
base = true;
gtk = true;
};
extraSessionCommands = ''
export GDK_BACKEND=wayland
export CLUTTER_BACKEND=wayland
export SDL_VIDEODRIVER=wayland
# needs qt5.qtwayland in systemPackages
export QT_QPA_PLATFORM=wayland-egl
export QT_WAYLAND_FORCE_DPI=physical
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
# Fix for some Java AWT applications (e.g. Android Studio),
# use this if they aren't displayed properly:
export _JAVA_AWT_WM_NONREPARENTING=1
# Chromium (based) applications
export NIXOS_OZONE_WL=1
'';
}; };
} extraPackages = with pkgs; [
file
gnome.adwaita-icon-theme
grim
gsettings-desktop-schemas
gtk3
i3status
kanagawa
light
mako
qt5.qtwayland
rofi-wayland
slurp
swayidle
swaylock
wf-recorder
wl-clipboard
];
wrapperFeatures = {
base = true;
gtk = true;
};
extraSessionCommands = ''
export GDK_BACKEND=wayland
export CLUTTER_BACKEND=wayland
export SDL_VIDEODRIVER=wayland
# needs qt5.qtwayland in systemPackages
export QT_QPA_PLATFORM=wayland-egl
export QT_WAYLAND_FORCE_DPI=physical
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
# Fix for some Java AWT applications (e.g. Android Studio),
# use this if they aren't displayed properly:
export _JAVA_AWT_WM_NONREPARENTING=1
# Chromium (based) applications
export NIXOS_OZONE_WL=1
'';
};
}

View file

@ -6,11 +6,15 @@
}: }:
# Note: add privileged users to docker group for access # Note: add privileged users to docker group for access
with lib; with lib;
mkIf ((elem "docker" config.machine.services) && !(elem "podman" config.machine.services)) { mkIf ((elem "docker" config.machine.services) && !(elem "podman" config.machine.services)) {
virtualisation.docker = { virtualisation.docker = {
enable = true; enable = true;
# Disable live restore as it tends to delay/block system shutdown # Disable live restore as it tends to delay/block system shutdown
liveRestore = false; liveRestore = false;
}; };
environment.systemPackages = with pkgs; [docker-compose docker-machine cntr]; environment.systemPackages = with pkgs; [
} docker-compose
docker-machine
cntr
];
}

View file

@ -3,102 +3,103 @@
lib, lib,
... ...
}: }:
with lib; let with lib;
let
cfg = config.machine; cfg = config.machine;
active = name: (elem name cfg.services); active = name: (elem name cfg.services);
in in
mkIf (elem "fail2ban" cfg.services) { mkIf (elem "fail2ban" cfg.services) {
services.fail2ban = { services.fail2ban = {
enable = true; enable = true;
jails = { jails = {
DEFAULT = '' DEFAULT = ''
bantime = 3600 bantime = 3600
blocktype = DROP blocktype = DROP
logpath = /var/log/auth.log logpath = /var/log/auth.log
''; '';
ssh = '' ssh = ''
enabled = ${boolToString (active "openssh")} enabled = ${boolToString (active "openssh")}
filter = sshd filter = sshd
maxretry = 4 maxretry = 4
action = iptables[name=SSH, port=ssh, protocol=tcp] action = iptables[name=SSH, port=ssh, protocol=tcp]
''; '';
sshd-ddos = '' sshd-ddos = ''
enabled = ${boolToString (active "openssh")} enabled = ${boolToString (active "openssh")}
filter = sshd-ddos filter = sshd-ddos
maxretry = 4 maxretry = 4
action = iptables[name=ssh, port=ssh, protocol=tcp] action = iptables[name=ssh, port=ssh, protocol=tcp]
''; '';
postfix = '' postfix = ''
enabled = ${boolToString (active "mailserver")} enabled = ${boolToString (active "mailserver")}
filter = postfix filter = postfix
maxretry = 3 maxretry = 3
action = iptables[name=postfix, port=smtp, protocol=tcp] action = iptables[name=postfix, port=smtp, protocol=tcp]
''; '';
postfix-sasl = '' postfix-sasl = ''
enabled = ${boolToString (active "mailserver")} enabled = ${boolToString (active "mailserver")}
filter = postfix-sasl filter = postfix-sasl
port = postfix,imap3,imaps,pop3,pop3s port = postfix,imap3,imaps,pop3,pop3s
maxretry = 3 maxretry = 3
action = iptables[name=postfix, port=smtp, protocol=tcp] action = iptables[name=postfix, port=smtp, protocol=tcp]
''; '';
postfix-ddos = '' postfix-ddos = ''
enabled = ${boolToString (active "mailserver")} enabled = ${boolToString (active "mailserver")}
filter = postfix-ddos filter = postfix-ddos
maxretry = 3 maxretry = 3
action = iptables[name=postfix, port=submission, protocol=tcp] action = iptables[name=postfix, port=submission, protocol=tcp]
bantime = 7200 bantime = 7200
''; '';
nginx-req-limit = '' nginx-req-limit = ''
enabled = ${boolToString (active "nginx")} enabled = ${boolToString (active "nginx")}
filter = nginx-req-limit filter = nginx-req-limit
maxretry = 10 maxretry = 10
action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp] action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp]
findtime = 600 findtime = 600
bantime = 7200 bantime = 7200
'';
};
};
environment.etc."fail2ban/filter.d/sshd-ddos.conf" = {
enable = active "openssh";
text = ''
[Definition]
failregex = sshd(?:\[\d+\])?: Did not receive identification string from <HOST>$
ignoreregex =
''; '';
}; };
};
environment.etc."fail2ban/filter.d/postfix-sasl.conf" = { environment.etc."fail2ban/filter.d/sshd-ddos.conf" = {
enable = active "mailserver"; enable = active "openssh";
text = '' text = ''
# Fail2Ban filter for postfix authentication failures [Definition]
[INCLUDES] failregex = sshd(?:\[\d+\])?: Did not receive identification string from <HOST>$
before = common.conf ignoreregex =
[Definition] '';
daemon = postfix/smtpd };
failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$
'';
};
environment.etc."fail2ban/filter.d/postfix-ddos.conf" = { environment.etc."fail2ban/filter.d/postfix-sasl.conf" = {
enable = active "mailserver"; enable = active "mailserver";
text = '' text = ''
[Definition] # Fail2Ban filter for postfix authentication failures
failregex = lost connection after EHLO from \S+\[<HOST>\] [INCLUDES]
''; before = common.conf
}; [Definition]
daemon = postfix/smtpd
failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$
'';
};
environment.etc."fail2ban/filter.d/nginx-req-limit.conf" = { environment.etc."fail2ban/filter.d/postfix-ddos.conf" = {
enable = active "nginx"; enable = active "mailserver";
text = '' text = ''
[Definition] [Definition]
failregex = limiting requests, excess:.* by zone.*client: <HOST> failregex = lost connection after EHLO from \S+\[<HOST>\]
''; '';
}; };
# Limit stack size to reduce memory usage environment.etc."fail2ban/filter.d/nginx-req-limit.conf" = {
systemd.services.fail2ban.serviceConfig.LimitSTACK = 256 * 1024; enable = active "nginx";
} text = ''
[Definition]
failregex = limiting requests, excess:.* by zone.*client: <HOST>
'';
};
# Limit stack size to reduce memory usage
systemd.services.fail2ban.serviceConfig.LimitSTACK = 256 * 1024;
}

View file

@ -4,12 +4,14 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "forgejo" config.machine.services) { mkIf (elem "forgejo" config.machine.services) {
services = { services = {
forgejo = let forgejo =
let
cfg = config.machine; cfg = config.machine;
inherit ((findFirst (s: s.service == "forgejo") cfg cfg.vHosts)) domain; inherit ((findFirst (s: s.service == "forgejo") cfg cfg.vHosts)) domain;
in { in
{
enable = true; enable = true;
user = "git"; user = "git";
database = { database = {
@ -44,16 +46,16 @@ with lib;
}; };
}; };
}; };
}; };
sops.secrets."services/forgejo/dbPass" = { sops.secrets."services/forgejo/dbPass" = {
owner = "git"; owner = "git";
group = "forgejo"; group = "forgejo";
}; };
users.users.git = { users.users.git = {
description = "Forgejo Service"; description = "Forgejo Service";
isNormalUser = true; isNormalUser = true;
home = config.services.forgejo.stateDir; home = config.services.forgejo.stateDir;
createHome = false; createHome = false;
useDefaultShell = true; useDefaultShell = true;
}; };
} }

View file

@ -4,8 +4,9 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "fprintd" config.machine.services) { mkIf (elem "fprintd" config.machine.services) {
security.pam.services = let security.pam.services =
let
unlock = [ unlock = [
"sudo" "sudo"
"i3lock" "i3lock"
@ -13,12 +14,16 @@ with lib;
"lightdm" "lightdm"
]; ];
in in
listToAttrs (forEach unlock (n: { listToAttrs (
forEach unlock (n: {
name = n; name = n;
value = {fprintAuth = true;}; value = {
})); fprintAuth = true;
};
})
);
services.fprintd = { services.fprintd = {
enable = true; enable = true;
}; };
} }

View file

@ -9,24 +9,32 @@
# https://qfpl.io/posts/nix/starting-simple-hydra/ # https://qfpl.io/posts/nix/starting-simple-hydra/
# also for reference a well written hydra config: # also for reference a well written hydra config:
# https://github.com/NixOS/nixos-org-configurations/blob/master/delft/hydra.nix # https://github.com/NixOS/nixos-org-configurations/blob/master/delft/hydra.nix
with lib; let with lib;
let
cacheDir = "/var/cache/hydra"; cacheDir = "/var/cache/hydra";
in in
mkIf (elem "hydra" config.machine.services) { mkIf (elem "hydra" config.machine.services) {
# also take a look at ../conf/nix.nix # also take a look at ../conf/nix.nix
nix.buildMachines = [ nix.buildMachines = [
{ {
hostName = "localhost"; hostName = "localhost";
system = "x86_64-linux"; system = "x86_64-linux";
supportedFeatures = ["kvm" "nixos-test" "big-parallel" "benchmark"]; supportedFeatures = [
maxJobs = 8; "kvm"
} "nixos-test"
]; "big-parallel"
"benchmark"
];
maxJobs = 8;
}
];
services = let services =
let
cfg = config.machine; cfg = config.machine;
inherit ((findFirst (s: s.service == "hydra") cfg cfg.vHosts)) domain; inherit ((findFirst (s: s.service == "hydra") cfg cfg.vHosts)) domain;
in { in
{
hydra = { hydra = {
enable = true; enable = true;
hydraURL = domain; # externally visible URL hydraURL = domain; # externally visible URL
@ -42,7 +50,9 @@ in
# hydra.conf: binary_cache_secret_key_file is deprecated and ignored. use store_uri=...?secret-key= instead # hydra.conf: binary_cache_secret_key_file is deprecated and ignored. use store_uri=...?secret-key= instead
extraConfig = '' extraConfig = ''
max_output_size = 4294967296 max_output_size = 4294967296
store_uri = file://${cacheDir}?secret-key=${config.sops.secrets."services.hydra.secretKey".path}&write-nar-listing=1&ls-compression=br&log-compression=br store_uri = file://${cacheDir}?secret-key=${
config.sops.secrets."services.hydra.secretKey".path
}&write-nar-listing=1&ls-compression=br&log-compression=br
# add ?local-nar-cache= to set nar cache location # add ?local-nar-cache= to set nar cache location
server_store_uri = https://cache.${cfg.domain} server_store_uri = https://cache.${cfg.domain}
binary_cache_public_uri https://cache.${cfg.domain} binary_cache_public_uri https://cache.${cfg.domain}
@ -62,10 +72,10 @@ in
''; '';
}; };
}; };
systemd.services.nix-serve.serviceConfig.User = mkForce "hydra"; systemd.services.nix-serve.serviceConfig.User = mkForce "hydra";
systemd.services.nix-serve.environment.NIX_STORE_DIR = cacheDir; systemd.services.nix-serve.environment.NIX_STORE_DIR = cacheDir;
sops.secrets."services/hydra/secretKey" = { sops.secrets."services/hydra/secretKey" = {
owner = "hydra"; owner = "hydra";
group = "hydra"; group = "hydra";
}; };
} }

View file

@ -6,32 +6,40 @@
... ...
}: }:
with lib; with lib;
{ {
imports = [ imports = [
mailserver.nixosModules.mailserver mailserver.nixosModules.mailserver
]; ];
} }
// mkIf (elem "mailserver" config.machine.services) { // mkIf (elem "mailserver" config.machine.services) {
mailserver = let mailserver =
let
cfg = config.machine; cfg = config.machine;
inherit (cfg) domain; inherit (cfg) domain;
fdomain = (findFirst (s: s.service == "mail") cfg cfg.vHosts).domain; fdomain = (findFirst (s: s.service == "mail") cfg cfg.vHosts).domain;
mkFqdnAlias = name: ["${name}@${domain}" "${name}@${fdomain}"]; mkFqdnAlias = name: [
"${name}@${domain}"
"${name}@${fdomain}"
];
mkExDomAlias = name: (map (exDom: "${name}@${exDom}") cfg.extraDomains); mkExDomAlias = name: (map (exDom: "${name}@${exDom}") cfg.extraDomains);
mkUser = user: rec { mkUser = user: rec {
name = "${user.name}@${domain}"; name = "${user.name}@${domain}";
value = { value = {
hashedPasswordFile = config.sops.secrets."users/${user.name}/mail".path; hashedPasswordFile = config.sops.secrets."users/${user.name}/mail".path;
aliases = aliases =
["${user.name}@${fdomain}"] [ "${user.name}@${fdomain}" ]
++ (flatten (map mkFqdnAlias user.aliases)) ++ (flatten (map mkFqdnAlias user.aliases))
++ (flatten (map mkExDomAlias ([user.name] ++ user.aliases))); ++ (flatten (map mkExDomAlias ([ user.name ] ++ user.aliases)));
}; };
}; };
in rec { in
rec {
enable = true; enable = true;
fqdn = fdomain; fqdn = fdomain;
domains = [fdomain domain] ++ cfg.extraDomains; domains = [
fdomain
domain
] ++ cfg.extraDomains;
loginAccounts = listToAttrs (map mkUser cfg.mailAccounts); loginAccounts = listToAttrs (map mkUser cfg.mailAccounts);
# Use Let's Encrypt certificates. Note that this needs to set up a stripped # Use Let's Encrypt certificates. Note that this needs to set up a stripped
@ -55,9 +63,5 @@ with lib;
# 1 Gb RAM for the server. Without virus scanning 256 MB RAM should be plenty) # 1 Gb RAM for the server. Without virus scanning 256 MB RAM should be plenty)
virusScanning = false; virusScanning = false;
}; };
sops.secrets = sops.secrets = fn.sopsHelper (user: "users/${user.name}/mail") config.machine.mailAccounts { };
fn.sopsHelper }
(user: "users/${user.name}/mail")
config.machine.mailAccounts
{};
}

View file

@ -5,9 +5,9 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "mariaDB" config.machine.services) { mkIf (elem "mariaDB" config.machine.services) {
services.mysql = rec { services.mysql = rec {
enable = true; enable = true;
package = pkgs.mariadb; package = pkgs.mariadb;
}; };
} }

View file

@ -4,6 +4,6 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "mullvad" config.machine.services) { mkIf (elem "mullvad" config.machine.services) {
services.mullvad-vpn.enable = true; services.mullvad-vpn.enable = true;
} }

View file

@ -6,11 +6,13 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "nextcloud" config.machine.services) { mkIf (elem "nextcloud" config.machine.services) {
services = let services =
let
cfg = config.machine; cfg = config.machine;
inherit ((findFirst (s: s.service == "nextcloud") cfg cfg.vHosts)) domain; inherit ((findFirst (s: s.service == "nextcloud") cfg cfg.vHosts)) domain;
in { in
{
nextcloud = { nextcloud = {
enable = true; enable = true;
home = "/var/lib/nextcloud"; home = "/var/lib/nextcloud";
@ -54,12 +56,14 @@ with lib;
''; '';
}; };
}; };
sops.secrets = sops.secrets =
fn.sopsHelper fn.sopsHelper (name: "services/nextcloud/${name}")
(name: "services/nextcloud/${name}") [
["adminPass" "dbPass"] "adminPass"
"dbPass"
]
{ {
owner = "nextcloud"; owner = "nextcloud";
group = "nextcloud"; group = "nextcloud";
}; };
} }

View file

@ -15,28 +15,35 @@
}: }:
with lib; with lib;
with builtins; with builtins;
mkIf (elem "nginx" config.machine.services) { mkIf (elem "nginx" config.machine.services) {
services.nginx = let services.nginx =
vHostConfigs = listToAttrs (map let
(name: { vHostConfigs = listToAttrs (
name = replaceStrings [".nix"] [""] name; map (name: {
value = import (./. + (toPath "/nginx_vHosts/${name}")) {inherit options config lib pkgs;}; name = replaceStrings [ ".nix" ] [ "" ] name;
}) value = import (./. + (toPath "/nginx_vHosts/${name}")) {
(attrNames (readDir ./nginx_vHosts))); inherit
options
config
lib
pkgs
;
};
}) (attrNames (readDir ./nginx_vHosts))
);
mkVHost = vHost: { mkVHost = vHost: {
name = vHost.domain; name = vHost.domain;
value = value = {
{ enableACME = true;
enableACME = true; forceSSL = true;
forceSSL = true; acmeRoot = "/var/lib/acme/acme-challenge";
acmeRoot = "/var/lib/acme/acme-challenge"; } // vHostConfigs."${vHost.service}";
}
// vHostConfigs."${vHost.service}";
}; };
vHosts = listToAttrs (map mkVHost config.machine.vHosts); vHosts = listToAttrs (map mkVHost config.machine.vHosts);
in { in
{
enable = true; enable = true;
recommendedGzipSettings = true; recommendedGzipSettings = true;
recommendedOptimisation = true; recommendedOptimisation = true;
@ -56,4 +63,4 @@ with builtins;
''; '';
virtualHosts = vHosts; virtualHosts = vHosts;
}; };
} }

View file

@ -4,10 +4,10 @@
... ...
}: }:
with lib; with lib;
{ {
vHost = vHost =
if config.services.nix-serve.enable if config.services.nix-serve.enable then
then { {
extraConfig = '' extraConfig = ''
location / { location / {
proxy_pass http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}; proxy_pass http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port};
@ -18,6 +18,7 @@ with lib;
} }
''; '';
} }
else {}; else
} { };
.vHost }
.vHost

View file

@ -4,10 +4,10 @@
... ...
}: }:
with lib; with lib;
{ {
vHost = vHost =
if config.services.forgejo.enable if config.services.forgejo.enable then
then { {
root = "${config.services.forgejo.stateDir}/public"; root = "${config.services.forgejo.stateDir}/public";
extraConfig = '' extraConfig = ''
location / { location / {
@ -28,6 +28,7 @@ with lib;
} }
''; '';
} }
else {}; else
} { };
.vHost }
.vHost

View file

@ -4,10 +4,10 @@
... ...
}: }:
with lib; with lib;
{ {
vHost = vHost =
if config.services.hydra.enable if config.services.hydra.enable then
then { {
extraConfig = '' extraConfig = ''
location / { location / {
proxy_pass http://${config.services.hydra.listenHost}:${toString config.services.hydra.port}; proxy_pass http://${config.services.hydra.listenHost}:${toString config.services.hydra.port};
@ -18,6 +18,7 @@ with lib;
} }
''; '';
} }
else {}; else
} { };
.vHost }
.vHost

View file

@ -4,14 +4,15 @@
... ...
}: }:
with lib; with lib;
{ {
vHost = vHost =
if config.mailserver.enable if config.mailserver.enable then
then { {
serverName = config.mailserver.fqdn; serverName = config.mailserver.fqdn;
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
} }
else {}; else
} { };
.vHost }
.vHost

View file

@ -6,13 +6,13 @@
... ...
}: }:
with lib; with lib;
if config.services.nextcloud.enable if config.services.nextcloud.enable then
then {
{ vHost = {
vHost = { enableACME = config.services.nextcloud.https;
enableACME = config.services.nextcloud.https; forceSSL = config.services.nextcloud.https;
forceSSL = config.services.nextcloud.https; };
}; }
} .vHost
.vHost else
else {} { }

View file

@ -4,9 +4,9 @@
... ...
}: }:
with lib; with lib;
{ {
vHost = { vHost = {
root = "/var/www"; root = "/var/www";
}; };
} }
.vHost .vHost

View file

@ -6,10 +6,11 @@
with lib; with lib;
let let
tandoor = config.services.tandoor-recipes; tandoor = config.services.tandoor-recipes;
in { in
vHost = {
if tandoor.enable vHost =
then { if tandoor.enable then
{
extraConfig = '' extraConfig = ''
location /media/ { location /media/ {
alias ${tandoor.extraConfig.MEDIA_ROOT}; alias ${tandoor.extraConfig.MEDIA_ROOT};
@ -24,6 +25,7 @@ in {
} }
''; '';
} }
else {}; else
} { };
.vHost }
.vHost

View file

@ -8,35 +8,38 @@
# https://infosec.mozilla.org/guidelines/openssh.html # https://infosec.mozilla.org/guidelines/openssh.html
# https://stribika.github.io/2015/01/04/secure-secure-shell.html # https://stribika.github.io/2015/01/04/secure-secure-shell.html
with lib; with lib;
mkIf (elem "openssh" config.machine.services) { mkIf (elem "openssh" config.machine.services) {
services.openssh = { services.openssh = {
enable = true; enable = true;
settings.KexAlgorithms = ["curve25519-sha256@libssh.org"]; settings.KexAlgorithms = [ "curve25519-sha256@libssh.org" ];
sftpFlags = ["-f AUTHPRIV" "-l INFO"]; sftpFlags = [
startWhenNeeded = false; "-f AUTHPRIV"
settings = { "-l INFO"
KbdInteractiveAuthentication = false; ];
PasswordAuthentication = false; startWhenNeeded = false;
PermitRootLogin = "no"; settings = {
}; KbdInteractiveAuthentication = false;
extraConfig = let PasswordAuthentication = false;
PermitRootLogin = "no";
};
extraConfig =
let
users = users =
concatMapStrings (user: "${user.name} ") config.machine.administrators concatMapStrings (user: "${user.name} ") config.machine.administrators
+ (optionalString config.services.forgejo.enable (config.services.forgejo.user + " ")); + (optionalString config.services.forgejo.enable (config.services.forgejo.user + " "));
in '' in
''
UsePAM no UsePAM no
AllowUsers ${users} AllowUsers ${users}
LogLevel VERBOSE LogLevel VERBOSE
''; '';
}; };
# Add public keys to /etc/ssh/authorized_keys.d # Add public keys to /etc/ssh/authorized_keys.d
# This replaces users.users.*.openssh.authorizedKeys.* # This replaces users.users.*.openssh.authorizedKeys.*
sops.secrets = sops.secrets =
fn.sopsHelper fn.sopsHelper (user: "users/${user.name}/publicKey") config.machine.administrators
(user: "users/${user.name}/publicKey")
config.machine.administrators
(user: { (user: {
path = "/etc/ssh/authorized_keys.d/${user.name}"; path = "/etc/ssh/authorized_keys.d/${user.name}";
mode = "444"; mode = "444";
}); });
} }

View file

@ -4,19 +4,25 @@
pkgs, pkgs,
... ...
}: }:
with lib; let with lib;
let
withDocker = elem "docker" config.machine.services; withDocker = elem "docker" config.machine.services;
in in
mkIf (elem "podman" config.machine.services) { mkIf (elem "podman" config.machine.services) {
virtualisation.podman = { virtualisation.podman = {
enable = true; enable = true;
dockerSocket.enable = withDocker; dockerSocket.enable = withDocker;
dockerCompat = withDocker; dockerCompat = withDocker;
defaultNetwork = { defaultNetwork = {
settings.dns_enabled = true; settings.dns_enabled = true;
};
}; };
environment.systemPackages = };
(with pkgs; [podman-compose cntr img skopeo]) environment.systemPackages =
++ (optional withDocker pkgs.docker-compose); (with pkgs; [
} podman-compose
cntr
img
skopeo
])
++ (optional withDocker pkgs.docker-compose);
}

View file

@ -5,12 +5,12 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "tandoor" config.machine.services) { mkIf (elem "tandoor" config.machine.services) {
services.tandoor-recipes = { services.tandoor-recipes = {
enable = true; enable = true;
extraConfig = { extraConfig = {
# Set explicitly so it can be referenced by web-server # Set explicitly so it can be referenced by web-server
MEDIA_ROOT = "/var/lib/tandoor-recipes/media/"; MEDIA_ROOT = "/var/lib/tandoor-recipes/media/";
};
}; };
} };
}

View file

@ -5,6 +5,6 @@
... ...
}: }:
with lib; with lib;
mkIf (elem "udev" config.machine.services) { mkIf (elem "udev" config.machine.services) {
hardware.steam-hardware.enable = true; hardware.steam-hardware.enable = true;
} }