mirror of
https://github.com/Stunkymonkey/nixos.git
synced 2025-05-24 01:44:40 +02:00
treewide: fmt
This commit is contained in:
parent
330abe53d2
commit
ea37c7b836
95 changed files with 1162 additions and 779 deletions
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.hardware.bluetooth;
|
||||
in
|
||||
|
@ -18,8 +23,6 @@ in
|
|||
};
|
||||
};
|
||||
services.blueman.enable = true;
|
||||
environment.systemPackages = with pkgs; [
|
||||
sony-headphones-client
|
||||
];
|
||||
environment.systemPackages = with pkgs; [ sony-headphones-client ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.hardware.debug;
|
||||
in
|
||||
|
|
|
@ -7,32 +7,39 @@ in
|
|||
enable = mkEnableOption "firmware configuration";
|
||||
|
||||
cpuFlavor = mkOption {
|
||||
type = with types; nullOr (enum [ "intel" "amd" ]);
|
||||
type =
|
||||
with types;
|
||||
nullOr (enum [
|
||||
"intel"
|
||||
"amd"
|
||||
]);
|
||||
default = null;
|
||||
example = "intel";
|
||||
description = "Which kind of CPU to activate micro-code updates";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
hardware = {
|
||||
enableRedistributableFirmware = true;
|
||||
};
|
||||
}
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
hardware = {
|
||||
enableRedistributableFirmware = true;
|
||||
};
|
||||
}
|
||||
|
||||
# Intel CPU
|
||||
(lib.mkIf (cfg.cpuFlavor == "intel") {
|
||||
hardware = {
|
||||
cpu.intel.updateMicrocode = true;
|
||||
};
|
||||
})
|
||||
# Intel CPU
|
||||
(lib.mkIf (cfg.cpuFlavor == "intel") {
|
||||
hardware = {
|
||||
cpu.intel.updateMicrocode = true;
|
||||
};
|
||||
})
|
||||
|
||||
# AMD CPU
|
||||
(lib.mkIf (cfg.cpuFlavor == "amd") {
|
||||
hardware = {
|
||||
cpu.amd.updateMicrocode = true;
|
||||
};
|
||||
})
|
||||
]);
|
||||
# AMD CPU
|
||||
(lib.mkIf (cfg.cpuFlavor == "amd") {
|
||||
hardware = {
|
||||
cpu.amd.updateMicrocode = true;
|
||||
};
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.hardware.graphics;
|
||||
in
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.hardware.keychron;
|
||||
in
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.hardware.sound;
|
||||
in
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.hardware.thunderbolt;
|
||||
in
|
||||
|
@ -8,9 +13,7 @@ in
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
thunderbolt
|
||||
];
|
||||
environment.systemPackages = with pkgs; [ thunderbolt ];
|
||||
services.hardware.bolt.enable = true;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.hardware.yubikey;
|
||||
in
|
||||
|
@ -18,8 +23,6 @@ in
|
|||
};
|
||||
services.pcscd.enable = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
yubikey-manager
|
||||
];
|
||||
environment.systemPackages = with pkgs; [ yubikey-manager ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -14,11 +14,7 @@
|
|||
receivers = [
|
||||
{
|
||||
name = "default";
|
||||
email_configs = [
|
||||
{
|
||||
to = "server@buehler.rocks";
|
||||
}
|
||||
];
|
||||
email_configs = [ { to = "server@buehler.rocks"; } ];
|
||||
webhook_configs = [
|
||||
{
|
||||
url = "http://localhost:4050/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2U";
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# monitoring system services
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.alertmanager;
|
||||
inherit (config.networking) domain;
|
||||
|
@ -37,24 +42,18 @@ in
|
|||
extraFlags = [ "--cluster.advertise-address 127.0.0.1:${toString cfg.port}" ];
|
||||
};
|
||||
|
||||
alertmanagers = [
|
||||
{
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "localhost:${toString cfg.port}" ];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
alertmanagers = [ { static_configs = [ { targets = [ "localhost:${toString cfg.port}" ]; } ]; } ];
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "alertmanager";
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString cfg.port}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}];
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "127.0.0.1:${toString cfg.port}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# to download things
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.aria2;
|
||||
inherit (config.networking) domain;
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.backup;
|
||||
in
|
||||
|
@ -52,9 +57,7 @@ in
|
|||
type = with types; listOf str;
|
||||
description = lib.mdDoc "additional path(s) to back up";
|
||||
default = [ "/" ];
|
||||
example = [
|
||||
"/home/user"
|
||||
];
|
||||
example = [ "/home/user" ];
|
||||
};
|
||||
exclude = mkOption {
|
||||
type = with types; listOf str;
|
||||
|
@ -100,8 +103,8 @@ in
|
|||
# other-os
|
||||
"**/.Trash" # apple
|
||||
"**/.DS_Store" # apple
|
||||
"**/$RECYCLE.BIN" #windows
|
||||
"**/System Volume Information" #windows
|
||||
"**/$RECYCLE.BIN" # windows
|
||||
"**/System Volume Information" # windows
|
||||
|
||||
# var data
|
||||
"/var/cache"
|
||||
|
@ -138,27 +141,31 @@ in
|
|||
inherit (cfg) doInit;
|
||||
compression = "auto,zstd";
|
||||
|
||||
postHook = ''
|
||||
if (( $exitStatus > 1 )); then
|
||||
'' + lib.optionalString cfg.OnFailureNotification ''
|
||||
# iterate over all logged in users
|
||||
for user in $(users); do
|
||||
sway_pid=$(${pkgs.procps}/bin/pgrep -x "sway" -u "$user")
|
||||
if [ -n "$sway_pid" ]; then
|
||||
# set environment variables
|
||||
export $(cat /proc/$sway_pid/environ | grep -z '^DBUS_SESSION_BUS_ADDRESS=' | tr -d '\0')
|
||||
export DISPLAY=:0
|
||||
# send notification via dbus: https://wiki.archlinux.org/title/Desktop_notifications#Bash
|
||||
${pkgs.sudo}/bin/sudo --preserve-env=DBUS_SESSION_BUS_ADDRESS,DISPLAY -u $user ${pkgs.libnotify}/bin/notify-send -u critical "BorgBackup Failed!" "Run journalctl -u borgbackup-job* for more details."
|
||||
echo "sent notification"
|
||||
postHook =
|
||||
''
|
||||
if (( $exitStatus > 1 )); then
|
||||
''
|
||||
+ lib.optionalString cfg.OnFailureNotification ''
|
||||
# iterate over all logged in users
|
||||
for user in $(users); do
|
||||
sway_pid=$(${pkgs.procps}/bin/pgrep -x "sway" -u "$user")
|
||||
if [ -n "$sway_pid" ]; then
|
||||
# set environment variables
|
||||
export $(cat /proc/$sway_pid/environ | grep -z '^DBUS_SESSION_BUS_ADDRESS=' | tr -d '\0')
|
||||
export DISPLAY=:0
|
||||
# send notification via dbus: https://wiki.archlinux.org/title/Desktop_notifications#Bash
|
||||
${pkgs.sudo}/bin/sudo --preserve-env=DBUS_SESSION_BUS_ADDRESS,DISPLAY -u $user ${pkgs.libnotify}/bin/notify-send -u critical "BorgBackup Failed!" "Run journalctl -u borgbackup-job* for more details."
|
||||
echo "sent notification"
|
||||
fi
|
||||
done
|
||||
''
|
||||
+ lib.optionalString (cfg.OnFailureMail != null) ''
|
||||
journalctl -u borgbackup-job-hetzner.service | ${pkgs.mailutils}/bin/mail -r "Administrator<root@buehler.rocks>" -s "Backup Error" server@buehler.rocks
|
||||
echo "sent mail"
|
||||
''
|
||||
+ ''
|
||||
fi
|
||||
done
|
||||
'' + lib.optionalString (cfg.OnFailureMail != null) ''
|
||||
journalctl -u borgbackup-job-hetzner.service | ${pkgs.mailutils}/bin/mail -r "Administrator<root@buehler.rocks>" -s "Backup Error" server@buehler.rocks
|
||||
echo "sent mail"
|
||||
'' + ''
|
||||
fi
|
||||
'';
|
||||
'';
|
||||
|
||||
# for mail sending
|
||||
readWritePaths = lib.optional (cfg.OnFailureMail != null) "/var/lib/postfix/queue/maildrop/";
|
||||
|
|
|
@ -31,12 +31,14 @@ in
|
|||
prometheus.scrapeConfigs = [
|
||||
{
|
||||
job_name = "bazarr";
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString port + 1}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}];
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "127.0.0.1:${toString port + 1}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# monitor urls
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.blackbox;
|
||||
blackBoxConfig = {
|
||||
|
@ -11,12 +16,8 @@ let
|
|||
ssh_banner = {
|
||||
prober = "tcp";
|
||||
tcp.query_response = [
|
||||
{
|
||||
send = "SSH-2.0-blackbox-ssh-check";
|
||||
}
|
||||
{
|
||||
expect = "^SSH-2.0-";
|
||||
}
|
||||
{ send = "SSH-2.0-blackbox-ssh-check"; }
|
||||
{ expect = "^SSH-2.0-"; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# Fast and lightweight DNS proxy as ad-blocker for local network
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.blocky;
|
||||
in
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# RSS aggregator and reader
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.freshrss;
|
||||
inherit (config.networking) domain;
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# self-hosted git service
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.gitea;
|
||||
inherit (config.networking) domain;
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# visualize monitoring services
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.grafana;
|
||||
inherit (config.networking) domain;
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# HedgeDoc is an open-source, web-based, self-hosted, collaborative markdown editor.
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.hedgedoc;
|
||||
inherit (config.networking) domain;
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# home automation
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.home-automation;
|
||||
inherit (config.networking) domain;
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# My own personal homepage
|
||||
{ config, lib, inputs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.homepage;
|
||||
inherit (config.networking) domain;
|
||||
|
|
|
@ -3,24 +3,26 @@
|
|||
{
|
||||
options.webapps = {
|
||||
dashboardCategories = lib.mkOption {
|
||||
type = lib.types.listOf (lib.types.submodule {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Category name.
|
||||
'';
|
||||
example = "Applications";
|
||||
type = lib.types.listOf (
|
||||
lib.types.submodule {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Category name.
|
||||
'';
|
||||
example = "Applications";
|
||||
};
|
||||
tag = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Category tag.
|
||||
'';
|
||||
example = "app";
|
||||
};
|
||||
};
|
||||
tag = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Category tag.
|
||||
'';
|
||||
example = "app";
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
description = ''
|
||||
App categories to display on the dashboard.
|
||||
'';
|
||||
|
@ -34,8 +36,8 @@
|
|||
};
|
||||
|
||||
apps = lib.mkOption {
|
||||
type = lib.types.attrsOf
|
||||
(lib.types.submodule {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule {
|
||||
options = {
|
||||
dashboard = {
|
||||
url = lib.mkOption {
|
||||
|
@ -79,7 +81,10 @@
|
|||
default = "Ping";
|
||||
};
|
||||
method = lib.mkOption {
|
||||
type = lib.types.enum [ "get" "head" ];
|
||||
type = lib.types.enum [
|
||||
"get"
|
||||
"head"
|
||||
];
|
||||
description = ''
|
||||
method of request used
|
||||
'';
|
||||
|
@ -88,7 +93,8 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
description = ''
|
||||
Defines a web application.
|
||||
'';
|
||||
|
@ -105,24 +111,33 @@
|
|||
let
|
||||
apps = builtins.filter (a: a.dashboard.name != null) (lib.attrValues cfg.apps);
|
||||
in
|
||||
lib.forEach cfg.dashboardCategories (cat:
|
||||
lib.forEach cfg.dashboardCategories (
|
||||
cat:
|
||||
let
|
||||
catApps = lib.sort (a: b: a.dashboard.name < b.dashboard.name) (
|
||||
builtins.filter
|
||||
(a:
|
||||
a.dashboard.category != null && a.dashboard.category == cat.tag ||
|
||||
a.dashboard.category == null && cat.tag == "misc")
|
||||
apps);
|
||||
builtins.filter (
|
||||
a:
|
||||
a.dashboard.category != null && a.dashboard.category == cat.tag
|
||||
|| a.dashboard.category == null && cat.tag == "misc"
|
||||
) apps
|
||||
);
|
||||
in
|
||||
{
|
||||
inherit (cat) name;
|
||||
items = lib.forEach catApps (a: {
|
||||
inherit (a.dashboard) method name type url;
|
||||
inherit (a.dashboard)
|
||||
method
|
||||
name
|
||||
type
|
||||
url
|
||||
;
|
||||
icon = lib.optionalString (a.dashboard.icon != null) "fas fa-${a.dashboard.icon}";
|
||||
target = "_blank";
|
||||
});
|
||||
}
|
||||
);
|
||||
my.services.blackbox.http_endpoints = lib.mapAttrsToList (_key: value: value.dashboard.url) config.webapps.apps ++ [ "https://${config.networking.domain}/" ];
|
||||
my.services.blackbox.http_endpoints =
|
||||
lib.mapAttrsToList (_key: value: value.dashboard.url) config.webapps.apps
|
||||
++ [ "https://${config.networking.domain}/" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# Dashboard site
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.homer;
|
||||
inherit (config.networking) domain;
|
||||
|
@ -14,9 +19,7 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./config.nix
|
||||
];
|
||||
imports = [ ./config.nix ];
|
||||
|
||||
options.my.services.homer = with lib; {
|
||||
enable = mkEnableOption "Homer Dashboard";
|
||||
|
@ -44,10 +47,22 @@ in
|
|||
|
||||
webapps = {
|
||||
dashboardCategories = [
|
||||
{ name = "Applications"; tag = "app"; }
|
||||
{ name = "Media"; tag = "media"; }
|
||||
{ name = "Infrastructure"; tag = "infra"; }
|
||||
{ name = "Others"; tag = "other"; }
|
||||
{
|
||||
name = "Applications";
|
||||
tag = "app";
|
||||
}
|
||||
{
|
||||
name = "Media";
|
||||
tag = "media";
|
||||
}
|
||||
{
|
||||
name = "Infrastructure";
|
||||
tag = "infra";
|
||||
}
|
||||
{
|
||||
name = "Others";
|
||||
tag = "other";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
@ -15,9 +15,7 @@ in
|
|||
ssh = {
|
||||
enable = true;
|
||||
port = 2222;
|
||||
hostKeys = [
|
||||
"/etc/secrets/initrd/ssh_host_ed25519_key"
|
||||
];
|
||||
hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ];
|
||||
authorizedKeys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFx6OLwL9MbkD3mnMsv+xrzZHN/rwCTgVs758SCLG0h felix@thinkman"
|
||||
];
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# The Free Software Media System
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.jellyfin;
|
||||
inherit (config.networking) domain;
|
||||
|
@ -8,10 +13,7 @@ let
|
|||
jellyfin-with-metrics = pkgs.jellyfin.overrideAttrs (attrs: {
|
||||
patches =
|
||||
let
|
||||
existingPatches =
|
||||
if attrs ? patches && builtins.isList attrs.patches
|
||||
then attrs.patches
|
||||
else [ ];
|
||||
existingPatches = if attrs ? patches && builtins.isList attrs.patches then attrs.patches else [ ];
|
||||
in
|
||||
# with this patch the default setting for metrics is changed
|
||||
existingPatches ++ [ ./enable-metrics.patch ];
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# log monitoring
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.loki;
|
||||
in
|
||||
|
@ -15,8 +20,8 @@ in
|
|||
};
|
||||
|
||||
rules = mkOption {
|
||||
type = types.attrsOf
|
||||
(types.submodule {
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
condition = mkOption {
|
||||
type = types.str;
|
||||
|
@ -53,7 +58,8 @@ in
|
|||
default = "2m";
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
description = ''
|
||||
Defines the loki rules.
|
||||
'';
|
||||
|
@ -67,14 +73,12 @@ in
|
|||
groups = [
|
||||
{
|
||||
name = "alerting-rules";
|
||||
rules = lib.mapAttrsToList
|
||||
(name: opts: {
|
||||
alert = name;
|
||||
inherit (opts) condition labels;
|
||||
for = opts.time;
|
||||
annotations.description = opts.description;
|
||||
})
|
||||
cfg.rules;
|
||||
rules = lib.mapAttrsToList (name: opts: {
|
||||
alert = name;
|
||||
inherit (opts) condition labels;
|
||||
for = opts.time;
|
||||
annotations.description = opts.description;
|
||||
}) cfg.rules;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
@ -114,16 +118,18 @@ in
|
|||
};
|
||||
|
||||
schema_config = {
|
||||
configs = [{
|
||||
from = "2020-11-08";
|
||||
store = "tsdb";
|
||||
object_store = "filesystem";
|
||||
schema = "v13";
|
||||
index = {
|
||||
prefix = "index_";
|
||||
period = "24h";
|
||||
};
|
||||
}];
|
||||
configs = [
|
||||
{
|
||||
from = "2020-11-08";
|
||||
store = "tsdb";
|
||||
object_store = "filesystem";
|
||||
schema = "v13";
|
||||
index = {
|
||||
prefix = "index_";
|
||||
period = "24h";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
limits_config = {
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# sandbox video game
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.minecraft-server;
|
||||
in
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# Have a good quality voice chat
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.mumble-server;
|
||||
domain = "voice.${config.networking.domain}";
|
||||
|
@ -28,7 +33,10 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
users.groups."voice-buehler-rocks".members = [ "murmur" "nginx" ];
|
||||
users.groups."voice-buehler-rocks".members = [
|
||||
"murmur"
|
||||
"nginx"
|
||||
];
|
||||
|
||||
my.services.prometheus.rules = {
|
||||
mumble_not_running = {
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# A FLOSS self-hosted, subsonic compatible music server
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.navidrome;
|
||||
inherit (config.networking) domain;
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# self-hosted cloud
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.nextcloud;
|
||||
inherit (config.networking) domain;
|
||||
|
@ -71,7 +76,12 @@ in
|
|||
};
|
||||
|
||||
extraApps = with pkgs.nextcloud29Packages.apps; {
|
||||
inherit calendar contacts tasks deck;
|
||||
inherit
|
||||
calendar
|
||||
contacts
|
||||
tasks
|
||||
deck
|
||||
;
|
||||
};
|
||||
extraAppsEnable = true;
|
||||
};
|
||||
|
|
|
@ -1,60 +1,65 @@
|
|||
# A simple abstraction layer for almost all of my services' needs
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.nginx;
|
||||
virtualHostOption = with lib; types.submodule {
|
||||
options = {
|
||||
subdomain = mkOption {
|
||||
type = types.str;
|
||||
example = "dev";
|
||||
description = ''
|
||||
Which subdomain, under config.networking.domain, to use
|
||||
for this virtual host.
|
||||
'';
|
||||
};
|
||||
port = mkOption {
|
||||
type = with types; nullOr port;
|
||||
default = null;
|
||||
example = 8080;
|
||||
description = ''
|
||||
Which port to proxy to, through 127.0.0.1, for this virtual host.
|
||||
This option is incompatible with `root`.
|
||||
'';
|
||||
};
|
||||
root = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
example = "/var/www/blog";
|
||||
description = ''
|
||||
The root folder for this virtual host. This option is incompatible
|
||||
with `port`.
|
||||
'';
|
||||
};
|
||||
sso = {
|
||||
enable = mkEnableOption "SSO authentication";
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs; # FIXME: forward type of virtualHosts
|
||||
example = literalExpression ''
|
||||
{
|
||||
locations."/socket" = {
|
||||
proxyPass = "http://127.0.0.1:8096/";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
}
|
||||
'';
|
||||
default = { };
|
||||
description = ''
|
||||
Any extra configuration that should be applied to this virtual host.
|
||||
'';
|
||||
virtualHostOption =
|
||||
with lib;
|
||||
types.submodule {
|
||||
options = {
|
||||
subdomain = mkOption {
|
||||
type = types.str;
|
||||
example = "dev";
|
||||
description = ''
|
||||
Which subdomain, under config.networking.domain, to use
|
||||
for this virtual host.
|
||||
'';
|
||||
};
|
||||
port = mkOption {
|
||||
type = with types; nullOr port;
|
||||
default = null;
|
||||
example = 8080;
|
||||
description = ''
|
||||
Which port to proxy to, through 127.0.0.1, for this virtual host.
|
||||
This option is incompatible with `root`.
|
||||
'';
|
||||
};
|
||||
root = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
example = "/var/www/blog";
|
||||
description = ''
|
||||
The root folder for this virtual host. This option is incompatible
|
||||
with `port`.
|
||||
'';
|
||||
};
|
||||
sso = {
|
||||
enable = mkEnableOption "SSO authentication";
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs; # FIXME: forward type of virtualHosts
|
||||
example = literalExpression ''
|
||||
{
|
||||
locations."/socket" = {
|
||||
proxyPass = "http://127.0.0.1:8096/";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
}
|
||||
'';
|
||||
default = { };
|
||||
description = ''
|
||||
Any extra configuration that should be applied to this virtual host.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./sso
|
||||
];
|
||||
imports = [ ./sso ];
|
||||
options.my.services.nginx = with lib; {
|
||||
enable = mkEnableOption "Nginx";
|
||||
acme = {
|
||||
|
@ -116,20 +121,22 @@ in
|
|||
description = "Port to use for internal webui.";
|
||||
};
|
||||
users = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
passwordHashFile = mkOption {
|
||||
type = types.str;
|
||||
example = "/var/lib/nginx-sso/alice/password-hash.txt";
|
||||
description = "Path to file containing the user's password hash.";
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
passwordHashFile = mkOption {
|
||||
type = types.str;
|
||||
example = "/var/lib/nginx-sso/alice/password-hash.txt";
|
||||
description = "Path to file containing the user's password hash.";
|
||||
};
|
||||
totpSecretFile = mkOption {
|
||||
type = types.str;
|
||||
example = "/var/lib/nginx-sso/alice/totp-secret.txt";
|
||||
description = "Path to file containing the user's TOTP secret.";
|
||||
};
|
||||
};
|
||||
totpSecretFile = mkOption {
|
||||
type = types.str;
|
||||
example = "/var/lib/nginx-sso/alice/totp-secret.txt";
|
||||
description = "Path to file containing the user's TOTP secret.";
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
example = literalExpression ''
|
||||
{
|
||||
alice = {
|
||||
|
@ -153,9 +160,13 @@ in
|
|||
};
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = lib.flip builtins.map cfg.virtualHosts ({ subdomain, ... } @ args:
|
||||
assertions = lib.flip builtins.map cfg.virtualHosts (
|
||||
{ subdomain, ... }@args:
|
||||
let
|
||||
conflicts = [ "port" "root" ];
|
||||
conflicts = [
|
||||
"port"
|
||||
"root"
|
||||
];
|
||||
optionsNotNull = builtins.map (v: args.${v} != null) conflicts;
|
||||
optionsSet = lib.filter lib.id optionsNotNull;
|
||||
in
|
||||
|
@ -166,39 +177,40 @@ in
|
|||
lib.concatStringsSep ", " (builtins.map (v: "'${v}'") conflicts)
|
||||
} configured.
|
||||
'';
|
||||
})
|
||||
# ++ (
|
||||
# let
|
||||
# ports = lib.my.mapFilter
|
||||
# (v: v != null)
|
||||
# ({ port, ... }: port)
|
||||
# cfg.virtualHosts;
|
||||
# lib.unique ports;
|
||||
# lib.compareLists ports
|
||||
# portCounts = lib.my.countValues ports;
|
||||
# nonUniquesCounts = lib.filterAttrs (_: v: v != 1) portCounts;
|
||||
# nonUniques = builtins.attrNames nonUniquesCounts;
|
||||
# mkAssertion = port: {
|
||||
# assertion = false;
|
||||
# message = "Port ${port} cannot appear in multiple virtual hosts.";
|
||||
# };
|
||||
# in
|
||||
# map mkAssertion nonUniques
|
||||
# ) ++ (
|
||||
# let
|
||||
# subs = map ({ subdomain, ... }: subdomain) cfg.virtualHosts;
|
||||
# subsCounts = lib.my.countValues subs;
|
||||
# nonUniquesCounts = lib.filterAttrs (_: v: v != 1) subsCounts;
|
||||
# nonUniques = builtins.attrNames nonUniquesCounts;
|
||||
# mkAssertion = v: {
|
||||
# assertion = false;
|
||||
# message = ''
|
||||
# Subdomain '${v}' cannot appear in multiple virtual hosts.
|
||||
# '';
|
||||
# };
|
||||
# in
|
||||
# map mkAssertion nonUniques
|
||||
# )
|
||||
}
|
||||
)
|
||||
# ++ (
|
||||
# let
|
||||
# ports = lib.my.mapFilter
|
||||
# (v: v != null)
|
||||
# ({ port, ... }: port)
|
||||
# cfg.virtualHosts;
|
||||
# lib.unique ports;
|
||||
# lib.compareLists ports
|
||||
# portCounts = lib.my.countValues ports;
|
||||
# nonUniquesCounts = lib.filterAttrs (_: v: v != 1) portCounts;
|
||||
# nonUniques = builtins.attrNames nonUniquesCounts;
|
||||
# mkAssertion = port: {
|
||||
# assertion = false;
|
||||
# message = "Port ${port} cannot appear in multiple virtual hosts.";
|
||||
# };
|
||||
# in
|
||||
# map mkAssertion nonUniques
|
||||
# ) ++ (
|
||||
# let
|
||||
# subs = map ({ subdomain, ... }: subdomain) cfg.virtualHosts;
|
||||
# subsCounts = lib.my.countValues subs;
|
||||
# nonUniquesCounts = lib.filterAttrs (_: v: v != 1) subsCounts;
|
||||
# nonUniques = builtins.attrNames nonUniquesCounts;
|
||||
# mkAssertion = v: {
|
||||
# assertion = false;
|
||||
# message = ''
|
||||
# Subdomain '${v}' cannot appear in multiple virtual hosts.
|
||||
# '';
|
||||
# };
|
||||
# in
|
||||
# map mkAssertion nonUniques
|
||||
# )
|
||||
;
|
||||
services = {
|
||||
nginx = {
|
||||
|
@ -251,67 +263,68 @@ in
|
|||
let
|
||||
genAttrs' = values: f: lib.listToAttrs (map f values);
|
||||
inherit (config.networking) domain;
|
||||
mkVHost = { subdomain, ... } @ args: lib.nameValuePair
|
||||
"${subdomain}.${domain}"
|
||||
(lib.foldl lib.recursiveUpdate { } [
|
||||
# Base configuration
|
||||
{
|
||||
forceSSL = true;
|
||||
useACMEHost = domain;
|
||||
}
|
||||
# Proxy to port
|
||||
(lib.optionalAttrs (args.port != null) {
|
||||
locations."/".proxyPass =
|
||||
"http://127.0.0.1:${toString args.port}";
|
||||
# TODO make ipv6 possible
|
||||
# http://[::1]:${toString args.port};
|
||||
})
|
||||
# Serve filesystem content
|
||||
(lib.optionalAttrs (args.root != null) {
|
||||
inherit (args) root;
|
||||
})
|
||||
# VHost specific configuration
|
||||
args.extraConfig
|
||||
# SSO configuration
|
||||
(lib.optionalAttrs args.sso.enable {
|
||||
extraConfig = (args.extraConfig.extraConfig or "") + ''
|
||||
error_page 401 = @error401;
|
||||
'';
|
||||
locations = {
|
||||
"@error401".return = ''
|
||||
302 https://${cfg.sso.subdomain}.${config.networking.domain}/login?go=$scheme://$http_host$request_uri
|
||||
'';
|
||||
"/" = {
|
||||
extraConfig =
|
||||
(args.extraConfig.locations."/".extraConfig or "") + ''
|
||||
# Use SSO
|
||||
auth_request /sso-auth;
|
||||
# Set username through header
|
||||
auth_request_set $username $upstream_http_x_username;
|
||||
proxy_set_header X-User $username;
|
||||
# Renew SSO cookie on request
|
||||
auth_request_set $cookie $upstream_http_set_cookie;
|
||||
add_header Set-Cookie $cookie;
|
||||
'';
|
||||
};
|
||||
"/sso-auth" = {
|
||||
proxyPass = "http://localhost:${toString cfg.sso.port}/auth";
|
||||
extraConfig = ''
|
||||
# Do not allow requests from outside
|
||||
internal;
|
||||
# Do not forward the request body
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
# Set X-Application according to subdomain for matching
|
||||
proxy_set_header X-Application "${subdomain}";
|
||||
# Set origin URI for matching
|
||||
proxy_set_header X-Origin-URI $request_uri;
|
||||
mkVHost =
|
||||
{ subdomain, ... }@args:
|
||||
lib.nameValuePair "${subdomain}.${domain}" (
|
||||
lib.foldl lib.recursiveUpdate { } [
|
||||
# Base configuration
|
||||
{
|
||||
forceSSL = true;
|
||||
useACMEHost = domain;
|
||||
}
|
||||
# Proxy to port
|
||||
(lib.optionalAttrs (args.port != null) {
|
||||
locations."/".proxyPass = "http://127.0.0.1:${toString args.port}";
|
||||
# TODO make ipv6 possible
|
||||
# http://[::1]:${toString args.port};
|
||||
})
|
||||
# Serve filesystem content
|
||||
(lib.optionalAttrs (args.root != null) { inherit (args) root; })
|
||||
# VHost specific configuration
|
||||
args.extraConfig
|
||||
# SSO configuration
|
||||
(lib.optionalAttrs args.sso.enable {
|
||||
extraConfig =
|
||||
(args.extraConfig.extraConfig or "")
|
||||
+ ''
|
||||
error_page 401 = @error401;
|
||||
'';
|
||||
locations = {
|
||||
"@error401".return = ''
|
||||
302 https://${cfg.sso.subdomain}.${config.networking.domain}/login?go=$scheme://$http_host$request_uri
|
||||
'';
|
||||
"/" = {
|
||||
extraConfig =
|
||||
(args.extraConfig.locations."/".extraConfig or "")
|
||||
+ ''
|
||||
# Use SSO
|
||||
auth_request /sso-auth;
|
||||
# Set username through header
|
||||
auth_request_set $username $upstream_http_x_username;
|
||||
proxy_set_header X-User $username;
|
||||
# Renew SSO cookie on request
|
||||
auth_request_set $cookie $upstream_http_set_cookie;
|
||||
add_header Set-Cookie $cookie;
|
||||
'';
|
||||
};
|
||||
"/sso-auth" = {
|
||||
proxyPass = "http://localhost:${toString cfg.sso.port}/auth";
|
||||
extraConfig = ''
|
||||
# Do not allow requests from outside
|
||||
internal;
|
||||
# Do not forward the request body
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
# Set X-Application according to subdomain for matching
|
||||
proxy_set_header X-Application "${subdomain}";
|
||||
# Set origin URI for matching
|
||||
proxy_set_header X-Origin-URI $request_uri;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
])
|
||||
;
|
||||
})
|
||||
]
|
||||
);
|
||||
in
|
||||
genAttrs' cfg.virtualHosts mkVHost;
|
||||
sso = {
|
||||
|
@ -322,9 +335,7 @@ in
|
|||
inherit (cfg.sso) port;
|
||||
};
|
||||
audit_log = {
|
||||
target = [
|
||||
"fd://stdout"
|
||||
];
|
||||
target = [ "fd://stdout" ];
|
||||
events = [
|
||||
"access_denied"
|
||||
"login_success"
|
||||
|
@ -359,21 +370,30 @@ in
|
|||
in
|
||||
{
|
||||
users = applyUsers (_: v: { _secret = v.passwordHashFile; });
|
||||
mfa = applyUsers (_: v: [{
|
||||
provider = "totp";
|
||||
attributes = {
|
||||
secret = {
|
||||
_secret = v.totpSecretFile;
|
||||
};
|
||||
};
|
||||
}]);
|
||||
mfa = applyUsers (
|
||||
_: v: [
|
||||
{
|
||||
provider = "totp";
|
||||
attributes = {
|
||||
secret = {
|
||||
_secret = v.totpSecretFile;
|
||||
};
|
||||
};
|
||||
}
|
||||
]
|
||||
);
|
||||
inherit (cfg.sso) groups;
|
||||
};
|
||||
};
|
||||
acl = {
|
||||
rule_sets = [
|
||||
{
|
||||
rules = [{ field = "x-application"; present = true; }];
|
||||
rules = [
|
||||
{
|
||||
field = "x-application";
|
||||
present = true;
|
||||
}
|
||||
];
|
||||
allow = [ "@root" ];
|
||||
}
|
||||
];
|
||||
|
@ -426,7 +446,10 @@ in
|
|||
];
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
];
|
||||
# Nginx needs to be able to read the certificates
|
||||
users.users.nginx.extraGroups = [ "acme" ];
|
||||
security.acme = {
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# I must override the module to allow having runtime secrets
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.nginx.sso;
|
||||
pkg = lib.getBin cfg.package;
|
||||
|
@ -8,7 +14,6 @@ in
|
|||
{
|
||||
disabledModules = [ "services/security/nginx-sso.nix" ];
|
||||
|
||||
|
||||
options.services.nginx.sso = with lib; {
|
||||
enable = mkEnableOption "nginx-sso service";
|
||||
|
||||
|
@ -67,8 +72,7 @@ in
|
|||
# Fix permissions
|
||||
chown nginx-sso:nginx-sso ${confPath}
|
||||
chmod 0600 ${confPath}
|
||||
''
|
||||
}'';
|
||||
''}'';
|
||||
ExecStart = lib.mkForce ''
|
||||
${pkg}/bin/nginx-sso \
|
||||
--config ${confPath} \
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# monitoring system services
|
||||
{ config, lib, pkgs, inputs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.node-exporter;
|
||||
in
|
||||
|
@ -17,9 +23,7 @@ in
|
|||
"systemd"
|
||||
"textfile"
|
||||
];
|
||||
extraFlags = [
|
||||
"--collector.textfile.directory=/etc/prometheus-node-exporter-text-files"
|
||||
];
|
||||
extraFlags = [ "--collector.textfile.directory=/etc/prometheus-node-exporter-text-files" ];
|
||||
port = 9100;
|
||||
listenAddress = "127.0.0.1";
|
||||
};
|
||||
|
@ -32,21 +36,25 @@ in
|
|||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "node";
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}];
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "systemd";
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.systemd.port}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}];
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.systemd.port}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
@ -55,10 +63,14 @@ in
|
|||
environment.etc =
|
||||
let
|
||||
inputsWithDate = lib.filterAttrs (_: input: input ? lastModified) inputs;
|
||||
flakeAttrs = input: (lib.mapAttrsToList (n: v: ''${n}="${v}"'')
|
||||
(lib.filterAttrs (_n: v: (builtins.typeOf v) == "string") input));
|
||||
lastModified = name: input: ''
|
||||
flake_input_last_modified{input="${name}",${lib.concatStringsSep "," (flakeAttrs input)}} ${toString input.lastModified}'';
|
||||
flakeAttrs =
|
||||
input:
|
||||
(lib.mapAttrsToList (n: v: ''${n}="${v}"'') (
|
||||
lib.filterAttrs (_n: v: (builtins.typeOf v) == "string") input
|
||||
));
|
||||
lastModified =
|
||||
name: input:
|
||||
''flake_input_last_modified{input="${name}",${lib.concatStringsSep "," (flakeAttrs input)}} ${toString input.lastModified}'';
|
||||
in
|
||||
{
|
||||
"prometheus-node-exporter-text-files/flake-inputs.prom" = {
|
||||
|
|
|
@ -19,14 +19,18 @@ in
|
|||
config = lib.mkIf cfg.enable {
|
||||
services.octoprint = {
|
||||
enable = true;
|
||||
plugins = plugins: with plugins; [
|
||||
costestimation
|
||||
displayprogress
|
||||
m86motorsoff
|
||||
stlviewer
|
||||
telegram
|
||||
titlestatus
|
||||
] ++ cfg.plugins;
|
||||
plugins =
|
||||
plugins:
|
||||
with plugins;
|
||||
[
|
||||
costestimation
|
||||
displayprogress
|
||||
m86motorsoff
|
||||
stlviewer
|
||||
telegram
|
||||
titlestatus
|
||||
]
|
||||
++ cfg.plugins;
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 5000 ];
|
||||
};
|
||||
|
|
|
@ -49,7 +49,12 @@ in
|
|||
config = lib.mkIf cfg.enable {
|
||||
services.photoprism = {
|
||||
enable = true;
|
||||
inherit (cfg) passwordFile port originalsPath settings;
|
||||
inherit (cfg)
|
||||
passwordFile
|
||||
port
|
||||
originalsPath
|
||||
settings
|
||||
;
|
||||
};
|
||||
|
||||
my.services.nginx.virtualHosts = [
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# monitoring system services
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.prometheus;
|
||||
inherit (config.networking) domain;
|
||||
|
@ -31,8 +36,8 @@ in
|
|||
|
||||
# a good collections for allerts can be found here: https://samber.github.io/awesome-prometheus-alerts/rules#blackbox
|
||||
rules = mkOption {
|
||||
type = types.attrsOf
|
||||
(types.submodule {
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
condition = mkOption {
|
||||
type = types.str;
|
||||
|
@ -69,7 +74,8 @@ in
|
|||
default = "2m";
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
description = ''
|
||||
Defines the prometheus rules.
|
||||
'';
|
||||
|
@ -92,12 +98,12 @@ in
|
|||
};
|
||||
|
||||
ruleFiles = [
|
||||
(pkgs.writeText "prometheus-rules.yml" (builtins.toJSON {
|
||||
groups = [
|
||||
{
|
||||
name = "alerting-rules";
|
||||
rules = lib.mapAttrsToList
|
||||
(name: opts: {
|
||||
(pkgs.writeText "prometheus-rules.yml" (
|
||||
builtins.toJSON {
|
||||
groups = [
|
||||
{
|
||||
name = "alerting-rules";
|
||||
rules = lib.mapAttrsToList (name: opts: {
|
||||
alert = name;
|
||||
expr = opts.condition;
|
||||
for = opts.time;
|
||||
|
@ -106,22 +112,24 @@ in
|
|||
inherit (opts) description;
|
||||
grafana = lib.optionalString config.services.grafana.enable "https://visualization.${domain}";
|
||||
};
|
||||
})
|
||||
cfg.rules;
|
||||
}
|
||||
];
|
||||
}))
|
||||
}) cfg.rules;
|
||||
}
|
||||
];
|
||||
}
|
||||
))
|
||||
];
|
||||
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "prometheus";
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString cfg.port}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}];
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "127.0.0.1:${toString cfg.port}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
|
|
@ -28,9 +28,11 @@ in
|
|||
positions = {
|
||||
filename = "/tmp/positions.yaml";
|
||||
};
|
||||
clients = [{
|
||||
url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
|
||||
}];
|
||||
clients = [
|
||||
{
|
||||
url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
|
||||
}
|
||||
];
|
||||
scrape_configs = [
|
||||
{
|
||||
job_name = "journal";
|
||||
|
@ -41,18 +43,18 @@ in
|
|||
host = config.networking.hostName;
|
||||
};
|
||||
};
|
||||
relabel_configs = [{
|
||||
source_labels = [ "__journal__systemd_unit" ];
|
||||
target_label = "unit";
|
||||
}];
|
||||
relabel_configs = [
|
||||
{
|
||||
source_labels = [ "__journal__systemd_unit" ];
|
||||
target_label = "unit";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "nginx";
|
||||
static_configs = [
|
||||
{
|
||||
targets = [
|
||||
"localhost"
|
||||
];
|
||||
targets = [ "localhost" ];
|
||||
labels = {
|
||||
job = "nginx";
|
||||
__path__ = "/var/log/nginx/*.log";
|
||||
|
|
|
@ -31,12 +31,14 @@ in
|
|||
prometheus.scrapeConfigs = [
|
||||
{
|
||||
job_name = "prowlarr";
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString port + 1}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}];
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "127.0.0.1:${toString port + 1}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
|
|
@ -31,12 +31,14 @@ in
|
|||
prometheus.scrapeConfigs = [
|
||||
{
|
||||
job_name = "radarr";
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString port + 1}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}];
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "127.0.0.1:${toString port + 1}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# manages remote builds
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.services.remote-build;
|
||||
in
|
||||
|
@ -15,7 +20,9 @@ in
|
|||
isSystemUser = true;
|
||||
group = "nixremote";
|
||||
shell = pkgs.bashInteractive;
|
||||
openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYSzDdxqaNHmaaLqEvOK/vB65zvqoCebI3Nxzgg5smq root@thinkman" ];
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYSzDdxqaNHmaaLqEvOK/vB65zvqoCebI3Nxzgg5smq root@thinkman"
|
||||
];
|
||||
};
|
||||
nix.settings.trusted-users = [ "nixremote" ];
|
||||
};
|
||||
|
|
|
@ -31,12 +31,14 @@ in
|
|||
prometheus.scrapeConfigs = [
|
||||
{
|
||||
job_name = "sonarr";
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString port + 1}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}];
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "127.0.0.1:${toString port + 1}" ];
|
||||
labels = {
|
||||
instance = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# avahi related settings
|
||||
{ config, lib, options, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.system.avahi;
|
||||
in
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# Docker related settings
|
||||
{ config, lib, options, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.system.docker;
|
||||
in
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.system.fonts;
|
||||
in
|
||||
|
@ -21,23 +26,26 @@ in
|
|||
monospace = [ "Ubuntu Mono" ];
|
||||
};
|
||||
|
||||
packages = with pkgs; [
|
||||
cantarell-fonts # gnome default
|
||||
fira
|
||||
fira-code # coding
|
||||
fira-code-symbols # ligatures
|
||||
fira-mono
|
||||
font-awesome # icons
|
||||
joypixels # emojis
|
||||
liberation_ttf # main microsoft fonts
|
||||
# mplus-outline-fonts.githubRelease # microsoft fonts
|
||||
noto-fonts
|
||||
noto-fonts-cjk-sans
|
||||
noto-fonts-color-emoji
|
||||
noto-fonts-extra
|
||||
ubuntu_font_family
|
||||
unifont # unicode fallback
|
||||
] ++ cfg.additionalFonts;
|
||||
packages =
|
||||
with pkgs;
|
||||
[
|
||||
cantarell-fonts # gnome default
|
||||
fira
|
||||
fira-code # coding
|
||||
fira-code-symbols # ligatures
|
||||
fira-mono
|
||||
font-awesome # icons
|
||||
joypixels # emojis
|
||||
liberation_ttf # main microsoft fonts
|
||||
# mplus-outline-fonts.githubRelease # microsoft fonts
|
||||
noto-fonts
|
||||
noto-fonts-cjk-sans
|
||||
noto-fonts-color-emoji
|
||||
noto-fonts-extra
|
||||
ubuntu_font_family
|
||||
unifont # unicode fallback
|
||||
]
|
||||
++ cfg.additionalFonts;
|
||||
};
|
||||
nixpkgs.config.joypixels.acceptLicense = true;
|
||||
};
|
||||
|
|
|
@ -7,32 +7,31 @@ in
|
|||
enable = mkEnableOption "kvm configuration";
|
||||
|
||||
cpuFlavor = mkOption {
|
||||
type = with types; nullOr (enum [ "intel" "amd" ]);
|
||||
type =
|
||||
with types;
|
||||
nullOr (enum [
|
||||
"intel"
|
||||
"amd"
|
||||
]);
|
||||
default = null;
|
||||
example = "intel";
|
||||
description = "Which kind of CPU to activate kernelModules";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
virtualisation.libvirtd.enable = true;
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
virtualisation.libvirtd.enable = true;
|
||||
|
||||
programs.virt-manager.enable = true;
|
||||
}
|
||||
programs.virt-manager.enable = true;
|
||||
}
|
||||
|
||||
# Intel CPU
|
||||
(lib.mkIf (cfg.cpuFlavor == "intel") {
|
||||
boot.kernelModules = [
|
||||
"kvm-intel"
|
||||
];
|
||||
})
|
||||
# Intel CPU
|
||||
(lib.mkIf (cfg.cpuFlavor == "intel") { boot.kernelModules = [ "kvm-intel" ]; })
|
||||
|
||||
# AMD CPU
|
||||
(lib.mkIf (cfg.cpuFlavor == "amd") {
|
||||
boot.kernelModules = [
|
||||
"kvm-amd"
|
||||
];
|
||||
})
|
||||
]);
|
||||
# AMD CPU
|
||||
(lib.mkIf (cfg.cpuFlavor == "amd") { boot.kernelModules = [ "kvm-amd" ]; })
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# Podman related settings
|
||||
{ config, lib, options, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.system.podman;
|
||||
in
|
||||
|
@ -10,9 +16,7 @@ in
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
podman-compose
|
||||
];
|
||||
environment.systemPackages = with pkgs; [ podman-compose ];
|
||||
|
||||
virtualisation.podman = {
|
||||
enable = true;
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# spell-checking
|
||||
{ config, lib, options, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.system.spell-check;
|
||||
in
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue