treewide: fmt

This commit is contained in:
Felix Buehler 2024-07-28 21:08:02 +02:00
parent 330abe53d2
commit ea37c7b836
95 changed files with 1162 additions and 779 deletions

View file

@ -43,7 +43,13 @@
};
};
outputs = inputs@{ self, flake-parts, nixinate, ... }:
outputs =
inputs@{
self,
flake-parts,
nixinate,
...
}:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
@ -52,51 +58,61 @@
inputs.git-hooks.flakeModule
];
systems = [ "x86_64-linux" "aarch64-linux" ];
systems = [
"x86_64-linux"
"aarch64-linux"
];
perSystem = { inputs', config, pkgs, system, ... }: {
# make pkgs available to all `perSystem` functions
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
};
perSystem =
{
inputs',
config,
pkgs,
system,
...
}:
{
# make pkgs available to all `perSystem` functions
_module.args.pkgs = import inputs.nixpkgs { inherit system; };
# enable pre-commit checks
pre-commit.settings = {
hooks = {
deadnix = {
enable = true;
settings.noLambdaPatternNames = true;
};
markdownlint.enable = true;
nixfmt = {
enable = true;
# TODO remove in 24.11
package = pkgs.nixfmt-rfc-style;
};
shellcheck.enable = true;
statix.enable = true;
typos = {
enable = true;
excludes = [ "secrets\\.yaml" "\\.sops\\.yaml" ];
settings.ignored-words = [ "flate" ];
};
yamllint = {
enable = true;
excludes = [ "secrets\\.yaml" ];
# enable pre-commit checks
pre-commit.settings = {
hooks = {
deadnix = {
enable = true;
settings.noLambdaPatternNames = true;
};
markdownlint.enable = true;
nixfmt = {
enable = true;
# TODO remove in 24.11
package = pkgs.nixfmt-rfc-style;
};
shellcheck.enable = true;
statix.enable = true;
typos = {
enable = true;
excludes = [
"secrets\\.yaml"
"\\.sops\\.yaml"
];
settings.ignored-words = [ "flate" ];
};
yamllint = {
enable = true;
excludes = [ "secrets\\.yaml" ];
};
};
};
};
devShells.default = pkgs.mkShell {
inputsFrom = [
config.pre-commit.devShell
];
nativeBuildInputs = with pkgs; [
inputs'.sops-nix.packages.sops-import-keys-hook
inputs'.disko.packages.disko
];
devShells.default = pkgs.mkShell {
inputsFrom = [ config.pre-commit.devShell ];
nativeBuildInputs = with pkgs; [
inputs'.sops-nix.packages.sops-import-keys-hook
inputs'.disko.packages.disko
];
};
};
};
# flake = {};
flake.apps = inputs.nixinate.nixinate."x86_64-linux" self;
};

View file

@ -1,9 +1,11 @@
# based on: https://github.com/Mic92/dotfiles/blob/main/nixos/images/base-config.nix
{ lib
, pkgs
, config
, ...
}: {
{
lib,
pkgs,
config,
...
}:
{
system.stateVersion = config.system.nixos.version;
networking = {
@ -23,7 +25,8 @@
network.enable = true;
network.networks =
lib.mapAttrs'
(num: _:
(
num: _:
lib.nameValuePair "eth${num}" {
matchConfig.Name = "eth${num}";
networkConfig = {
@ -40,7 +43,8 @@
RouteMetric = 512;
};
ipv6AcceptRAConfig.Token = "::521a:c5ff:fefe:65d9";
})
}
)
{
"0" = { };
"1" = { };

View file

@ -2,25 +2,19 @@
let
inherit (self.inputs) nixos-generators;
defaultModule = {
imports = [
./base-config.nix
];
imports = [ ./base-config.nix ];
_module.args.inputs = self.inputs;
};
in
{
perSystem =
{ pkgs
, ...
}:
{ pkgs, ... }:
{
packages = {
install-iso = nixos-generators.nixosGenerate {
system = "x86_64-linux";
inherit pkgs;
modules = [
defaultModule
];
modules = [ defaultModule ];
format = "install-iso";
};

View file

@ -1,6 +1,7 @@
# nix build .#install-sd-aarch64 --system aarch64-linux
# zstd -vdcfT6 /nix/store/...-aarch64-linux.img/sd-image/...-aarch64-linux.img.zst | dd of=/dev/sdX status=progress bs=64K
{ ... }: {
{ ... }:
{
nixpkgs.localSystem.system = "aarch64-linux";
imports = [
<nixpkgs/nixos/modules/installer/sd-card/sd-image-aarch64.nix>

View file

@ -2,7 +2,13 @@
# nix build -f yubikey-installer.nix nixos-yubikey
# sudo cp -v installer/iso/*.iso /dev/sdb; sync
let
configuration = { config, lib, pkgs, ... }:
configuration =
{
config,
lib,
pkgs,
...
}:
with pkgs;
let
src = fetchGit "https://github.com/drduh/YubiKey-Guide";
@ -54,12 +60,17 @@ let
yubikey-guide = symlinkJoin {
name = "yubikey-guide";
paths = [ view-yubikey-guide shortcut ];
paths = [
view-yubikey-guide
shortcut
];
};
in
{
nixpkgs.config = { allowBroken = true; };
nixpkgs.config = {
allowBroken = true;
};
isoImage.isoBaseName = lib.mkForce "nixos-yubikey";
# Uncomment this to disable compression and speed up image creation time
@ -72,7 +83,9 @@ let
kernelParams = [ "copytoram" ];
# Secure defaults
tmp.cleanOnBoot = true;
kernel.sysctl = { "kernel.unprivileged_bpf_disabled" = 1; };
kernel.sysctl = {
"kernel.unprivileged_bpf_disabled" = 1;
};
};
services.pcscd.enable = true;

View file

@ -1,7 +1,6 @@
{ self, ... }:
let
inherit
(self.inputs)
inherit (self.inputs)
nixpkgs
nixpkgs-unstable
sops-nix
@ -26,18 +25,19 @@ let
}
{
imports = [
({ pkgs, ... }: {
nixpkgs.config.allowUnfree = true;
nixpkgs.overlays = [
overlay-unstable
(import ../overlays)
(import ../pkgs)
];
nix.nixPath = [
"nixpkgs=${pkgs.path}"
];
documentation.info.enable = false;
})
(
{ pkgs, ... }:
{
nixpkgs.config.allowUnfree = true;
nixpkgs.overlays = [
overlay-unstable
(import ../overlays)
(import ../pkgs)
];
nix.nixPath = [ "nixpkgs=${pkgs.path}" ];
documentation.info.enable = false;
}
)
disko.nixosModules.disko
passworts.nixosModules.passworts
sops-nix.nixosModules.sops
@ -60,9 +60,7 @@ in
};
newton = nixosSystem {
system = "x86_64-linux";
modules = defaultModules ++ [
./newton/configuration.nix
];
modules = defaultModules ++ [ ./newton/configuration.nix ];
};
serverle = nixosSystem {
system = "aarch64-linux";

View file

@ -1,5 +1,4 @@
_:
{
_: {
boot.initrd = {
availableKernelModules = [
"ahci"

View file

@ -1,5 +1,4 @@
_:
{
_: {
networking.networkmanager = {
enable = true;

View file

@ -1,5 +1,4 @@
_:
{
_: {
boot.loader = {
timeout = 1;
grub = {

View file

@ -18,9 +18,7 @@
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
];
mountOptions = [ "defaults" ];
};
};
luks = {

View file

@ -1,4 +1,9 @@
{ config, lib, modulesPath, ... }:
{
config,
lib,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
@ -9,9 +14,7 @@
"virtio_pci"
"virtio_scsi"
];
boot.initrd.kernelModules = [
"dm-snapshot"
];
boot.initrd.kernelModules = [ "dm-snapshot" ];
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -27,7 +27,9 @@ let
in
{
# kernel parameters are needed for initrd
boot.kernelParams = [ "ip=${ip4_addr}::${ip4_gw}:${ip4_mask}:${config.networking.hostName}:${ifname}:off" ];
boot.kernelParams = [
"ip=${ip4_addr}::${ip4_gw}:${ip4_mask}:${config.networking.hostName}:${ifname}:off"
];
networking = {
nameservers = ip4_dns ++ ip6_dns;
domain = "buehler.rocks";

View file

@ -1,6 +1,5 @@
# enabled system services
_:
{
_: {
my.system = {
podman.enable = true;
};

View file

@ -18,9 +18,7 @@
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
];
mountOptions = [ "defaults" ];
};
};
luks = {

View file

@ -1,5 +1,4 @@
_:
{
_: {
networking.firewall.allowedTCPPorts = [
8080 # aria
];

View file

@ -74,9 +74,7 @@
"Aria2" = {
id = "jjnzq-pgzua";
path = "/data/tmp/aria2";
devices = [
"thinkman"
];
devices = [ "thinkman" ];
};
};
};

View file

@ -1,6 +1,5 @@
# enabled system services
_:
{
_: {
my.system = {
avahi.enable = true;
docker.enable = true;

View file

@ -1,5 +1,4 @@
_:
{
_: {
boot = {
loader = {
timeout = 1;

View file

@ -18,9 +18,7 @@
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
];
mountOptions = [ "defaults" ];
};
};
luks = {

View file

@ -1,6 +1,5 @@
# network settings
_:
{
_: {
# hotfixes for dns settings
networking.extraHosts =
let

View file

@ -1,6 +1,5 @@
# enabled profiles
_:
{
_: {
my.profiles = {
"3d-design".enable = true;
android.enable = true;

View file

@ -9,7 +9,11 @@ in
{
hostName = "buehler.rocks";
system = "x86_64-linux";
supportedFeatures = [ "benchmark" "kvm" "big-parallel" ];
supportedFeatures = [
"benchmark"
"kvm"
"big-parallel"
];
sshUser = "nixremote";
sshKey = secrets."nixremote/ssh_key".path;
maxJobs = 4;

View file

@ -1,6 +1,5 @@
# enabled system services
_:
{
_: {
my.system = {
avahi.enable = true;
fonts.enable = true;

View file

@ -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 ];
};
}

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.hardware.debug;
in

View file

@ -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;
};
})
]
);
}

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.hardware.graphics;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.hardware.keychron;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.hardware.sound;
in

View file

@ -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;
};
}

View file

@ -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 ];
};
}

View file

@ -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";

View file

@ -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;
};
}
];
}
];
};

View file

@ -1,5 +1,10 @@
# to download things
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.aria2;
inherit (config.networking) domain;

View file

@ -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/";

View file

@ -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;
};
}
];
}
];
};

View file

@ -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-"; }
];
};
};

View file

@ -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

View file

@ -1,5 +1,10 @@
# RSS aggregator and reader
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.freshrss;
inherit (config.networking) domain;

View file

@ -1,5 +1,10 @@
# self-hosted git service
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.gitea;
inherit (config.networking) domain;

View file

@ -1,5 +1,10 @@
# visualize monitoring services
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.grafana;
inherit (config.networking) domain;

View file

@ -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;

View file

@ -1,5 +1,10 @@
# home automation
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.home-automation;
inherit (config.networking) domain;

View file

@ -1,5 +1,10 @@
# My own personal homepage
{ config, lib, inputs, ... }:
{
config,
lib,
inputs,
...
}:
let
cfg = config.my.services.homepage;
inherit (config.networking) domain;

View file

@ -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}/" ];
};
}

View file

@ -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";
}
];
};
};

