Compare commits
1 Commits
main
...
deploy-doo
Author | SHA1 | Date | |
---|---|---|---|
7e7b576540 |
.mailmap.sops.yamlREADME.MDbase.nixjustfileshell.nix
base
default.nixnetworking.nixnix.nix
flake.lockflake.nixservices
acme.nixauto-upgrade.nixdbus.nixfwupd.nixirqbalance.nixlogrotate.nixnginx.nixopenssh.nixpostfix.nixsmartd.nixthermald.nixuptimed.nixuserborn.nixuserdbd.nix
vm.nixhosts
bekkalokk
configuration.nix
services
bicep
bob
brzeczyszczykiewicz
buskerud
georg
ildkule
kommode
shark
ustetind
wenche
keys
misc
modules
packages
secrets
bekkalokk
bicep
ildkule
kommode
ustetind
shells
users
values.nix
25
.mailmap
25
.mailmap
@ -1,25 +0,0 @@
|
||||
Daniel Løvbrøtte Olsen <danio@pvv.ntnu.no> <daniel.olsen99@gmail.com>
|
||||
Daniel Løvbrøtte Olsen <danio@pvv.ntnu.no> Daniel <danio@pvv.ntnu.no>
|
||||
Daniel Løvbrøtte Olsen <danio@pvv.ntnu.no> Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
|
||||
Daniel Løvbrøtte Olsen <danio@pvv.ntnu.no> Daniel Olsen <danio@pvv.ntnu.no>
|
||||
Daniel Løvbrøtte Olsen <danio@pvv.ntnu.no> danio <danio@pvv.ntnu.no>
|
||||
Daniel Løvbrøtte Olsen <danio@pvv.ntnu.no> Daniel Olsen <danio@bicep.pvv.ntnu.no>
|
||||
|
||||
|
||||
Øystein Kristoffer Tveit <oysteikt@pvv.ntnu.no> h7x4 <h7x4@nani.wtf>
|
||||
Øystein Kristoffer Tveit <oysteikt@pvv.ntnu.no> Øystein Tveit <oysteikt@pvv.ntnu.no>
|
||||
Øystein Kristoffer Tveit <oysteikt@pvv.ntnu.no> oysteikt <oysteikt@pvv.ntnu.no>
|
||||
Øystein Kristoffer Tveit <oysteikt@pvv.ntnu.no> Øystein <oysteikt@pvv.org>
|
||||
Øystein Kristoffer Tveit <oysteikt@pvv.ntnu.no> Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
|
||||
|
||||
Felix Albrigtsen <felixalb@pvv.ntnu.no> <felix@albrigtsen.it>
|
||||
Felix Albrigtsen <felixalb@pvv.ntnu.no> <felixalbrigtsen@gmail.com>
|
||||
Felix Albrigtsen <felixalb@pvv.ntnu.no> felixalb <felixalb@pvv.ntnu.no>
|
||||
|
||||
Peder Bergebakken Sundt <pederbs@pvv.ntnu.no> <pbsds@hotmail.com>
|
||||
|
||||
Adrian Gunnar Lauterer <adriangl@pvv.ntnu.no> Adrian G L <adrian@lauterer.it>
|
||||
Adrian Gunnar Lauterer <adriangl@pvv.ntnu.no> Adrian Gunnar Lauterer <adrian@lauterer.it>
|
||||
|
||||
Fredrik Robertsen <frero@pvv.ntnu.no> frero <frero@pvv.ntnu.no>
|
||||
Fredrik Robertsen <frero@pvv.ntnu.no> fredrikr79 <fredrikrobertsen7@gmail.com>
|
26
.sops.yaml
26
.sops.yaml
@ -13,8 +13,6 @@ keys:
|
||||
- &host_ildkule age1x28hmzvuv6f2n66c0jtqcca3h9rput8d7j5uek6jcpx8n9egd52sqpejq0
|
||||
- &host_bekkalokk age12nj59tguy9wg882updc2vjdusx5srnxmjyfaqve4zx6jnnsaw3qsyjq6zd
|
||||
- &host_bicep age1sl43gc9cw939z5tgha2lpwf0xxxgcnlw7w4xem4sqgmt2pt264vq0dmwx2
|
||||
- &host_ustetind age1hffjafs4slznksefmtqrlj7rdaqgzqncn4un938rhr053237ry8s3rs0v8
|
||||
- &host_kommode age1mt4d0hg5g76qp7j0884llemy0k2ymr5up8vfudz6vzvsflk5nptqqd32ly
|
||||
|
||||
creation_rules:
|
||||
# Global secrets
|
||||
@ -45,18 +43,6 @@ creation_rules:
|
||||
pgp:
|
||||
- *user_oysteikt
|
||||
|
||||
- path_regex: secrets/kommode/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *host_kommode
|
||||
- *user_danio
|
||||
- *user_felixalb
|
||||
- *user_pederbs_sopp
|
||||
- *user_pederbs_nord
|
||||
- *user_pederbs_bjarte
|
||||
pgp:
|
||||
- *user_oysteikt
|
||||
|
||||
- path_regex: secrets/jokum/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
@ -92,15 +78,3 @@ creation_rules:
|
||||
- *user_pederbs_bjarte
|
||||
pgp:
|
||||
- *user_oysteikt
|
||||
|
||||
- path_regex: secrets/ustetind/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *host_ustetind
|
||||
- *user_danio
|
||||
- *user_felixalb
|
||||
- *user_pederbs_sopp
|
||||
- *user_pederbs_nord
|
||||
- *user_pederbs_bjarte
|
||||
pgp:
|
||||
- *user_oysteikt
|
||||
|
@ -26,14 +26,10 @@ Det er sikkert lurt å lage en PR først om du ikke er vandt til nix enda.
|
||||
Innen 24h skal alle systemene hente ned den nye konfigurasjonen og deploye den.
|
||||
|
||||
Du kan tvinge en maskin til å oppdatere seg før dette ved å kjøre:
|
||||
`nixos-rebuild switch --update-input nixpkgs --update-input nixpkgs-unstable --no-write-lock-file --refresh --upgrade --flake git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git`
|
||||
`nixos-rebuild switch --update-input nixpkgs --update-input nixpkgs-unstable --no-write-lock-file --refresh --flake git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git --upgrade`
|
||||
|
||||
som root på maskinen.
|
||||
|
||||
Hvis du ikke har lyst til å oppdatere alle pakkene (og kanskje måtte vente en stund!) kan du kjøre
|
||||
|
||||
`nixos-rebuild switch --override-input nixpkgs nixpkgs --override-input nixpkgs-unstable nixpkgs-unstable --flake git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git`
|
||||
|
||||
## Seksjonen for hemmeligheter
|
||||
|
||||
For at hemmeligheter ikke skal deles med hele verden i git - eller å være world
|
||||
|
150
base.nix
Normal file
150
base.nix
Normal file
@ -0,0 +1,150 @@
|
||||
{ config, lib, pkgs, inputs, values, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./users
|
||||
./modules/snakeoil-certs.nix
|
||||
];
|
||||
|
||||
networking.domain = "pvv.ntnu.no";
|
||||
networking.useDHCP = false;
|
||||
# networking.search = [ "pvv.ntnu.no" "pvv.org" ];
|
||||
# networking.nameservers = lib.mkDefault [ "129.241.0.200" "129.241.0.201" ];
|
||||
# networking.tempAddresses = lib.mkDefault "disabled";
|
||||
# networking.defaultGateway = values.hosts.gateway;
|
||||
|
||||
systemd.network.enable = true;
|
||||
|
||||
services.resolved = {
|
||||
enable = lib.mkDefault true;
|
||||
dnssec = "false"; # Supposdly this keeps breaking and the default is to allow downgrades anyways...
|
||||
};
|
||||
|
||||
time.timeZone = "Europe/Oslo";
|
||||
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
console = {
|
||||
font = "Lat2-Terminus16";
|
||||
keyMap = "no";
|
||||
};
|
||||
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
flake = "git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git";
|
||||
flags = [
|
||||
"--update-input" "nixpkgs"
|
||||
"--update-input" "nixpkgs-unstable"
|
||||
"--no-write-lock-file"
|
||||
];
|
||||
};
|
||||
nix.gc.automatic = true;
|
||||
nix.gc.options = "--delete-older-than 2d";
|
||||
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
|
||||
/* This makes commandline tools like
|
||||
** nix run nixpkgs#hello
|
||||
** and nix-shell -p hello
|
||||
** use the same channel the system
|
||||
** was built with
|
||||
*/
|
||||
nix.registry = {
|
||||
nixpkgs.flake = inputs.nixpkgs;
|
||||
};
|
||||
nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
file
|
||||
git
|
||||
gnupg
|
||||
htop
|
||||
nano
|
||||
ripgrep
|
||||
rsync
|
||||
screen
|
||||
tmux
|
||||
vim
|
||||
wget
|
||||
|
||||
kitty.terminfo
|
||||
];
|
||||
|
||||
programs.zsh.enable = true;
|
||||
|
||||
users.groups."drift".name = "drift";
|
||||
|
||||
# Trusted users on the nix builder machines
|
||||
users.groups."nix-builder-users".name = "nix-builder-users";
|
||||
|
||||
# Let's not thermal throttle
|
||||
services.thermald.enable = lib.mkIf (lib.all (x: x) [
|
||||
(config.nixpkgs.system == "x86_64-linux")
|
||||
(!config.boot.isContainer or false)
|
||||
]) true;
|
||||
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
PubkeyAcceptedAlgorithms=+ssh-rsa
|
||||
Match Group wheel
|
||||
PasswordAuthentication no
|
||||
Match All
|
||||
'';
|
||||
settings.PermitRootLogin = "yes";
|
||||
};
|
||||
|
||||
# nginx return 444 for all nonexistent virtualhosts
|
||||
|
||||
systemd.services.nginx.after = [ "generate-snakeoil-certs.service" ];
|
||||
|
||||
environment.snakeoil-certs = lib.mkIf config.services.nginx.enable {
|
||||
"/etc/certs/nginx" = {
|
||||
owner = "nginx";
|
||||
group = "nginx";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
recommendedTlsSettings = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
|
||||
appendConfig = ''
|
||||
pcre_jit on;
|
||||
worker_processes auto;
|
||||
worker_rlimit_nofile 100000;
|
||||
'';
|
||||
eventsConfig = ''
|
||||
worker_connections 2048;
|
||||
use epoll;
|
||||
multi_accept on;
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.nginx.serviceConfig = lib.mkIf config.services.nginx.enable {
|
||||
LimitNOFILE = 65536;
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."_" = lib.mkIf config.services.nginx.enable {
|
||||
sslCertificate = "/etc/certs/nginx.crt";
|
||||
sslCertificateKey = "/etc/certs/nginx.key";
|
||||
addSSL = true;
|
||||
extraConfig = "return 444;";
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf config.services.nginx.enable [ 80 443 ];
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "drift@pvv.ntnu.no";
|
||||
};
|
||||
# Let's not spam LetsEncrypt in `nixos-rebuild build-vm` mode:
|
||||
virtualisation.vmVariant = {
|
||||
security.acme.defaults.server = "https://127.0.0.1";
|
||||
security.acme.preliminarySelfsigned = true;
|
||||
|
||||
users.users.root.initialPassword = "root";
|
||||
};
|
||||
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
{ pkgs, lib, fp, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(fp /users)
|
||||
(fp /modules/snakeoil-certs.nix)
|
||||
|
||||
./networking.nix
|
||||
./nix.nix
|
||||
./vm.nix
|
||||
|
||||
./services/acme.nix
|
||||
./services/uptimed.nix
|
||||
./services/auto-upgrade.nix
|
||||
./services/dbus.nix
|
||||
./services/fwupd.nix
|
||||
./services/irqbalance.nix
|
||||
./services/logrotate.nix
|
||||
./services/nginx.nix
|
||||
./services/openssh.nix
|
||||
./services/postfix.nix
|
||||
./services/smartd.nix
|
||||
./services/thermald.nix
|
||||
./services/userborn.nix
|
||||
./services/userdbd.nix
|
||||
];
|
||||
|
||||
boot.tmp.cleanOnBoot = lib.mkDefault true;
|
||||
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
|
||||
|
||||
time.timeZone = "Europe/Oslo";
|
||||
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
console = {
|
||||
font = "Lat2-Terminus16";
|
||||
keyMap = "no";
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
file
|
||||
git
|
||||
gnupg
|
||||
htop
|
||||
nano
|
||||
ripgrep
|
||||
rsync
|
||||
screen
|
||||
tmux
|
||||
vim
|
||||
wget
|
||||
|
||||
kitty.terminfo
|
||||
];
|
||||
|
||||
# .bash_profile already works, but lets also use .bashrc like literally every other distro
|
||||
# https://man.archlinux.org/man/core/bash/bash.1.en#INVOCATION
|
||||
# home-manager usually handles this for you: https://github.com/nix-community/home-manager/blob/22a36aa709de7dd42b562a433b9cefecf104a6ee/modules/programs/bash.nix#L203-L209
|
||||
# btw, programs.bash.shellInit just goes into environment.shellInit which in turn goes into /etc/profile, spooky shit
|
||||
programs.bash.shellInit = ''
|
||||
if [ -n "''${BASH_VERSION:-}" ]; then
|
||||
if [[ ! -f ~/.bash_profile && ! -f ~/.bash_login ]]; then
|
||||
[[ -f ~/.bashrc ]] && . ~/.bashrc
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.zsh.enable = true;
|
||||
|
||||
security.lockKernelModules = true;
|
||||
security.protectKernelImage = true;
|
||||
security.sudo.execWheelOnly = true;
|
||||
security.sudo.extraConfig = ''
|
||||
Defaults lecture = never
|
||||
'';
|
||||
|
||||
users.groups."drift".name = "drift";
|
||||
|
||||
# Trusted users on the nix builder machines
|
||||
users.groups."nix-builder-users".name = "nix-builder-users";
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
{ lib, values, ... }:
|
||||
{
|
||||
systemd.network.enable = true;
|
||||
networking.domain = "pvv.ntnu.no";
|
||||
networking.useDHCP = false;
|
||||
|
||||
# The rest of the networking configuration is usually sourced from /values.nix
|
||||
|
||||
services.resolved = {
|
||||
enable = lib.mkDefault true;
|
||||
dnssec = "false"; # Supposdly this keeps breaking and the default is to allow downgrades anyways...
|
||||
};
|
||||
}
|
39
base/nix.nix
39
base/nix.nix
@ -1,39 +0,0 @@
|
||||
{ lib, config, inputs, ... }:
|
||||
{
|
||||
nix = {
|
||||
gc = {
|
||||
automatic = true;
|
||||
options = "--delete-older-than 2d";
|
||||
};
|
||||
optimise.automatic = true;
|
||||
|
||||
settings = {
|
||||
allow-dirty = true;
|
||||
builders-use-substitutes = true;
|
||||
experimental-features = [ "nix-command" "flakes" ];
|
||||
log-lines = 50;
|
||||
use-xdg-base-directories = true;
|
||||
};
|
||||
|
||||
/* This makes commandline tools like
|
||||
** nix run nixpkgs#hello
|
||||
** and nix-shell -p hello
|
||||
** use the same channel the system
|
||||
** was built with
|
||||
*/
|
||||
registry = lib.mkMerge [
|
||||
{
|
||||
"nixpkgs".flake = inputs.nixpkgs;
|
||||
"nixpkgs-unstable".flake = inputs.nixpkgs-unstable;
|
||||
}
|
||||
# We avoid the reference to self in vmVariant to get a stable system .outPath for equivalence testing
|
||||
(lib.mkIf (!config.virtualisation.isVmVariant) {
|
||||
"pvv-nix".flake = inputs.self;
|
||||
})
|
||||
];
|
||||
nixPath = [
|
||||
"nixpkgs=${inputs.nixpkgs}"
|
||||
"unstable=${inputs.nixpkgs-unstable}"
|
||||
];
|
||||
};
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "drift@pvv.ntnu.no";
|
||||
};
|
||||
|
||||
# Let's not spam LetsEncrypt in `nixos-rebuild build-vm` mode:
|
||||
virtualisation.vmVariant = {
|
||||
security.acme.defaults.server = "https://127.0.0.1";
|
||||
security.acme.preliminarySelfsigned = true;
|
||||
|
||||
users.users.root.initialPassword = "root";
|
||||
};
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
{ config, inputs, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
inputUrls = lib.mapAttrs (input: value: value.url) (import "${inputs.self}/flake.nix").inputs;
|
||||
in
|
||||
|
||||
{
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
flake = "git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git";
|
||||
flags = [
|
||||
"--refresh"
|
||||
"--no-write-lock-file"
|
||||
# --update-input is deprecated since nix 2.22, and removed in lix 2.90
|
||||
# as such we instead use --override-input combined with --refresh
|
||||
# https://git.lix.systems/lix-project/lix/issues/400
|
||||
] ++ (lib.pipe inputUrls [
|
||||
(lib.intersectAttrs {
|
||||
nixpkgs = { };
|
||||
nixpkgs-unstable = { };
|
||||
})
|
||||
(lib.mapAttrsToList (input: url: ["--override-input" input url]))
|
||||
lib.concatLists
|
||||
]);
|
||||
};
|
||||
|
||||
# workaround for https://github.com/NixOS/nix/issues/6895
|
||||
# via https://git.lix.systems/lix-project/lix/issues/400
|
||||
environment.etc = lib.mkIf (!config.virtualisation.isVmVariant) {
|
||||
"current-system-flake-inputs.json".source
|
||||
= pkgs.writers.writeJSON "flake-inputs.json" (
|
||||
lib.flip lib.mapAttrs inputs (name: input:
|
||||
# inputs.*.sourceInfo sans outPath, since writeJSON will otherwise serialize sourceInfo like a derivation
|
||||
lib.removeAttrs (input.sourceInfo or {}) [ "outPath" ]
|
||||
// { store-path = input.outPath; } # comment this line if you don't want to retain a store reference to the flake inputs
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.dbus = {
|
||||
enable = true;
|
||||
implementation = "broker";
|
||||
};
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.fwupd.enable = true;
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.irqbalance.enable = true;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
systemd.services.logrotate = {
|
||||
documentation = [ "man:logrotate(8)" "man:logrotate.conf(5)" ];
|
||||
unitConfig.RequiresMountsFor = "/var/log";
|
||||
serviceConfig.ReadWritePaths = [ "/var/log" ];
|
||||
};
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
# nginx return 444 for all nonexistent virtualhosts
|
||||
|
||||
systemd.services.nginx.after = [ "generate-snakeoil-certs.service" ];
|
||||
|
||||
environment.snakeoil-certs = lib.mkIf config.services.nginx.enable {
|
||||
"/etc/certs/nginx" = {
|
||||
owner = "nginx";
|
||||
group = "nginx";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf config.services.nginx.enable [ 80 443 ];
|
||||
|
||||
services.nginx = {
|
||||
recommendedTlsSettings = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
|
||||
appendConfig = ''
|
||||
# pcre_jit on;
|
||||
worker_processes auto;
|
||||
worker_rlimit_nofile 100000;
|
||||
'';
|
||||
eventsConfig = ''
|
||||
worker_connections 2048;
|
||||
use epoll;
|
||||
# multi_accept on;
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.nginx.serviceConfig = lib.mkIf config.services.nginx.enable {
|
||||
LimitNOFILE = 65536;
|
||||
# We use jit my dudes
|
||||
MemoryDenyWriteExecute = lib.mkForce false;
|
||||
# What the fuck do we use that where the defaults are not enough???
|
||||
SystemCallFilter = lib.mkForce null;
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."_" = lib.mkIf config.services.nginx.enable {
|
||||
sslCertificate = "/etc/certs/nginx.crt";
|
||||
sslCertificateKey = "/etc/certs/nginx.key";
|
||||
addSSL = true;
|
||||
extraConfig = "return 444;";
|
||||
};
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
startWhenNeeded = true;
|
||||
extraConfig = ''
|
||||
PubkeyAcceptedAlgorithms=+ssh-rsa
|
||||
Match Group wheel
|
||||
PasswordAuthentication no
|
||||
Match All
|
||||
'';
|
||||
settings.PermitRootLogin = "yes";
|
||||
|
||||
};
|
||||
users.users."root".openssh.authorizedKeys.keys = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqVt4LCe0YIttr9swFxjkjn37ZDY9JxwVC+2gvfSINDJorOCtqPjDOTD2fTS1Gz08QCwpnLWq2kyvRchu6WgriAbSACpbZZBgxRaF/FVh3oiMVFGnNKGnv6/fdo/vZtu8mUVuqtmTrgLYpZdbR4oD3XiBlDKs7Cv5hPqt95lnP6MNFvE8mICCfd1PwhsABd2IQ5laz3u77/RXhNFJL0Kf2/+6gk9awcLuwHrPdvq7c3BxRHbc9UMRQENyjyQPa7aLe+uJBFLKP51I8VBuDpDacuibQx7nMt6N2UJ2KWI0JxRMHuJNq4S5jidR82aOw9gzGbTv30SKNLMqsZ0xj4LtdqCXDiZF6Lr09PsJYsvnBUFWa14HGcThKDtgwQwBryNViYmfv//0h9+RLZiU0ab+NEwSs7Zh5iAD+vhx64QqNX3tR7Le4SWXh8W0eShU9N78qYdSkiC3Ui7htxeqOocXM/P4AwbnHsLELIvkHdvgchCPvl8ygZa4WJTEWv16+ICskJcAKWGuqjvXAFuwjJJmPp9xLW9O0DFfQhMELiGamQR9wK07yYQVr34iah6qZO7cwhSKyEPFrVPIaNtfDhsjED639F7vmktf26SWNJHWfW0wOHILjI6TgqUvy0JDd8W8w0CHlAfz6Fs2l99NNgNF8dB3vBASbxS0hu/y0PVu/xQ== openstack-sleipner"
|
||||
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICCbgJ0Uwh9VSVhfId7l9i5/jk4CvAK5rbkiab8R+moF root@sleipner"
|
||||
];
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
cfg = config.services.postfix;
|
||||
in
|
||||
{
|
||||
services.postfix = {
|
||||
enable = true;
|
||||
|
||||
hostname = "${config.networking.hostName}.pvv.ntnu.no";
|
||||
domain = "pvv.ntnu.no";
|
||||
|
||||
relayHost = "smtp.pvv.ntnu.no";
|
||||
relayPort = 465;
|
||||
|
||||
config = {
|
||||
smtp_tls_wrappermode = "yes";
|
||||
smtp_tls_security_level = "encrypt";
|
||||
};
|
||||
|
||||
# Nothing should be delivered to this machine
|
||||
destination = [ ];
|
||||
};
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
services.smartd = {
|
||||
enable = lib.mkDefault true;
|
||||
notifications = {
|
||||
mail = {
|
||||
enable = true;
|
||||
sender = "root@pvv.ntnu.no";
|
||||
recipient = "root@pvv.ntnu.no";
|
||||
};
|
||||
wall.enable = false;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = lib.optionals config.services.smartd.enable (with pkgs; [
|
||||
smartmontools
|
||||
]);
|
||||
|
||||
systemd.services.smartd.unitConfig.ConditionVirtualization = "no";
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
# Let's not thermal throttle
|
||||
services.thermald.enable = lib.mkIf (lib.all (x: x) [
|
||||
(config.nixpkgs.system == "x86_64-linux")
|
||||
(!config.boot.isContainer or false)
|
||||
]) true;
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
cfg = config.services.uptimed;
|
||||
in
|
||||
{
|
||||
options.services.uptimed.settings = lib.mkOption {
|
||||
description = "";
|
||||
default = { };
|
||||
type = lib.types.submodule {
|
||||
freeformType = with lib.types; attrsOf (either str (listOf str));
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
services.uptimed = {
|
||||
enable = true;
|
||||
|
||||
settings = let
|
||||
stateDir = "/var/lib/uptimed";
|
||||
in {
|
||||
PIDFILE = "${stateDir}/pid";
|
||||
SENDMAIL = lib.mkDefault "${pkgs.system-sendmail}/bin/sendmail -t";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.uptimed = lib.mkIf (cfg.enable) {
|
||||
serviceConfig = let
|
||||
uptimed = pkgs.uptimed.overrideAttrs (prev: {
|
||||
postPatch = ''
|
||||
substituteInPlace Makefile.am \
|
||||
--replace-fail '$(sysconfdir)/uptimed.conf' '/var/lib/uptimed/uptimed.conf'
|
||||
substituteInPlace src/Makefile.am \
|
||||
--replace-fail '$(sysconfdir)/uptimed.conf' '/var/lib/uptimed/uptimed.conf'
|
||||
'';
|
||||
});
|
||||
|
||||
in {
|
||||
Type = "notify";
|
||||
|
||||
ExecStart = lib.mkForce "${uptimed}/sbin/uptimed -f";
|
||||
|
||||
BindReadOnlyPaths = let
|
||||
configFile = lib.pipe cfg.settings [
|
||||
(lib.mapAttrsToList
|
||||
(k: v:
|
||||
if builtins.isList v
|
||||
then lib.mapConcatStringsSep "\n" (v': "${k}=${v'}") v
|
||||
else "${k}=${v}")
|
||||
)
|
||||
(lib.concatStringsSep "\n")
|
||||
(pkgs.writeText "uptimed.conf")
|
||||
];
|
||||
in [
|
||||
"${configFile}:/var/lib/uptimed/uptimed.conf"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.userborn.enable = true;
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.userdbd.enable = true;
|
||||
}
|
15
base/vm.nix
15
base/vm.nix
@ -1,15 +0,0 @@
|
||||
{ lib, ... }:
|
||||
|
||||
# This enables
|
||||
# lib.mkIf (!config.virtualisation.isVmVariant) { ... }
|
||||
|
||||
{
|
||||
options.virtualisation.isVmVariant = lib.mkOption {
|
||||
description = "`true` if system is build with 'nixos-rebuild build-vm'";
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
config.virtualisation.vmVariant = {
|
||||
virtualisation.isVmVariant = true;
|
||||
};
|
||||
}
|
261
flake.lock
generated
261
flake.lock
generated
@ -7,11 +7,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1752113600,
|
||||
"narHash": "sha256-7LYDxKxZgBQ8LZUuolAQ8UkIB+jb4A2UmiR+kzY9CLI=",
|
||||
"lastModified": 1715445235,
|
||||
"narHash": "sha256-SUu+oIWn+xqQIOlwfwNfS9Sek4i1HKsrLJchsDReXwA=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "79264292b7e3482e5702932949de9cbb69fedf6d",
|
||||
"rev": "159d87ea5b95bbdea46f0288a33c5e1570272725",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -20,45 +20,64 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gergle": {
|
||||
"fix-python": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": [
|
||||
"grzegorz",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1736621371,
|
||||
"narHash": "sha256-45UIQSQA7R5iU4YWvilo7mQbhY1Liql9bHBvYa3qRI0=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "3729796c1213fe76e568ac28f1df8de4e596950b",
|
||||
"revCount": 20,
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Grzegorz/gergle.git"
|
||||
"lastModified": 1713887124,
|
||||
"narHash": "sha256-hGTSm0p9xXUYDgsAAr/ORZICo6T6u33vLfX3tILikaQ=",
|
||||
"owner": "GuillaumeDesforges",
|
||||
"repo": "fix-python",
|
||||
"rev": "f7f4b33e22414071fc1f9cbf68072c413c3a7fdf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Grzegorz/gergle.git"
|
||||
"owner": "GuillaumeDesforges",
|
||||
"repo": "fix-python",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"greg-ng": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"rust-overlay": "rust-overlay"
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1752258704,
|
||||
"narHash": "sha256-pRK99+MCgkeVptbJxXhVMXIXl8uwSdkZDpQzFi3OgkA=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "9ff525339b62855d53a44b4dc0154a33ac19e44d",
|
||||
"revCount": 48,
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Grzegorz/greg-ng.git"
|
||||
"lastModified": 1689068808,
|
||||
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Grzegorz/greg-ng.git"
|
||||
"id": "flake-utils",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"grzegorz": {
|
||||
"inputs": {
|
||||
"fix-python": "fix-python",
|
||||
"nixpkgs": [
|
||||
"nixpkgs-unstable"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1715364232,
|
||||
"narHash": "sha256-ZJC3SkanEgbV7p+LFhP+85CviRWOXJNHzZwR/Stb7hE=",
|
||||
"owner": "Programvareverkstedet",
|
||||
"repo": "grzegorz",
|
||||
"rev": "3841cda1cdcac470440b06838d56a2eb2256378c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Programvareverkstedet",
|
||||
"repo": "grzegorz",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"grzegorz-clients": {
|
||||
@ -68,17 +87,17 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1736178795,
|
||||
"narHash": "sha256-mPdi8cgvIDYcgG3FRG7A4BOIMu2Jef96TPMnV00uXlM=",
|
||||
"ref": "refs/heads/master",
|
||||
"rev": "fde738910de1fd8293535a6382c2f0c2749dd7c1",
|
||||
"revCount": 79,
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Grzegorz/grzegorz-clients.git"
|
||||
"lastModified": 1715384651,
|
||||
"narHash": "sha256-7RhckgUTjqeCjWkhiCc1iB+5CBx9fl80d/3O4Jh+5kM=",
|
||||
"owner": "Programvareverkstedet",
|
||||
"repo": "grzegorz-clients",
|
||||
"rev": "738a4f3dd887f7c3612e4e772b83cbfa3cde5693",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Grzegorz/grzegorz-clients.git"
|
||||
"owner": "Programvareverkstedet",
|
||||
"repo": "grzegorz-clients",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"matrix-next": {
|
||||
@ -88,35 +107,20 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735857245,
|
||||
"narHash": "sha256-AKLLPrgXTxgzll3DqVUMa4QlPlRN3QceutgFBmEf8Nk=",
|
||||
"lastModified": 1717234745,
|
||||
"narHash": "sha256-MFyKRdw4WQD6V3vRGbP6MYbtJhZp712zwzjW6YiOBYM=",
|
||||
"owner": "dali99",
|
||||
"repo": "nixos-matrix-modules",
|
||||
"rev": "da9dc0479ffe22362793c87dc089035facf6ec4d",
|
||||
"rev": "d7dc42c9bbb155c5e4aa2f0985d0df75ce978456",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "dali99",
|
||||
"ref": "0.7.0",
|
||||
"ref": "v0.6.0",
|
||||
"repo": "nixos-matrix-modules",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"minecraft-data": {
|
||||
"locked": {
|
||||
"lastModified": 1725277886,
|
||||
"narHash": "sha256-Fw4VbbE3EfypQWSgPDFfvVH47BHeg3ptsO715NlUM8Q=",
|
||||
"ref": "refs/heads/master",
|
||||
"rev": "1b4087bd3322a2e2ba84271c8fcc013e6b641a58",
|
||||
"revCount": 2,
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Projects/minecraft-kartverket.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Projects/minecraft-kartverket.git"
|
||||
}
|
||||
},
|
||||
"nix-gitea-themes": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@ -124,43 +128,63 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1743881366,
|
||||
"narHash": "sha256-ScGA2IHPk9ugf9bqEZnp+YB/OJgrkZblnG/XLEKvJAo=",
|
||||
"lastModified": 1714416973,
|
||||
"narHash": "sha256-aZUcvXjdETUC6wVQpWDVjLUzwpDAEca8yR0ITDeK39o=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "db2e4becf1b11e5dfd33de12a90a7d089fcf68ec",
|
||||
"revCount": 11,
|
||||
"rev": "2b23c0ba8aae68d3cb6789f0f6e4891cef26cc6d",
|
||||
"revCount": 6,
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Drift/nix-gitea-themes.git"
|
||||
"url": "https://git.pvv.ntnu.no/oysteikt/nix-gitea-themes.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Drift/nix-gitea-themes.git"
|
||||
"url": "https://git.pvv.ntnu.no/oysteikt/nix-gitea-themes.git"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1752439653,
|
||||
"narHash": "sha256-mG27U2CFuggpAuozOu/4XAMKaOtJxzJVzdEemjQEBgg=",
|
||||
"rev": "dfcd5b901dbab46c9c6e80b265648481aafb01f8",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/25.05-small/nixos-25.05.806304.dfcd5b901dba/nixexprs.tar.xz"
|
||||
"lastModified": 1719520878,
|
||||
"narHash": "sha256-5BXzNOl2RVHcfS/oxaZDKOi7gVuTyWPibQG0DHd5sSc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a44bedbb48c367f0476e6a3a27bf28f6330faf23",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://nixos.org/channels/nixos-25.05-small/nixexprs.tar.xz"
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-24.05-small",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1714858427,
|
||||
"narHash": "sha256-tCxeDP4C1pWe2rYY3IIhdA40Ujz32Ufd4tcrHPSKx2M=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b980b91038fc4b09067ef97bbe5ad07eecca1e76",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "release-23.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1752439402,
|
||||
"narHash": "sha256-xDfOnjnKStgsgcn9SFPgOV6qzwac4JvGKYyfR++49Pw=",
|
||||
"rev": "b47d4f01d4213715a1f09b999bab96bb6a5b675e",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/unstable-small/nixos-25.11pre829909.b47d4f01d421/nixexprs.tar.xz"
|
||||
"lastModified": 1715435713,
|
||||
"narHash": "sha256-lb2HqDQGfTdnCCpc1pgF6fkdgIOuBQ0nP8jjVSfLFqg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "52b40f6c4be12742b1504ca2eb4527e597bf2526",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://nixos.org/channels/nixos-unstable-small/nixexprs.tar.xz"
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-unstable-small",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"pvv-calendar-bot": {
|
||||
@ -170,11 +194,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1742225512,
|
||||
"narHash": "sha256-OB0ndlrGLE5wMUeYP4lmxly9JUEpPCeZRQyMzITKCB0=",
|
||||
"lastModified": 1723850344,
|
||||
"narHash": "sha256-aT37O9l9eclWEnqxASVNBL1dKwDHZUOqdbA4VO9DJvw=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "c4a6a02c84d8227abf00305dc995d7242176e6f6",
|
||||
"revCount": 21,
|
||||
"rev": "38b66677ab8c01aee10cd59e745af9ce3ea88092",
|
||||
"revCount": 19,
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Projects/calendar-bot.git"
|
||||
},
|
||||
@ -183,6 +207,25 @@
|
||||
"url": "https://git.pvv.ntnu.no/Projects/calendar-bot.git"
|
||||
}
|
||||
},
|
||||
"pvv-doorbell-bot": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"dirtyRev": "cec320746bbf5b5bc6618a145c1a997ebd0b5196-dirty",
|
||||
"dirtyShortRev": "cec3207-dirty",
|
||||
"lastModified": 1724515328,
|
||||
"narHash": "sha256-Vj3ZJkCaLq+6d1LJtl7Hg5f7XV4NDPeNC1xEyu9QkOI=",
|
||||
"type": "git",
|
||||
"url": "file:///home/felixalb/doorbell-matrix-bot"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "file:///home/felixalb/doorbell-matrix-bot"
|
||||
}
|
||||
},
|
||||
"pvv-nettsiden": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@ -190,11 +233,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1742344479,
|
||||
"narHash": "sha256-9vzkDdcJPkZIHJ+fQZjC6MepicBQiMzldNhjBR58qWY=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "20bab54235488b66f30acceece4f7721f280ef85",
|
||||
"revCount": 493,
|
||||
"lastModified": 1722722932,
|
||||
"narHash": "sha256-K81a2GQpY2kRX+C9ek9r91THlZB674CqRTSMMb5IO7E=",
|
||||
"ref": "refs/heads/master",
|
||||
"rev": "6580cfe546c902cdf11e17b0b8aa30b3c412bb34",
|
||||
"revCount": 465,
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Projects/nettsiden.git"
|
||||
},
|
||||
@ -206,52 +249,31 @@
|
||||
"root": {
|
||||
"inputs": {
|
||||
"disko": "disko",
|
||||
"gergle": "gergle",
|
||||
"greg-ng": "greg-ng",
|
||||
"grzegorz": "grzegorz",
|
||||
"grzegorz-clients": "grzegorz-clients",
|
||||
"matrix-next": "matrix-next",
|
||||
"minecraft-data": "minecraft-data",
|
||||
"nix-gitea-themes": "nix-gitea-themes",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"pvv-calendar-bot": "pvv-calendar-bot",
|
||||
"pvv-doorbell-bot": "pvv-doorbell-bot",
|
||||
"pvv-nettsiden": "pvv-nettsiden",
|
||||
"sops-nix": "sops-nix"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"greg-ng",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1752201818,
|
||||
"narHash": "sha256-d8KczaVT8WFEZdWg//tMAbv8EDyn2YTWcJvSY8gqKBU=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "bd8f8329780b348fedcd37b53dbbee48c08c496d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"sops-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1751606940,
|
||||
"narHash": "sha256-KrDPXobG7DFKTOteqdSVeL1bMVitDcy7otpVZWDE6MA=",
|
||||
"lastModified": 1715244550,
|
||||
"narHash": "sha256-ffOZL3eaZz5Y1nQ9muC36wBCWwS1hSRLhUzlA9hV2oI=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "3633fc4acf03f43b260244d94c71e9e14a2f6e0d",
|
||||
"rev": "0dc50257c00ee3c65fef3a255f6564cfbfe6eb7f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -259,6 +281,21 @@
|
||||
"repo": "sops-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
112
flake.nix
112
flake.nix
@ -2,8 +2,8 @@
|
||||
description = "PVV System flake";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "https://nixos.org/channels/nixos-25.05-small/nixexprs.tar.xz";
|
||||
nixpkgs-unstable.url = "https://nixos.org/channels/nixos-unstable-small/nixexprs.tar.xz";
|
||||
nixpkgs.url = "nixpkgs/nixos-24.05-small";
|
||||
nixpkgs-unstable.url = "nixpkgs/nixos-unstable-small";
|
||||
|
||||
sops-nix.url = "github:Mic92/sops-nix";
|
||||
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
@ -17,31 +17,31 @@
|
||||
pvv-calendar-bot.url = "git+https://git.pvv.ntnu.no/Projects/calendar-bot.git";
|
||||
pvv-calendar-bot.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
matrix-next.url = "github:dali99/nixos-matrix-modules/0.7.0";
|
||||
pvv-doorbell-bot.url = "git+https://git.pvv.ntnu.no/Projects/doorbell-matrix-bot.git";
|
||||
#pvv-doorbell-bot.url = "git+file:///home/felixalb/doorbell-matrix-bot";
|
||||
pvv-doorbell-bot.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
matrix-next.url = "github:dali99/nixos-matrix-modules/v0.6.0";
|
||||
matrix-next.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
nix-gitea-themes.url = "git+https://git.pvv.ntnu.no/Drift/nix-gitea-themes.git";
|
||||
nix-gitea-themes.url = "git+https://git.pvv.ntnu.no/oysteikt/nix-gitea-themes.git";
|
||||
nix-gitea-themes.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
greg-ng.url = "git+https://git.pvv.ntnu.no/Grzegorz/greg-ng.git";
|
||||
greg-ng.inputs.nixpkgs.follows = "nixpkgs";
|
||||
gergle.url = "git+https://git.pvv.ntnu.no/Grzegorz/gergle.git";
|
||||
gergle.inputs.nixpkgs.follows = "nixpkgs";
|
||||
grzegorz-clients.url = "git+https://git.pvv.ntnu.no/Grzegorz/grzegorz-clients.git";
|
||||
grzegorz.url = "github:Programvareverkstedet/grzegorz";
|
||||
grzegorz.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
grzegorz-clients.url = "github:Programvareverkstedet/grzegorz-clients";
|
||||
grzegorz-clients.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
minecraft-data.url = "git+https://git.pvv.ntnu.no/Projects/minecraft-kartverket.git";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, nixpkgs-unstable, sops-nix, disko, ... }@inputs:
|
||||
let
|
||||
inherit (nixpkgs) lib;
|
||||
nixlib = nixpkgs.lib;
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
forAllSystems = f: lib.genAttrs systems f;
|
||||
forAllSystems = f: nixlib.genAttrs systems f;
|
||||
allMachines = builtins.attrNames self.nixosConfigurations;
|
||||
importantMachines = [
|
||||
"bekkalokk"
|
||||
@ -51,17 +51,16 @@
|
||||
"ildkule"
|
||||
];
|
||||
in {
|
||||
inputs = lib.mapAttrs (_: src: src.outPath) inputs;
|
||||
inherit inputs;
|
||||
|
||||
nixosConfigurations = let
|
||||
unstablePkgs = nixpkgs-unstable.legacyPackages.x86_64-linux;
|
||||
nixosConfig = nixpkgs: name: config: lib.nixosSystem (lib.recursiveUpdate
|
||||
nixosConfig = nixpkgs: name: config: nixpkgs.lib.nixosSystem (nixpkgs.lib.recursiveUpdate
|
||||
rec {
|
||||
system = "x86_64-linux";
|
||||
specialArgs = {
|
||||
inherit unstablePkgs inputs;
|
||||
inherit nixpkgs-unstable inputs;
|
||||
values = import ./values.nix;
|
||||
fp = path: ./${path};
|
||||
};
|
||||
|
||||
modules = [
|
||||
@ -71,11 +70,6 @@
|
||||
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg)
|
||||
[
|
||||
"nvidia-x11"
|
||||
"nvidia-settings"
|
||||
];
|
||||
overlays = [
|
||||
# Global overlays go here
|
||||
] ++ config.overlays or [ ];
|
||||
@ -91,14 +85,11 @@
|
||||
modules = [
|
||||
inputs.matrix-next.nixosModules.default
|
||||
inputs.pvv-calendar-bot.nixosModules.default
|
||||
self.nixosModules.gickup
|
||||
self.nixosModules.matrix-ooye
|
||||
inputs.pvv-doorbell-bot.nixosModules.default
|
||||
];
|
||||
overlays = [
|
||||
inputs.pvv-calendar-bot.overlays.x86_64-linux.default
|
||||
(final: prev: {
|
||||
inherit (self.packages.${prev.system}) out-of-your-element;
|
||||
})
|
||||
inputs.pvv-doorbell-bot.overlays.x86_64-linux.default
|
||||
];
|
||||
};
|
||||
bekkalokk = stableNixosConfig "bekkalokk" {
|
||||
@ -107,77 +98,47 @@
|
||||
heimdal = unstablePkgs.heimdal;
|
||||
mediawiki-extensions = final.callPackage ./packages/mediawiki-extensions { };
|
||||
simplesamlphp = final.callPackage ./packages/simplesamlphp { };
|
||||
bluemap = final.callPackage ./packages/bluemap.nix { };
|
||||
})
|
||||
inputs.nix-gitea-themes.overlays.default
|
||||
inputs.pvv-nettsiden.overlays.default
|
||||
];
|
||||
modules = [
|
||||
inputs.nix-gitea-themes.nixosModules.default
|
||||
inputs.pvv-nettsiden.nixosModules.default
|
||||
];
|
||||
};
|
||||
bob = stableNixosConfig "bob" {
|
||||
modules = [
|
||||
disko.nixosModules.disko
|
||||
{ disko.devices.disk.disk1.device = "/dev/vda"; }
|
||||
];
|
||||
};
|
||||
ildkule = stableNixosConfig "ildkule" { };
|
||||
#ildkule-unstable = unstableNixosConfig "ildkule" { };
|
||||
shark = stableNixosConfig "shark" { };
|
||||
wenche = stableNixosConfig "wenche" { };
|
||||
|
||||
kommode = stableNixosConfig "kommode" {
|
||||
overlays = [
|
||||
inputs.nix-gitea-themes.overlays.default
|
||||
];
|
||||
modules = [
|
||||
inputs.nix-gitea-themes.nixosModules.default
|
||||
];
|
||||
};
|
||||
|
||||
ustetind = stableNixosConfig "ustetind" {
|
||||
modules = [
|
||||
"${nixpkgs}/nixos/modules/virtualisation/lxc-container.nix"
|
||||
];
|
||||
};
|
||||
|
||||
brzeczyszczykiewicz = stableNixosConfig "brzeczyszczykiewicz" {
|
||||
modules = [
|
||||
inputs.grzegorz.nixosModules.grzegorz-kiosk
|
||||
inputs.grzegorz-clients.nixosModules.grzegorz-webui
|
||||
inputs.gergle.nixosModules.default
|
||||
inputs.greg-ng.nixosModules.default
|
||||
];
|
||||
overlays = [
|
||||
inputs.greg-ng.overlays.default
|
||||
inputs.gergle.overlays.default
|
||||
];
|
||||
};
|
||||
georg = stableNixosConfig "georg" {
|
||||
modules = [
|
||||
inputs.grzegorz.nixosModules.grzegorz-kiosk
|
||||
inputs.grzegorz-clients.nixosModules.grzegorz-webui
|
||||
inputs.gergle.nixosModules.default
|
||||
inputs.greg-ng.nixosModules.default
|
||||
];
|
||||
overlays = [
|
||||
inputs.greg-ng.overlays.default
|
||||
inputs.gergle.overlays.default
|
||||
];
|
||||
};
|
||||
buskerud = stableNixosConfig "buskerud" { };
|
||||
};
|
||||
|
||||
nixosModules = {
|
||||
snakeoil-certs = ./modules/snakeoil-certs.nix;
|
||||
snappymail = ./modules/snappymail.nix;
|
||||
robots-txt = ./modules/robots-txt.nix;
|
||||
gickup = ./modules/gickup;
|
||||
matrix-ooye = ./modules/matrix-ooye.nix;
|
||||
};
|
||||
|
||||
devShells = forAllSystems (system: {
|
||||
default = nixpkgs-unstable.legacyPackages.${system}.callPackage ./shell.nix { };
|
||||
cuda = let
|
||||
cuda-pkgs = import nixpkgs-unstable {
|
||||
inherit system;
|
||||
config = {
|
||||
allowUnfree = true;
|
||||
cudaSupport = true;
|
||||
};
|
||||
};
|
||||
in cuda-pkgs.callPackage ./shells/cuda.nix { };
|
||||
default = nixpkgs.legacyPackages.${system}.callPackage ./shell.nix { };
|
||||
});
|
||||
|
||||
packages = {
|
||||
@ -186,20 +147,19 @@
|
||||
in rec {
|
||||
default = important-machines;
|
||||
important-machines = pkgs.linkFarm "important-machines"
|
||||
(lib.getAttrs importantMachines self.packages.x86_64-linux);
|
||||
(nixlib.getAttrs importantMachines self.packages.x86_64-linux);
|
||||
all-machines = pkgs.linkFarm "all-machines"
|
||||
(lib.getAttrs allMachines self.packages.x86_64-linux);
|
||||
(nixlib.getAttrs allMachines self.packages.x86_64-linux);
|
||||
|
||||
simplesamlphp = pkgs.callPackage ./packages/simplesamlphp { };
|
||||
|
||||
out-of-your-element = pkgs.callPackage ./packages/out-of-your-element.nix { };
|
||||
} //
|
||||
(lib.pipe null [
|
||||
(nixlib.pipe null [
|
||||
(_: pkgs.callPackage ./packages/mediawiki-extensions { })
|
||||
(lib.flip builtins.removeAttrs ["override" "overrideDerivation"])
|
||||
(lib.mapAttrs' (name: lib.nameValuePair "mediawiki-${name}"))
|
||||
(nixlib.flip builtins.removeAttrs ["override" "overrideDerivation"])
|
||||
(nixlib.mapAttrs' (name: nixlib.nameValuePair "mediawiki-${name}"))
|
||||
])
|
||||
// lib.genAttrs allMachines
|
||||
// nixlib.genAttrs allMachines
|
||||
(machine: self.nixosConfigurations.${machine}.config.system.build.toplevel);
|
||||
};
|
||||
};
|
||||
|
@ -1,24 +1,22 @@
|
||||
{ fp, pkgs, values, ... }:
|
||||
{ pkgs, values, ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
|
||||
(fp /base)
|
||||
(fp /misc/metrics-exporters.nix)
|
||||
../../base.nix
|
||||
../../misc/metrics-exporters.nix
|
||||
|
||||
./services/bluemap/default.nix
|
||||
./services/gitea/default.nix
|
||||
./services/idp-simplesamlphp
|
||||
./services/kerberos
|
||||
./services/mediawiki
|
||||
./services/nginx.nix
|
||||
./services/phpfpm.nix
|
||||
./services/vaultwarden.nix
|
||||
./services/webmail
|
||||
./services/website
|
||||
./services/well-known
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = fp /secrets/bekkalokk/bekkalokk.yaml;
|
||||
sops.defaultSopsFile = ../../secrets/bekkalokk/bekkalokk.yaml;
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sops.age.generateKey = true;
|
||||
@ -33,8 +31,6 @@
|
||||
address = with values.hosts.bekkalokk; [ (ipv4 + "/25") (ipv6 + "/64") ];
|
||||
};
|
||||
|
||||
services.btrfs.autoScrub.enable = true;
|
||||
|
||||
# Do not change, even during upgrades.
|
||||
# See https://search.nixos.org/options?show=system.stateVersion
|
||||
system.stateVersion = "22.11";
|
||||
|
@ -1,85 +0,0 @@
|
||||
{ config, lib, pkgs, inputs, ... }:
|
||||
let
|
||||
vanillaSurvival = "/var/lib/bluemap/vanilla_survival_world";
|
||||
in {
|
||||
imports = [
|
||||
./module.nix # From danio, pending upstreaming
|
||||
];
|
||||
|
||||
disabledModules = [ "services/web-apps/bluemap.nix" ];
|
||||
|
||||
sops.secrets."bluemap/ssh-key" = { };
|
||||
sops.secrets."bluemap/ssh-known-hosts" = { };
|
||||
|
||||
services.bluemap = {
|
||||
enable = true;
|
||||
package = pkgs.callPackage ./package.nix { };
|
||||
|
||||
eula = true;
|
||||
onCalendar = "*-*-* 05:45:00"; # a little over an hour after auto-upgrade
|
||||
|
||||
host = "minecraft.pvv.ntnu.no";
|
||||
|
||||
maps = {
|
||||
"verden" = {
|
||||
settings = {
|
||||
world = vanillaSurvival;
|
||||
sorting = 0;
|
||||
ambient-light = 0.1;
|
||||
cave-detection-ocean-floor = -5;
|
||||
marker-sets = inputs.minecraft-data.map-markers.vanillaSurvival.verden;
|
||||
};
|
||||
};
|
||||
"underverden" = {
|
||||
settings = {
|
||||
world = "${vanillaSurvival}/DIM-1";
|
||||
sorting = 100;
|
||||
sky-color = "#290000";
|
||||
void-color = "#150000";
|
||||
ambient-light = 0.6;
|
||||
world-sky-light = 0;
|
||||
remove-caves-below-y = -10000;
|
||||
cave-detection-ocean-floor = -5;
|
||||
cave-detection-uses-block-light = true;
|
||||
max-y = 90;
|
||||
marker-sets = inputs.minecraft-data.map-markers.vanillaSurvival.underverden;
|
||||
};
|
||||
};
|
||||
"enden" = {
|
||||
settings = {
|
||||
world = "${vanillaSurvival}/DIM1";
|
||||
sorting = 200;
|
||||
sky-color = "#080010";
|
||||
void-color = "#080010";
|
||||
ambient-light = 0.6;
|
||||
world-sky-light = 0;
|
||||
remove-caves-below-y = -10000;
|
||||
cave-detection-ocean-floor = -5;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."minecraft.pvv.ntnu.no" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
|
||||
# TODO: render somewhere else lmao
|
||||
systemd.services."render-bluemap-maps" = {
|
||||
preStart = ''
|
||||
mkdir -p /var/lib/bluemap/world
|
||||
${pkgs.rsync}/bin/rsync \
|
||||
-e "${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$CREDENTIALS_DIRECTORY/ssh-known-hosts -i $CREDENTIALS_DIRECTORY/sshkey" \
|
||||
-avz --no-owner --no-group \
|
||||
root@innovation.pvv.ntnu.no:/ \
|
||||
${vanillaSurvival}
|
||||
'';
|
||||
serviceConfig = {
|
||||
LoadCredential = [
|
||||
"sshkey:${config.sops.secrets."bluemap/ssh-key".path}"
|
||||
"ssh-known-hosts:${config.sops.secrets."bluemap/ssh-known-hosts".path}"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
@ -1,351 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.bluemap;
|
||||
format = pkgs.formats.hocon { };
|
||||
|
||||
coreConfig = format.generate "core.conf" cfg.coreSettings;
|
||||
webappConfig = format.generate "webapp.conf" cfg.webappSettings;
|
||||
webserverConfig = format.generate "webserver.conf" cfg.webserverSettings;
|
||||
|
||||
storageFolder = pkgs.linkFarm "storage"
|
||||
(lib.attrsets.mapAttrs' (name: value:
|
||||
lib.nameValuePair "${name}.conf"
|
||||
(format.generate "${name}.conf" value))
|
||||
cfg.storage);
|
||||
|
||||
mapsFolder = pkgs.linkFarm "maps"
|
||||
(lib.attrsets.mapAttrs' (name: value:
|
||||
lib.nameValuePair "${name}.conf"
|
||||
(format.generate "${name}.conf" value.settings))
|
||||
cfg.maps);
|
||||
|
||||
webappConfigFolder = pkgs.linkFarm "bluemap-config" {
|
||||
"maps" = mapsFolder;
|
||||
"storages" = storageFolder;
|
||||
"core.conf" = coreConfig;
|
||||
"webapp.conf" = webappConfig;
|
||||
"webserver.conf" = webserverConfig;
|
||||
"packs" = cfg.resourcepacks;
|
||||
};
|
||||
|
||||
renderConfigFolder = name: value: pkgs.linkFarm "bluemap-${name}-config" {
|
||||
"maps" = pkgs.linkFarm "maps" {
|
||||
"${name}.conf" = (format.generate "${name}.conf" value.settings);
|
||||
};
|
||||
"storages" = storageFolder;
|
||||
"core.conf" = coreConfig;
|
||||
"webapp.conf" = format.generate "webapp.conf" (cfg.webappSettings // { "update-settings-file" = false; });
|
||||
"webserver.conf" = webserverConfig;
|
||||
"packs" = value.resourcepacks;
|
||||
};
|
||||
|
||||
inherit (lib) mkOption;
|
||||
in {
|
||||
options.services.bluemap = {
|
||||
enable = lib.mkEnableOption "bluemap";
|
||||
package = lib.mkPackageOption pkgs "bluemap" { };
|
||||
|
||||
eula = mkOption {
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
By changing this option to true you confirm that you own a copy of minecraft Java Edition,
|
||||
and that you agree to minecrafts EULA.
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
|
||||
defaultWorld = mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
The world used by the default map ruleset.
|
||||
If you configure your own maps you do not need to set this.
|
||||
'';
|
||||
example = lib.literalExpression "\${config.services.minecraft.dataDir}/world";
|
||||
};
|
||||
|
||||
enableRender = mkOption {
|
||||
type = lib.types.bool;
|
||||
description = "Enable rendering";
|
||||
default = true;
|
||||
};
|
||||
|
||||
webRoot = mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/bluemap/web";
|
||||
description = "The directory for saving and serving the webapp and the maps";
|
||||
};
|
||||
|
||||
enableNginx = mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Enable configuring a virtualHost for serving the bluemap webapp";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = lib.types.str;
|
||||
default = "bluemap.${config.networking.domain}";
|
||||
defaultText = lib.literalExpression "bluemap.\${config.networking.domain}";
|
||||
description = "Domain to configure nginx for";
|
||||
};
|
||||
|
||||
onCalendar = mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
How often to trigger rendering the map,
|
||||
in the format of a systemd timer onCalendar configuration.
|
||||
See {manpage}`systemd.timer(5)`.
|
||||
'';
|
||||
default = "*-*-* 03:10:00";
|
||||
};
|
||||
|
||||
coreSettings = mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
data = mkOption {
|
||||
type = lib.types.path;
|
||||
description = "Folder for where bluemap stores its data";
|
||||
default = "/var/lib/bluemap";
|
||||
};
|
||||
metrics = lib.mkEnableOption "Sending usage metrics containing the version of bluemap in use";
|
||||
};
|
||||
};
|
||||
description = "Settings for the core.conf file, [see upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/core.conf).";
|
||||
};
|
||||
|
||||
webappSettings = mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
};
|
||||
default = {
|
||||
enabled = true;
|
||||
webroot = cfg.webRoot;
|
||||
};
|
||||
defaultText = lib.literalExpression ''
|
||||
{
|
||||
enabled = true;
|
||||
webroot = config.services.bluemap.webRoot;
|
||||
}
|
||||
'';
|
||||
description = "Settings for the webapp.conf file, see [upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/webapp.conf).";
|
||||
};
|
||||
|
||||
webserverSettings = mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
enabled = mkOption {
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Enable bluemap's built-in webserver.
|
||||
Disabled by default in nixos for use of nginx directly.
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = ''
|
||||
Settings for the webserver.conf file, usually not required.
|
||||
[See upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/webserver.conf).
|
||||
'';
|
||||
};
|
||||
|
||||
maps = mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule {
|
||||
options = {
|
||||
resourcepacks = mkOption {
|
||||
type = lib.types.path;
|
||||
default = cfg.resourcepacks;
|
||||
defaultText = lib.literalExpression "config.services.bluemap.resourcepacks";
|
||||
description = "A set of resourcepacks/mods/bluemap-addons to extract models from loaded in alphabetical order";
|
||||
};
|
||||
settings = mkOption {
|
||||
type = (lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
world = mkOption {
|
||||
type = lib.types.path;
|
||||
description = "Path to world folder containing the dimension to render";
|
||||
};
|
||||
};
|
||||
});
|
||||
description = ''
|
||||
Settings for files in `maps/`.
|
||||
See the default for an example with good options for the different world types.
|
||||
For valid values [consult upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/maps/map.conf).
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = {
|
||||
"overworld".settings = {
|
||||
world = "${cfg.defaultWorld}";
|
||||
ambient-light = 0.1;
|
||||
cave-detection-ocean-floor = -5;
|
||||
};
|
||||
|
||||
"nether".settings = {
|
||||
world = "${cfg.defaultWorld}/DIM-1";
|
||||
sorting = 100;
|
||||
sky-color = "#290000";
|
||||
void-color = "#150000";
|
||||
ambient-light = 0.6;
|
||||
world-sky-light = 0;
|
||||
remove-caves-below-y = -10000;
|
||||
cave-detection-ocean-floor = -5;
|
||||
cave-detection-uses-block-light = true;
|
||||
max-y = 90;
|
||||
};
|
||||
|
||||
"end".settings = {
|
||||
world = "${cfg.defaultWorld}/DIM1";
|
||||
sorting = 200;
|
||||
sky-color = "#080010";
|
||||
void-color = "#080010";
|
||||
ambient-light = 0.6;
|
||||
world-sky-light = 0;
|
||||
remove-caves-below-y = -10000;
|
||||
cave-detection-ocean-floor = -5;
|
||||
};
|
||||
};
|
||||
defaultText = lib.literalExpression ''
|
||||
{
|
||||
"overworld".settings = {
|
||||
world = "''${cfg.defaultWorld}";
|
||||
ambient-light = 0.1;
|
||||
cave-detection-ocean-floor = -5;
|
||||
};
|
||||
|
||||
"nether".settings = {
|
||||
world = "''${cfg.defaultWorld}/DIM-1";
|
||||
sorting = 100;
|
||||
sky-color = "#290000";
|
||||
void-color = "#150000";
|
||||
ambient-light = 0.6;
|
||||
world-sky-light = 0;
|
||||
remove-caves-below-y = -10000;
|
||||
cave-detection-ocean-floor = -5;
|
||||
cave-detection-uses-block-light = true;
|
||||
max-y = 90;
|
||||
};
|
||||
|
||||
"end".settings = {
|
||||
world = "''${cfg.defaultWorld}/DIM1";
|
||||
sorting = 200;
|
||||
sky-color = "#080010";
|
||||
void-color = "#080010";
|
||||
ambient-light = 0.6;
|
||||
world-sky-light = 0;
|
||||
remove-caves-below-y = -10000;
|
||||
cave-detection-ocean-floor = -5;
|
||||
};
|
||||
};
|
||||
'';
|
||||
description = ''
|
||||
map-specific configuration.
|
||||
These correspond to views in the webapp and are usually
|
||||
different dimension of a world or different render settings of the same dimension.
|
||||
If you set anything in this option you must configure all dimensions yourself!
|
||||
'';
|
||||
};
|
||||
|
||||
storage = mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
storage-type = mkOption {
|
||||
type = lib.types.enum [ "FILE" "SQL" ];
|
||||
description = "Type of storage config";
|
||||
default = "FILE";
|
||||
};
|
||||
};
|
||||
});
|
||||
description = ''
|
||||
Where the rendered map will be stored.
|
||||
Unless you are doing something advanced you should probably leave this alone and configure webRoot instead.
|
||||
[See upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/tree/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/storages)
|
||||
'';
|
||||
default = {
|
||||
"file" = {
|
||||
root = "${cfg.webRoot}/maps";
|
||||
};
|
||||
};
|
||||
defaultText = lib.literalExpression ''
|
||||
{
|
||||
"file" = {
|
||||
root = "''${config.services.bluemap.webRoot}/maps";
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
resourcepacks = mkOption {
|
||||
type = lib.types.path;
|
||||
default = pkgs.linkFarm "resourcepacks" { };
|
||||
description = ''
|
||||
A set of resourcepacks/mods to extract models from loaded in alphabetical order.
|
||||
Can be overriden on a per-map basis with `services.bluemap.maps.<name>.resourcepacks`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions =
|
||||
[ { assertion = config.services.bluemap.eula;
|
||||
message = ''
|
||||
You have enabled bluemap but have not accepted minecraft's EULA.
|
||||
You can achieve this through setting `services.bluemap.eula = true`
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
services.bluemap.coreSettings.accept-download = cfg.eula;
|
||||
|
||||
systemd.services."render-bluemap-maps" = lib.mkIf cfg.enableRender {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
Group = "nginx";
|
||||
UMask = "026";
|
||||
};
|
||||
script = ''
|
||||
# If web folder doesnt exist generate it
|
||||
test -f "${cfg.webRoot}" || ${lib.getExe cfg.package} -c ${webappConfigFolder} -gs
|
||||
|
||||
# Render each minecraft map
|
||||
${lib.strings.concatStringsSep "\n" (lib.attrsets.mapAttrsToList
|
||||
(name: value: "${lib.getExe cfg.package} -c ${renderConfigFolder name value} -r")
|
||||
cfg.maps)}
|
||||
|
||||
# Generate updated webapp
|
||||
${lib.getExe cfg.package} -c ${webappConfigFolder} -gs
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers."render-bluemap-maps" = lib.mkIf cfg.enableRender {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = cfg.onCalendar;
|
||||
Persistent = true;
|
||||
Unit = "render-bluemap-maps.service";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts = lib.mkIf cfg.enableNginx {
|
||||
"${cfg.host}" = {
|
||||
root = config.services.bluemap.webRoot;
|
||||
locations = {
|
||||
"~* ^/maps/[^/]*/tiles/".extraConfig = ''
|
||||
error_page 404 = @empty;
|
||||
'';
|
||||
"@empty".return = "204";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ dandellion h7x4 ];
|
||||
};
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
{ lib, stdenvNoCC, fetchurl, makeWrapper, jre }:
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
pname = "bluemap";
|
||||
version = "5.7";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/BlueMap-Minecraft/BlueMap/releases/download/v${version}/BlueMap-${version}-cli.jar";
|
||||
hash = "sha256-8udZYJgrr4bi2mjRYrASd8JwUoUVZW1tZpOLRgafAIw=";
|
||||
};
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
makeWrapper ${jre}/bin/java $out/bin/bluemap --add-flags "-jar $src"
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "3D minecraft map renderer";
|
||||
homepage = "https://bluemap.bluecolored.de/";
|
||||
sourceProvenance = with lib.sourceTypes; [ binaryBytecode ];
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ dandellion h7x4 ];
|
||||
mainProgram = "bluemap";
|
||||
};
|
||||
}
|
@ -15,8 +15,8 @@ let
|
||||
enable = true;
|
||||
name = "git-runner-${name}"; url = "https://git.pvv.ntnu.no";
|
||||
labels = [
|
||||
"debian-latest:docker://node:current-bookworm"
|
||||
"ubuntu-latest:docker://node:current-bookworm"
|
||||
"debian-latest:docker://node:18-bullseye"
|
||||
"ubuntu-latest:docker://node:18-bullseye"
|
||||
];
|
||||
tokenFile = config.sops.secrets."gitea/runners/${name}".path;
|
||||
};
|
||||
@ -27,15 +27,5 @@ lib.mkMerge [
|
||||
(mkRunner "alpha")
|
||||
(mkRunner "beta")
|
||||
(mkRunner "epsilon")
|
||||
{
|
||||
virtualisation.podman = {
|
||||
enable = true;
|
||||
defaultNetwork.settings.dns_enabled = true;
|
||||
autoPrune.enable = true;
|
||||
};
|
||||
|
||||
networking.dhcpcd.IPv6rs = false;
|
||||
|
||||
networking.firewall.interfaces."podman+".allowedUDPPorts = [53 5353];
|
||||
}
|
||||
{ virtualisation.podman.enable = true; }
|
||||
]
|
@ -1,14 +1,12 @@
|
||||
{ config, values, lib, unstablePkgs, ... }:
|
||||
{ config, values, pkgs, lib, ... }:
|
||||
let
|
||||
cfg = config.services.gitea;
|
||||
domain = "git.pvv.ntnu.no";
|
||||
sshPort = 2222;
|
||||
in {
|
||||
imports = [
|
||||
./customization
|
||||
./gpg.nix
|
||||
./import-users
|
||||
./web-secret-provider
|
||||
./ci.nix
|
||||
./import-users.nix
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
@ -26,8 +24,6 @@ in {
|
||||
enable = true;
|
||||
appName = "PVV Git";
|
||||
|
||||
package = unstablePkgs.gitea;
|
||||
|
||||
database = {
|
||||
type = "postgres";
|
||||
host = "postgres.pvv.ntnu.no";
|
||||
@ -49,10 +45,6 @@ in {
|
||||
START_LFS_SERVER = true;
|
||||
LANDING_PAGE = "explore";
|
||||
};
|
||||
"git.timeout" = {
|
||||
MIGRATE = 3600;
|
||||
MIRROR = 1800;
|
||||
};
|
||||
mailer = {
|
||||
ENABLED = true;
|
||||
FROM = "gitea@pvv.ntnu.no";
|
||||
@ -62,16 +54,10 @@ in {
|
||||
USER = "gitea@pvv.ntnu.no";
|
||||
SUBJECT_PREFIX = "[pvv-git]";
|
||||
};
|
||||
metrics = {
|
||||
ENABLED = true;
|
||||
ENABLED_ISSUE_BY_LABEL = true;
|
||||
ENABLED_ISSUE_BY_REPOSITORY = true;
|
||||
};
|
||||
indexer.REPO_INDEXER_ENABLED = true;
|
||||
service = {
|
||||
DISABLE_REGISTRATION = true;
|
||||
ENABLE_NOTIFY_MAIL = true;
|
||||
AUTO_WATCH_NEW_REPOS = false;
|
||||
};
|
||||
admin.DEFAULT_EMAIL_NOTIFICATIONS = "onmention";
|
||||
session.COOKIE_SECURE = true;
|
||||
@ -111,65 +97,54 @@ in {
|
||||
ENABLE_FEDERATED_AVATAR = false;
|
||||
};
|
||||
actions.ENABLED = true;
|
||||
ui = {
|
||||
REACTIONS = lib.concatStringsSep "," [
|
||||
"+1"
|
||||
"-1"
|
||||
"laugh"
|
||||
"confused"
|
||||
"heart"
|
||||
"hooray"
|
||||
"rocket"
|
||||
"eyes"
|
||||
"100"
|
||||
"anger"
|
||||
"astonished"
|
||||
"no_good"
|
||||
"ok_hand"
|
||||
"pensive"
|
||||
"pizza"
|
||||
"point_up"
|
||||
"sob"
|
||||
"skull"
|
||||
"upside_down_face"
|
||||
"shrug"
|
||||
];
|
||||
};
|
||||
"ui.meta".DESCRIPTION = "Bokstavelig talt programvareverkstedet";
|
||||
};
|
||||
|
||||
dump = {
|
||||
enable = true;
|
||||
interval = "weekly";
|
||||
type = "tar.gz";
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
systemd.services.gitea.serviceConfig.CPUSchedulingPolicy = "batch";
|
||||
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
kTLS = true;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://unix:${cfg.settings.server.HTTP_ADDR}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 512M;
|
||||
'';
|
||||
};
|
||||
"/metrics" = {
|
||||
proxyPass = "http://unix:${cfg.settings.server.HTTP_ADDR}";
|
||||
extraConfig = ''
|
||||
allow ${values.hosts.ildkule.ipv4}/32;
|
||||
allow ${values.hosts.ildkule.ipv6}/128;
|
||||
deny all;
|
||||
'';
|
||||
};
|
||||
locations."/" = {
|
||||
proxyPass = "http://unix:${cfg.settings.server.HTTP_ADDR}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 512M;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ sshPort ];
|
||||
|
||||
# Extra customization
|
||||
|
||||
services.gitea-themes.monokai = pkgs.gitea-theme-monokai;
|
||||
|
||||
systemd.services.install-gitea-customization = {
|
||||
description = "Install extra customization in gitea's CUSTOM_DIR";
|
||||
wantedBy = [ "gitea.service" ];
|
||||
requiredBy = [ "gitea.service" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
};
|
||||
|
||||
script = let
|
||||
logo-svg = ../../../../assets/logo_blue_regular.svg;
|
||||
logo-png = ../../../../assets/logo_blue_regular.png;
|
||||
extraLinks = pkgs.writeText "gitea-extra-links.tmpl" ''
|
||||
<a class="item" href="https://www.pvv.ntnu.no/">PVV</a>
|
||||
<a class="item" href="https://wiki.pvv.ntnu.no/">Wiki</a>
|
||||
<a class="item" href="https://git.pvv.ntnu.no/Drift/-/projects/4">Tokyo Drift Issues</a>
|
||||
'';
|
||||
in ''
|
||||
install -Dm444 ${logo-svg} ${cfg.customDir}/public/assets/img/logo.svg
|
||||
install -Dm444 ${logo-png} ${cfg.customDir}/public/assets/img/logo.png
|
||||
install -Dm444 ${./loading.apng} ${cfg.customDir}/public/assets/img/loading.png
|
||||
install -Dm444 ${extraLinks} ${cfg.customDir}/templates/custom/extra_links.tmpl
|
||||
'';
|
||||
};
|
||||
}
|
94
hosts/bekkalokk/services/gitea/gitea-import-users.py
Normal file
94
hosts/bekkalokk/services/gitea/gitea-import-users.py
Normal file
@ -0,0 +1,94 @@
|
||||
import requests
|
||||
import secrets
|
||||
import os
|
||||
|
||||
EMAIL_DOMAIN = os.getenv('EMAIL_DOMAIN')
|
||||
if EMAIL_DOMAIN is None:
|
||||
EMAIL_DOMAIN = 'pvv.ntnu.no'
|
||||
|
||||
API_TOKEN = os.getenv('API_TOKEN')
|
||||
if API_TOKEN is None:
|
||||
raise Exception('API_TOKEN not set')
|
||||
|
||||
GITEA_API_URL = os.getenv('GITEA_API_URL')
|
||||
if GITEA_API_URL is None:
|
||||
GITEA_API_URL = 'https://git.pvv.ntnu.no/api/v1'
|
||||
|
||||
BANNED_SHELLS = [
|
||||
"/usr/bin/nologin",
|
||||
"/usr/sbin/nologin",
|
||||
"/sbin/nologin",
|
||||
"/bin/false",
|
||||
"/bin/msgsh",
|
||||
]
|
||||
|
||||
existing_users = {}
|
||||
|
||||
|
||||
# This function should only ever be called when adding users
|
||||
# from the passwd file
|
||||
def add_user(username, name):
|
||||
user = {
|
||||
"full_name": name,
|
||||
"username": username,
|
||||
"login_name": username,
|
||||
"source_id": 1, # 1 = SMTP
|
||||
}
|
||||
|
||||
if username not in existing_users:
|
||||
user["password"] = secrets.token_urlsafe(32)
|
||||
user["must_change_password"] = False
|
||||
user["visibility"] = "private"
|
||||
user["email"] = username + '@' + EMAIL_DOMAIN
|
||||
|
||||
r = requests.post(GITEA_API_URL + '/admin/users', json=user,
|
||||
headers={'Authorization': 'token ' + API_TOKEN})
|
||||
if r.status_code != 201:
|
||||
print('ERR: Failed to create user ' + username + ': ' + r.text)
|
||||
return
|
||||
|
||||
print('Created user ' + username)
|
||||
existing_users[username] = user
|
||||
|
||||
else:
|
||||
user["visibility"] = existing_users[username]["visibility"]
|
||||
r = requests.patch(GITEA_API_URL + f'/admin/users/{username}',
|
||||
json=user,
|
||||
headers={'Authorization': 'token ' + API_TOKEN})
|
||||
if r.status_code != 200:
|
||||
print('ERR: Failed to update user ' + username + ': ' + r.text)
|
||||
return
|
||||
|
||||
print('Updated user ' + username)
|
||||
|
||||
|
||||
def main():
|
||||
# Fetch existing users
|
||||
r = requests.get(GITEA_API_URL + '/admin/users',
|
||||
headers={'Authorization': 'token ' + API_TOKEN})
|
||||
|
||||
if r.status_code != 200:
|
||||
raise Exception('Failed to get users: ' + r.text)
|
||||
|
||||
for user in r.json():
|
||||
existing_users[user['login']] = user
|
||||
|
||||
# Read the file, add each user
|
||||
with open("/tmp/passwd-import", 'r') as f:
|
||||
for line in f.readlines():
|
||||
uid = int(line.split(':')[2])
|
||||
if uid < 1000:
|
||||
continue
|
||||
|
||||
shell = line.split(':')[-1]
|
||||
if shell in BANNED_SHELLS:
|
||||
continue
|
||||
|
||||
username = line.split(':')[0]
|
||||
name = line.split(':')[4].split(',')[0]
|
||||
|
||||
add_user(username, name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -14,9 +14,6 @@ in
|
||||
preStart=''${pkgs.rsync}/bin/rsync -e "${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$CREDENTIALS_DIRECTORY/ssh-known-hosts -i $CREDENTIALS_DIRECTORY/sshkey" -a pvv@smtp.pvv.ntnu.no:/etc/passwd /tmp/passwd-import'';
|
||||
serviceConfig = {
|
||||
ExecStart = pkgs.writers.writePython3 "gitea-import-users" {
|
||||
flakeIgnore = [
|
||||
"E501" # Line over 80 chars lol
|
||||
];
|
||||
libraries = with pkgs.python3Packages; [ requests ];
|
||||
} (builtins.readFile ./gitea-import-users.py);
|
||||
LoadCredential=[
|
Before (image error) Size: 1.1 MiB After (image error) Size: 1.1 MiB |
@ -202,12 +202,6 @@ in
|
||||
rewrite ^/simplesaml/(.*)$ /$1 redirect;
|
||||
return 404;
|
||||
'';
|
||||
"/robots.txt" = {
|
||||
root = pkgs.writeTextDir "robots.txt" ''
|
||||
User-agent: *
|
||||
Disallow: /
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ pkgs, lib, fp, config, values, pkgs-unstable, ... }: let
|
||||
{ pkgs, lib, config, values, pkgs-unstable, ... }: let
|
||||
cfg = config.services.mediawiki;
|
||||
|
||||
# "mediawiki"
|
||||
@ -61,6 +61,7 @@ in {
|
||||
user = "mediawiki";
|
||||
passwordFile = config.sops.secrets."mediawiki/postgres_password".path;
|
||||
createLocally = false;
|
||||
# TODO: create a normal database and copy over old data when the service is production ready
|
||||
name = "mediawiki";
|
||||
};
|
||||
|
||||
@ -209,16 +210,16 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
"= /PNG/PVV-logo.svg".alias = fp /assets/logo_blue_regular.svg;
|
||||
"= /PNG/PVV-logo.png".alias = fp /assets/logo_blue_regular.png;
|
||||
"= /PNG/PVV-logo.svg".alias = ../../../../assets/logo_blue_regular.svg;
|
||||
"= /PNG/PVV-logo.png".alias = ../../../../assets/logo_blue_regular.png;
|
||||
"= /favicon.ico".alias = pkgs.runCommandLocal "mediawiki-favicon.ico" {
|
||||
buildInputs = with pkgs; [ imagemagick ];
|
||||
} ''
|
||||
magick \
|
||||
${fp /assets/logo_blue_regular.png} \
|
||||
convert \
|
||||
-resize x64 \
|
||||
-gravity center \
|
||||
-crop 64x64+0+0 \
|
||||
${../../../../assets/logo_blue_regular.png} \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
-background transparent \
|
||||
|
@ -1,51 +0,0 @@
|
||||
{ lib, ... }:
|
||||
let
|
||||
pools = map (pool: "phpfpm-${pool}") [
|
||||
"idp"
|
||||
"mediawiki"
|
||||
"pvv-nettsiden"
|
||||
"roundcube"
|
||||
"snappymail"
|
||||
];
|
||||
in
|
||||
{
|
||||
# Source: https://www.pierreblazquez.com/2023/06/17/how-to-harden-apache-php-fpm-daemons-using-systemd/
|
||||
systemd.services = lib.genAttrs pools (_: {
|
||||
serviceConfig = let
|
||||
caps = [
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
"CAP_SETGID"
|
||||
"CAP_SETUID"
|
||||
"CAP_CHOWN"
|
||||
"CAP_KILL"
|
||||
"CAP_IPC_LOCK"
|
||||
"CAP_DAC_OVERRIDE"
|
||||
];
|
||||
in {
|
||||
AmbientCapabilities = caps;
|
||||
CapabilityBoundingSet = caps;
|
||||
DeviceAllow = [ "" ];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = false;
|
||||
NoNewPrivileges = true;
|
||||
PrivateMounts = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
RemoveIPC = true;
|
||||
UMask = "0077";
|
||||
RestrictNamespaces = "~mnt";
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
KeyringMode = "private";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
@ -65,38 +65,4 @@ in {
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.vaultwarden = lib.mkIf cfg.enable {
|
||||
serviceConfig = {
|
||||
AmbientCapabilities = [ "" ];
|
||||
CapabilityBoundingSet = [ "" ];
|
||||
DeviceAllow = [ "" ];
|
||||
LockPersonality = true;
|
||||
NoNewPrivileges = true;
|
||||
# MemoryDenyWriteExecute = true;
|
||||
PrivateMounts = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_UNIX"
|
||||
];
|
||||
RemoveIPC = true;
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@privileged"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -6,11 +6,6 @@ let
|
||||
domain = "webmail.pvv.ntnu.no";
|
||||
in
|
||||
{
|
||||
sops.secrets."roundcube/postgres_password" = {
|
||||
owner = "nginx";
|
||||
group = "nginx";
|
||||
};
|
||||
|
||||
services.roundcube = {
|
||||
enable = true;
|
||||
|
||||
@ -21,15 +16,10 @@ in
|
||||
custom_from
|
||||
]);
|
||||
|
||||
dicts = with pkgs.aspellDicts; [ en en-computers nb nn fr de it ];
|
||||
dicts = with pkgs.aspellDicts; [ en en-science en-computers nb nn fr de it ];
|
||||
maxAttachmentSize = 20;
|
||||
hostName = "roundcubeplaceholder.example.com";
|
||||
|
||||
database = {
|
||||
host = "postgres.pvv.ntnu.no";
|
||||
passwordFile = config.sops.secrets."roundcube/postgres_password".path;
|
||||
};
|
||||
|
||||
extraConfig = ''
|
||||
$config['enable_installer'] = false;
|
||||
$config['default_host'] = "ssl://imap.pvv.ntnu.no";
|
||||
|
@ -1,8 +1,8 @@
|
||||
{ config, lib, fp, pkgs, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.snappymail;
|
||||
in {
|
||||
imports = [ (fp /modules/snappymail.nix) ];
|
||||
imports = [ ../../../../modules/snappymail.nix ];
|
||||
|
||||
services.snappymail = {
|
||||
enable = true;
|
||||
|
@ -67,12 +67,7 @@ in {
|
||||
ADMIN_NAME = "PVV Drift";
|
||||
ADMIN_EMAIL = "drift@pvv.ntnu.no";
|
||||
ADMIN_PASSWORD = includeFromSops "simplesamlphp/admin_password";
|
||||
TRUSTED_DOMAINS = [
|
||||
"www.pvv.ntnu.no"
|
||||
"pvv.ntnu.no"
|
||||
"www.pvv.org"
|
||||
"pvv.org"
|
||||
];
|
||||
TRUSTED_DOMAINS = [ cfg.domainName ];
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -121,6 +116,16 @@ in {
|
||||
"/drift".return = "301 https://wiki.pvv.ntnu.no/wiki/Drift";
|
||||
"/diverse/abuse.php".return = "301 https://wiki.pvv.ntnu.no/wiki/CERT/Abuse";
|
||||
"/nerds/".return = "301 https://wiki.pvv.ntnu.no/wiki/Nerdepizza";
|
||||
|
||||
# Proxy the matrix well-known files
|
||||
# Host has be set before proxy_pass
|
||||
# The header must be set so nginx on the other side routes it to the right place
|
||||
"^~ /.well-known/matrix/" = {
|
||||
extraConfig = ''
|
||||
proxy_set_header Host matrix.pvv.ntnu.no;
|
||||
proxy_pass https://matrix.pvv.ntnu.no/.well-known/matrix/;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ in {
|
||||
|
||||
echo "Creating thumbnail for $fname"
|
||||
mkdir -p $(dirname ".thumbnails/$fname")
|
||||
magick -define jpeg:size=200x200 "$fname" -thumbnail 300 -auto-orient ".thumbnails/$fname.png" ||:
|
||||
convert -define jpeg:size=200x200 "$fname" -thumbnail 300 -auto-orient ".thumbnails/$fname.png" ||:
|
||||
touch -m -d "$(date -R -r "$fname")" ".thumbnails/$fname.png"
|
||||
done <<< "$images"
|
||||
'';
|
||||
@ -62,33 +62,6 @@ in {
|
||||
WorkingDirectory = galleryDir;
|
||||
User = config.services.pvv-nettsiden.user;
|
||||
Group = config.services.pvv-nettsiden.group;
|
||||
|
||||
AmbientCapabilities = [ "" ];
|
||||
CapabilityBoundingSet = [ "" ];
|
||||
DeviceAllow = [ "" ];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true; # disable for third party rotate scripts
|
||||
PrivateDevices = true;
|
||||
PrivateNetwork = true; # disable for mail delivery
|
||||
PrivateTmp = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true; # disable for userdir logs
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "full";
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true; # disable for creating setgid directories
|
||||
SocketBindDeny = [ "any" ];
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.nginx.virtualHosts."www.pvv.ntnu.no".locations = {
|
||||
"^~ /.well-known/" = {
|
||||
alias = (toString ./root) + "/";
|
||||
};
|
||||
|
||||
# Proxy the matrix well-known files
|
||||
# Host has be set before proxy_pass
|
||||
# The header must be set so nginx on the other side routes it to the right place
|
||||
"^~ /.well-known/matrix/" = {
|
||||
extraConfig = ''
|
||||
proxy_set_header Host matrix.pvv.ntnu.no;
|
||||
proxy_pass https://matrix.pvv.ntnu.no/.well-known/matrix/;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<clientConfig version="1.1">
|
||||
<emailProvider id="pvv.ntnu.no">
|
||||
<domain>pvv.ntnu.no</domain>
|
||||
<domain>pvv.org</domain>
|
||||
|
||||
<displayName>Programvareverkstedet</displayName>
|
||||
|
||||
<incomingServer type="imap">
|
||||
<hostname>imap.pvv.ntnu.no</hostname>
|
||||
<port>993</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILLOCALPART%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</incomingServer>
|
||||
|
||||
<outgoingServer type="smtp">
|
||||
<hostname>smtp.pvv.ntnu.no</hostname>
|
||||
<port>587</port>
|
||||
<socketType>STARTTLS</socketType>
|
||||
<username>%EMAILLOCALPART%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
<useGlobalPreferredServer>true</useGlobalPreferredServer>
|
||||
</outgoingServer>
|
||||
|
||||
<documentation url="https://www.pvv.ntnu.no/pvv/Drift/Mail/IMAP_POP3">
|
||||
<descr lang="en">Setup programvareverkstedet email user with IMAP or POP3</descr>
|
||||
<descr lang="nb">Sett opp programvareverkstedet email bruker med IMAP eller POP3</descr>
|
||||
</documentation>
|
||||
</emailProvider>
|
||||
</clientConfig>
|
@ -1,12 +0,0 @@
|
||||
Contact: mailto:drift@pvv.ntnu.no
|
||||
Contact: mailto:cert@pvv.ntnu.no
|
||||
# drift@pvv.ntnu.no is read by more people and have a quicker reaction time,
|
||||
# but cert@pvv.ntnu.no can be used for more severe issues.
|
||||
|
||||
Preferred-Languages: no, en
|
||||
|
||||
Expires: 2032-12-31T23:59:59.000Z
|
||||
# This file was last updated 2024-09-14.
|
||||
|
||||
# You can find a wikipage for our security policies at:
|
||||
# https://wiki.pvv.ntnu.no/wiki/CERT
|
24
hosts/bicep/acmeCert.nix
Normal file
24
hosts/bicep/acmeCert.nix
Normal file
@ -0,0 +1,24 @@
|
||||
{ values, ... }:
|
||||
{
|
||||
users.groups.acme.members = [ "nginx" ];
|
||||
|
||||
security.acme.certs."postgres.pvv.ntnu.no" = {
|
||||
group = "acme";
|
||||
extraDomainNames = [
|
||||
# "postgres.pvv.org"
|
||||
"bicep.pvv.ntnu.no"
|
||||
# "bicep.pvv.org"
|
||||
# values.hosts.bicep.ipv4
|
||||
# values.hosts.bicep.ipv6
|
||||
];
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts."postgres.pvv.ntnu.no" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
# useACMEHost = "postgres.pvv.ntnu.no";
|
||||
};
|
||||
};
|
||||
}
|
@ -1,21 +1,24 @@
|
||||
{ fp, pkgs, values, ... }:
|
||||
{ pkgs, values, ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
|
||||
(fp /base)
|
||||
(fp /misc/metrics-exporters.nix)
|
||||
../../base.nix
|
||||
../../misc/metrics-exporters.nix
|
||||
./services/nginx
|
||||
|
||||
./acmeCert.nix
|
||||
|
||||
./services/calendar-bot.nix
|
||||
./services/git-mirrors
|
||||
./services/doorbell-bot.nix
|
||||
./services/mysql.nix
|
||||
./services/mysql.nix
|
||||
./services/postgres.nix
|
||||
|
||||
./services/matrix
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = fp /secrets/bicep/bicep.yaml;
|
||||
sops.defaultSopsFile = ../../secrets/bicep/bicep.yaml;
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sops.age.generateKey = true;
|
||||
@ -34,9 +37,6 @@
|
||||
anyInterface = true;
|
||||
};
|
||||
|
||||
# There are no smart devices
|
||||
services.smartd.enable = false;
|
||||
|
||||
# Do not change, even during upgrades.
|
||||
# See https://search.nixos.org/options?show=system.stateVersion
|
||||
system.stateVersion = "22.11";
|
||||
|
@ -1,16 +1,16 @@
|
||||
{ config, fp, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.pvv-calendar-bot;
|
||||
in {
|
||||
sops.secrets = {
|
||||
"calendar-bot/matrix_token" = {
|
||||
sopsFile = fp /secrets/bicep/bicep.yaml;
|
||||
sopsFile = ../../../secrets/bicep/bicep.yaml;
|
||||
key = "calendar-bot/matrix_token";
|
||||
owner = cfg.user;
|
||||
group = cfg.group;
|
||||
};
|
||||
"calendar-bot/mysql_password" = {
|
||||
sopsFile = fp /secrets/bicep/bicep.yaml;
|
||||
sopsFile = ../../../secrets/bicep/bicep.yaml;
|
||||
key = "calendar-bot/mysql_password";
|
||||
owner = cfg.user;
|
||||
group = cfg.group;
|
||||
|
16
hosts/bicep/services/doorbell-bot.nix
Normal file
16
hosts/bicep/services/doorbell-bot.nix
Normal file
@ -0,0 +1,16 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.pvv-doorbell-bot;
|
||||
in {
|
||||
sops.secrets."doorbell-bot/config-json" = {
|
||||
owner = cfg.user;
|
||||
group = cfg.group;
|
||||
};
|
||||
|
||||
services.pvv-doorbell-bot = {
|
||||
enable = true;
|
||||
settings = {
|
||||
configFile = config.sops.secrets."doorbell-bot/config-json".path;
|
||||
};
|
||||
};
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
{ config, pkgs, lib, fp, ... }:
|
||||
let
|
||||
cfg = config.services.gickup;
|
||||
in
|
||||
{
|
||||
sops.secrets."gickup/github-token" = {
|
||||
owner = "gickup";
|
||||
};
|
||||
|
||||
services.gickup = {
|
||||
enable = true;
|
||||
|
||||
dataDir = "/data/gickup";
|
||||
|
||||
destinationSettings = {
|
||||
structured = true;
|
||||
zip = false;
|
||||
keep = 10;
|
||||
bare = true;
|
||||
lfs = false;
|
||||
};
|
||||
|
||||
instances = let
|
||||
defaultGithubConfig = {
|
||||
settings.token_file = config.sops.secrets."gickup/github-token".path;
|
||||
};
|
||||
defaultGitlabConfig = {
|
||||
# settings.token_file = ...
|
||||
};
|
||||
in {
|
||||
"github:Git-Mediawiki/Git-Mediawiki" = defaultGithubConfig;
|
||||
"github:NixOS/nixpkgs" = defaultGithubConfig;
|
||||
"github:go-gitea/gitea" = defaultGithubConfig;
|
||||
"github:heimdal/heimdal" = defaultGithubConfig;
|
||||
"github:saltstack/salt" = defaultGithubConfig;
|
||||
"github:typst/typst" = defaultGithubConfig;
|
||||
"github:unmojang/FjordLauncher" = defaultGithubConfig;
|
||||
"github:unmojang/drasl" = defaultGithubConfig;
|
||||
"github:yushijinhun/authlib-injector" = defaultGithubConfig;
|
||||
|
||||
"gitlab:mx-puppet/discord/better-discord.js" = defaultGitlabConfig;
|
||||
"gitlab:mx-puppet/discord/discord-markdown" = defaultGitlabConfig;
|
||||
"gitlab:mx-puppet/discord/matrix-discord-parser" = defaultGitlabConfig;
|
||||
"gitlab:mx-puppet/discord/mx-puppet-discord" = defaultGitlabConfig;
|
||||
"gitlab:mx-puppet/mx-puppet-bridge" = defaultGitlabConfig;
|
||||
|
||||
"any:glibc" = {
|
||||
settings.url = "https://sourceware.org/git/glibc.git";
|
||||
};
|
||||
|
||||
"any:out-of-your-element" = {
|
||||
settings.url = "https://gitdab.com/cadence/out-of-your-element.git";
|
||||
};
|
||||
|
||||
"any:out-of-your-element-module" = {
|
||||
settings.url = "https://cgit.rory.gay/nix/OOYE-module.git";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.cgit = let
|
||||
domain = "mirrors.pvv.ntnu.no";
|
||||
in {
|
||||
${domain} = {
|
||||
enable = true;
|
||||
package = pkgs.callPackage (fp /packages/cgit.nix) { };
|
||||
group = "gickup";
|
||||
scanPath = "${cfg.dataDir}/linktree";
|
||||
settings = {
|
||||
enable-commit-graph = true;
|
||||
enable-follow-links = true;
|
||||
enable-http-clone = true;
|
||||
enable-remote-branches = true;
|
||||
clone-url = "https://${domain}/$CGIT_REPO_URL";
|
||||
remove-suffix = true;
|
||||
root-title = "PVVSPPP";
|
||||
root-desc = "PVV Speiler Praktisk og Prominent Programvare";
|
||||
snapshots = "all";
|
||||
logo = "/PVV-logo.png";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."mirrors.pvv.ntnu.no" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
|
||||
locations."= /PVV-logo.png".alias = let
|
||||
small-pvv-logo = pkgs.runCommandLocal "pvv-logo-96x96" {
|
||||
nativeBuildInputs = [ pkgs.imagemagick ];
|
||||
} ''
|
||||
magick '${fp /assets/logo_blue_regular.svg}' -resize 96x96 PNG:"$out"
|
||||
'';
|
||||
in toString small-pvv-logo;
|
||||
};
|
||||
|
||||
systemd.services."fcgiwrap-cgit-mirrors.pvv.ntnu.no" = {
|
||||
serviceConfig.BindReadOnlyPaths = [ cfg.dataDir ];
|
||||
};
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
{ config, lib, fp, pkgs, secrets, values, ... }:
|
||||
{ config, lib, pkgs, secrets, ... }:
|
||||
|
||||
{
|
||||
sops.secrets."matrix/synapse/turnconfig" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
sopsFile = ../../../../secrets/bicep/matrix.yaml;
|
||||
key = "synapse/turnconfig";
|
||||
owner = config.users.users.matrix-synapse.name;
|
||||
group = config.users.users.matrix-synapse.group;
|
||||
};
|
||||
sops.secrets."matrix/coturn/static-auth-secret" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
sopsFile = ../../../../secrets/bicep/matrix.yaml;
|
||||
key = "coturn/static-auth-secret";
|
||||
owner = config.users.users.turnserver.name;
|
||||
group = config.users.users.turnserver.group;
|
||||
@ -48,9 +48,6 @@
|
||||
|
||||
users.users.turnserver.extraGroups = [ "acme" ];
|
||||
|
||||
# It needs this to be allowed to access the files with the acme group
|
||||
systemd.services.coturn.serviceConfig.PrivateUsers = lib.mkForce false;
|
||||
|
||||
systemd.services."acme-${config.services.coturn.realm}".serviceConfig = {
|
||||
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||
};
|
||||
@ -63,14 +60,12 @@
|
||||
pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";
|
||||
|
||||
use-auth-secret = true;
|
||||
# World readable but I dont think it's that bad
|
||||
static-auth-secret-file = config.sops.secrets."matrix/coturn/static-auth-secret".path;
|
||||
|
||||
secure-stun = true;
|
||||
|
||||
listening-ips = [
|
||||
values.services.turn.ipv4
|
||||
values.services.turn.ipv6
|
||||
];
|
||||
listening-ips = [ "129.241.210.213" "2001:700:300:1900::213" ];
|
||||
|
||||
tls-listening-port = 443;
|
||||
alt-tls-listening-port = 5349;
|
||||
|
@ -9,9 +9,7 @@
|
||||
./coturn.nix
|
||||
./mjolnir.nix
|
||||
|
||||
# ./discord.nix
|
||||
./out-of-your-element.nix
|
||||
./hookshot
|
||||
./discord.nix
|
||||
];
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ config, lib, fp, ... }:
|
||||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.mx-puppet-discord;
|
||||
@ -6,46 +6,19 @@ in
|
||||
{
|
||||
users.groups.keys-matrix-registrations = { };
|
||||
|
||||
sops.secrets."matrix/discord/as_token" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
key = "discord/as_token";
|
||||
};
|
||||
sops.secrets."matrix/discord/hs_token" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
key = "discord/hs_token";
|
||||
};
|
||||
|
||||
sops.templates."discord-registration.yaml" = {
|
||||
sops.secrets."matrix/registrations/mx-puppet-discord" = {
|
||||
sopsFile = ../../../../secrets/bicep/matrix.yaml;
|
||||
key = "registrations/mx-puppet-discord";
|
||||
owner = config.users.users.matrix-synapse.name;
|
||||
group = config.users.groups.keys-matrix-registrations.name;
|
||||
content = ''
|
||||
as_token: "${config.sops.placeholder."matrix/discord/as_token"}"
|
||||
hs_token: "${config.sops.placeholder."matrix/discord/hs_token"}"
|
||||
id: discord-puppet
|
||||
namespaces:
|
||||
users:
|
||||
- exclusive: true
|
||||
regex: '@_discordpuppet_.*'
|
||||
rooms: []
|
||||
aliases:
|
||||
- exclusive: true
|
||||
regex: '#_discordpuppet_.*'
|
||||
protocols: []
|
||||
rate_limited: false
|
||||
sender_localpart: _discordpuppet_bot
|
||||
url: 'http://localhost:8434'
|
||||
de.sorunome.msc2409.push_ephemeral: true
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.mx-puppet-discord = {
|
||||
serviceConfig.SupplementaryGroups = [
|
||||
config.users.groups.keys-matrix-registrations.name
|
||||
];
|
||||
serviceConfig.SupplementaryGroups = [ config.users.groups.keys-matrix-registrations.name ];
|
||||
};
|
||||
|
||||
|
||||
services.mx-puppet-discord.enable = false;
|
||||
services.mx-puppet-discord.enable = true;
|
||||
services.mx-puppet-discord.settings = {
|
||||
bridge = {
|
||||
bindAddress = "localhost";
|
||||
@ -56,16 +29,11 @@ in
|
||||
relay.whitelist = [ ".*" ];
|
||||
selfService.whitelist = [ "@danio:pvv\\.ntnu\\.no" "@dandellion:dodsorf\\.as" ];
|
||||
};
|
||||
services.mx-puppet-discord.serviceDependencies = [
|
||||
"matrix-synapse.target"
|
||||
"nginx.service"
|
||||
];
|
||||
services.mx-puppet-discord.serviceDependencies = [ "matrix-synapse.target" "nginx.service" ];
|
||||
|
||||
|
||||
services.matrix-synapse-next.settings = {
|
||||
app_service_config_files = [
|
||||
config.sops.templates."discord-registration.yaml".path
|
||||
];
|
||||
app_service_config_files = [ config.sops.secrets."matrix/registrations/mx-puppet-discord".path ];
|
||||
use_appservice_legacy_authorization = true;
|
||||
};
|
||||
|
||||
|
@ -1,135 +0,0 @@
|
||||
{ config, lib, fp, unstablePkgs, inputs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-hookshot;
|
||||
webhookListenAddress = "127.0.0.1";
|
||||
webhookListenPort = 8435;
|
||||
in
|
||||
{
|
||||
sops.secrets."matrix/hookshot/as_token" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
key = "hookshot/as_token";
|
||||
};
|
||||
sops.secrets."matrix/hookshot/hs_token" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
key = "hookshot/hs_token";
|
||||
};
|
||||
|
||||
sops.templates."hookshot-registration.yaml" = {
|
||||
owner = config.users.users.matrix-synapse.name;
|
||||
group = config.users.groups.keys-matrix-registrations.name;
|
||||
content = ''
|
||||
id: matrix-hookshot
|
||||
as_token: "${config.sops.placeholder."matrix/hookshot/as_token"}"
|
||||
hs_token: "${config.sops.placeholder."matrix/hookshot/hs_token"}"
|
||||
namespaces:
|
||||
rooms: []
|
||||
users:
|
||||
- regex: "@_webhooks_.*:pvv.ntnu.no"
|
||||
exclusive: true
|
||||
- regex: "@bot_feeds:pvv.ntnu.no"
|
||||
exclusive: true
|
||||
aliases: []
|
||||
|
||||
sender_localpart: hookshot
|
||||
url: "http://${cfg.settings.bridge.bindAddress}:${toString cfg.settings.bridge.port}"
|
||||
rate_limited: false
|
||||
|
||||
# If enabling encryption
|
||||
de.sorunome.msc2409.push_ephemeral: true
|
||||
push_ephemeral: true
|
||||
org.matrix.msc3202: true
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.matrix-hookshot = {
|
||||
serviceConfig.SupplementaryGroups = [
|
||||
config.users.groups.keys-matrix-registrations.name
|
||||
];
|
||||
};
|
||||
|
||||
services.matrix-hookshot = {
|
||||
enable = true;
|
||||
package = unstablePkgs.matrix-hookshot;
|
||||
registrationFile = config.sops.templates."hookshot-registration.yaml".path;
|
||||
settings = {
|
||||
bridge = {
|
||||
bindAddress = "127.0.0.1";
|
||||
domain = "pvv.ntnu.no";
|
||||
url = "https://matrix.pvv.ntnu.no";
|
||||
mediaUrl = "https://matrix.pvv.ntnu.no";
|
||||
port = 9993;
|
||||
};
|
||||
listeners = [
|
||||
{
|
||||
bindAddress = webhookListenAddress;
|
||||
port = webhookListenPort;
|
||||
resources = [
|
||||
"webhooks"
|
||||
# "metrics"
|
||||
# "provisioning"
|
||||
"widgets"
|
||||
];
|
||||
}
|
||||
];
|
||||
generic = {
|
||||
enabled = true;
|
||||
outbound = true;
|
||||
urlPrefix = "https://hookshot.pvv.ntnu.no/webhook/";
|
||||
userIdPrefix = "_webhooks_";
|
||||
allowJsTransformationFunctions = false;
|
||||
waitForComplete = false;
|
||||
};
|
||||
feeds = {
|
||||
enabled = true;
|
||||
pollIntervalSeconds = 600;
|
||||
};
|
||||
|
||||
serviceBots = [
|
||||
{ localpart = "bot_feeds";
|
||||
displayname = "Aya";
|
||||
avatar = ./feeds.png;
|
||||
prefix = "!aya";
|
||||
service = "feeds";
|
||||
}
|
||||
];
|
||||
|
||||
permissions = [
|
||||
# Users of the PVV Server
|
||||
{ actor = "pvv.ntnu.no";
|
||||
services = [ { service = "*"; level = "commands"; } ];
|
||||
}
|
||||
# Members of Medlem space (for people with their own hs)
|
||||
{ actor = "!pZOTJQinWyyTWaeOgK:pvv.ntnu.no";
|
||||
services = [ { service = "*"; level = "commands"; } ];
|
||||
}
|
||||
# Members of Drift
|
||||
{ actor = "!eYgeufLrninXxQpYml:pvv.ntnu.no";
|
||||
services = [ { service = "*"; level = "admin"; } ];
|
||||
}
|
||||
# Dan bootstrap
|
||||
{ actor = "@dandellion:dodsorf.as";
|
||||
services = [ { service = "*"; level = "admin"; } ];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services.matrix-hookshot.serviceDependencies = [
|
||||
"matrix-synapse.target"
|
||||
"nginx.service"
|
||||
];
|
||||
|
||||
services.matrix-synapse-next.settings = {
|
||||
app_service_config_files = [
|
||||
config.sops.templates."hookshot-registration.yaml".path
|
||||
];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."hookshot.pvv.ntnu.no" = {
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://${webhookListenAddress}:${toString webhookListenPort}";
|
||||
};
|
||||
};
|
||||
}
|
Binary file not shown.
Before ![]() (image error) Size: 1.1 MiB |
@ -1,8 +1,8 @@
|
||||
{ config, lib, fp, ... }:
|
||||
{ config, lib, ... }:
|
||||
|
||||
{
|
||||
sops.secrets."matrix/mjolnir/access_token" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
sopsFile = ../../../../secrets/bicep/matrix.yaml;
|
||||
key = "mjolnir/access_token";
|
||||
owner = config.users.users.mjolnir.name;
|
||||
group = config.users.users.mjolnir.group;
|
||||
@ -11,7 +11,7 @@
|
||||
services.mjolnir = {
|
||||
enable = true;
|
||||
pantalaimon.enable = false;
|
||||
homeserverUrl = "https://matrix.pvv.ntnu.no";
|
||||
homeserverUrl = "http://127.0.0.1:8008";
|
||||
accessTokenFile = config.sops.secrets."matrix/mjolnir/access_token".path;
|
||||
managementRoom = "!gsdeCoWjvYRBrzuiRq:pvv.ntnu.no";
|
||||
protectedRooms = map (a: "https://matrix.to/#/${a}") [
|
||||
|
@ -1,66 +0,0 @@
|
||||
{ config, pkgs, fp, ... }:
|
||||
let
|
||||
cfg = config.services.matrix-ooye;
|
||||
in
|
||||
{
|
||||
users.groups.keys-matrix-registrations = { };
|
||||
|
||||
sops.secrets = {
|
||||
"matrix/ooye/as_token" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
key = "ooye/as_token";
|
||||
};
|
||||
"matrix/ooye/hs_token" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
key = "ooye/hs_token";
|
||||
};
|
||||
"matrix/ooye/discord_token" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
key = "ooye/discord_token";
|
||||
};
|
||||
"matrix/ooye/discord_client_secret" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
key = "ooye/discord_client_secret";
|
||||
};
|
||||
};
|
||||
|
||||
services.matrix-ooye = {
|
||||
enable = true;
|
||||
homeserver = "https://matrix.pvv.ntnu.no";
|
||||
homeserverName = "pvv.ntnu.no";
|
||||
discordTokenPath = config.sops.secrets."matrix/ooye/discord_token".path;
|
||||
discordClientSecretPath = config.sops.secrets."matrix/ooye/discord_client_secret".path;
|
||||
bridgeOrigin = "https://ooye.pvv.ntnu.no";
|
||||
|
||||
enableSynapseIntegration = false;
|
||||
};
|
||||
|
||||
systemd.services."matrix-synapse" = {
|
||||
after = [
|
||||
"matrix-ooye-pre-start.service"
|
||||
"network-online.target"
|
||||
];
|
||||
requires = [ "matrix-ooye-pre-start.service" ];
|
||||
serviceConfig = {
|
||||
LoadCredential = [
|
||||
"matrix-ooye-registration:/var/lib/matrix-ooye/registration.yaml"
|
||||
];
|
||||
ExecStartPre = [
|
||||
"+${pkgs.coreutils}/bin/cp /run/credentials/matrix-synapse.service/matrix-ooye-registration ${config.services.matrix-synapse-next.dataDir}/ooye-registration.yaml"
|
||||
"+${pkgs.coreutils}/bin/chown matrix-synapse:keys-matrix-registrations ${config.services.matrix-synapse-next.dataDir}/ooye-registration.yaml"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services.matrix-synapse-next.settings = {
|
||||
app_service_config_files = [
|
||||
"${config.services.matrix-synapse-next.dataDir}/ooye-registration.yaml"
|
||||
];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."ooye.pvv.ntnu.no" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".proxyPass = "http://localhost:${cfg.socket}";
|
||||
};
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
{ config, lib, fp, pkgs, values, inputs, ... }:
|
||||
{ config, lib, pkgs, values, inputs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-synapse-next;
|
||||
@ -10,18 +10,23 @@ let
|
||||
in {
|
||||
sops.secrets."matrix/synapse/signing_key" = {
|
||||
key = "synapse/signing_key";
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
sopsFile = ../../../../secrets/bicep/matrix.yaml;
|
||||
owner = config.users.users.matrix-synapse.name;
|
||||
group = config.users.users.matrix-synapse.group;
|
||||
};
|
||||
|
||||
sops.secrets."matrix/synapse/user_registration" = {
|
||||
sopsFile = fp /secrets/bicep/matrix.yaml;
|
||||
sopsFile = ../../../../secrets/bicep/matrix.yaml;
|
||||
key = "synapse/signing_key";
|
||||
owner = config.users.users.matrix-synapse.name;
|
||||
group = config.users.users.matrix-synapse.group;
|
||||
};
|
||||
|
||||
sops.secrets."matrix/sliding-sync/env" = {
|
||||
sopsFile = ../../../../secrets/bicep/matrix.yaml;
|
||||
key = "sliding-sync/env";
|
||||
};
|
||||
|
||||
services.matrix-synapse-next = {
|
||||
enable = true;
|
||||
|
||||
@ -38,6 +43,8 @@ in {
|
||||
workers.eventPersisters = 2;
|
||||
workers.useUserDirectoryWorker = true;
|
||||
|
||||
enableSlidingSync = true;
|
||||
|
||||
enableNginx = true;
|
||||
|
||||
settings = {
|
||||
@ -130,6 +137,9 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
services.matrix-synapse.sliding-sync.environmentFile = config.sops.secrets."matrix/sliding-sync/env".path;
|
||||
|
||||
|
||||
services.redis.servers."".enable = true;
|
||||
|
||||
services.nginx.virtualHosts."matrix.pvv.ntnu.no" = lib.mkMerge [
|
||||
@ -147,18 +157,6 @@ in {
|
||||
'';
|
||||
};
|
||||
}
|
||||
{
|
||||
locations."/_synapse/admin" = {
|
||||
proxyPass = "http://$synapse_backend";
|
||||
extraConfig = ''
|
||||
allow 127.0.0.1;
|
||||
allow ::1;
|
||||
allow ${values.hosts.bicep.ipv4};
|
||||
allow ${values.hosts.bicep.ipv6};
|
||||
deny all;
|
||||
'';
|
||||
};
|
||||
}
|
||||
{
|
||||
locations = let
|
||||
connectionInfo = w: matrix-lib.workerConnectionResource "metrics" w;
|
||||
@ -172,6 +170,8 @@ in {
|
||||
extraConfig = ''
|
||||
allow ${values.hosts.ildkule.ipv4};
|
||||
allow ${values.hosts.ildkule.ipv6};
|
||||
allow ${values.hosts.ildkule.ipv4_global};
|
||||
allow ${values.hosts.ildkule.ipv6_global};
|
||||
deny all;
|
||||
'';
|
||||
})
|
||||
@ -183,6 +183,8 @@ in {
|
||||
extraConfig = ''
|
||||
allow ${values.hosts.ildkule.ipv4};
|
||||
allow ${values.hosts.ildkule.ipv6};
|
||||
allow ${values.hosts.ildkule.ipv4_global};
|
||||
allow ${values.hosts.ildkule.ipv6_global};
|
||||
deny all;
|
||||
'';
|
||||
};
|
||||
|
@ -1,4 +1,7 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
sslCert = config.security.acme.certs."postgres.pvv.ntnu.no";
|
||||
in
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
@ -76,16 +79,12 @@
|
||||
|
||||
systemd.services.postgresql.serviceConfig = {
|
||||
LoadCredential = [
|
||||
"cert:/etc/certs/postgres.crt"
|
||||
"key:/etc/certs/postgres.key"
|
||||
"cert:${sslCert.directory}/cert.pem"
|
||||
"key:${sslCert.directory}/key.pem"
|
||||
];
|
||||
};
|
||||
|
||||
environment.snakeoil-certs."/etc/certs/postgres" = {
|
||||
owner = "postgres";
|
||||
group = "postgres";
|
||||
subject = "/C=NO/O=Programvareverkstedet/CN=postgres.pvv.ntnu.no/emailAddress=drift@pvv.ntnu.no";
|
||||
};
|
||||
users.groups.acme.members = [ "postgres" ];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 5432 ];
|
||||
networking.firewall.allowedUDPPorts = [ 5432 ];
|
||||
|
46
hosts/bob/configuration.nix
Normal file
46
hosts/bob/configuration.nix
Normal file
@ -0,0 +1,46 @@
|
||||
{ config, pkgs, values, ... }:
|
||||
{
|
||||
imports = [
|
||||
# Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
../../base.nix
|
||||
../../misc/metrics-exporters.nix
|
||||
./disks.nix
|
||||
|
||||
../../misc/builder.nix
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = ../../secrets/bob/bob.yaml;
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sops.age.generateKey = true;
|
||||
|
||||
boot.loader.grub = {
|
||||
enable = true;
|
||||
efiSupport = true;
|
||||
efiInstallAsRemovable = true;
|
||||
};
|
||||
|
||||
networking.hostName = "bob"; # Define your hostname.
|
||||
|
||||
systemd.network.networks."30-all" = values.defaultNetworkConfig // {
|
||||
matchConfig.Name = "en*";
|
||||
DHCP = "yes";
|
||||
gateway = [ ];
|
||||
};
|
||||
|
||||
# List packages installed in system profile
|
||||
environment.systemPackages = with pkgs; [
|
||||
];
|
||||
|
||||
# List services that you want to enable:
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "23.05"; # Did you read the comment?
|
||||
|
||||
}
|
39
hosts/bob/disks.nix
Normal file
39
hosts/bob/disks.nix
Normal file
@ -0,0 +1,39 @@
|
||||
# Example to create a bios compatible gpt partition
|
||||
{ lib, ... }:
|
||||
{
|
||||
disko.devices = {
|
||||
disk.disk1 = {
|
||||
device = lib.mkDefault "/dev/sda";
|
||||
type = "disk";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
name = "boot";
|
||||
size = "1M";
|
||||
type = "EF02";
|
||||
};
|
||||
esp = {
|
||||
name = "ESP";
|
||||
size = "500M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
name = "root";
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -8,32 +8,17 @@
|
||||
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_blk" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/d421538f-a260-44ae-8e03-47cac369dcc1";
|
||||
fsType = "btrfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/86CD-4C23";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0077" "dmask=0077" ];
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/4cfbb41e-801f-40dd-8c58-0a0c1a6025f6"; }
|
||||
];
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
# still possible to use this option, but it's recommended to use it in conjunction
|
||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.ens18.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.ens3.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
{ config, fp, pkgs, values, ... }:
|
||||
{ config, pkgs, values, ... }:
|
||||
{
|
||||
imports = [
|
||||
# Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
(fp /base)
|
||||
(fp /misc/metrics-exporters.nix)
|
||||
../../base.nix
|
||||
../../misc/metrics-exporters.nix
|
||||
|
||||
./services/grzegorz.nix
|
||||
];
|
||||
|
@ -1,6 +1,6 @@
|
||||
{ config, fp, ... }:
|
||||
{ config, ... }:
|
||||
{
|
||||
imports = [ (fp /modules/grzegorz.nix) ];
|
||||
imports = [ ../../../modules/grzegorz.nix ];
|
||||
|
||||
services.nginx.virtualHosts."${config.networking.fqdn}" = {
|
||||
serverAliases = [
|
||||
|
38
hosts/buskerud/configuration.nix
Normal file
38
hosts/buskerud/configuration.nix
Normal file
@ -0,0 +1,38 @@
|
||||
{ config, pkgs, values, ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../base.nix
|
||||
../../misc/metrics-exporters.nix
|
||||
|
||||
./services/libvirt.nix
|
||||
];
|
||||
|
||||
# buskerud does not support efi?
|
||||
# boot.loader.systemd-boot.enable = true;
|
||||
# boot.loader.efi.canTouchEfiVariables = true;
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.device = "/dev/sdb";
|
||||
|
||||
networking.hostName = "buskerud";
|
||||
networking.search = [ "pvv.ntnu.no" "pvv.org" ];
|
||||
networking.nameservers = [ "129.241.0.200" "129.241.0.201" ];
|
||||
networking.tempAddresses = "disabled";
|
||||
|
||||
systemd.network.networks."enp3s0f0" = values.defaultNetworkConfig // {
|
||||
matchConfig.Name = "enp3s0f0";
|
||||
address = with values.hosts.buskerud; [ (ipv4 + "/25") (ipv6 + "/64") ];
|
||||
};
|
||||
|
||||
# List packages installed in system profile
|
||||
environment.systemPackages = with pkgs; [
|
||||
];
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "23.05"; # Did you read the comment?
|
||||
}
|
37
hosts/buskerud/hardware-configuration.nix
Normal file
37
hosts/buskerud/hardware-configuration.nix
Normal file
@ -0,0 +1,37 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ata_piix" "hpsa" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/ed9654fe-575a-4fb3-b6ff-1b059479acff";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
# still possible to use this option, but it's recommended to use it in conjunction
|
||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp14s0f0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp14s0f1.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp3s0f0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp3s0f1.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp4s0f0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp4s0f1.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
10
hosts/buskerud/services/libvirt.nix
Normal file
10
hosts/buskerud/services/libvirt.nix
Normal file
@ -0,0 +1,10 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
virtualisation.libvirtd.enable = true;
|
||||
programs.dconf.enable = true;
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
|
||||
# On a gui-enabled machine, connect with:
|
||||
# $ virt-manager --connect "qemu+ssh://buskerud/system?socket=/var/run/libvirt/libvirt-sock"
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
{ config, fp, pkgs, values, ... }:
|
||||
{ config, pkgs, values, ... }:
|
||||
{
|
||||
imports = [
|
||||
# Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
(fp /base)
|
||||
(fp /misc/metrics-exporters.nix)
|
||||
../../base.nix
|
||||
../../misc/metrics-exporters.nix
|
||||
|
||||
(fp /modules/grzegorz.nix)
|
||||
../../modules/grzegorz.nix
|
||||
];
|
||||
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
@ -25,26 +25,6 @@
|
||||
|
||||
# List services that you want to enable:
|
||||
|
||||
|
||||
|
||||
services.spotifyd = {
|
||||
enable = true;
|
||||
settings.global = {
|
||||
device_name = "georg";
|
||||
use_mpris = false;
|
||||
#dbus_type = "system";
|
||||
#zeroconf_port = 1234;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
# config.services.spotifyd.settings.zeroconf_port
|
||||
5353 # spotifyd is its own mDNS service wtf
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
|
@ -1,16 +1,16 @@
|
||||
{ config, fp, pkgs, lib, values, ... }:
|
||||
{ config, pkgs, values, ... }:
|
||||
{
|
||||
imports = [
|
||||
# Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
(fp /base)
|
||||
(fp /misc/metrics-exporters.nix)
|
||||
../../base.nix
|
||||
../../misc/metrics-exporters.nix
|
||||
|
||||
./services/monitoring
|
||||
./services/nginx
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = fp /secrets/ildkule/ildkule.yaml;
|
||||
sops.defaultSopsFile = ../../secrets/ildkule/ildkule.yaml;
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sops.age.generateKey = true;
|
||||
@ -19,37 +19,33 @@
|
||||
boot.tmp.cleanOnBoot = true;
|
||||
zramSwap.enable = true;
|
||||
|
||||
# Openstack Neutron and systemd-networkd are not best friends, use something else:
|
||||
systemd.network.enable = lib.mkForce false;
|
||||
networking = let
|
||||
hostConf = values.hosts.ildkule;
|
||||
in {
|
||||
hostName = "ildkule";
|
||||
tempAddresses = "disabled";
|
||||
useDHCP = lib.mkForce true;
|
||||
networking.hostName = "ildkule"; # Define your hostname.
|
||||
|
||||
search = values.defaultNetworkConfig.domains;
|
||||
nameservers = values.defaultNetworkConfig.dns;
|
||||
defaultGateway.address = hostConf.ipv4_internal_gw;
|
||||
# Main connection, using the global/floatig IP, for communications with the world
|
||||
systemd.network.networks."30-ntnu-global" = values.openstackGlobalNetworkConfig // {
|
||||
matchConfig.Name = "ens4";
|
||||
|
||||
interfaces."ens4" = {
|
||||
ipv4.addresses = [
|
||||
{ address = hostConf.ipv4; prefixLength = 32; }
|
||||
{ address = hostConf.ipv4_internal; prefixLength = 24; }
|
||||
];
|
||||
ipv6.addresses = [
|
||||
{ address = hostConf.ipv6; prefixLength = 64; }
|
||||
];
|
||||
};
|
||||
# Add the global addresses in addition to the local address learned from DHCP
|
||||
addresses = [
|
||||
{ addressConfig.Address = "${values.hosts.ildkule.ipv4_global}/32"; }
|
||||
{ addressConfig.Address = "${values.hosts.ildkule.ipv6_global}/128"; }
|
||||
];
|
||||
};
|
||||
|
||||
# Secondary connection only for use within the university network
|
||||
systemd.network.networks."40-ntnu-internal" = values.openstackLocalNetworkConfig // {
|
||||
matchConfig.Name = "ens3";
|
||||
# Add the ntnu-internal addresses in addition to the local address learned from DHCP
|
||||
addresses = [
|
||||
{ addressConfig.Address = "${values.hosts.ildkule.ipv4}/32"; }
|
||||
{ addressConfig.Address = "${values.hosts.ildkule.ipv6}/128"; }
|
||||
];
|
||||
};
|
||||
|
||||
# List packages installed in system profile
|
||||
environment.systemPackages = with pkgs; [
|
||||
];
|
||||
|
||||
# No devices with SMART
|
||||
services.smartd.enable = false;
|
||||
|
||||
system.stateVersion = "23.11"; # Did you read the comment?
|
||||
|
||||
}
|
||||
|
@ -3,14 +3,7 @@
|
||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
|
||||
boot.initrd.kernelModules = [ "nvme" ];
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/e35eb4ce-aac3-4f91-8383-6e7cd8bbf942";
|
||||
fsType = "ext4";
|
||||
};
|
||||
fileSystems."/data" = {
|
||||
device = "/dev/disk/by-uuid/0a4c1234-02d3-4b53-aeca-d95c4c8d534b";
|
||||
fsType = "ext4";
|
||||
};
|
||||
fileSystems."/" = { device = "/dev/vda1"; fsType = "ext4"; };
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -56,12 +56,13 @@ in {
|
||||
url = "https://raw.githubusercontent.com/matrix-org/synapse/develop/contrib/grafana/synapse.json";
|
||||
options.path = dashboards/synapse.json;
|
||||
}
|
||||
{
|
||||
name = "MySQL";
|
||||
type = "file";
|
||||
url = "https://raw.githubusercontent.com/prometheus/mysqld_exporter/main/mysqld-mixin/dashboards/mysql-overview.json";
|
||||
options.path = dashboards/mysql.json;
|
||||
}
|
||||
# TODO: enable once https://github.com/NixOS/nixpkgs/pull/242365 gets merged
|
||||
# {
|
||||
# name = "MySQL";
|
||||
# type = "file";
|
||||
# url = "https://raw.githubusercontent.com/prometheus/mysqld_exporter/main/mysqld-mixin/dashboards/mysql-overview.json";
|
||||
# options.path = dashboards/mysql.json;
|
||||
# }
|
||||
{
|
||||
name = "Postgresql";
|
||||
type = "file";
|
||||
@ -74,12 +75,6 @@ in {
|
||||
url = "https://grafana.com/api/dashboards/240/revisions/3/download";
|
||||
options.path = dashboards/go-processes.json;
|
||||
}
|
||||
{
|
||||
name = "Gitea Dashboard";
|
||||
type = "file";
|
||||
url = "https://grafana.com/api/dashboards/17802/revisions/3/download";
|
||||
options.path = dashboards/gitea-dashboard.json;
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
let
|
||||
cfg = config.services.loki;
|
||||
stateDir = "/data/monitoring/loki";
|
||||
in {
|
||||
services.loki = {
|
||||
enable = true;
|
||||
@ -17,7 +16,7 @@ in {
|
||||
ingester = {
|
||||
wal = {
|
||||
enabled = true;
|
||||
dir = "${stateDir}/wal";
|
||||
dir = "/var/lib/loki/wal";
|
||||
};
|
||||
lifecycler = {
|
||||
address = "127.0.0.1";
|
||||
@ -49,12 +48,12 @@ in {
|
||||
|
||||
storage_config = {
|
||||
boltdb_shipper = {
|
||||
active_index_directory = "${stateDir}/boltdb-shipper-index";
|
||||
cache_location = "${stateDir}/boltdb-shipper-cache";
|
||||
active_index_directory = "/var/lib/loki/boltdb-shipper-index";
|
||||
cache_location = "/var/lib/loki/boltdb-shipper-cache";
|
||||
cache_ttl = "24h";
|
||||
};
|
||||
filesystem = {
|
||||
directory = "${stateDir}/chunks";
|
||||
directory = "/var/lib/loki/chunks";
|
||||
};
|
||||
};
|
||||
|
||||
@ -65,14 +64,14 @@ in {
|
||||
};
|
||||
|
||||
compactor = {
|
||||
working_directory = "${stateDir}/compactor";
|
||||
working_directory = "/var/lib/loki/compactor";
|
||||
};
|
||||
|
||||
# ruler = {
|
||||
# storage = {
|
||||
# type = "local";
|
||||
# local = {
|
||||
# directory = "${stateDir}/rules";
|
||||
# directory = "/var/lib/loki/rules";
|
||||
# };
|
||||
# };
|
||||
# rule_path = "/etc/loki/rules";
|
||||
|
@ -1,25 +1,18 @@
|
||||
{ config, ... }: let
|
||||
stateDir = "/data/monitoring/prometheus";
|
||||
in {
|
||||
{ config, ... }: {
|
||||
imports = [
|
||||
./gitea.nix
|
||||
./gogs.nix
|
||||
./matrix-synapse.nix
|
||||
./mysqld.nix
|
||||
# TODO: enable once https://github.com/NixOS/nixpkgs/pull/242365 gets merged
|
||||
# ./mysqld.nix
|
||||
./node.nix
|
||||
./postgres.nix
|
||||
./machines.nix
|
||||
];
|
||||
|
||||
services.prometheus = {
|
||||
enable = true;
|
||||
|
||||
listenAddress = "127.0.0.1";
|
||||
port = 9001;
|
||||
|
||||
ruleFiles = [ rules/synapse-v2.rules ];
|
||||
};
|
||||
|
||||
fileSystems."/var/lib/prometheus2" = {
|
||||
device = stateDir;
|
||||
options = [ "bind" ];
|
||||
};
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.prometheus.scrapeConfigs = [{
|
||||
job_name = "gitea";
|
||||
scrape_interval = "60s";
|
||||
scheme = "https";
|
||||
|
||||
static_configs = [
|
||||
{
|
||||
targets = [
|
||||
"git.pvv.ntnu.no:443"
|
||||
];
|
||||
}
|
||||
];
|
||||
}];
|
||||
}
|
16
hosts/ildkule/services/monitoring/prometheus/gogs.nix
Normal file
16
hosts/ildkule/services/monitoring/prometheus/gogs.nix
Normal file
@ -0,0 +1,16 @@
|
||||
{ config, ... }: let
|
||||
cfg = config.services.prometheus;
|
||||
in {
|
||||
services.prometheus.scrapeConfigs = [{
|
||||
job_name = "git-gogs";
|
||||
scheme = "https";
|
||||
metrics_path = "/-/metrics";
|
||||
static_configs = [
|
||||
{
|
||||
targets = [
|
||||
"essendrop.pvv.ntnu.no:443"
|
||||
];
|
||||
}
|
||||
];
|
||||
}];
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
{ config, ... }: let
|
||||
cfg = config.services.prometheus;
|
||||
in {
|
||||
services.prometheus.scrapeConfigs = [{
|
||||
job_name = "base_info";
|
||||
static_configs = [
|
||||
{ labels.hostname = "ildkule";
|
||||
targets = [
|
||||
"ildkule.pvv.ntnu.no:${toString cfg.exporters.node.port}"
|
||||
"ildkule.pvv.ntnu.no:${toString cfg.exporters.systemd.port}"
|
||||
];
|
||||
}
|
||||
{ labels.hostname = "bekkalokk";
|
||||
targets = [
|
||||
"bekkalokk.pvv.ntnu.no:9100"
|
||||
"bekkalokk.pvv.ntnu.no:9101"
|
||||
];
|
||||
}
|
||||
{ labels.hostname = "kommode";
|
||||
targets = [
|
||||
"kommode.pvv.ntnu.no:9100"
|
||||
"kommode.pvv.ntnu.no:9101"
|
||||
];
|
||||
}
|
||||
{ labels.hostname = "bicep";
|
||||
targets = [
|
||||
"bicep.pvv.ntnu.no:9100"
|
||||
"bicep.pvv.ntnu.no:9101"
|
||||
];
|
||||
}
|
||||
{ labels.hostname = "brzeczyszczykiewicz";
|
||||
targets = [
|
||||
"brzeczyszczykiewicz.pvv.ntnu.no:9100"
|
||||
"brzeczyszczykiewicz.pvv.ntnu.no:9101"
|
||||
];
|
||||
}
|
||||
{ labels.hostname = "georg";
|
||||
targets = [
|
||||
"georg.pvv.ntnu.no:9100"
|
||||
"georg.pvv.ntnu.no:9101"
|
||||
];
|
||||
}
|
||||
{ labels.hostname = "ustetind";
|
||||
targets = [
|
||||
"ustetind.pvv.ntnu.no:9100"
|
||||
"ustetind.pvv.ntnu.no:9101"
|
||||
];
|
||||
}
|
||||
{ labels.hostname = "hildring";
|
||||
targets = [
|
||||
"hildring.pvv.ntnu.no:9100"
|
||||
];
|
||||
}
|
||||
{ labels.hostname = "isvegg";
|
||||
targets = [
|
||||
"isvegg.pvv.ntnu.no:9100"
|
||||
];
|
||||
}
|
||||
{ labels.hostname = "microbel";
|
||||
targets = [
|
||||
"microbel.pvv.ntnu.no:9100"
|
||||
];
|
||||
}
|
||||
];
|
||||
}];
|
||||
}
|
@ -1,22 +1,7 @@
|
||||
{ config, ... }: let
|
||||
cfg = config.services.prometheus;
|
||||
in {
|
||||
sops = {
|
||||
secrets."config/mysqld_exporter_password" = { };
|
||||
|
||||
templates."mysqld_exporter.conf" = {
|
||||
restartUnits = [ "prometheus-mysqld-exporter.service" ];
|
||||
content = let
|
||||
inherit (config.sops) placeholder;
|
||||
in ''
|
||||
[client]
|
||||
host = bicep.pvv.ntnu.no
|
||||
port = 3306
|
||||
user = prometheus_mysqld_exporter
|
||||
password = ${placeholder."config/mysqld_exporter_password"}
|
||||
'';
|
||||
};
|
||||
};
|
||||
sops.secrets."config/mysqld_exporter" = { };
|
||||
|
||||
services.prometheus = {
|
||||
scrapeConfigs = [{
|
||||
@ -34,7 +19,7 @@ in {
|
||||
|
||||
exporters.mysqld = {
|
||||
enable = true;
|
||||
configFile = config.sops.templates."mysqld_exporter.conf".path;
|
||||
configFilePath = config.sops.secrets."config/mysqld_exporter".path;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
22
hosts/ildkule/services/monitoring/prometheus/node.nix
Normal file
22
hosts/ildkule/services/monitoring/prometheus/node.nix
Normal file
@ -0,0 +1,22 @@
|
||||
{ config, ... }: let
|
||||
cfg = config.services.prometheus;
|
||||
in {
|
||||
services.prometheus.scrapeConfigs = [{
|
||||
job_name = "node";
|
||||
static_configs = [
|
||||
{
|
||||
targets = [
|
||||
"ildkule.pvv.ntnu.no:${toString cfg.exporters.node.port}"
|
||||
"microbel.pvv.ntnu.no:9100"
|
||||
"isvegg.pvv.ntnu.no:9100"
|
||||
"knakelibrak.pvv.ntnu.no:9100"
|
||||
"hildring.pvv.ntnu.no:9100"
|
||||
"bicep.pvv.ntnu.no:9100"
|
||||
"essendrop.pvv.ntnu.no:9100"
|
||||
"andresbu.pvv.ntnu.no:9100"
|
||||
"bekkalokk.pvv.ntnu.no:9100"
|
||||
];
|
||||
}
|
||||
];
|
||||
}];
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
let
|
||||
cfg = config.services.uptime-kuma;
|
||||
domain = "status.pvv.ntnu.no";
|
||||
stateDir = "/data/monitoring/uptime-kuma";
|
||||
in {
|
||||
services.uptime-kuma = {
|
||||
enable = true;
|
||||
@ -18,9 +17,4 @@ in {
|
||||
kTLS = true;
|
||||
locations."/".proxyPass = "http://${cfg.settings.HOST}:${cfg.settings.PORT}";
|
||||
};
|
||||
|
||||
fileSystems."/var/lib/uptime-kuma" = {
|
||||
device = stateDir;
|
||||
options = [ "bind" ];
|
||||
};
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
{ pkgs, values, fp, ... }:
|
||||
{
|
||||
imports = [
|
||||
# Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
(fp /base)
|
||||
(fp /misc/metrics-exporters.nix)
|
||||
|
||||
./services/gitea
|
||||
./services/nginx.nix
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = fp /secrets/kommode/kommode.yaml;
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sops.age.generateKey = true;
|
||||
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
networking.hostName = "kommode"; # Define your hostname.
|
||||
|
||||
systemd.network.networks."30-ens18" = values.defaultNetworkConfig // {
|
||||
matchConfig.Name = "ens18";
|
||||
address = with values.hosts.kommode; [ (ipv4 + "/25") (ipv6 + "/64") ];
|
||||
};
|
||||
|
||||
services.btrfs.autoScrub.enable = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [];
|
||||
|
||||
system.stateVersion = "24.11";
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
{ config, pkgs, lib, fp, ... }:
|
||||
let
|
||||
cfg = config.services.gitea;
|
||||
in
|
||||
{
|
||||
services.gitea-themes = {
|
||||
monokai = pkgs.gitea-theme-monokai;
|
||||
earl-grey = pkgs.gitea-theme-earl-grey;
|
||||
pitch-black = pkgs.gitea-theme-pitch-black;
|
||||
catppuccin = pkgs.gitea-theme-catppuccin;
|
||||
};
|
||||
|
||||
systemd.services.gitea-customization = lib.mkIf cfg.enable {
|
||||
description = "Install extra customization in gitea's CUSTOM_DIR";
|
||||
wantedBy = [ "gitea.service" ];
|
||||
requiredBy = [ "gitea.service" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
};
|
||||
|
||||
script = let
|
||||
logo-svg = fp /assets/logo_blue_regular.svg;
|
||||
logo-png = fp /assets/logo_blue_regular.png;
|
||||
extraLinks = pkgs.writeText "gitea-extra-links.tmpl" ''
|
||||
<a class="item" href="https://www.pvv.ntnu.no/">PVV</a>
|
||||
<a class="item" href="https://wiki.pvv.ntnu.no/">Wiki</a>
|
||||
<a class="item" href="https://git.pvv.ntnu.no/Drift/-/projects/4">Tokyo Drift Issues</a>
|
||||
'';
|
||||
|
||||
project-labels = (pkgs.formats.yaml { }).generate "gitea-project-labels.yaml" {
|
||||
labels = lib.importJSON ./labels/projects.json;
|
||||
};
|
||||
|
||||
customTemplates = pkgs.runCommandLocal "gitea-templates" {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
coreutils
|
||||
gnused
|
||||
];
|
||||
} ''
|
||||
# Bigger icons
|
||||
install -Dm444 "${cfg.package.src}/templates/repo/icon.tmpl" "$out/repo/icon.tmpl"
|
||||
sed -i -e 's/24/48/g' "$out/repo/icon.tmpl"
|
||||
'';
|
||||
in ''
|
||||
install -Dm444 ${logo-svg} ${cfg.customDir}/public/assets/img/logo.svg
|
||||
install -Dm444 ${logo-png} ${cfg.customDir}/public/assets/img/logo.png
|
||||
install -Dm444 ${./loading.apng} ${cfg.customDir}/public/assets/img/loading.png
|
||||
install -Dm444 ${extraLinks} ${cfg.customDir}/templates/custom/extra_links.tmpl
|
||||
install -Dm444 ${project-labels} ${cfg.customDir}/options/label/project-labels.yaml
|
||||
|
||||
"${lib.getExe pkgs.rsync}" -a "${customTemplates}/" ${cfg.customDir}/templates/
|
||||
'';
|
||||
};
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
[
|
||||
{
|
||||
"name": "art",
|
||||
"exclusive": false,
|
||||
"color": "#006b75",
|
||||
"description": "Requires some creativity"
|
||||
},
|
||||
{
|
||||
"name": "big",
|
||||
"exclusive": false,
|
||||
"color": "#754bc4",
|
||||
"description": "This is gonna take a while"
|
||||
},
|
||||
{
|
||||
"name": "blocked",
|
||||
"exclusive": false,
|
||||
"color": "#850021",
|
||||
"description": "This issue/PR depends on one or more other issues/PRs"
|
||||
},
|
||||
{
|
||||
"name": "bug",
|
||||
"exclusive": false,
|
||||
"color": "#f05048",
|
||||
"description": "Something brokey"
|
||||
},
|
||||
{
|
||||
"name": "ci-cd",
|
||||
"exclusive": false,
|
||||
"color": "#d1ff78",
|
||||
"description": "Continuous integrals and continuous derivation"
|
||||
},
|
||||
{
|
||||
"name": "crash report",
|
||||
"exclusive": false,
|
||||
"color": "#ed1111",
|
||||
"description": "Report an oopsie"
|
||||
},
|
||||
{
|
||||
"name": "disputed",
|
||||
"exclusive": false,
|
||||
"color": "#5319e7",
|
||||
"description": "Kranglefanter"
|
||||
},
|
||||
{
|
||||
"name": "documentation",
|
||||
"exclusive": false,
|
||||
"color": "#fbca04",
|
||||
"description": "Documentation changes required"
|
||||
},
|
||||
{
|
||||
"name": "duplicate",
|
||||
"exclusive": false,
|
||||
"color": "#cccccc",
|
||||
"description": "This issue or pull request already exists"
|
||||
},
|
||||
{
|
||||
"name": "feature request",
|
||||
"exclusive": false,
|
||||
"color": "#0052cc",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"name": "good first issue",
|
||||
"exclusive": false,
|
||||
"color": "#009800",
|
||||
"description": "Get your hands dirty with a new project here"
|
||||
},
|
||||
{
|
||||
"name": "me gusta",
|
||||
"exclusive": false,
|
||||
"color": "#30ff36",
|
||||
"description": "( ͡° ͜ʖ ͡°)"
|
||||
},
|
||||
{
|
||||
"name": "packaging",
|
||||
"exclusive": false,
|
||||
"color": "#bf642b",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"name": "question",
|
||||
"exclusive": false,
|
||||
"color": "#cc317c",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"name": "security",
|
||||
"exclusive": false,
|
||||
"color": "#ed1111",
|
||||
"description": "Skommel"
|
||||
},
|
||||
{
|
||||
"name": "techdebt spring cleaning",
|
||||
"exclusive": false,
|
||||
"color": "#8c6217",
|
||||
"description": "The code is smelly 👃"
|
||||
},
|
||||
{
|
||||
"name": "testing",
|
||||
"exclusive": false,
|
||||
"color": "#52b373",
|
||||
"description": "Poke it and see if it explodes"
|
||||
},
|
||||
{
|
||||
"name": "ui/ux",
|
||||
"exclusive": false,
|
||||
"color": "#f28852",
|
||||
"description": "User complaints about ergonomics and economics and whatever"
|
||||
},
|
||||
{
|
||||
"name": "wontfix",
|
||||
"exclusive": false,
|
||||
"color": "#ffffff",
|
||||
"description": "Nei, vil ikke"
|
||||
}
|
||||
]
|
@ -1,38 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
cfg = config.services.gitea;
|
||||
GNUPGHOME = "${config.users.users.gitea.home}/gnupg";
|
||||
in
|
||||
{
|
||||
sops.secrets."gitea/gpg-signing-key" = {
|
||||
owner = cfg.user;
|
||||
inherit (cfg) group;
|
||||
};
|
||||
|
||||
systemd.services.gitea.environment = { inherit GNUPGHOME; };
|
||||
|
||||
systemd.tmpfiles.settings."20-gitea-gnugpg".${GNUPGHOME}.d = {
|
||||
inherit (cfg) user group;
|
||||
mode = "700";
|
||||
};
|
||||
|
||||
systemd.services.gitea-ensure-gnupg-homedir = {
|
||||
description = "Import gpg key for gitea";
|
||||
environment = { inherit GNUPGHOME; };
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = cfg.user;
|
||||
PrivateNetwork = true;
|
||||
};
|
||||
script = ''
|
||||
${lib.getExe pkgs.gnupg} --import ${config.sops.secrets."gitea/gpg-signing-key".path}
|
||||
'';
|
||||
};
|
||||
|
||||
services.gitea.settings."repository.signing" = {
|
||||
SIGNING_KEY = "0549C43374D2253C";
|
||||
SIGNING_NAME = "PVV Git";
|
||||
SIGNING_EMAIL = "gitea@git.pvv.ntnu.no";
|
||||
INITIAL_COMMIT = "always";
|
||||
};
|
||||
}
|
@ -1,199 +0,0 @@
|
||||
import requests
|
||||
import secrets
|
||||
import os
|
||||
|
||||
|
||||
EMAIL_DOMAIN = os.getenv('EMAIL_DOMAIN')
|
||||
if EMAIL_DOMAIN is None:
|
||||
EMAIL_DOMAIN = 'pvv.ntnu.no'
|
||||
|
||||
|
||||
API_TOKEN = os.getenv('API_TOKEN')
|
||||
if API_TOKEN is None:
|
||||
raise Exception('API_TOKEN not set')
|
||||
|
||||
|
||||
GITEA_API_URL = os.getenv('GITEA_API_URL')
|
||||
if GITEA_API_URL is None:
|
||||
GITEA_API_URL = 'https://git.pvv.ntnu.no/api/v1'
|
||||
|
||||
|
||||
def gitea_list_all_users() -> dict[str, dict[str, any]] | None:
|
||||
r = requests.get(
|
||||
GITEA_API_URL + '/admin/users',
|
||||
headers={'Authorization': 'token ' + API_TOKEN}
|
||||
)
|
||||
|
||||
if r.status_code != 200:
|
||||
print('Failed to get users:', r.text)
|
||||
return None
|
||||
|
||||
return {user['login']: user for user in r.json()}
|
||||
|
||||
|
||||
def gitea_create_user(username: str, userdata: dict[str, any]) -> bool:
|
||||
r = requests.post(
|
||||
GITEA_API_URL + '/admin/users',
|
||||
json=userdata,
|
||||
headers={'Authorization': 'token ' + API_TOKEN},
|
||||
)
|
||||
|
||||
if r.status_code != 201:
|
||||
print(f'ERR: Failed to create user {username}:', r.text)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def gitea_edit_user(username: str, userdata: dict[str, any]) -> bool:
|
||||
r = requests.patch(
|
||||
GITEA_API_URL + f'/admin/users/{username}',
|
||||
json=userdata,
|
||||
headers={'Authorization': 'token ' + API_TOKEN},
|
||||
)
|
||||
|
||||
if r.status_code != 200:
|
||||
print(f'ERR: Failed to update user {username}:', r.text)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def gitea_list_teams_for_organization(org: str) -> dict[str, any] | None:
|
||||
r = requests.get(
|
||||
GITEA_API_URL + f'/orgs/{org}/teams',
|
||||
headers={'Authorization': 'token ' + API_TOKEN},
|
||||
)
|
||||
|
||||
if r.status_code != 200:
|
||||
print(f"ERR: Failed to list teams for {org}:", r.text)
|
||||
return None
|
||||
|
||||
return {team['name']: team for team in r.json()}
|
||||
|
||||
|
||||
def gitea_add_user_to_organization_team(username: str, team_id: int) -> bool:
|
||||
r = requests.put(
|
||||
GITEA_API_URL + f'/teams/{team_id}/members/{username}',
|
||||
headers={'Authorization': 'token ' + API_TOKEN},
|
||||
)
|
||||
|
||||
if r.status_code != 204:
|
||||
print(f'ERR: Failed to add user {username} to org team {team_id}:', r.text)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
# If a passwd user has one of the following shells,
|
||||
# it is most likely not a PVV user, but rather a system user.
|
||||
# Users with these shells should thus be ignored.
|
||||
BANNED_SHELLS = [
|
||||
"/usr/bin/nologin",
|
||||
"/usr/sbin/nologin",
|
||||
"/sbin/nologin",
|
||||
"/bin/false",
|
||||
"/bin/msgsh",
|
||||
]
|
||||
|
||||
|
||||
# Reads out a passwd-file line for line, and filters out
|
||||
# real PVV users (as opposed to system users meant for daemons and such)
|
||||
def passwd_file_parser(passwd_path):
|
||||
with open(passwd_path, 'r') as f:
|
||||
for line in f.readlines():
|
||||
uid = int(line.split(':')[2])
|
||||
if uid < 1000:
|
||||
continue
|
||||
|
||||
shell = line.split(':')[-1]
|
||||
if shell in BANNED_SHELLS:
|
||||
continue
|
||||
|
||||
username = line.split(':')[0]
|
||||
name = line.split(':')[4].split(',')[0]
|
||||
yield (username, name)
|
||||
|
||||
|
||||
# This function either creates a new user in gitea
|
||||
# and fills it out with some default information if
|
||||
# it does not exist, or ensures that the default information
|
||||
# is correct if the user already exists. All user information
|
||||
# (including non-default fields) is pulled from gitea and added
|
||||
# to the `existing_users` dict
|
||||
def add_or_patch_gitea_user(
|
||||
username: str,
|
||||
name: str,
|
||||
existing_users: dict[str, dict[str, any]],
|
||||
) -> None:
|
||||
user = {
|
||||
"full_name": name,
|
||||
"username": username,
|
||||
"login_name": username,
|
||||
"source_id": 1, # 1 = SMTP
|
||||
}
|
||||
|
||||
if username not in existing_users:
|
||||
user["password"] = secrets.token_urlsafe(32)
|
||||
user["must_change_password"] = False
|
||||
user["visibility"] = "private"
|
||||
user["email"] = username + '@' + EMAIL_DOMAIN
|
||||
|
||||
if not gitea_create_user(username, user):
|
||||
return
|
||||
|
||||
print('Created user', username)
|
||||
existing_users[username] = user
|
||||
|
||||
else:
|
||||
user["visibility"] = existing_users[username]["visibility"]
|
||||
|
||||
if not gitea_edit_user(username, user):
|
||||
return
|
||||
|
||||
print('Updated user', username)
|
||||
|
||||
|
||||
# This function adds a user to a gitea team (part of organization)
|
||||
# if the user is not already part of said team.
|
||||
def ensure_gitea_user_is_part_of_team(
|
||||
username: str,
|
||||
org: str,
|
||||
team_name: str,
|
||||
) -> None:
|
||||
teams = gitea_list_teams_for_organization(org)
|
||||
|
||||
if teams is None:
|
||||
return
|
||||
|
||||
if team_name not in teams:
|
||||
print(f'ERR: could not find team "{team_name}" in organization "{org}"')
|
||||
|
||||
gitea_add_user_to_organization_team(username, teams[team_name]['id'])
|
||||
|
||||
print(f'User {username} is now part of {org}/{team_name}')
|
||||
|
||||
|
||||
# List of teams that all users should be part of by default
|
||||
COMMON_USER_TEAMS = [
|
||||
("Projects", "Members"),
|
||||
("Grzegorz", "Members"),
|
||||
("Kurs", "Members"),
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
existing_users = gitea_list_all_users()
|
||||
if existing_users is None:
|
||||
exit(1)
|
||||
|
||||
for username, name in passwd_file_parser("/tmp/passwd-import"):
|
||||
print(f"Processing {username}")
|
||||
add_or_patch_gitea_user(username, name, existing_users)
|
||||
for org, team_name in COMMON_USER_TEAMS:
|
||||
ensure_gitea_user_is_part_of_team(username, org, team_name)
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,117 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
organizations = [
|
||||
"Drift"
|
||||
"Projects"
|
||||
"Grzegorz"
|
||||
"Kurs"
|
||||
];
|
||||
|
||||
giteaCfg = config.services.gitea;
|
||||
|
||||
giteaWebSecretProviderScript = pkgs.writers.writePython3 "gitea-web-secret-provider" {
|
||||
libraries = with pkgs.python3Packages; [ requests ];
|
||||
flakeIgnore = [
|
||||
"E501" # Line over 80 chars lol
|
||||
"E201" # "whitespace after {"
|
||||
"E202" # "whitespace after }"
|
||||
"E251" # unexpected spaces around keyword / parameter equals
|
||||
"W391" # Newline at end of file
|
||||
];
|
||||
makeWrapperArgs = [
|
||||
"--prefix PATH : ${(lib.makeBinPath [ pkgs.openssh ])}"
|
||||
];
|
||||
} (builtins.readFile ./gitea-web-secret-provider.py);
|
||||
in
|
||||
{
|
||||
users.groups."gitea-web" = { };
|
||||
users.users."gitea-web" = {
|
||||
group = "gitea-web";
|
||||
isSystemUser = true;
|
||||
shell = pkgs.bash;
|
||||
};
|
||||
|
||||
sops.secrets."gitea/web-secret-provider/token" = {
|
||||
owner = "gitea-web";
|
||||
group = "gitea-web";
|
||||
restartUnits = [
|
||||
"gitea-web-secret-provider@"
|
||||
] ++ (map (org: "gitea-web-secret-provider@${org}") organizations);
|
||||
};
|
||||
|
||||
systemd.slices.system-giteaweb = {
|
||||
description = "Gitea web directories";
|
||||
};
|
||||
|
||||
# https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Specifiers
|
||||
# %i - instance name (after the @)
|
||||
# %d - secrets directory
|
||||
systemd.services."gitea-web-secret-provider@" = {
|
||||
description = "Ensure all repos in %i has an SSH key to push web content";
|
||||
requires = [ "gitea.service" "network.target" ];
|
||||
serviceConfig = {
|
||||
Slice = "system-giteaweb.slice";
|
||||
Type = "oneshot";
|
||||
ExecStart = let
|
||||
args = lib.cli.toGNUCommandLineShell { } {
|
||||
org = "%i";
|
||||
token-path = "%d/token";
|
||||
api-url = "${giteaCfg.settings.server.ROOT_URL}api/v1";
|
||||
key-dir = "/var/lib/gitea-web/keys/%i";
|
||||
authorized-keys-path = "/var/lib/gitea-web/authorized_keys.d/%i";
|
||||
rrsync-script = pkgs.writeShellScript "rrsync-chown" ''
|
||||
mkdir -p "$1"
|
||||
${lib.getExe pkgs.rrsync} -wo "$1"
|
||||
${pkgs.coreutils}/bin/chown -R gitea-web:gitea-web "$1"
|
||||
'';
|
||||
web-dir = "/var/lib/gitea-web/web";
|
||||
};
|
||||
in "${giteaWebSecretProviderScript} ${args}";
|
||||
|
||||
User = "gitea-web";
|
||||
Group = "gitea-web";
|
||||
|
||||
StateDirectory = "gitea-web";
|
||||
StateDirectoryMode = "0750";
|
||||
LoadCredential = [
|
||||
"token:${config.sops.secrets."gitea/web-secret-provider/token".path}"
|
||||
];
|
||||
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectSystem = true;
|
||||
ProtectHome = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
LockPersonality = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.timers."gitea-web-secret-provider@" = {
|
||||
description = "Ensure all repos in %i has an SSH key to push web content";
|
||||
timerConfig = {
|
||||
RandomizedDelaySec = "1h";
|
||||
Persistent = true;
|
||||
Unit = "gitea-web-secret-provider@%i.service";
|
||||
OnCalendar = "daily";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.targets.timers.wants = map (org: "gitea-web-secret-provider@${org}.timer") organizations;
|
||||
|
||||
services.openssh.authorizedKeysFiles = map (org: "/var/lib/gitea-web/authorized_keys.d/${org}") organizations;
|
||||
|
||||
users.users.nginx.extraGroups = [ "gitea-web" ];
|
||||
services.nginx.virtualHosts."pages.pvv.ntnu.no" = {
|
||||
kTLS = true;
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
root = "/var/lib/gitea-web/web";
|
||||
};
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
import argparse
|
||||
import hashlib
|
||||
import os
|
||||
import requests
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Generate SSH keys for Gitea repositories and add them as secrets")
|
||||
parser.add_argument("--org", required=True, type=str, help="The organization to generate keys for")
|
||||
parser.add_argument("--token-path", metavar='PATH', required=True, type=Path, help="Path to a file containing the Gitea API token")
|
||||
parser.add_argument("--api-url", metavar='URL', type=str, help="The URL of the Gitea API", default="https://git.pvv.ntnu.no/api/v1")
|
||||
parser.add_argument("--key-dir", metavar='PATH', type=Path, help="The directory to store the generated keys in", default="/run/gitea-web-secret-provider")
|
||||
parser.add_argument("--authorized-keys-path", metavar='PATH', type=Path, help="The path to the resulting authorized_keys file", default="/etc/ssh/authorized_keys.d/gitea-web-secret-provider")
|
||||
parser.add_argument("--rrsync-script", metavar='PATH', type=Path, help="The path to a rrsync script, taking the destination path as its single argument")
|
||||
parser.add_argument("--web-dir", metavar='PATH', type=Path, help="The directory to sync the repositories to", default="/var/www")
|
||||
parser.add_argument("--force", action="store_true", help="Overwrite existing keys")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def add_secret(args: argparse.Namespace, token: str, repo: str, name: str, secret: str):
|
||||
result = requests.put(
|
||||
f"{args.api_url}/repos/{args.org}/{repo}/actions/secrets/{name}",
|
||||
json = { 'data': secret },
|
||||
headers = { 'Authorization': 'token ' + token },
|
||||
)
|
||||
if result.status_code not in (201, 204):
|
||||
raise Exception(f"Failed to add secret: {result.json()}")
|
||||
|
||||
|
||||
def get_org_repo_list(args: argparse.Namespace, token: str):
|
||||
result = requests.get(
|
||||
f"{args.api_url}/orgs/{args.org}/repos",
|
||||
headers = { 'Authorization': 'token ' + token },
|
||||
)
|
||||
|
||||
results = [repo["name"] for repo in result.json()]
|
||||
target = int(result.headers['X-Total-Count'])
|
||||
|
||||
i = 2
|
||||
while len(results) < target:
|
||||
result = requests.get(
|
||||
f"{args.api_url}/orgs/{args.org}/repos",
|
||||
params = { 'page': i },
|
||||
headers = { 'Authorization': 'token ' + token },
|
||||
)
|
||||
results += [repo["name"] for repo in result.json()]
|
||||
i += 1
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def generate_ssh_key(args: argparse.Namespace, repository: str):
|
||||
keyname = hashlib.sha256(args.org.encode() + repository.encode()).hexdigest()
|
||||
key_path = args.key_dir / keyname
|
||||
if not key_path.is_file() or args.force:
|
||||
subprocess.run(
|
||||
[
|
||||
"ssh-keygen",
|
||||
*("-t", "ed25519"),
|
||||
*("-f", key_path),
|
||||
*("-N", ""),
|
||||
*("-C", f"{args.org}/{repository}"),
|
||||
],
|
||||
check=True,
|
||||
stdin=subprocess.DEVNULL,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
print(f"Generated SSH key for `{args.org}/{repository}`")
|
||||
|
||||
with open(key_path, "r") as f:
|
||||
private_key = f.read()
|
||||
|
||||
pub_key_path = args.key_dir / (keyname + '.pub')
|
||||
with open(pub_key_path, "r") as f:
|
||||
public_key = f.read()
|
||||
|
||||
return private_key, public_key
|
||||
|
||||
|
||||
SSH_OPTS = ",".join([
|
||||
"restrict",
|
||||
"no-agent-forwarding",
|
||||
"no-port-forwarding",
|
||||
"no-pty",
|
||||
"no-X11-forwarding",
|
||||
])
|
||||
|
||||
|
||||
def generate_authorized_keys(args: argparse.Namespace, repo_public_keys: list[tuple[str, str]]):
|
||||
lines = []
|
||||
for repo, public_key in repo_public_keys:
|
||||
command = f"{args.rrsync_script} {args.web_dir}/{args.org}/{repo}"
|
||||
lines.append(f'command="{command}",{SSH_OPTS} {public_key}')
|
||||
|
||||
with open(args.authorized_keys_path, "w") as f:
|
||||
f.writelines(lines)
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
with open(args.token_path, "r") as f:
|
||||
token = f.read().strip()
|
||||
|
||||
os.makedirs(args.key_dir, 0o700, exist_ok=True)
|
||||
os.makedirs(args.authorized_keys_path.parent, 0o700, exist_ok=True)
|
||||
|
||||
repos = get_org_repo_list(args, token)
|
||||
print(f'Found {len(repos)} repositories in `{args.org}`')
|
||||
|
||||
repo_public_keys = []
|
||||
for repo in repos:
|
||||
print(f"Locating key for `{args.org}/{repo}`")
|
||||
private_key, public_key = generate_ssh_key(args, repo)
|
||||
add_secret(args, token, repo, "WEB_SYNC_SSH_KEY", private_key)
|
||||
repo_public_keys.append((repo, public_key))
|
||||
|
||||
generate_authorized_keys(args, repo_public_keys)
|
||||
print(f"Wrote authorized_keys file to `{args.authorized_keys_path}`")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,4 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.nginx.enable = true;
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
{ config, fp, pkgs, values, ... }:
|
||||
{ config, pkgs, values, ... }:
|
||||
{
|
||||
imports = [
|
||||
# Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
(fp /base)
|
||||
(fp /misc/metrics-exporters.nix)
|
||||
../../base.nix
|
||||
../../misc/metrics-exporters.nix
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = fp /secrets/shark/shark.yaml;
|
||||
sops.defaultSopsFile = ../../secrets/shark/shark.yaml;
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sops.age.generateKey = true;
|
||||
|
@ -1,44 +0,0 @@
|
||||
{ config, fp, pkgs, lib, values, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(fp /base)
|
||||
(fp /misc/metrics-exporters.nix)
|
||||
|
||||
./services/gitea-runners.nix
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = fp /secrets/ustetind/ustetind.yaml;
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sops.age.generateKey = true;
|
||||
|
||||
networking.hostName = "ustetind";
|
||||
|
||||
networking.useHostResolvConf = lib.mkForce false;
|
||||
|
||||
systemd.network.networks = {
|
||||
"30-lxc-eth" = values.defaultNetworkConfig // {
|
||||
matchConfig = {
|
||||
Type = "ether";
|
||||
Kind = "veth";
|
||||
Name = [
|
||||
"eth*"
|
||||
];
|
||||
};
|
||||
address = with values.hosts.ustetind; [ (ipv4 + "/25") (ipv6 + "/64") ];
|
||||
};
|
||||
"40-podman-veth" = values.defaultNetworkConfig // {
|
||||
matchConfig = {
|
||||
Type = "ether";
|
||||
Kind = "veth";
|
||||
Name = [
|
||||
"veth*"
|
||||
];
|
||||
};
|
||||
DHCP = "yes";
|
||||
};
|
||||
};
|
||||
|
||||
system.stateVersion = "24.11";
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
{ config, fp, pkgs, values, lib, ... }:
|
||||
{
|
||||
imports = [
|
||||
# Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
(fp /base)
|
||||
(fp /misc/metrics-exporters.nix)
|
||||
|
||||
(fp /misc/builder.nix)
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = fp /secrets/wenche/wenche.yaml;
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sops.age.generateKey = true;
|
||||
|
||||
boot.loader.grub.device = "/dev/sda";
|
||||
|
||||
networking.hostName = "wenche"; # Define your hostname.
|
||||
|
||||
systemd.network.networks."30-ens18" = values.defaultNetworkConfig // {
|
||||
matchConfig.Name = "ens18";
|
||||
address = with values.hosts.wenche; [ (ipv4 + "/25") (ipv6 + "/64") ];
|
||||
};
|
||||
|
||||
hardware.graphics.enable = true;
|
||||
services.xserver.videoDrivers = [ "nvidia" ];
|
||||
hardware.nvidia = {
|
||||
modesetting.enable = true;
|
||||
open = false;
|
||||
package = config.boot.kernelPackages.nvidiaPackages.production;
|
||||
};
|
||||
|
||||
# List packages installed in system profile
|
||||
environment.systemPackages = with pkgs; [
|
||||
];
|
||||
|
||||
system.stateVersion = "24.11"; # Did you read the comment?
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "nvidia" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/4e8ecdd2-d453-4fff-b952-f06da00f3b85";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
swapDevices = [ {
|
||||
device = "/var/lib/swapfile";
|
||||
size = 16*1024;
|
||||
} ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault false;
|
||||
# networking.interfaces.ens18.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
57
justfile
57
justfile
@ -1,56 +1,25 @@
|
||||
set positional-arguments # makes variables accesible as $1 $2 $@
|
||||
export GUM_FILTER_HEIGHT := "15"
|
||||
nom := `if [[ -t 1 ]] && command -v nom >/dev/null; then echo nom; else echo nix; fi`
|
||||
nix_eval_opts := "--log-format raw --option warn-dirty false"
|
||||
nom := `if command -v nom >/dev/null; then echo nom; else echo nix; fi`
|
||||
|
||||
@_default:
|
||||
just "$(gum choose --ordered --header "Pick a recipie..." $(just --summary --unsorted))"
|
||||
|
||||
check *_:
|
||||
nix flake check --keep-going "$@"
|
||||
check:
|
||||
nix flake check --keep-going
|
||||
|
||||
build-machine machine=`just _a_machine` *_:
|
||||
{{nom}} build .#nixosConfigurations.{{ machine }}.config.system.build.toplevel "${@:2}"
|
||||
build-machine machine=`just _a_machine`:
|
||||
{{nom}} build .#nixosConfigurations.{{ machine }}.config.system.build.toplevel
|
||||
|
||||
run-vm machine=`just _a_machine` *_:
|
||||
nixos-rebuild build-vm --flake .#{{ machine }} "${@:2}"
|
||||
run-vm machine=`just _a_machine`:
|
||||
nixos-rebuild build-vm --flake .#{{ machine }}
|
||||
QEMU_NET_OPTS="hostfwd=tcp::8080-:80,hostfwd=tcp::8081-:443,hostfwd=tcp::2222-:22" ./result/bin/run-*-vm
|
||||
|
||||
@update-inputs *_:
|
||||
@git reset flake.lock
|
||||
@git restore flake.lock
|
||||
nix eval {{nix_eval_opts}} --file flake.nix --apply 'x: builtins.attrNames x.inputs' --json \
|
||||
| { printf "%s\n" --commit-lock-file; jq '.[]' -r | grep -vxF "self" ||:; } \
|
||||
| gum choose --no-limit --header "Choose extra arguments:" \
|
||||
| tee >(xargs -d'\n' echo + nix flake update "$@" >&2) \
|
||||
| xargs -d'\n' nix flake update "$@"
|
||||
|
||||
@repl $machine=`just _a_machine` *_:
|
||||
set -v; nixos-rebuild --flake .#"$machine" repl "${@:2}"
|
||||
|
||||
@eval $machine=`just _a_machine` $attrpath="system.build.toplevel.outPath" *_:
|
||||
set -v; nix eval {{nix_eval_opts}} ".#nixosConfigurations.\"$machine\".config.$attrpath" --show-trace "${@:3}"
|
||||
|
||||
@eval-vm $machine=`just _a_machine` $attrpath="system.build.toplevel.outPath" *_:
|
||||
just eval "$machine" "virtualisation.vmVariant.$attrpath" "${@:3}"
|
||||
@update-inputs:
|
||||
nix eval .#inputs --apply builtins.attrNames --json \
|
||||
| jq '.[]' -r \
|
||||
| gum choose --no-limit --height=15 \
|
||||
| xargs nix flake update --commit-lock-file
|
||||
|
||||
|
||||
# helpers
|
||||
|
||||
[no-exit-message]
|
||||
_a_machine:
|
||||
#!/usr/bin/env -S sh -euo pipefail
|
||||
machines="$(
|
||||
nix eval {{nix_eval_opts}} .#nixosConfigurations --apply builtins.attrNames --json | jq .[] -r
|
||||
)"
|
||||
[ -n "$machines" ] || { echo >&2 "ERROR: no machines found"; false; }
|
||||
if [ -s .direnv/vars/last-machine.txt ]; then
|
||||
machines="$(
|
||||
grep <<<"$machines" -xF "$(cat .direnv/vars/last-machine.txt)" ||:
|
||||
grep <<<"$machines" -xFv "$(cat .direnv/vars/last-machine.txt)" ||:
|
||||
)"
|
||||
fi
|
||||
choice="$(gum filter <<<"$machines")"
|
||||
mkdir -p .direnv/vars
|
||||
cat <<<"$choice" >.direnv/vars/last-machine.txt
|
||||
cat <<<"$choice"
|
||||
nix eval .#nixosConfigurations --apply builtins.attrNames --json | jq .[] -r | gum filter
|
||||
|
@ -8,47 +8,34 @@ FgIDAQACHgECF4AACgkQRrkijoFKKqxIlQD9F0EedrFpHAVuaVas9ZWRZb4xv3zM
|
||||
N3g0IDxoN3g0QG5hbmkud3RmPoiTBBMWCgA7AhsBBQsJCAcDBRUKCQgLBRYCAwEA
|
||||
Ah4BAheAFiEE99N4kCKKkHRA4f1IRrkijoFKKqwFAmL7l8ACGQEACgkQRrkijoFK
|
||||
KqxI4wD9EIGpb3Gt5s5e8waH7XaLSlquOrW1RID3sSuzWI4DvikBAMncfBbtkpzH
|
||||
EYU2Ufm8VxzgJDnyeB+lcdeSJXWaIwYLiJAEExYKADgWIQT303iQIoqQdEDh/UhG
|
||||
uSKOgUoqrAUCYuaF5AIbAQULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRBGuSKO
|
||||
gUoqrKWiAQC1yFpodz5PGsZbFgihEA0UQ5jcoXBojoAlVRgmkwm41gEA782rsvyl
|
||||
87ExoluDD3eV/Z5ILp7Ex6JeaE3JUix8Sgi0Jmg3eDQgKGFsdGVybmF0aXZlKSA8
|
||||
aDd4NC5hbHRAbmFuaS53dGY+iJAEExYKADgWIQT303iQIoqQdEDh/UhGuSKOgUoq
|
||||
rAUCYvuPSgIbAQULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRBGuSKOgUoqrK3L
|
||||
AP4h0cjFuNFwMQlg6oVfWvjCvKZO+ePP+SnTNRKvKbAxSgEA/yG48r9im6M0Xr9z
|
||||
DAHcDlbClaONX4X+6rZ6OoU6hw24MwRi5oZHFgkrBgEEAdpHDwEBB0CyZzQZNAiz
|
||||
OmSMNjCBK3rMjzU/b6T1a8GDogQhKfK5VYj1BBgWCgAmFiEE99N4kCKKkHRA4f1I
|
||||
RrkijoFKKqwFAmLmhkcCGwIFCQPCZwAAgQkQRrkijoFKKqx2IAQZFgoAHRYhBPPN
|
||||
qGzFWp8Q16BpgZ8vfYJQ81FGBQJi5oZHAAoJEJ8vfYJQ81FGFZgBALN+Rh4m323T
|
||||
aM5zdJfCTV7V0aP3J0RdKmtKvz/Y9a7uAP4oP8UlbM9ucyG252gZ8IjM0VprNzP9
|
||||
CpNl4GzpD4CRDu55AP9mpAyRoKt3yjYvTaHz1TpsXHLzqfJO6sYBRXH3YXyNTAEA
|
||||
prtmn/S9HltHijnsLs1PEHmRua14XQBdL1HuzFID8ASI9QQYFgoAJgIbAhYhBPfT
|
||||
eJAiipB0QOH9SEa5Io6BSiqsBQJmqp4CBQkFpUs7AIF2IAQZFgoAHRYhBPPNqGzF
|
||||
Wp8Q16BpgZ8vfYJQ81FGBQJi5oZHAAoJEJ8vfYJQ81FGFZgBALN+Rh4m323TaM5z
|
||||
dJfCTV7V0aP3J0RdKmtKvz/Y9a7uAP4oP8UlbM9ucyG252gZ8IjM0VprNzP9CpNl
|
||||
4GzpD4CRDgkQRrkijoFKKqwYoQEAz0D3G/dD6DBYBf7p6pGYqXd2X0Dv8nmnalol
|
||||
Z6SxfUMA/jT/XjPh7c4Ui8nZO7XDzYWrbV/eZwGMd1zXq2mU42MLuQINBGLmhnoB
|
||||
EADa1yBK0NKxVIto3hSh21hooYpWcEXWqMPXHO34rcAhktVFOOHIl2bFGScQAZXt
|
||||
jAcqUmMyC+PMs1DZoocFk+9PJt17hAa/s6CRrw8vK+1fVqhj0XOLtevGV9iC6IRv
|
||||
hPxzTsOaeOssgMGIU8xDmMKT2nGHGNUkqOXGld63E3NKsK3lnl+BCdpJ0f3GEB7a
|
||||
SQ+pk6k1uzODXX/mhAUJmL1MkVZ6jJA3vhsre0Kfa9p+C5mP4hLJ6jF+oESvA4HC
|
||||
+LuCSGm66gIDMC39jnLo6hwYEEjfPXD7CUAN4S2eISSFd+ZclN2vYcrKYgsCZS0h
|
||||
BFOgDhKKCHBuMwP12AIM8y8L64/eOWFpR7s2StAPjjYbZeZECHLWZt1zGVvkS7Xp
|
||||
6lsAg6/T8EysKG7vTl2Qq9W0BmzNgk2ODTZkhv0gqqXppdr8eRiq+h0qMfJptG0G
|
||||
ycOvqb9PoEO2dfNCjjII8VfaSGfSEYo8UwsqYTtfgdoNnFCXKd1r7QmvrdbNsFDR
|
||||
mkv+wWJoipwUaVquyb2KN652jSlpwMECW6fSEsT/5C3mJLgAmi6l6yosw6HdIY6j
|
||||
gpCGtxnHW2zReIS6ezZdtxYBCkEHK70yASyaIHrLLDknw+DuKvXAWOAecob8GNBH
|
||||
OjXZe3LzBt2rVgOCRa+W7milNgjUCsz+R3rM8XfR+wNEGwARAQABiH4EGBYKACYW
|
||||
IQT303iQIoqQdEDh/UhGuSKOgUoqrAUCYuaGegIbDAUJA8JnAAAKCRBGuSKOgUoq
|
||||
rDE0AQDBxRsmW9L60mxGCp1CpNWBXD2T6D605PlNiNCcM+cOCgD/c2OitSSG50M0
|
||||
YRbyh1LPYL6YQePL0dQkYsjm6XVmrAKIfgQYFgoAJgIbDBYhBPfTeJAiipB0QOH9
|
||||
SEa5Io6BSiqsBQJmqp4FBQkFpUsIAAoJEEa5Io6BSiqsydsA/ihBulpSSLg4B9pJ
|
||||
sffqphMht7yT3Dnz57iexUEgj3jBAQDedI+gwpZlMjV6IdH/Epz244j82Ta04cqk
|
||||
SOz2Y63LBrgzBGLmhsUWCSsGAQQB2kcPAQEHQFg/avgj0sZbxqL58tZEpcaieeL1
|
||||
OWOoVU3mZX/K7GU+iH4EGBYKACYWIQT303iQIoqQdEDh/UhGuSKOgUoqrAUCYuaG
|
||||
xQIbIAUJA8JnAAAKCRBGuSKOgUoqrN5jAP96aO0MEPQSIKdLaa9+ilpPp+glJ9du
|
||||
IJ7zdR0U15tONAEA0WqeRc8Jhv10UjIz/Q3UlcfvKPzVW6yVKo+Lg1FI2QSIfgQY
|
||||
FgoAJgIbIBYhBPfTeJAiipB0QOH9SEa5Io6BSiqsBQJmqp4GBQkFpUq9AAoJEEa5
|
||||
Io6BSiqsjF0BAJn0EBEJfszskYiZzMshFHW5k0QUF+Ak3JNh2UG+M6FJAQCQVY/l
|
||||
DkrvOytuFnKbkDrCaTrtLh/JAmBXpSERIejmDw==
|
||||
=7cFp
|
||||
EYU2Ufm8VxzgJDnyeB+lcdeSJXWaIwYLtCZoN3g0IChhbHRlcm5hdGl2ZSkgPGg3
|
||||
eDQuYWx0QG5hbmkud3RmPoiQBBMWCgA4FiEE99N4kCKKkHRA4f1IRrkijoFKKqwF
|
||||
AmL7j0oCGwEFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQRrkijoFKKqytywD+
|
||||
IdHIxbjRcDEJYOqFX1r4wrymTvnjz/kp0zUSrymwMUoBAP8huPK/YpujNF6/cwwB
|
||||
3A5WwpWjjV+F/uq2ejqFOocNuDMEYuaGRxYJKwYBBAHaRw8BAQdAsmc0GTQIszpk
|
||||
jDYwgSt6zI81P2+k9WvBg6IEISnyuVWI9QQYFgoAJhYhBPfTeJAiipB0QOH9SEa5
|
||||
Io6BSiqsBQJi5oZHAhsCBQkDwmcAAIEJEEa5Io6BSiqsdiAEGRYKAB0WIQTzzahs
|
||||
xVqfENegaYGfL32CUPNRRgUCYuaGRwAKCRCfL32CUPNRRhWYAQCzfkYeJt9t02jO
|
||||
c3SXwk1e1dGj9ydEXSprSr8/2PWu7gD+KD/FJWzPbnMhtudoGfCIzNFaazcz/QqT
|
||||
ZeBs6Q+AkQ7ueQD/ZqQMkaCrd8o2L02h89U6bFxy86nyTurGAUVx92F8jUwBAKa7
|
||||
Zp/0vR5bR4o57C7NTxB5kbmteF0AXS9R7sxSA/AEuQINBGLmhnoBEADa1yBK0NKx
|
||||
VIto3hSh21hooYpWcEXWqMPXHO34rcAhktVFOOHIl2bFGScQAZXtjAcqUmMyC+PM
|
||||
s1DZoocFk+9PJt17hAa/s6CRrw8vK+1fVqhj0XOLtevGV9iC6IRvhPxzTsOaeOss
|
||||
gMGIU8xDmMKT2nGHGNUkqOXGld63E3NKsK3lnl+BCdpJ0f3GEB7aSQ+pk6k1uzOD
|
||||
XX/mhAUJmL1MkVZ6jJA3vhsre0Kfa9p+C5mP4hLJ6jF+oESvA4HC+LuCSGm66gID
|
||||
MC39jnLo6hwYEEjfPXD7CUAN4S2eISSFd+ZclN2vYcrKYgsCZS0hBFOgDhKKCHBu
|
||||
MwP12AIM8y8L64/eOWFpR7s2StAPjjYbZeZECHLWZt1zGVvkS7Xp6lsAg6/T8Eys
|
||||
KG7vTl2Qq9W0BmzNgk2ODTZkhv0gqqXppdr8eRiq+h0qMfJptG0GycOvqb9PoEO2
|
||||
dfNCjjII8VfaSGfSEYo8UwsqYTtfgdoNnFCXKd1r7QmvrdbNsFDRmkv+wWJoipwU
|
||||
aVquyb2KN652jSlpwMECW6fSEsT/5C3mJLgAmi6l6yosw6HdIY6jgpCGtxnHW2zR
|
||||
eIS6ezZdtxYBCkEHK70yASyaIHrLLDknw+DuKvXAWOAecob8GNBHOjXZe3LzBt2r
|
||||
VgOCRa+W7milNgjUCsz+R3rM8XfR+wNEGwARAQABiH4EGBYKACYWIQT303iQIoqQ
|
||||
dEDh/UhGuSKOgUoqrAUCYuaGegIbDAUJA8JnAAAKCRBGuSKOgUoqrDE0AQDBxRsm
|
||||
W9L60mxGCp1CpNWBXD2T6D605PlNiNCcM+cOCgD/c2OitSSG50M0YRbyh1LPYL6Y
|
||||
QePL0dQkYsjm6XVmrAK4MwRi5obFFgkrBgEEAdpHDwEBB0BYP2r4I9LGW8ai+fLW
|
||||
RKXGonni9TljqFVN5mV/yuxlPoh+BBgWCgAmFiEE99N4kCKKkHRA4f1IRrkijoFK
|
||||
KqwFAmLmhsUCGyAFCQPCZwAACgkQRrkijoFKKqzeYwD/emjtDBD0EiCnS2mvfopa
|
||||
T6foJSfXbiCe83UdFNebTjQBANFqnkXPCYb9dFIyM/0N1JXH7yj81VuslSqPi4NR
|
||||
SNkE
|
||||
=oTMO
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
@ -2,10 +2,4 @@
|
||||
|
||||
{
|
||||
nix.settings.trusted-users = [ "@nix-builder-users" ];
|
||||
nix.daemonCPUSchedPolicy = "batch";
|
||||
|
||||
boot.binfmt.emulatedSystems = [
|
||||
"aarch64-linux"
|
||||
"armv7l-linux"
|
||||
];
|
||||
}
|
||||
|
@ -14,31 +14,13 @@
|
||||
"::1"
|
||||
values.hosts.ildkule.ipv4
|
||||
values.hosts.ildkule.ipv6
|
||||
values.hosts.ildkule.ipv4_global
|
||||
values.hosts.ildkule.ipv6_global
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
services.prometheus.exporters.systemd = {
|
||||
enable = true;
|
||||
port = 9101;
|
||||
extraFlags = [
|
||||
"--systemd.collector.enable-restart-count"
|
||||
"--systemd.collector.enable-ip-accounting"
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services.prometheus-systemd-exporter.serviceConfig = {
|
||||
IPAddressDeny = "any";
|
||||
IPAddressAllow = [
|
||||
"127.0.0.1"
|
||||
"::1"
|
||||
values.hosts.ildkule.ipv4
|
||||
values.hosts.ildkule.ipv6
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 9100 9101 ];
|
||||
networking.firewall.allowedTCPPorts = [ 9100 ];
|
||||
|
||||
services.promtail = {
|
||||
enable = true;
|
||||
|
@ -1,310 +0,0 @@
|
||||
{ config, pkgs, lib, utils, ... }:
|
||||
let
|
||||
cfg = config.services.gickup;
|
||||
format = pkgs.formats.yaml { };
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./set-description.nix
|
||||
./hardlink-files.nix
|
||||
./import-from-toml.nix
|
||||
./update-linktree.nix
|
||||
];
|
||||
|
||||
options.services.gickup = {
|
||||
enable = lib.mkEnableOption "gickup, a git repository mirroring service";
|
||||
|
||||
package = lib.mkPackageOption pkgs "gickup" { };
|
||||
gitPackage = lib.mkPackageOption pkgs "git" { };
|
||||
gitLfsPackage = lib.mkPackageOption pkgs "git-lfs" { };
|
||||
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = "The directory to mirror repositories to.";
|
||||
default = "/var/lib/gickup";
|
||||
example = "/data/gickup";
|
||||
};
|
||||
|
||||
destinationSettings = lib.mkOption {
|
||||
description = ''
|
||||
Settings for destination local, see gickup configuration file
|
||||
|
||||
Note that `path` will be set automatically to `/var/lib/gickup`
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
};
|
||||
default = { };
|
||||
example = {
|
||||
structured = true;
|
||||
zip = false;
|
||||
keep = 10;
|
||||
bare = true;
|
||||
lfs = true;
|
||||
};
|
||||
};
|
||||
|
||||
instances = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule (submoduleInputs@{ name, ... }: let
|
||||
submoduleName = name;
|
||||
|
||||
nameParts = rec {
|
||||
repoType = builtins.head (lib.splitString ":" submoduleName);
|
||||
|
||||
owner = if repoType == "any"
|
||||
then null
|
||||
else lib.pipe submoduleName [
|
||||
(lib.removePrefix "${repoType}:")
|
||||
(lib.splitString "/")
|
||||
builtins.head
|
||||
];
|
||||
|
||||
repo = if repoType == "any"
|
||||
then null
|
||||
else lib.pipe submoduleName [
|
||||
(lib.removePrefix "${repoType}:")
|
||||
(lib.splitString "/")
|
||||
lib.last
|
||||
];
|
||||
|
||||
slug = if repoType == "any"
|
||||
then lib.toLower (builtins.replaceStrings [ ":" "/" ] [ "-" "-" ] submoduleName)
|
||||
else "${lib.toLower repoType}-${lib.toLower owner}-${lib.toLower repo}";
|
||||
};
|
||||
in {
|
||||
options = {
|
||||
interval = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "daily";
|
||||
example = "weekly";
|
||||
description = ''
|
||||
Specification (in the format described by {manpage}`systemd.time(7)`) of the time
|
||||
interval at which to run the service.
|
||||
'';
|
||||
};
|
||||
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"github"
|
||||
"gitlab"
|
||||
"gitea"
|
||||
"gogs"
|
||||
"bitbucket"
|
||||
"onedev"
|
||||
"sourcehut"
|
||||
"any"
|
||||
];
|
||||
example = "github";
|
||||
default = nameParts.repoType;
|
||||
description = ''
|
||||
The type of the repository to mirror.
|
||||
'';
|
||||
};
|
||||
|
||||
owner = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
example = "go-gitea";
|
||||
default = nameParts.owner;
|
||||
description = ''
|
||||
The owner of the repository to mirror (if applicable)
|
||||
'';
|
||||
};
|
||||
|
||||
repo = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
example = "gitea";
|
||||
default = nameParts.repo;
|
||||
description = ''
|
||||
The name of the repository to mirror (if applicable)
|
||||
'';
|
||||
};
|
||||
|
||||
slug = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = nameParts.slug;
|
||||
example = "github-go-gitea-gitea";
|
||||
description = ''
|
||||
The slug of the repository to mirror.
|
||||
'';
|
||||
};
|
||||
|
||||
description = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
example = "A project which does this and that";
|
||||
description = ''
|
||||
A description of the project. This isn't used directly by gickup for anything,
|
||||
but can be useful if gickup is used together with cgit or similar.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
description = "Instance specific settings, see gickup configuration file";
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
};
|
||||
default = { };
|
||||
example = {
|
||||
username = "gickup";
|
||||
password = "hunter2";
|
||||
wiki = true;
|
||||
issues = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.users.gickup = {
|
||||
isSystemUser = true;
|
||||
group = "gickup";
|
||||
home = "/var/lib/gickup";
|
||||
};
|
||||
|
||||
users.groups.gickup = { };
|
||||
|
||||
services.gickup.destinationSettings.path = "/var/lib/gickup/raw";
|
||||
|
||||
systemd.tmpfiles.settings."10-gickup" = lib.mkIf (cfg.dataDir != "/var/lib/gickup") {
|
||||
${cfg.dataDir}.d = {
|
||||
user = "gickup";
|
||||
group = "gickup";
|
||||
mode = "0755";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.slices."system-gickup" = {
|
||||
description = "Gickup git repository mirroring service";
|
||||
after = [ "network.target" ];
|
||||
};
|
||||
|
||||
systemd.targets.gickup = {
|
||||
description = "Gickup git repository mirroring service";
|
||||
wants = map ({ slug, ... }: "gickup@${slug}.service") (lib.attrValues cfg.instances);
|
||||
};
|
||||
|
||||
systemd.timers = {
|
||||
"gickup@" = {
|
||||
description = "Gickup git repository mirroring service for %i";
|
||||
|
||||
timerConfig = {
|
||||
OnCalendar = "daily";
|
||||
RandomizedDelaySec = "1h";
|
||||
Persistent = true;
|
||||
AccuracySec = "1s";
|
||||
};
|
||||
};
|
||||
}
|
||||
//
|
||||
# Overrides for mirrors which are not "daily"
|
||||
(lib.pipe cfg.instances [
|
||||
builtins.attrValues
|
||||
(builtins.filter (instance: instance.interval != "daily"))
|
||||
(map ({ slug, interval, ... }: {
|
||||
name = "gickup@${slug}";
|
||||
value = {
|
||||
overrideStrategy = "asDropin";
|
||||
timerConfig.OnCalendar = interval;
|
||||
};
|
||||
}))
|
||||
builtins.listToAttrs
|
||||
]);
|
||||
|
||||
systemd.targets.timers.wants = map ({ slug, ... }: "gickup@${slug}.timer") (lib.attrValues cfg.instances);
|
||||
|
||||
systemd.services = {
|
||||
"gickup@" = let
|
||||
configDir = lib.pipe cfg.instances [
|
||||
(lib.mapAttrsToList (name: instance: {
|
||||
name = "${instance.slug}.yml";
|
||||
path = format.generate "gickup-configuration-${name}.yml" {
|
||||
destination.local = [ cfg.destinationSettings ];
|
||||
source.${instance.type} = [
|
||||
(
|
||||
(lib.optionalAttrs (instance.type != "any") {
|
||||
user = instance.owner;
|
||||
includeorgs = [ instance.owner ];
|
||||
include = [ instance.repo ];
|
||||
})
|
||||
//
|
||||
instance.settings
|
||||
)
|
||||
];
|
||||
};
|
||||
}))
|
||||
(pkgs.linkFarm "gickup-configuration-files")
|
||||
];
|
||||
in {
|
||||
description = "Gickup git repository mirroring service for %i";
|
||||
after = [ "network.target" ];
|
||||
|
||||
path = [
|
||||
cfg.gitPackage
|
||||
cfg.gitLfsPackage
|
||||
];
|
||||
|
||||
restartIfChanged = false;
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "'${pkgs.gickup}/bin/gickup' '${configDir}/%i.yml'";
|
||||
ExecStartPost = "";
|
||||
|
||||
User = "gickup";
|
||||
Group = "gickup";
|
||||
|
||||
BindPaths = lib.optionals (cfg.dataDir != "/var/lib/gickup") [
|
||||
"${cfg.dataDir}:/var/lib/gickup"
|
||||
];
|
||||
|
||||
Slice = "system-gickup.slice";
|
||||
|
||||
SyslogIdentifier = "gickup-%i";
|
||||
StateDirectory = "gickup";
|
||||
# WorkingDirectory = "gickup";
|
||||
# RuntimeDirectory = "gickup";
|
||||
# RuntimeDirectoryMode = "0700";
|
||||
|
||||
# https://discourse.nixos.org/t/how-to-prevent-custom-systemd-service-from-restarting-on-nixos-rebuild-switch/43431
|
||||
RemainAfterExit = true;
|
||||
|
||||
# Hardening options
|
||||
AmbientCapabilities = [];
|
||||
LockPersonality = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
# ProtectProc = "invisible";
|
||||
# ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
# SystemCallFilter = [
|
||||
# "@system-service"
|
||||
# "~@resources"
|
||||
# "~@privileged"
|
||||
# ];
|
||||
UMask = "0002";
|
||||
CapabilityBoundingSet = [];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.gickup;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
# TODO: add a service that will look at the backed up files and hardlink
|
||||
# the ones that have a matching hash together to save space. This can
|
||||
# either run routinely (i.e. trigger by systemd-timer), or be activated
|
||||
# whenever a gickup@<slug>.service finishes. The latter is probably better.
|
||||
|
||||
# systemd.services."gickup-hardlink" = {
|
||||
# serviceConfig = {
|
||||
# Type = "oneshot";
|
||||
# ExecStart = let
|
||||
# script = pkgs.writeShellApplication {
|
||||
# name = "gickup-hardlink-files.sh";
|
||||
# runtimeInputs = [ pkgs.coreutils pkgs.jdupes ];
|
||||
# text = ''
|
||||
|
||||
# '';
|
||||
# };
|
||||
# in lib.getExe script;
|
||||
|
||||
# User = "gickup";
|
||||
# Group = "gickup";
|
||||
|
||||
# BindPaths = lib.optionals (cfg.dataDir != "/var/lib/gickup") [
|
||||
# "${cfg.dataDir}:/var/lib/gickup"
|
||||
# ];
|
||||
|
||||
# Slice = "system-gickup.slice";
|
||||
|
||||
# StateDirectory = "gickup";
|
||||
|
||||
# # Hardening options
|
||||
# # TODO:
|
||||
# PrivateNetwork = true;
|
||||
# };
|
||||
# };
|
||||
};
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.gickup;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
# TODO: import cfg.instances from a toml file to make it easier for non-nix users
|
||||
# to add repositories to mirror
|
||||
};
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.gickup;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
# TODO: create .git/description files for each repo where cfg.instances.<instance>.description is set
|
||||
};
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.gickup;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
# TODO: run upon completion of cloning a repository
|
||||
systemd.timers."gickup-linktree" = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = true;
|
||||
Unit = "gickup-linktree.service";
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: update symlink for one repo at a time (e.g. gickup-linktree@<instance>.service)
|
||||
systemd.services."gickup-linktree" = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = let
|
||||
script = pkgs.writeShellApplication {
|
||||
name = "gickup-update-symlink-tree.sh";
|
||||
runtimeInputs = [
|
||||
pkgs.coreutils
|
||||
pkgs.findutils
|
||||
];
|
||||
text = ''
|
||||
shopt -s nullglob
|
||||
|
||||
for repository in ./*/*/*; do
|
||||
REPOSITORY_RELATIVE_DIRS=''${repository#"./"}
|
||||
|
||||
echo "Checking $REPOSITORY_RELATIVE_DIRS"
|
||||
|
||||
declare -a REVISIONS
|
||||
readarray -t REVISIONS < <(find "$repository" -mindepth 1 -maxdepth 1 -printf "%f\n" | sort --numeric-sort --reverse)
|
||||
|
||||
if [[ "''${#REVISIONS[@]}" == 0 ]]; then
|
||||
echo "Found no revisions for $repository, continuing"
|
||||
continue
|
||||
fi
|
||||
|
||||
LAST_REVISION="''${REVISIONS[0]}"
|
||||
SYMLINK_PATH="../linktree/''${REPOSITORY_RELATIVE_DIRS}"
|
||||
|
||||
mkdir -p "$(dirname "$SYMLINK_PATH")"
|
||||
|
||||
EXPECTED_SYMLINK_TARGET=$(realpath "''${repository}/''${LAST_REVISION}")
|
||||
EXISTING_SYMLINK_TARGET=$(realpath "$SYMLINK_PATH" || echo "<none>")
|
||||
|
||||
if [[ "$EXISTING_SYMLINK_TARGET" != "$EXPECTED_SYMLINK_TARGET" ]]; then
|
||||
echo "Updating symlink for $REPOSITORY_RELATIVE_DIRS"
|
||||
rm "$SYMLINK_PATH" ||:
|
||||
ln -rs "$EXPECTED_SYMLINK_TARGET" "$SYMLINK_PATH"
|
||||
else
|
||||
echo "Symlink already up to date, continuing..."
|
||||
fi
|
||||
|
||||
echo "---"
|
||||
done
|
||||
'';
|
||||
};
|
||||
in lib.getExe script;
|
||||
|
||||
User = "gickup";
|
||||
Group = "gickup";
|
||||
|
||||
BindPaths = lib.optionals (cfg.dataDir != "/var/lib/gickup") [
|
||||
"${cfg.dataDir}:/var/lib/gickup"
|
||||
];
|
||||
|
||||
Slice = "system-gickup.slice";
|
||||
|
||||
StateDirectory = "gickup";
|
||||
WorkingDirectory = "/var/lib/gickup/raw";
|
||||
|
||||
# Hardening options
|
||||
# TODO:
|
||||
PrivateNetwork = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user