View file

@ -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"
];

View file

@ -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 ];

View file

@ -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 = {

View file

@ -1,5 +1,10 @@
# sandbox video game
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.minecraft-server;
in

View file

@ -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 = {

View file

@ -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;

View file

@ -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;
};

View file

@ -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 = {

View file

@ -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} \

View file

@ -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" = {

View file

@ -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 ];
};

View file

@ -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 = [

View file

@ -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;
};
}
];
}
];
};

View file

@ -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";

View file

@ -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;
};
}
];
}
];
};

View file

@ -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;
};
}
];
}
];
};

View file

@ -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" ];
};

View file

@ -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;
};
}
];
}
];
};

View file

@ -1,5 +1,10 @@
# avahi related settings
{ config, lib, options, ... }:
{
config,
lib,
options,
...
}:
let
cfg = config.my.system.avahi;
in

View file

@ -1,5 +1,11 @@
# Docker related settings
{ config, lib, options, pkgs, ... }:
{
config,
lib,
options,
pkgs,
...
}:
let
cfg = config.my.system.docker;
in

View file

@ -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;
};

View file

@ -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" ]; })
]
);
}

View file

@ -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;

View file

@ -1,5 +1,11 @@
# spell-checking
{ config, lib, options, pkgs, ... }:
{
config,
lib,
options,
pkgs,
...
}:
let
cfg = config.my.system.spell-check;
in

View file

@ -1,6 +1,5 @@
# overlays for nixpkgs
_self: _super:
{
_self: _super: {
# freshrss = _super.freshrss.overrideAttrs (old: {
# version = "1.21.0";
# src = _super.fetchFromGitHub {

View file

@ -1,5 +1,4 @@
final: _prev:
{
final: _prev: {
homer = final.callPackage ./homer { };
grafana-dashboards = final.callPackage ./grafana-dashboards { };
}

View file

@ -6,139 +6,164 @@ let
inherit (pkgs) stdenv fetchurl;
in
lib.makeScope pkgs.newScope (_self:
let
buildGrafanaDashboard = args: stdenv.mkDerivation (args // {
pname = "grafana-dashboard-${args.pname}-${toString args.id}";
inherit (args) version;
src = fetchurl {
url = "https://grafana.com/api/dashboards/${toString args.id}/revisions/${args.version}/download";
inherit (args) hash;
lib.makeScope pkgs.newScope (
_self:
let
buildGrafanaDashboard =
args:
stdenv.mkDerivation (
args
// {
pname = "grafana-dashboard-${args.pname}-${toString args.id}";
inherit (args) version;
src = fetchurl {
url = "https://grafana.com/api/dashboards/${toString args.id}/revisions/${args.version}/download";
inherit (args) hash;
};
dontUnpack = true;
installPhase = ''
runHook preInstall
mkdir -p $out
cp $src $out/${args.pname}-${toString args.id}.json
runHook postInstall
'';
}
);
in
{
inherit buildGrafanaDashboard;
node-exporter = buildGrafanaDashboard {
id = 1860;
pname = "node-exporter-full";
version = "31";
hash = "sha256-QsRHsnayYRRGc+2MfhaKGYpNdH02PesnR5b50MDzHIg=";
};
dontUnpack = true;
installPhase = ''
runHook preInstall
mkdir -p $out
cp $src $out/${args.pname}-${toString args.id}.json
runHook postInstall
'';
});
in
{
inherit buildGrafanaDashboard;
node-systemd =
(buildGrafanaDashboard {
id = 1617;
pname = "node-systemd";
version = "1";
hash = "sha256-MEWU5rIqlbaGu3elqdSoMZfbk67WDnH0VWuC8FqZ8v8=";
}).overrideAttrs
(_: {
src = ./node-systemd.json; # sadly only imported dashboards work
});
node-exporter = buildGrafanaDashboard {
id = 1860;
pname = "node-exporter-full";
version = "31";
hash = "sha256-QsRHsnayYRRGc+2MfhaKGYpNdH02PesnR5b50MDzHIg=";
};
node-systemd = (buildGrafanaDashboard {
id = 1617;
pname = "node-systemd";
version = "1";
hash = "sha256-MEWU5rIqlbaGu3elqdSoMZfbk67WDnH0VWuC8FqZ8v8=";
}).overrideAttrs (_: {
src = ./node-systemd.json; # sadly only imported dashboards work
});
nginx = buildGrafanaDashboard {
id = 12708;
pname = "nginx";
version = "1";
hash = "sha256-T1HqWbwt+i/We+Y2B7hcl3CijGxZF5QI38aPcXjk9y0=";
};
nginx = buildGrafanaDashboard {
id = 12708;
pname = "nginx";
version = "1";
hash = "sha256-T1HqWbwt+i/We+Y2B7hcl3CijGxZF5QI38aPcXjk9y0=";
};
nextcloud =
(buildGrafanaDashboard {
id = 9632;
pname = "nextcloud";
version = "1";
hash = "sha256-Z28Q/sMg3jxglkszAs83IpL8f4p9loNnTQzjc3S/SAQ=";
}).overrideAttrs
(_: {
src = ./nextcloud.json; # sadly only imported dashboards work
});
nextcloud = (buildGrafanaDashboard {
id = 9632;
pname = "nextcloud";
version = "1";
hash = "sha256-Z28Q/sMg3jxglkszAs83IpL8f4p9loNnTQzjc3S/SAQ=";
}).overrideAttrs (_: {
src = ./nextcloud.json; # sadly only imported dashboards work
});
blocky = buildGrafanaDashboard {
id = 13768;
pname = "blocky";
version = "3";
hash = "sha256-T1HqWbwt+i/Wa+Y2B7hcl3CijGxZF5aI38aPcXjk9y0=";
};
blocky = buildGrafanaDashboard {
id = 13768;
pname = "blocky";
version = "3";
hash = "sha256-T1HqWbwt+i/Wa+Y2B7hcl3CijGxZF5aI38aPcXjk9y0=";
};
navidrome =
(buildGrafanaDashboard {
id = 18038;
pname = "navidrome";
version = "1";
hash = "sha256-MU890UAEI9wrnVIC/R0HkYwFa6mJ8Y7ESAWuaSQ8FQ8=";
}).overrideAttrs
(_: {
src = ./navidrome.json; # sadly data source is not detected
});
navidrome = (buildGrafanaDashboard {
id = 18038;
pname = "navidrome";
version = "1";
hash = "sha256-MU890UAEI9wrnVIC/R0HkYwFa6mJ8Y7ESAWuaSQ8FQ8=";
}).overrideAttrs (_: {
src = ./navidrome.json; # sadly data source is not detected
});
# taken from https://gitlab.archlinux.org/archlinux/infrastructure/-/blob/master/roles/grafana/files/dashboards/Hedgedoc.json?ref_type=heads
hedgedoc =
(buildGrafanaDashboard {
id = -1;
pname = "hedgedoc";
version = "1";
hash = lib.fakeSha256;
}).overrideAttrs
(_: {
src = ./hedgedoc.json; # sadly data source is not detected
});
# taken from https://gitlab.archlinux.org/archlinux/infrastructure/-/blob/master/roles/grafana/files/dashboards/Hedgedoc.json?ref_type=heads
hedgedoc = (buildGrafanaDashboard {
id = -1;
pname = "hedgedoc";
version = "1";
hash = lib.fakeSha256;
}).overrideAttrs (_: {
src = ./hedgedoc.json; # sadly data source is not detected
});
cadvisor = buildGrafanaDashboard {
id = 10619;
pname = "cadvisor";
version = "1";
hash = "sha256-T1HqWbwt+i/Wa+Y2B7hclaCijGxZF5QI38aPcXjk9y0=";
};
cadvisor = buildGrafanaDashboard {
id = 10619;
pname = "cadvisor";
version = "1";
hash = "sha256-T1HqWbwt+i/Wa+Y2B7hclaCijGxZF5QI38aPcXjk9y0=";
};
loki =
(buildGrafanaDashboard {
id = 13407;
pname = "loki";
version = "1";
hash = "sha256-1sxTDSEwi2O/Ce+rWqqhMvsYEJeELBfkb9W2R6cDjcU=";
}).overrideAttrs
(_: {
src = ./loki.json; # sadly not yet updated to latest grafana
});
loki = (buildGrafanaDashboard {
id = 13407;
pname = "loki";
version = "1";
hash = "sha256-1sxTDSEwi2O/Ce+rWqqhMvsYEJeELBfkb9W2R6cDjcU=";
}).overrideAttrs (_: {
src = ./loki.json; # sadly not yet updated to latest grafana
});
alertmanager = buildGrafanaDashboard {
id = 9578;
pname = "alertmanager";
version = "4";
hash = "sha256-/scCKBKqTjRKKImIrEYLBKGweOUnkx+QsD5yLfdXW5o=";
};
alertmanager = buildGrafanaDashboard {
id = 9578;
pname = "alertmanager";
version = "4";
hash = "sha256-/scCKBKqTjRKKImIrEYLBKGweOUnkx+QsD5yLfdXW5o=";
};
gitea =
(buildGrafanaDashboard {
id = 13192;
pname = "gitea";
version = "1";
hash = "sha256-IAaI/HvMxcWE3PGQFK8avNjgj88DgcDvkWRcDAWSejM=";
}).overrideAttrs
(_: {
src = ./gitea.json; # sadly not yet updated to latest grafana
});
gitea = (buildGrafanaDashboard {
id = 13192;
pname = "gitea";
version = "1";
hash = "sha256-IAaI/HvMxcWE3PGQFK8avNjgj88DgcDvkWRcDAWSejM=";
}).overrideAttrs (_: {
src = ./gitea.json; # sadly not yet updated to latest grafana
});
prometheus =
(buildGrafanaDashboard {
id = 3662;
pname = "prometheus";
version = "2";
hash = "sha256-+nsi8/dYNvGVGV+ftfO1gSAQbO5GpZwW480T5mHMM4Q=";
}).overrideAttrs
(_: {
src = ./prometheus.json; # sadly only imported dashboards work
});
prometheus = (buildGrafanaDashboard {
id = 3662;
pname = "prometheus";
version = "2";
hash = "sha256-+nsi8/dYNvGVGV+ftfO1gSAQbO5GpZwW480T5mHMM4Q=";
}).overrideAttrs (_: {
src = ./prometheus.json; # sadly only imported dashboards work
});
grafana =
(buildGrafanaDashboard {
id = 3590;
pname = "grafana";
version = "3";
}).overrideAttrs
(_: {
src = ./grafana.json; # sadly only imported dashboards work
});
grafana = (buildGrafanaDashboard {
id = 3590;
pname = "grafana";
version = "3";
}).overrideAttrs (_: {
src = ./grafana.json; # sadly only imported dashboards work
});
blackbox = (buildGrafanaDashboard {
id = 13659;
pname = "blackbox";
version = "1";
hash = "sha256-nnBFWFDAqKUqTOYxOrkRPlVla4ioQZ6rqEqakdzUj1Q=";
}).overrideAttrs (_: {
src = ./blackbox.json; # sadly only imported dashboards work
});
})
blackbox =
(buildGrafanaDashboard {
id = 13659;
pname = "blackbox";
version = "1";
hash = "sha256-nnBFWFDAqKUqTOYxOrkRPlVla4ioQZ6rqEqakdzUj1Q=";
}).overrideAttrs
(_: {
src = ./blackbox.json; # sadly only imported dashboards work
});
}
)

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles."3d-design";
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.android;
in
@ -9,8 +14,6 @@ in
config = lib.mkIf cfg.enable {
programs.adb.enable = true;
environment.systemPackages = with pkgs; [
scrcpy
];
environment.systemPackages = with pkgs; [ scrcpy ];
};
}

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.clean;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.desktop-apps;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.desktop-dev;
in
@ -22,7 +27,8 @@ in
(vscode-with-extensions.override {
vscode = vscodium;
vscodeExtensions =
with vscode-extensions; [
with vscode-extensions;
[
bbenoist.nix
editorconfig.editorconfig
github.copilot
@ -31,11 +37,13 @@ in
ms-python.python
ms-vscode-remote.remote-ssh
pkief.material-icon-theme
] ++ [
]
++ [
# remove in 24.05
unstable.vscode-extensions.equinusocio.vsc-material-theme
unstable.vscode-extensions.hiukky.flate
] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
]
++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
# {
# name = "vsc-material-theme";
# publisher = "Equinusocio";

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.development;
in
@ -23,18 +28,20 @@ in
# websites
hugo
# scripts
(python3.withPackages (ps: with ps; [
jupyter # notebooks
matplotlib
numpy
pandas
pillow
plotly
scikitlearn
scipy
tqdm # progressbar in pandas
wheel # python development
]))
(python3.withPackages (
ps: with ps; [
jupyter # notebooks
matplotlib
numpy
pandas
pillow
plotly
scikitlearn
scipy
tqdm # progressbar in pandas
wheel # python development
]
))
# linter
shellcheck
typos

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.filesystem;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.gaming;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.gnome;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.latex;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.media;
in
@ -31,9 +36,7 @@ in
shotwell # photo management
sonixd # cloud-music-player
soundkonverter # audio converter
(yt-dlp.override {
withAlias = true;
}) # video download
(yt-dlp.override { withAlias = true; }) # video download
];
};
}

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.meeting;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.nautilus;
in
@ -31,9 +36,7 @@ in
];
sessionVariables.NAUTILUS_4_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-4";
pathsToLink = [
"/share/nautilus-python/extensions"
];
pathsToLink = [ "/share/nautilus-python/extensions" ];
};
programs.nautilus-open-any-terminal = {

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.powersave;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.printing;
in
@ -16,8 +21,6 @@ in
];
programs.system-config-printer.enable = true;
environment.systemPackages = with pkgs; [
gnome.simple-scan
];
environment.systemPackages = with pkgs; [ gnome.simple-scan ];
};
}

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.sway;
in
@ -23,9 +28,7 @@ in
sway-theme.enable = true;
};
environment.systemPackages = with pkgs; [
polkit_gnome
];
environment.systemPackages = with pkgs; [ polkit_gnome ];
environment.pathsToLink = [ "/libexec" ];
programs = {

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.sway-screen-sharing;
in
@ -8,18 +13,14 @@ in
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
remmina
];
environment.systemPackages = with pkgs; [ remmina ];
services.pipewire.enable = true;
xdg.portal = {
enable = true;
wlr.enable = true;
extraPortals = with pkgs; [
xdg-desktop-portal-gtk
];
extraPortals = with pkgs; [ xdg-desktop-portal-gtk ];
};
# for firefox

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.sway-theme;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.sync;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.update;
in
@ -11,8 +16,6 @@ in
# Enable firmware update daemon
services.fwupd.enable = true;
environment.systemPackages = with pkgs; [
topgrade
];
environment.systemPackages = with pkgs; [ topgrade ];
};
}

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.usb-iso;
in

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.profiles.webcam;
in