Compare commits
1 commit
main
...
mattermost
Author | SHA1 | Date | |
---|---|---|---|
6928675baf |
35 changed files with 689 additions and 721 deletions
|
@ -15,7 +15,6 @@
|
|||
SystemMaxUse=512M
|
||||
MaxRetentionSec=48h
|
||||
'';
|
||||
nix.package = pkgs.lix;
|
||||
nix.gc.automatic = lib.mkDefault true;
|
||||
nix.gc.options = lib.mkDefault "--delete-older-than 7d";
|
||||
nix.settings.trusted-users = [ "root" "@wheel" ];
|
||||
|
@ -75,8 +74,6 @@
|
|||
ffmpeg-full
|
||||
bat
|
||||
niv
|
||||
sqlite-interactive
|
||||
hacc-scripts
|
||||
];
|
||||
|
||||
security.acme.defaults.email = "info+acme@hacc.space";
|
||||
|
|
103
flake.lock
103
flake.lock
|
@ -25,11 +25,11 @@
|
|||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1727447169,
|
||||
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=",
|
||||
"lastModified": 1708091384,
|
||||
"narHash": "sha256-dTGGw2y8wvfjr+J9CjQbfdulOq72hUG17HXVNxpH1yE=",
|
||||
"owner": "serokell",
|
||||
"repo": "deploy-rs",
|
||||
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76",
|
||||
"rev": "0a0187794ac7f7a1e62cda3dabf8dc041f868790",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -61,53 +61,58 @@
|
|||
"deploy-rs",
|
||||
"flake-compat"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs-unstable"
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-23_05": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-24_05": "nixpkgs-24_05"
|
||||
"nixpkgs-23_11": "nixpkgs-23_11",
|
||||
"utils": [
|
||||
"deploy-rs",
|
||||
"utils"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734370678,
|
||||
"narHash": "sha256-a8zkti1QM5Oxkdfnzr/NjrFlyqI36/kYV/X8G1jOmB4=",
|
||||
"lastModified": 1706219574,
|
||||
"narHash": "sha256-qO+8UErk+bXCq2ybHU4GzXG4Ejk4Tk0rnnTPNyypW4g=",
|
||||
"owner": "simple-nixos-mailserver",
|
||||
"repo": "nixos-mailserver",
|
||||
"rev": "c43d8c4a3ce84a7bebd110b06e69365484db6208",
|
||||
"rev": "e47f3719f1db3e0961a4358d4cb234a0acaa7baf",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
"owner": "simple-nixos-mailserver",
|
||||
"ref": "master",
|
||||
"ref": "nixos-23.11",
|
||||
"repo": "nixos-mailserver",
|
||||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1734298236,
|
||||
"narHash": "sha256-aWhhqY44xBjMoO9r5fyPp5u8tqUNWRZ/m/P+abMSs5c=",
|
||||
"lastModified": 1705856552,
|
||||
"narHash": "sha256-JXfnuEf5Yd6bhMs/uvM67/joxYKoysyE3M2k6T3eWbg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "eb919d9300b6a18f8583f58aef16db458fbd7bec",
|
||||
"rev": "612f97239e2cc474c13c9dafa0df378058c5ad8d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-24.11-small",
|
||||
"ref": "nixos-unstable",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs-24_05": {
|
||||
"nixpkgs-23_11": {
|
||||
"locked": {
|
||||
"lastModified": 1731797254,
|
||||
"narHash": "sha256-df3dJApLPhd11AlueuoN0Q4fHo/hagP75LlM5K1sz9g=",
|
||||
"lastModified": 1706098335,
|
||||
"narHash": "sha256-r3dWjT8P9/Ah5m5ul4WqIWD8muj5F+/gbCdjiNVBKmU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e8c38b73aeb218e27163376a2d617e61a2ad9b59",
|
||||
"rev": "a77ab169a83a4175169d78684ddd2e54486ac651",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-24.05",
|
||||
"ref": "nixos-23.11",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
|
@ -129,24 +134,55 @@
|
|||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1734318609,
|
||||
"narHash": "sha256-VPbVfHSvFs58T+kbseS7wa9WP6p2z7RJmjTnV4pAPQ0=",
|
||||
"lastModified": 1709479366,
|
||||
"narHash": "sha256-n6F0n8UV6lnTZbYPl1A9q1BS0p4hduAv1mGAP17CVd0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "66cdf593c0041cf1efc9b2889d80c9a5c497b284",
|
||||
"rev": "b8697e57f10292a6165a20f03d2f42920dfaf973",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-unstable-small",
|
||||
"ref": "nixos-unstable",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1709569716,
|
||||
"narHash": "sha256-iOR44RU4jQ+YPGrn+uQeYAp7Xo7Z/+gT+wXJoGxxLTY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "617579a787259b9a6419492eaac670a5f7663917",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-23.11",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1709356872,
|
||||
"narHash": "sha256-mvxCirJbtkP0cZ6ABdwcgTk0u3bgLoIoEFIoYBvD6+4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "458b097d81f90275b3fdf03796f0563844926708",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"deploy-rs": "deploy-rs",
|
||||
"nixos-mailserver": "nixos-mailserver",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs-oldstable": "nixpkgs-oldstable",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"sops-nix": "sops-nix",
|
||||
|
@ -155,16 +191,17 @@
|
|||
},
|
||||
"sops-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs-unstable"
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"nixpkgs-stable": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1733965552,
|
||||
"narHash": "sha256-GZ4YtqkfyTjJFVCub5yAFWsHknG1nS/zfk7MuHht4Fs=",
|
||||
"lastModified": 1709591996,
|
||||
"narHash": "sha256-0sQcalXSgqlO6mnxBTXkSQChBHy2GQsokB1XY8r+LpQ=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "2d73fc6ac4eba4b9a83d3cb8275096fbb7ab4004",
|
||||
"rev": "291aad29b59ceda517a06e59809f35cb0bb17c6b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -191,11 +228,11 @@
|
|||
"tracktrain": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1720213096,
|
||||
"narHash": "sha256-GrSXD6WvyiXcHx1s+48PEZVn/MTtBJAXpgds+NdEL2g=",
|
||||
"lastModified": 1688154251,
|
||||
"narHash": "sha256-iv2xUUYhjIcKWs1+l7h43z7v/a9/OamBKXi/gcl4ppI=",
|
||||
"ref": "main",
|
||||
"rev": "2943327863bfe5c6e793e5c40e473a2755d45642",
|
||||
"revCount": 126,
|
||||
"rev": "a995dabf07574a32c1ae62ad23b96ba7d8e076ee",
|
||||
"revCount": 92,
|
||||
"type": "git",
|
||||
"url": "https://stuebinm.eu/git/tracktrain"
|
||||
},
|
||||
|
|
45
flake.nix
45
flake.nix
|
@ -2,23 +2,24 @@
|
|||
description = "hacc infra stuff";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-24.11-small";
|
||||
nixpkgs-unstable.url = "nixpkgs/nixos-unstable-small";
|
||||
nixpkgs.url = "nixpkgs/nixos-23.11";
|
||||
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
|
||||
nixpkgs-oldstable.url = "github:/NixOS/nixpkgs?rev=c4aec3c021620d98861639946123214207e98344";
|
||||
|
||||
nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master";
|
||||
nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-23.11";
|
||||
tracktrain.url = "git+https://stuebinm.eu/git/tracktrain?ref=main";
|
||||
tracktrain.flake = false;
|
||||
|
||||
deploy-rs.url = "github:serokell/deploy-rs";
|
||||
deploy-rs.inputs.nixpkgs.follows = "nixpkgs";
|
||||
sops-nix.url = "github:Mic92/sops-nix";
|
||||
sops-nix.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
sops-nix.inputs.nixpkgs-stable.follows = "nixpkgs";
|
||||
|
||||
# these exist mostly to make the flake.lock somewhat more human-friendly
|
||||
# note that in theory doing this might break things, but it seems fairly unlikely
|
||||
nixos-mailserver.inputs = {
|
||||
nixpkgs.follows = "nixpkgs-unstable";
|
||||
"nixpkgs-23_05".follows = "nixpkgs";
|
||||
utils.follows = "/deploy-rs/utils";
|
||||
flake-compat.follows = "/deploy-rs/flake-compat";
|
||||
};
|
||||
};
|
||||
|
@ -37,20 +38,33 @@
|
|||
system = "x86_64-linux";
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
evalConfig = config: (nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
config
|
||||
{
|
||||
nixpkgs.pkgs = pkgs.lib.mkForce pkgs;
|
||||
imports = [ modules.nopersist profiles.container ];
|
||||
}
|
||||
];
|
||||
specialArgs = {
|
||||
# some of our modules import each other, and evalConfig is used for containers
|
||||
inherit modules evalConfig;
|
||||
sources = inputs;
|
||||
};
|
||||
}).config.system.build.toplevel;
|
||||
in {
|
||||
nixosConfigurations.parsons = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
./parsons/configuration.nix
|
||||
./modules/buildinfo.nix
|
||||
./modules/containers.nix
|
||||
sops-nix.nixosModules.sops
|
||||
{ nixpkgs.pkgs = pkgs; }
|
||||
{ environment.etc."haccfiles".source = self.outPath; }
|
||||
];
|
||||
specialArgs = {
|
||||
sources = inputs;
|
||||
inherit modules profiles;
|
||||
inherit (nixpkgs.lib) nixosSystem;
|
||||
inherit modules evalConfig;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -69,20 +83,11 @@
|
|||
(system: deployLib: deployLib.deployChecks self.deploy)
|
||||
deploy-rs.lib;
|
||||
|
||||
apps.x86_64-linux =
|
||||
packages.x86_64-linux =
|
||||
let
|
||||
mkApp = pkg: {
|
||||
type = "app";
|
||||
program = pkgs.lib.getExe pkg;
|
||||
};
|
||||
websites = pkgs.lib.mapAttrs (name: mkApp)
|
||||
self.nixosConfigurations.parsons.config.hacc.websites.builders;
|
||||
websites = self.nixosConfigurations.parsons.config.hacc.websites.builders;
|
||||
in
|
||||
{ docs = websites."docs.hacc.space"; } // websites;
|
||||
|
||||
packages.x86_64-linux = {
|
||||
inherit (pkgs) mattermost hacc-scripts;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
{ config, lib, pkgs, sources, ... }:
|
||||
|
||||
let
|
||||
self = sources.self;
|
||||
|
||||
formatDate = date: with lib.strings;
|
||||
let
|
||||
year = substring 0 4 date;
|
||||
month = substring 4 2 date;
|
||||
day = substring 6 2 date;
|
||||
hour = substring 8 2 date;
|
||||
minute = substring 10 2 date;
|
||||
second = substring 12 2 date;
|
||||
in
|
||||
"${year}-${month}-${day} ${hour}:${minute}:${second} UTC";
|
||||
in
|
||||
{
|
||||
system.nixos.label = "${config.system.nixos.release}-haccfiles-${self.shortRev or self.dirtyShortRev}";
|
||||
users.motd = ''
|
||||
Welcome to ${config.networking.hostName}, running NixOS ${config.system.nixos.release}!
|
||||
Built from haccfiles ${self.rev or self.dirtyRev}.
|
||||
Last commit was at ${formatDate self.lastModifiedDate}.
|
||||
${if self ? dirtyRev then "\nPlease remember to commit your changes.\n" else ""}
|
||||
'';
|
||||
|
||||
# used by monit
|
||||
environment.etc."haccfiles-commit".text = self.rev or self.dirtyRev;
|
||||
environment.etc."haccfiles-timestamp".text = builtins.toString self.lastModified;
|
||||
}
|
|
@ -14,5 +14,12 @@
|
|||
'';
|
||||
};
|
||||
|
||||
# I /suspect/ this is not actually needed.
|
||||
# TODO: find spoons to deal with potential breakage, test removing this
|
||||
networking.defaultGateway = {
|
||||
address = "192.168.100.1";
|
||||
interface = "eth0";
|
||||
};
|
||||
|
||||
system.stateVersion = lib.mkDefault "21.05";
|
||||
}
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
{ config, lib, pkgs, modules, profiles, sources, nixosSystem, ... }:
|
||||
|
||||
let
|
||||
mkIPv4 = index: local:
|
||||
"192.168.${if local then "100" else "101"}.${toString index}";
|
||||
mkIPv6 = index: local:
|
||||
"fd00::${if local then "100" else "101"}:${toString index}";
|
||||
|
||||
evalConfig = nixosConfig: (nixosSystem {
|
||||
inherit (config.nixpkgs) system;
|
||||
modules = [
|
||||
nixosConfig
|
||||
modules.nopersist
|
||||
profiles.container
|
||||
{ nixpkgs.pkgs = lib.mkForce pkgs; }
|
||||
];
|
||||
specialArgs = {
|
||||
inherit modules sources;
|
||||
};
|
||||
}).config.system.build.toplevel;
|
||||
|
||||
in {
|
||||
options.hacc.containers = with lib.options;
|
||||
mkOption {
|
||||
description = ''
|
||||
hacc-specific containers. These are a thin wrapper around "normal" nixos containers:
|
||||
- they automatically get an IPv4/IPv6 address assigned
|
||||
(note that these are not guaranteed to be stable across config changes,
|
||||
so please use {option}`containers.<name>.hostAddress` & friends to
|
||||
reference them elsewhere)
|
||||
- they set a couple default options (e.g. ephemeral, autoStart, privateNetwork)
|
||||
- they are evaluated with our own version of {nix}`evalConfig`, which includes a
|
||||
couple more modules by default, use our version of `nixpkgs`, and includes the
|
||||
{nix}`profiles.containers` profile setting sane defaults for containers.
|
||||
'';
|
||||
default = { };
|
||||
type = with lib.types;
|
||||
types.attrsOf (types.submodule {
|
||||
options = {
|
||||
bindToPersist = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description =
|
||||
"Wether to mount /persist/containers/<name> at /persist into this container.";
|
||||
};
|
||||
|
||||
bindSecrets = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description =
|
||||
"Whether to mount /run/secrets/<name> at /secrets into this container.";
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.unspecified;
|
||||
description =
|
||||
"The container's config, to be evaluated with our own {nix}`evalConfig`.";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
# wrapped into imap1, which enumerates the containers; IP addresses are then
|
||||
# simply assigned based on the order the containers are in the list.
|
||||
config.containers = lib.mkMerge (lib.imap1
|
||||
(index: { name, value }: let container = value; in {
|
||||
${name} = {
|
||||
hostAddress = mkIPv4 index false;
|
||||
localAddress = mkIPv4 index true;
|
||||
hostAddress6 = mkIPv6 index false;
|
||||
localAddress6 = mkIPv6 index true;
|
||||
|
||||
privateNetwork = true;
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
|
||||
bindMounts = lib.mkMerge [
|
||||
(lib.mkIf container.bindToPersist {
|
||||
"/persist" = {
|
||||
hostPath = "/persist/containers/${name}";
|
||||
isReadOnly = false;
|
||||
};
|
||||
})
|
||||
(lib.mkIf container.bindSecrets {
|
||||
"/secrets" = {
|
||||
hostPath = "/run/secrets/${name}";
|
||||
isReadOnly = true;
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
path = evalConfig container.config;
|
||||
};
|
||||
}) (lib.attrsToList config.hacc.containers));
|
||||
}
|
|
@ -7,7 +7,7 @@ with lib;
|
|||
|
||||
users.mutableUsers = false;
|
||||
|
||||
boot.initrd = mkIf (config.fileSystems."/".fsType or "notzfs" == "zfs") {
|
||||
boot.initrd = mkIf (config.fileSystems."/".fsType == "zfs") {
|
||||
network.ssh.hostKeys = mkIf config.hacc.encboot.enable
|
||||
(mkForce [ /persist/ssh/encboot_host ]);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
./tracktrain.nix
|
||||
./uffd.nix
|
||||
./lxc.nix
|
||||
./monit.nix
|
||||
./mattermost-s4f.nix
|
||||
];
|
||||
|
||||
hacc.bindToPersist = [ "/var/lib/acme" ];
|
||||
|
@ -51,6 +51,13 @@
|
|||
address = "fe80::1";
|
||||
interface = "enp35s0";
|
||||
};
|
||||
boot = {
|
||||
kernelModules = [ "nf_nat_ftp" ];
|
||||
kernel.sysctl = {
|
||||
"net.ipv4.conf.all.forwarding" = lib.mkOverride 90 true;
|
||||
"net.ipv4.conf.default.forwarding" = lib.mkOverride 90 true;
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, evalConfig, ... }:
|
||||
|
||||
{
|
||||
hacc.containers.forgejo = {
|
||||
config = { lib, pkgs, ... }: {
|
||||
containers.forgejo = {
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.1";
|
||||
localAddress = "192.168.100.10";
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
bindMounts = {
|
||||
"/persist" = {
|
||||
hostPath = "/persist/containers/forgejo";
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
path = evalConfig ({ config, lib, pkgs, ... }: {
|
||||
system.stateVersion = "21.11";
|
||||
|
||||
environment.systemPackages = [ pkgs.forgejo ];
|
||||
|
@ -11,7 +22,6 @@
|
|||
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
package = pkgs.forgejo;
|
||||
lfs.enable = true;
|
||||
database.type = "postgres";
|
||||
settings = {
|
||||
|
@ -68,12 +78,16 @@
|
|||
};
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
listenAddresses = [ {
|
||||
addr = "192.168.100.10";
|
||||
port = 22;
|
||||
} ];
|
||||
settings = {
|
||||
PasswordAuthentication = false;
|
||||
AcceptEnv = "GIT_PROTOCOL";
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."git.infra4future.de" = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, evalConfig, ... }:
|
||||
|
||||
{
|
||||
|
||||
|
@ -6,11 +6,20 @@
|
|||
"hedgedoc-hacc/env" = {};
|
||||
};
|
||||
|
||||
containers.pad-hacc.bindMounts = {
|
||||
"/secrets".hostPath = "/run/secrets/hedgedoc-hacc";
|
||||
};
|
||||
hacc.containers.pad-hacc = {
|
||||
config = { config, lib, ... }: {
|
||||
containers.pad-hacc = {
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.1";
|
||||
localAddress = "192.168.100.5";
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
bindMounts = {
|
||||
"/persist" = {
|
||||
hostPath = "/persist/containers/pad-hacc";
|
||||
isReadOnly = false;
|
||||
};
|
||||
"/secrets".hostPath = "/run/secrets/hedgedoc-hacc";
|
||||
};
|
||||
path = evalConfig ({ config, lib, ... }: {
|
||||
services.hedgedoc = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
@ -69,7 +78,7 @@
|
|||
location = "/persist/backups/postgres";
|
||||
};
|
||||
hacc.bindToPersist = [ "/var/lib/hedgedoc" ];
|
||||
};
|
||||
});
|
||||
};
|
||||
services.nginx.virtualHosts."pad.hacc.earth" = {
|
||||
enableACME = true;
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, evalConfig, ... }:
|
||||
|
||||
{
|
||||
hacc.containers.pad-i4f = {
|
||||
config = { config, lib, ... }: {
|
||||
containers.pad-i4f = {
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.1";
|
||||
localAddress = "192.168.100.6";
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
bindMounts = {
|
||||
"/persist" = {
|
||||
hostPath = "/persist/containers/pad-i4f";
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
path = evalConfig ({ config, lib, ... }: {
|
||||
services.hedgedoc = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
@ -46,7 +57,7 @@
|
|||
location = "/persist/backups/postgres";
|
||||
};
|
||||
hacc.bindToPersist = [ "/var/lib/hedgedoc" ];
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."pad.infra4future.de" = {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
networking.nat.internalInterfaces = [ "lxcbr0" ];
|
||||
|
||||
virtualisation.lxc.enable = true;
|
||||
virtualisation.lxc.systemConfig = ''
|
||||
|
|
|
@ -20,6 +20,14 @@
|
|||
monitoring = {
|
||||
enable = true;
|
||||
alertAddress = "admin@hacc.space";
|
||||
config = (lib.replaceStrings ["port 22"] ["port ${toString (lib.head config.services.openssh.ports)}"] options.mailserver.monitoring.config.default) + ''
|
||||
check host onlyoffice with address onlyoffice.infra4future.de
|
||||
if failed
|
||||
port 443
|
||||
protocol https
|
||||
status = 302
|
||||
then alert
|
||||
'';
|
||||
};
|
||||
domains = [
|
||||
"hacc.space"
|
||||
|
|
215
parsons/mattermost-s4f.nix
Normal file
215
parsons/mattermost-s4f.nix
Normal file
|
@ -0,0 +1,215 @@
|
|||
{ config, lib, pkgs, evalConfig, ... }:
|
||||
|
||||
{
|
||||
sops.secrets = {
|
||||
"mattermost-s4f/env" = {};
|
||||
};
|
||||
|
||||
containers.mattermost-staging = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.11";
|
||||
localAddress = "192.168.100.13";
|
||||
ephemeral = true;
|
||||
|
||||
bindMounts = {
|
||||
"/persist" = {
|
||||
hostPath = "/persist/containers/mattermost-s4f";
|
||||
isReadOnly = false;
|
||||
};
|
||||
"/secrets".hostPath = "/run/secrets/mattermost-s4f";
|
||||
"/cert".hostPath = "/var/lib/acme/kanidm.infra4future.de";
|
||||
};
|
||||
|
||||
path = evalConfig ({ config, lib, pkgs, ... }: {
|
||||
systemd.services.mattermost.serviceConfig.EnvironmentFile =
|
||||
lib.mkForce "/secrets/env";
|
||||
|
||||
services.mattermost = {
|
||||
enable = true;
|
||||
siteUrl = "https://mattermost-staging.infra4future.de";
|
||||
siteName = "Mattermost for testing";
|
||||
listenAddress = "0.0.0.0:3000";
|
||||
mutableConfig = false;
|
||||
|
||||
statePath = "/persist/mattermost";
|
||||
|
||||
extraConfig = {
|
||||
ServiceSettings = {
|
||||
TrustedProxyIPHeader = [ "X-Forwarded-For" "X-Real-Ip" ];
|
||||
ReadTimeout = 300;
|
||||
WriteTimeout = 600;
|
||||
IdleTimeout = 60;
|
||||
MaximumLoginAttempts = 10;
|
||||
AllowCorsFrom = "*.infra4future.de/*";
|
||||
WebserverMode = "gzip";
|
||||
EnableCustomEmoji = true;
|
||||
EnableEmojiPicker = true;
|
||||
EnableGifPicker = false;
|
||||
RestrictCustomEmojiCreation = "all";
|
||||
RestrictPostDelete = "all";
|
||||
AllowEditPost = "always";
|
||||
PostEditTimeout = -1;
|
||||
EnableTutorial = false;
|
||||
ExperimentalChannelSidebarOrganization = "default_on";
|
||||
ExperimentalChannelOrganization = true;
|
||||
ExperimentalDataPrefetch = true;
|
||||
EnableEmailInvitations = true;
|
||||
DisableLegacyMFA = true;
|
||||
EnableSVGs = true;
|
||||
EnableLaTeX = true;
|
||||
ThreadAutoFollow = true;
|
||||
EnableSecurityFixAlert = false;
|
||||
CollapsedThreads = "default_on";
|
||||
};
|
||||
TeamSettings = {
|
||||
EnableTeamCreation = true;
|
||||
EnableUserCreation = true;
|
||||
MaxUsersPerTeam = 250;
|
||||
EnableOpenServer = false;
|
||||
EnableUserDeactivation = true;
|
||||
ExperimentalViewArchivedChannels = true;
|
||||
ExperimentalEnableAutomaticReplies = true;
|
||||
};
|
||||
LogSettings = {
|
||||
EnableConsole = true;
|
||||
# note: for some reason this doesn't work (mattermost still sets it to DEBUG);
|
||||
# it's also set in secrets.env, where for some reason it does
|
||||
ConsoleLevel = "ERROR";
|
||||
EnableDiagnostics = false;
|
||||
EnableWebhookDebugging = false;
|
||||
};
|
||||
NotificationLogSettings = {
|
||||
EnableConsole = true;
|
||||
ConsoleLevel = "INFO";
|
||||
};
|
||||
PasswordSettings = {
|
||||
MinimumLength = 10;
|
||||
# turn of all the bullshit requirements
|
||||
Lowercase = false;
|
||||
Number = false;
|
||||
Uppercase = false;
|
||||
Symbol = false;
|
||||
};
|
||||
FileSettings = {
|
||||
EnableFileAttachments = true;
|
||||
MaxFileSize = 52428800;
|
||||
DriverName = "local";
|
||||
Directory = "/persist/mattermost/upload-storage";
|
||||
EnablePublicLink = true;
|
||||
PublicLinkSalt = "3k7p3yxdhz6798b3b9openfr9rn3ymwu";
|
||||
};
|
||||
EmailSettings = {
|
||||
EnableSignUpWithEmail = false;
|
||||
EnableSignInWithEmail = false;
|
||||
EnableSignInWithUsername = false;
|
||||
SendEmailNotifications = true;
|
||||
FeedbackName = "mattermost";
|
||||
FeedbackEmail = "mattermost@infra4future.de";
|
||||
ReplyToAddress = "mattermost@infra4future.de";
|
||||
FeedbackOrganization = "∆infra4future.de";
|
||||
EnableSMTPAuth = true;
|
||||
SMTPUsername = "noreply@infra4future.de";
|
||||
SMTPServer = "mail.hacc.space";
|
||||
SMTPPort = "465";
|
||||
SMTPServerTimeout = 10;
|
||||
ConnectionSecurity = "TLS";
|
||||
};
|
||||
RateLimitSettings.Enable = false;
|
||||
PrivacySettings = {
|
||||
ShowEmailAddress = false;
|
||||
ShowFullName = true;
|
||||
};
|
||||
# to disable the extra landing page advertising the app
|
||||
NativeAppSettings = {
|
||||
AppDownloadLink = "";
|
||||
AndroidAppDownloadLink = "";
|
||||
IosAppDownloadLink = "";
|
||||
};
|
||||
SupportSettings = {
|
||||
TermsOfServiceLink = "https://infra4future.de/nutzungsbedingungen.html";
|
||||
PrivacyPolicyLink = "https://infra4future.de/nutzungsbedingungen.html";
|
||||
AboutLink = "https://infra4future.de";
|
||||
SupportEmail = "info@infra4future.de";
|
||||
CustomTermsOfServiceEnabled = false;
|
||||
EnableAskCommunityLink = true;
|
||||
};
|
||||
AnnouncementSettings.EnableBanner = false;
|
||||
GitLabSettings = {
|
||||
Enable = true;
|
||||
Id = "mattermost";
|
||||
Scope = "users";
|
||||
AuthEndpoint = "https://kanidm.infra4future.de/ui/oauth2";
|
||||
TokenEndpoint = "https://kanidm.infra4future.de/oauth2/token";
|
||||
UserApiEndpoint = "https://kanidm.infra4future.de/oauth2/openid/mattermost/userinfo";
|
||||
};
|
||||
# for some reason, these don't appear to be working; the startup
|
||||
# process complaines and sets these back to en
|
||||
LocalizationSettings = {
|
||||
DefaultServerLocale = "de";
|
||||
DefaultClientLocale = "de";
|
||||
AvailableLocales = "de,en";
|
||||
};
|
||||
MessageExportSettings.EnableExport = false;
|
||||
ComplianceSettings.Enable = false;
|
||||
ClusterSettings.Enable = false;
|
||||
MetricsSettings.Enable = false;
|
||||
GuestAccountsSettings.Enable = false;
|
||||
FeatureFlags.CollapsedThreads = true;
|
||||
};
|
||||
|
||||
# eh, why not try it this time
|
||||
localDatabaseCreate = true;
|
||||
};
|
||||
services.postgresqlBackup = {
|
||||
enable = true;
|
||||
databases = [ "mattermost" ];
|
||||
startAt = "*-*-* 23:45:00";
|
||||
location = "/persist/backups/postgres";
|
||||
};
|
||||
|
||||
services.kanidm = {
|
||||
enableServer = true;
|
||||
serverSettings = {
|
||||
bindaddress = "[::]:4000";
|
||||
domain = "kanidm.infra4future.de";
|
||||
origin = "https://kanidm.infra4future.de";
|
||||
tls_chain = "/cert/fullchain.pem";
|
||||
tls_key = "/cert/key.pem";
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.kanidm ];
|
||||
|
||||
# can't configure db location because of hardening options
|
||||
# https://github.com/NixOS/nixpkgs/pull/143134/files#r800231100
|
||||
hacc.bindToPersist = [ "/var/lib/kanidm" ];
|
||||
|
||||
services.postgresql.package = pkgs.postgresql;
|
||||
});
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."mattermost-staging.infra4future.de" = {
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.containers.mattermost-staging.localAddress}:3000";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
# Mattermost CSR Patch
|
||||
proxy_hide_header Content-Security-Policy;
|
||||
proxy_hide_header X-Frame-Options;
|
||||
proxy_redirect off;
|
||||
'';
|
||||
};
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
services.nginx.virtualHosts."kanidm.infra4future.de" = {
|
||||
locations."/" = {
|
||||
proxyPass = "https://${config.containers.mattermost-staging.localAddress}:4000";
|
||||
|
||||
};
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,16 +1,26 @@
|
|||
{ config, pkgs, lib, ...}:
|
||||
{ config, pkgs, lib, evalConfig, ...}:
|
||||
|
||||
{
|
||||
sops.secrets = {
|
||||
"mattermost/env" = {};
|
||||
};
|
||||
|
||||
hacc.containers.mattermost = {
|
||||
bindSecrets = true;
|
||||
containers.mattermost = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.1";
|
||||
localAddress = "192.168.100.3";
|
||||
ephemeral = true;
|
||||
|
||||
config = { config, lib, pkgs, ... }: {
|
||||
environment.systemPackages = [ pkgs.morph pkgs.pgloader ];
|
||||
bindMounts = {
|
||||
"/persist" = {
|
||||
hostPath = "/persist/containers/mattermost";
|
||||
isReadOnly = false;
|
||||
};
|
||||
"/secrets".hostPath = "/run/secrets/mattermost";
|
||||
};
|
||||
|
||||
path = evalConfig ({ config, lib, pkgs, ... }: {
|
||||
systemd.services.mattermost.serviceConfig.EnvironmentFile =
|
||||
lib.mkForce "/secrets/env";
|
||||
|
||||
|
@ -62,6 +72,8 @@
|
|||
};
|
||||
LogSettings = {
|
||||
EnableConsole = true;
|
||||
# note: for some reason this doesn't work (mattermost still sets it to DEBUG);
|
||||
# it's also set in secrets.env, where for some reason it does
|
||||
ConsoleLevel = "ERROR";
|
||||
EnableDiagnostics = false;
|
||||
EnableWebhookDebugging = false;
|
||||
|
@ -144,12 +156,18 @@
|
|||
Enable = true;
|
||||
EnableUploads = true;
|
||||
Plugins = {
|
||||
bigbluebutton = {
|
||||
adminonly = false;
|
||||
base_url = "https://bbb.infra4future.de/bigbluebutton/api";
|
||||
salt = "zKCsNeaEniC115ynHOsZopgA4iTiJjzgeiPNoCEc";
|
||||
};
|
||||
"com.github.matterpoll.matterpoll" = {
|
||||
experimentalui = true;
|
||||
trigger = "poll";
|
||||
};
|
||||
};
|
||||
PluginStates = {
|
||||
bigbluebutton.Enable = true;
|
||||
"com.github.matterpoll.matterpoll".Enable = true;
|
||||
};
|
||||
};
|
||||
|
@ -158,8 +176,6 @@
|
|||
MetricsSettings.Enable = false;
|
||||
GuestAccountsSettings.Enable = false;
|
||||
FeatureFlags.CollapsedThreads = true;
|
||||
SqlSettings.DriverName = "postgres";
|
||||
SqlSettings.DataSource = "postgres:///mattermost?host=/run/postgresql";
|
||||
};
|
||||
|
||||
# turn of the weirder parts of this module (which insist on passwords
|
||||
|
@ -170,6 +186,17 @@
|
|||
localDatabaseCreate = false;
|
||||
};
|
||||
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ "mattermost" ];
|
||||
ensureUsers = [ {
|
||||
name = "mattermost";
|
||||
ensurePermissions = { "mattermost.*" = "ALL PRIVILEGES"; };
|
||||
} ];
|
||||
package = pkgs.mysql80;
|
||||
dataDir = "/persist/mysql";
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
enable = lib.mkForce true; # mattermost sets this to false. wtf.
|
||||
package = pkgs.postgresql_15;
|
||||
|
@ -181,17 +208,17 @@
|
|||
|
||||
authentication = lib.mkForce ''
|
||||
# Generated file; do not edit!
|
||||
local all all trust
|
||||
local all all trust
|
||||
host mattermost mattermost ::1/128 trust
|
||||
'';
|
||||
};
|
||||
|
||||
services.postgresqlBackup = {
|
||||
enable = true;
|
||||
databases = [ "mattermost" ];
|
||||
startAt = "*-*-* 23:45:00";
|
||||
location = "/persist/backups/postgres";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."mattermost.infra4future.de" = {
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
{ config, options, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
checkHash = pkgs.writeScriptBin "check-commit-hash" ''
|
||||
#!${lib.getExe pkgs.fish}
|
||||
set wanted (${lib.getExe pkgs.curl} -s https://git.infra4future.de/api/v1/repos/hacc/haccfiles/branches/main \
|
||||
-H 'accept: application/json' | jq -r .commit.id)
|
||||
|
||||
if test $status != 0
|
||||
echo "could not reach git.infra4future.de"
|
||||
exit 2
|
||||
end
|
||||
|
||||
set actual (cat /etc/haccfiles-commit)
|
||||
if test $status != 0
|
||||
echo "/etc/haccfiles-commit does not exist??"
|
||||
exit 2
|
||||
end
|
||||
|
||||
if test $actual != $wanted
|
||||
echo "parsons was built on $actual, but commit on main is $wanted"
|
||||
exit 1
|
||||
end
|
||||
'';
|
||||
|
||||
checkDeployAge = pkgs.writeScriptBin "check-deploy-age" ''
|
||||
#!${lib.getExe pkgs.fish}
|
||||
|
||||
set date (date +%s)
|
||||
# we do this indirection here so monit's config won't change on each deploy
|
||||
set deploytimestamp (cat /etc/haccfiles-timestamp)
|
||||
set age (expr $date - $deploytimestamp)
|
||||
|
||||
if test $age -ge (expr 3600 \* 24 \* 10)
|
||||
echo "${config.networking.hostName} has not been deployed since 10 days, perhaps someone should do updates?"
|
||||
exit 1
|
||||
end
|
||||
'';
|
||||
in
|
||||
{
|
||||
mailserver.monitoring = {
|
||||
enable = true;
|
||||
alertAddress = "admin@hacc.space";
|
||||
config = (lib.replaceStrings ["port 22"] ["port ${toString (lib.head config.services.openssh.ports)}"] options.mailserver.monitoring.config.default);
|
||||
};
|
||||
|
||||
services.monit.config = ''
|
||||
check host onlyoffice with address onlyoffice.infra4future.de
|
||||
start program "/run/current-system/sw/bin/lxc-start -n onlyoffice -f /persist/lxc/onlyoffice/config"
|
||||
stop program "/run/current-system/sw/bin/lxc-stop -n onlyoffice"
|
||||
if failed port 443 protocol https status = 302
|
||||
then restart
|
||||
|
||||
check program deployed-commit-on-main path ${lib.getExe checkHash}
|
||||
if status == 1 for 64 cycles then alert
|
||||
if status == 2 for 3 cycles then alert
|
||||
|
||||
check program is-system-running path ${pkgs.systemd}/bin/systemctl is-system-running
|
||||
if status != 0 then alert
|
||||
|
||||
check program check-deploy-age path ${lib.getExe checkDeployAge}
|
||||
if status == 1 then alert
|
||||
'';
|
||||
}
|
|
@ -1,9 +1,19 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, evalConfig, ... }:
|
||||
|
||||
{
|
||||
containers.nextcloud.timeoutStartSec = "10 min";
|
||||
hacc.containers.nextcloud = {
|
||||
config = { config, lib, pkgs, ... }: {
|
||||
containers.nextcloud = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.1";
|
||||
localAddress = "192.168.100.2";
|
||||
ephemeral = true;
|
||||
bindMounts = {
|
||||
"/persist" = {
|
||||
hostPath = "/persist/containers/nextcloud";
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
path = evalConfig ({ config, lib, pkgs, ... }: {
|
||||
environment.systemPackages = [ pkgs.htop ];
|
||||
|
||||
services.nextcloud = {
|
||||
|
@ -11,7 +21,7 @@
|
|||
|
||||
# must be set manually; may not be incremented by more than one at
|
||||
# a time, otherwise nextcloud WILL break
|
||||
package = pkgs.nextcloud30;
|
||||
package = pkgs.nextcloud27;
|
||||
|
||||
home = "/persist/nextcloud";
|
||||
https = true;
|
||||
|
@ -39,7 +49,7 @@
|
|||
"pm.start_servers" = "2";
|
||||
};
|
||||
|
||||
settings = {
|
||||
extraOptions = {
|
||||
instanceid = "ocxlphb7fbju";
|
||||
datadirectory = "/persist/nextcloud/data";
|
||||
loglevel = 0;
|
||||
|
@ -72,7 +82,7 @@
|
|||
requires = ["postgresql.service"];
|
||||
after = ["postgresql.service"];
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."cloud.infra4future.de" = {
|
||||
|
|
|
@ -1,22 +1,77 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
networking.firewall.enable = true;
|
||||
networking.firewall.logRefusedConnections = false;
|
||||
networking.nat.enable = true;
|
||||
networking.firewall.enable = false;
|
||||
networking.nat.enable = false;
|
||||
boot = {
|
||||
kernelModules = [ "nf_nat_ftp" ];
|
||||
kernel.sysctl = {
|
||||
"net.ipv4.conf.all.forwarding" = true;
|
||||
"net.ipv4.conf.default.forwarding" = true;
|
||||
};
|
||||
};
|
||||
|
||||
networking.nftables.enable = true;
|
||||
networking.nftables.tables.nat = {
|
||||
family = "ip";
|
||||
content = ''
|
||||
chain prerouting {
|
||||
type nat hook prerouting priority -100
|
||||
iifname enp35s0 tcp dport { 22 } dnat ${config.containers.forgejo.localAddress}:22
|
||||
networking.nftables = {
|
||||
enable = true;
|
||||
|
||||
ruleset = ''
|
||||
table inet filter {
|
||||
chain input {
|
||||
type filter hook input priority filter
|
||||
policy drop
|
||||
|
||||
icmpv6 type {
|
||||
echo-request,
|
||||
echo-reply,
|
||||
mld-listener-query,
|
||||
mld-listener-report,
|
||||
mld-listener-done,
|
||||
nd-router-advert,
|
||||
nd-neighbor-solicit,
|
||||
nd-neighbor-advert,
|
||||
packet-too-big
|
||||
} accept
|
||||
|
||||
icmp type echo-request accept
|
||||
|
||||
ct state invalid drop
|
||||
ct state established,related accept
|
||||
|
||||
iifname { lo } accept
|
||||
|
||||
tcp dport { 25, 80, 443, 465, 587, 993, 4190, 62954, 64738 } accept
|
||||
|
||||
udp dport { 60000-61000, 64738 } accept
|
||||
|
||||
# DHCPv6
|
||||
ip6 daddr fe80::/64 udp dport 546 accept
|
||||
|
||||
counter
|
||||
}
|
||||
chain output {
|
||||
type filter hook output priority filter
|
||||
policy accept
|
||||
|
||||
counter
|
||||
}
|
||||
chain forward {
|
||||
type filter hook forward priority filter
|
||||
policy accept
|
||||
|
||||
counter
|
||||
}
|
||||
}
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 100
|
||||
iifname lxcbr0 oifname enp35s0 masquerade
|
||||
iifname ve-* oifname enp35s0 masquerade
|
||||
|
||||
table ip nat {
|
||||
chain prerouting {
|
||||
type nat hook prerouting priority -100
|
||||
iifname enp35s0 tcp dport { 22 } dnat ${config.containers.forgejo.localAddress}:22
|
||||
}
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 100
|
||||
iifname lxcbr0 oifname enp35s0 masquerade
|
||||
iifname ve-* oifname enp35s0 masquerade
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
sops.secrets = {
|
||||
"s4f-conference/env" = {};
|
||||
};
|
||||
|
||||
hacc.containers.s4f-conference = {
|
||||
bindSecrets = true;
|
||||
|
||||
config = { config, lib, pkgs, ... }: {
|
||||
systemd.services.mattermost.serviceConfig.EnvironmentFile =
|
||||
lib.mkForce "/secrets/env";
|
||||
|
||||
services.mattermost = {
|
||||
enable = true;
|
||||
siteUrl = "https://s4f-conference.infra4future.de";
|
||||
siteName = "Scientists for Future Chat";
|
||||
listenAddress = "0.0.0.0:3000";
|
||||
mutableConfig = false;
|
||||
|
||||
statePath = "/persist/mattermost";
|
||||
|
||||
extraConfig = {
|
||||
ServiceSettings = {
|
||||
TrustedProxyIPHeader = [ "X-Forwarded-For" "X-Real-Ip" ];
|
||||
EnableEmailInvitations = true;
|
||||
};
|
||||
TeamSettings = {
|
||||
EnableUserCreation = true;
|
||||
MaxUsersPerTeam = 2500;
|
||||
EnableUserDeactivation = true;
|
||||
EnableOpenServer = false;
|
||||
};
|
||||
PasswordSettings = {
|
||||
MinimumLength = 10;
|
||||
};
|
||||
FileSettings = {
|
||||
EnableFileAttachments = true;
|
||||
MaxFileSize = 52428800;
|
||||
DriverName = "local";
|
||||
Directory = "/persist/upload-storage";
|
||||
EnablePublicLink = true;
|
||||
PublicLinkSalt = "3k7p3yxdhz6798b3b9openfr9rn3ymwu";
|
||||
};
|
||||
EmailSettings = {
|
||||
EnableSignUpWithEmail = true;
|
||||
EnableSignInWithEmail = true;
|
||||
EnableSignInWithUsername = true;
|
||||
SendEmailNotifications = true;
|
||||
FeedbackName = "mattermost";
|
||||
FeedbackEmail = "mattermost@infra4future.de";
|
||||
ReplyToAddress = "mattermost@infra4future.de";
|
||||
FeedbackOrganization = "∆infra4future.de";
|
||||
EnableSMTPAuth = true;
|
||||
SMTPUsername = "noreply@infra4future.de";
|
||||
SMTPServer = "mail.hacc.space";
|
||||
SMTPPort = "465";
|
||||
SMTPServerTimeout = 10;
|
||||
ConnectionSecurity = "TLS";
|
||||
};
|
||||
RateLimitSettings.Enable = false;
|
||||
PrivacySettings = {
|
||||
ShowEmailAddress = false;
|
||||
ShowFullName = true;
|
||||
};
|
||||
# to disable the extra landing page advertising the app
|
||||
NativeAppSettings = {
|
||||
AppDownloadLink = "";
|
||||
AndroidAppDownloadLink = "";
|
||||
IosAppDownloadLink = "";
|
||||
};
|
||||
LogSettings = {
|
||||
EnableConsole = true;
|
||||
ConsoleLevel = "ERROR";
|
||||
EnableDiagnostics = false;
|
||||
EnableWebhookDebugging = false;
|
||||
};
|
||||
SupportSettings = {
|
||||
TermsOfServiceLink = "https://infra4future.de/nutzungsbedingungen.html";
|
||||
PrivacyPolicyLink = "https://infra4future.de/nutzungsbedingungen.html";
|
||||
AboutLink = "https://infra4future.de";
|
||||
SupportEmail = "info@infra4future.de";
|
||||
CustomTermsOfServiceEnabled = false;
|
||||
EnableAskCommunityLink = true;
|
||||
};
|
||||
AnnouncementSettings.EnableBanner = false;
|
||||
ComplianceSettings.Enable = false;
|
||||
ClusterSettings.Enable = false;
|
||||
MetricsSettings.Enable = false;
|
||||
GuestAccountsSettings.Enable = true;
|
||||
};
|
||||
|
||||
localDatabaseCreate = false;
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
enable = lib.mkForce true; # mattermost sets this to false. wtf.
|
||||
package = pkgs.postgresql_15;
|
||||
ensureDatabases = [ "mattermost" ];
|
||||
ensureUsers = [ {
|
||||
name = "mattermost";
|
||||
ensureDBOwnership = true;
|
||||
} ];
|
||||
|
||||
authentication = lib.mkForce ''
|
||||
# Generated file; do not edit!
|
||||
local all all trust
|
||||
host mattermost mattermost ::1/128 trust
|
||||
'';
|
||||
};
|
||||
services.postgresqlBackup = {
|
||||
enable = true;
|
||||
databases = [ "mattermost" ];
|
||||
startAt = "*-*-* 23:45:00";
|
||||
location = "/persist/backups/postgres";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."s4f-conference.infra4future.de" = {
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.containers.s4f-conference.localAddress}:3000";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
# Mattermost CSR Patch
|
||||
proxy_hide_header Content-Security-Policy;
|
||||
proxy_hide_header X-Frame-Options;
|
||||
proxy_redirect off;
|
||||
|
||||
client_max_body_size 100M;
|
||||
'';
|
||||
};
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, evalConfig, ... }:
|
||||
|
||||
let
|
||||
tracktrain-config = ''
|
||||
|
@ -12,12 +12,8 @@ let
|
|||
login:
|
||||
enable: true
|
||||
url: https://login.infra4future.de
|
||||
clientName: tracktrain
|
||||
# clientSecret defined in env file
|
||||
|
||||
logging:
|
||||
ntfyTopic: ping.stuebinm.eu/monit
|
||||
name: ilztalbahn
|
||||
clientname: tracktrain
|
||||
# clientsecret defined in env file
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
@ -29,14 +25,14 @@ in
|
|||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.containers.tracktrain.localAddress}:4000";
|
||||
proxyPass = "http://192.168.42.41:4000";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
# note: this shadows the /metrics endpoint of tracktrain
|
||||
# in case you remove this, please consider putting something
|
||||
# else here to keep it from being publicly scrapable
|
||||
locations."/metrics/" = {
|
||||
proxyPass = "http://${config.containers.tracktrain.localAddress}:2342";
|
||||
proxyPass = "http://192.168.42.41:2342";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
rewrite ^/metrics/(.*) /$1 break;
|
||||
|
@ -44,10 +40,28 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
hacc.containers.tracktrain = {
|
||||
bindSecrets = true;
|
||||
containers.tracktrain = {
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.42.40";
|
||||
localAddress = "192.168.42.41";
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
bindMounts = {
|
||||
"/persist" = {
|
||||
hostPath = "/persist/containers/tracktrain";
|
||||
isReadOnly = false;
|
||||
};
|
||||
"/secrets".hostPath = "/run/secrets/tracktrain";
|
||||
};
|
||||
|
||||
config = { config, lib, pkgs, ... }: {
|
||||
path = evalConfig ({ config, lib, pkgs, ... }: {
|
||||
system.stateVersion = "21.11";
|
||||
|
||||
users.users.tracktrain = {
|
||||
group = "tracktrain";
|
||||
isSystemUser = true;
|
||||
};
|
||||
users.groups.tracktrain = {};
|
||||
|
||||
systemd.services.tracktrain = {
|
||||
enable = true;
|
||||
|
@ -59,21 +73,22 @@ in
|
|||
serviceConfig = {
|
||||
Type = "simple";
|
||||
EnvironmentFile = "/secrets/env";
|
||||
DynamicUser = true;
|
||||
User = "tracktrain";
|
||||
Group = "tracktrain";
|
||||
};
|
||||
path = [ pkgs.wget pkgs.ntfy-sh ];
|
||||
path = [ pkgs.wget ];
|
||||
script = ''
|
||||
cd /tmp
|
||||
mkdir -p /persist/tracktrain
|
||||
cd /persist/tracktrain
|
||||
ln -sf ${pkgs.writeText "tracktrain-config.yaml" tracktrain-config} config.yaml
|
||||
sleep 3
|
||||
wget "https://ilztalbahn.eu/wp-content/uploads/2020/07/gtfs.zip" || sleep 4; wget "https://ilztalbahn.eu/wp-content/uploads/2020/07/gtfs.zip"
|
||||
${pkgs.tracktrain}/bin/tracktrain +RTS -T
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.postgresql.wantedBy = [ "tracktrain.service" ];
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
|
||||
package = pkgs.postgresql_15;
|
||||
ensureDatabases = [ "tracktrain" ];
|
||||
ensureUsers = [ {
|
||||
|
@ -81,7 +96,8 @@ in
|
|||
ensureDBOwnership = true;
|
||||
} ];
|
||||
authentication = ''
|
||||
local all all trust
|
||||
local all all trust
|
||||
host all all 127.0.0.1/32 trust
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -96,10 +112,46 @@ in
|
|||
} ];
|
||||
};
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings.server = {
|
||||
serve_from_sub_path = true;
|
||||
domain = "tracktrain.ilztalbahn.eu";
|
||||
root_url = "https://%(domain)s/metrics/";
|
||||
http_port = 2342;
|
||||
http_addr = "0.0.0.0";
|
||||
};
|
||||
|
||||
settings."auth.generic_oauth" = {
|
||||
name = "uffd";
|
||||
enabled = true;
|
||||
allow_sign_up = true;
|
||||
empty_scopes = true;
|
||||
client_id = "ilztalbahn-grafana";
|
||||
client_secret = "\${GRAFANA_CLIENT_SECRET}";
|
||||
auth_url = "https://login.infra4future.de/oauth2/authorize";
|
||||
token_url = "https://login.infra4future.de/oauth2/token";
|
||||
api_url = "https://login.infra4future.de/oauth2/userinfo";
|
||||
};
|
||||
# disables the default login screen. comment out if for some
|
||||
# reason you do need it
|
||||
settings.auth.oauth_auto_login = true;
|
||||
settings.users.auto_assign_org_role = "Admin";
|
||||
|
||||
provision = {
|
||||
enable = true;
|
||||
datasources.settings.datasources = [ {
|
||||
url = "http://localhost:9001";
|
||||
type = "prometheus";
|
||||
name = "prometheus";
|
||||
} ];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.grafana.serviceConfig.EnvironmentFile =
|
||||
"/secrets/env";
|
||||
hacc.bindToPersist = [ "/var/lib/grafana" ];
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, evalConfig, ... }:
|
||||
|
||||
{
|
||||
hacc.containers.uffd = {
|
||||
config = { config, lib, pkgs, ... }: {
|
||||
containers.uffd = {
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.1";
|
||||
localAddress = "192.168.100.9";
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
bindMounts = {
|
||||
"/persist" = {
|
||||
hostPath = "/persist/containers/uffd";
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
path = evalConfig ({ config, lib, pkgs, ... }: {
|
||||
services.uwsgi = {
|
||||
enable = true;
|
||||
plugins = [ "python3" ];
|
||||
|
@ -18,7 +29,7 @@
|
|||
hook-pre-app = "exec:FLASK_APP=${pkgs.uffd}/lib/python3.10/site-packages/uffd flask db upgrade";
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
services.nginx.virtualHosts."login.infra4future.de" = {
|
||||
enableACME = true;
|
||||
|
@ -43,21 +54,62 @@
|
|||
after = [ "network.target" ];
|
||||
serviceConfig.Type = "simple";
|
||||
path = [ pkgs.fish pkgs.curl pkgs.jq ];
|
||||
script = "${pkgs.hacc-scripts}/bin/uffd-sync-mattermost-groups.fish";
|
||||
startAt = "*:0/15";
|
||||
};
|
||||
script = (pkgs.writeTextFile {
|
||||
name = "auamost.fish";
|
||||
executable = true;
|
||||
checkPhase = ''
|
||||
${lib.getExe pkgs.fish} -n $target
|
||||
'';
|
||||
text = ''
|
||||
#!${lib.getExe pkgs.fish}
|
||||
source /run/secrets/auamost/secrets.fish
|
||||
|
||||
systemd.services.uffd-account-expiry-notification = {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig.Type = "simple";
|
||||
path = [ pkgs.hacc-scripts pkgs.sqlite-interactive pkgs.postfix ];
|
||||
script = ''
|
||||
uffd-unused-accounts-notification.scm -v admin
|
||||
'';
|
||||
startAt = "weekly";
|
||||
restartIfChanged = false;
|
||||
for i in (seq 1 (count $groups))
|
||||
set team $teams[$i]
|
||||
set group $groups[$i]
|
||||
set users (curl -u $uffd_token --basic https://login.infra4future.de/api/v1/getusers -d group="$group")
|
||||
set usernames (echo "$users" | jq -c "[.[] | .loginname]")
|
||||
for user in (echo "$users" | jq -c ".[]")
|
||||
set id (echo "$user" | jq .id)
|
||||
set username (echo "$user" | jq .loginname)
|
||||
set email (echo "$user" | jq .email)
|
||||
curl -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/users \
|
||||
-d '{"email": '"$email"', "username": '"$username"', "auth_service": "gitlab", "auth_data": "'"$id"'"}'
|
||||
end
|
||||
set userids (curl -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/users/usernames \
|
||||
-d "$usernames" | jq '[.[] | {user_id: .id, team_id: "'$team'"} ]')
|
||||
curl -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/teams/"$team"/members/batch \
|
||||
-d "$userids"
|
||||
|
||||
if test "$group" = "hacc"
|
||||
continue
|
||||
end
|
||||
|
||||
set current_members (curl -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/teams/"$team"/members | jq '[.[] | .user_id]')
|
||||
|
||||
# membership relations don't contain e.g. usernames, so fetch those, too
|
||||
set current_users (curl -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/users/ids \
|
||||
-d "$current_members" | jq -c '.[]')
|
||||
|
||||
set userids (echo "$userids" | jq -c ".[].user_id")
|
||||
for member in $current_users
|
||||
set id (echo $member | jq .id)
|
||||
if not contains -i $id $userids > /dev/null then
|
||||
set id_unquoted (echo $member | jq -r .id)
|
||||
echo removing $id_unquoted (echo $member | jq '.email') from $team \($group\)
|
||||
curl -X DELETE -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/teams/"$team"/members/"$id_unquoted"
|
||||
end
|
||||
end
|
||||
end
|
||||
'';
|
||||
}).outPath;
|
||||
startAt = "*:0/15";
|
||||
};
|
||||
|
||||
sops.secrets."auamost/secrets.fish" = { };
|
||||
|
|
|
@ -13,20 +13,16 @@ let
|
|||
buildGoModule = unstable.buildGo122Module;
|
||||
};
|
||||
|
||||
morph = callPackage ./morph.nix {
|
||||
buildGoModule = unstable.buildGo122Module;
|
||||
};
|
||||
|
||||
tracktrain = import sources.tracktrain {
|
||||
nixpkgs = unstable;
|
||||
nixpkgs = pkgs;
|
||||
compiler = "default";
|
||||
};
|
||||
|
||||
uffd = oldstable.callPackage ./uffd { };
|
||||
|
||||
hacc-scripts = callPackage ./scripts {};
|
||||
|
||||
inherit (oldstable) uwsgi flask;
|
||||
|
||||
inherit (unstable) kanidm;
|
||||
};
|
||||
|
||||
in pkgs.extend(_: _: newpkgs)
|
||||
|
|
|
@ -12,13 +12,13 @@ buildGoModule rec {
|
|||
# See https://docs.mattermost.com/upgrade/extended-support-release.html
|
||||
# When a new ESR version is available (e.g. 8.1.x -> 9.5.x), update
|
||||
# the version regex in passthru.updateScript as well.
|
||||
version = "9.11.5";
|
||||
version = "9.5.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "mattermost";
|
||||
repo = "mattermost";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-bLZFeG6kBVP0ws50wtBam/bO206sQnz6va8PATAoRAQ=";
|
||||
hash = "sha256-NYP0mhON+TCvNTSx4I4hddFGF9TWtnMAwyJvX8sEdWU=";
|
||||
};
|
||||
|
||||
# Needed because buildGoModule does not support go workspaces yet.
|
||||
|
@ -34,10 +34,10 @@ buildGoModule rec {
|
|||
|
||||
webapp = fetchurl {
|
||||
url = "https://releases.mattermost.com/${version}/mattermost-${version}-linux-amd64.tar.gz";
|
||||
hash = "sha256-jyaJUN8wpuBivKNdm7f1mYwygO8xC+Zxy0SdkDovdsA=";
|
||||
hash = "sha256-ogiowbNYHo9NTQLAg1OKXp8pV1Zn7kPcZR9ukaKvpKA=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-Gwv6clnq7ihoFC8ox8iEM5xp/us9jWUrcmqA9/XbxBE=";
|
||||
vendorHash = "sha256-TJCtgNf56A1U0EbV5gXjTro+YudVBRWiSZoBC3nJxnE=";
|
||||
|
||||
modRoot = "./server";
|
||||
preBuild = ''
|
||||
|
@ -45,7 +45,6 @@ buildGoModule rec {
|
|||
'';
|
||||
|
||||
subPackages = [ "cmd/mattermost" ];
|
||||
offlineCache = webapp;
|
||||
|
||||
tags = [ "production" ];
|
||||
|
||||
|
@ -70,7 +69,7 @@ buildGoModule rec {
|
|||
|
||||
passthru = {
|
||||
updateScript = nix-update-script {
|
||||
extraArgs = [ "--version-regex" "^v(9\.11\.([0-9.]+))" ];
|
||||
extraArgs = [ "--version-regex" "^v(9\.5\.([0-9.]+))" ];
|
||||
};
|
||||
tests.mattermost = nixosTests.mattermost;
|
||||
};
|
||||
|
@ -78,7 +77,7 @@ buildGoModule rec {
|
|||
meta = with lib; {
|
||||
description = "Mattermost is an open source platform for secure collaboration across the entire software development lifecycle";
|
||||
homepage = "https://www.mattermost.org";
|
||||
license = with licenses; [ agpl3Only asl20 ];
|
||||
license = with licenses; [ agpl3 asl20 ];
|
||||
maintainers = with maintainers; [ ryantm numinit kranzes mgdelacroix ];
|
||||
mainProgram = "mattermost";
|
||||
};
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
{ buildGoModule
|
||||
, fetchFromGitHub
|
||||
}:
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "mattermost-morph";
|
||||
version = "1.1.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "mattermost";
|
||||
repo = "morph";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-Orh/a9OlUVIlDdLXRpDAnHUmWRiM1N2oO+dijbuJzx8=";
|
||||
};
|
||||
|
||||
vendorHash = null;
|
||||
|
||||
subPackages = [ "cmd/morph" ];
|
||||
|
||||
tags = [ "production" ];
|
||||
|
||||
ldflags = [
|
||||
"-s"
|
||||
"-w"
|
||||
"-X github.com/mattermost/mattermost/server/public/model.Version=${version}"
|
||||
"-X github.com/mattermost/mattermost/server/public/model.BuildNumber=${version}-nixpkgs"
|
||||
"-X github.com/mattermost/mattermost/server/public/model.BuildDate=1970-01-01"
|
||||
"-X github.com/mattermost/mattermost/server/public/model.BuildHash=v${version}"
|
||||
"-X github.com/mattermost/mattermost/server/public/model.BuildHashEnterprise=none"
|
||||
"-X github.com/mattermost/mattermost/server/public/model.BuildEnterpriseReady=false"
|
||||
];
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{ stdenvNoCC, gauche, fish }:
|
||||
|
||||
stdenvNoCC.mkDerivation {
|
||||
name = "hacc-utility-scripts";
|
||||
|
||||
src = ./.;
|
||||
|
||||
buildInputs = [ gauche fish ];
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
fish -n $out/bin/*.fish
|
||||
cp *.{scm,fish} $out/bin
|
||||
chmod +x $out/bin/*
|
||||
'';
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/env fish
|
||||
|
||||
source /run/secrets/auamost/secrets.fish
|
||||
|
||||
for i in (seq 1 (count $groups))
|
||||
set team $teams[$i]
|
||||
set group $groups[$i]
|
||||
set users (curl -s -u $uffd_token --basic https://login.infra4future.de/api/v1/getusers -d group="$group")
|
||||
set usernames (echo "$users" | jq -c "[.[] | .loginname]")
|
||||
for user in (echo "$users" | jq -c ".[]")
|
||||
set id (echo "$user" | jq .id)
|
||||
set username (echo "$user" | jq .loginname)
|
||||
set email (echo "$user" | jq .email)
|
||||
curl -s -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/users \
|
||||
-d '{"email": '"$email"', "username": '"$username"', "auth_service": "gitlab", "auth_data": "'"$id"'"}'
|
||||
end
|
||||
set userids (curl -s -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/users/usernames \
|
||||
-d "$usernames" | jq '[.[] | {user_id: .id, team_id: "'$team'"} ]')
|
||||
curl -s -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/teams/"$team"/members/batch \
|
||||
-d "$userids"
|
||||
|
||||
if test "$group" = "hacc"
|
||||
continue
|
||||
end
|
||||
|
||||
set current_members (curl -s -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/teams/"$team"/members | jq '[.[] | .user_id]')
|
||||
|
||||
# membership relations don't contain e.g. usernames, so fetch those, too
|
||||
set current_users (curl -s -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/users/ids \
|
||||
-d "$current_members" | jq -c '.[]')
|
||||
|
||||
set userids (echo "$userids" | jq -c ".[].user_id")
|
||||
for member in $current_users
|
||||
set id (echo $member | jq .id)
|
||||
if not contains -i $id $userids > /dev/null then
|
||||
set id_unquoted (echo $member | jq -r .id)
|
||||
echo removing $id_unquoted (echo $member | jq '.email') from $team \($group\)
|
||||
curl -s -X DELETE -H $mattermost_token \
|
||||
-H "Content-Type: application/json" https://mattermost.infra4future.de/api/v4/teams/"$team"/members/"$id_unquoted"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,121 +0,0 @@
|
|||
#!/usr/bin/env gosh
|
||||
|
||||
(use gauche.process)
|
||||
(use text.csv)
|
||||
(use scheme.list)
|
||||
(use gauche.parseopt)
|
||||
(use util.match)
|
||||
|
||||
(define cutoff-date "2023-01-01")
|
||||
|
||||
(define sqlite-path "/persist/containers/uffd/uffd/db.sqlite")
|
||||
(define sqlite-query
|
||||
"select displayname, mail, max(expires) as last_login from oauth2token join user on user_id=user.id group by user_id having last_login < '2023-01-01'
|
||||
union all select displayname, mail, '2022' from user where not exists (select * from oauth2token where user_id = user.id);")
|
||||
|
||||
(define dry #f)
|
||||
(define verbose #f)
|
||||
(define very-verbose #f)
|
||||
|
||||
(define (main args)
|
||||
(let-args (cdr args)
|
||||
((averbose "v|verbose")
|
||||
(averyverbose "very-verbose")
|
||||
(adry "n|dry-run")
|
||||
(help "h|help" => (cut show-help (car args)))
|
||||
. restargs
|
||||
)
|
||||
(set! dry adry)
|
||||
(set! verbose averbose)
|
||||
(when averyverbose
|
||||
(set! verbose #t)
|
||||
(set! very-verbose #t))
|
||||
(match restargs
|
||||
[("admin") (do-admin-mail)]
|
||||
[("send-reminder") (send-reminder-mails)]
|
||||
[("list-accounts") (do-list-accounts)]
|
||||
[_ (display "unknown command") (exit 1)]))
|
||||
0)
|
||||
|
||||
(define (do-admin-mail)
|
||||
(send-email "admin@hacc.space" "unused accounts list" (mk-admin-mail unused-accounts))
|
||||
(when verbose
|
||||
(display "done")))
|
||||
|
||||
(define (do-list-accounts)
|
||||
(display (string-join
|
||||
(map
|
||||
(lambda (row) (format "~a (~a)" (list-ref row 0) (list-ref row 1)))
|
||||
unused-accounts)
|
||||
"\n")))
|
||||
|
||||
(define (send-reminder-mails)
|
||||
(map (lambda (row)
|
||||
(send-email (list-ref row 1) "Unbenutzter infra4future.de Account" (mk-email (list-ref row 0) (list-ref row 2))))
|
||||
unused-accounts)
|
||||
(when verbose
|
||||
(display "done")))
|
||||
|
||||
|
||||
(define csv-reader
|
||||
(make-csv-reader #\,))
|
||||
|
||||
(define unused-accounts
|
||||
(map (lambda (str) (with-input-from-string str csv-reader))
|
||||
;; (process-output->string-list `(cat example.csv))))
|
||||
(process-output->string-list `(sqlite3 -csv ,sqlite-path ,sqlite-query))))
|
||||
|
||||
(define (mk-email displayname last-login)
|
||||
#"
|
||||
Hallo ~|displayname|!
|
||||
|
||||
Wir haben schon lange (seit über einem Jahr; dein letzter Login war um ~|last-login|)
|
||||
nichts mehr von dir gehört und würden demnächst deinen Account löschen wollen.
|
||||
Solltest du ihn noch benötigen logge dich bitte einfach auf https://login.infra4future.de ein.
|
||||
Falls nicht, musst du weiter nichts tun und wir werden deine Account in ca. 3 Monaten löschen.
|
||||
|
||||
Viele Grüße,
|
||||
das Infra4Future Team
|
||||
")
|
||||
|
||||
(define (mk-admin-mail rows)
|
||||
(format #"
|
||||
Meow!
|
||||
|
||||
this is the uffd-unused-accounts-notification.scm script. There are currently
|
||||
~~s accounts which have not logged in since ~|cutoff-date|. To mass-send account
|
||||
expiry reminders, invoke this script with the \"send-reminder\" option. To see a
|
||||
list of these accounts, invoke it with the \"list-accounts\" option.
|
||||
|
||||
(invoke me,, 🥺)
|
||||
" (length unused-accounts)))
|
||||
|
||||
; utility definitions
|
||||
|
||||
(define (send-email address subject text)
|
||||
(when verbose
|
||||
(display (format "sending email to ~a\n" address)))
|
||||
(let ([text (string-append "from: admin@hacc.space\n" "subject: " subject "\n" text "\n")])
|
||||
(when very-verbose
|
||||
(display text))
|
||||
(call-with-output-process
|
||||
(if dry '(cat) `(sendmail ,address))
|
||||
(lambda (port) (display text port))
|
||||
:on-abnormal-exit :ignore)))
|
||||
|
||||
(define (show-help progname)
|
||||
(display #"
|
||||
~|progname|: unused account expiry helper script.
|
||||
|
||||
Invoke as `~|progname| [options] admin' to send a list of unused accounts to administrators.
|
||||
|
||||
Invoke as `~|progname| [options] send-reminder' to send a reminder email to all
|
||||
currently unused accounts.
|
||||
|
||||
Options:
|
||||
-v --verbose show which emails are being sent
|
||||
--very-verbose also print emails to stdout
|
||||
-n --dry-run print emails to stdout instead
|
||||
-h --help show this help
|
||||
"))
|
||||
|
12
secrets.yaml
12
secrets.yaml
|
@ -1,13 +1,15 @@
|
|||
hedgedoc-hacc:
|
||||
env: ENC[AES256_GCM,data:e2vSolxJNucya9QNs28gAVDBJQq5AJh7jS1nBh0UTkDnhNL8NPW1KTxcun4rM99EhiNZsz6Z9qHRMejmP4frQw==,iv:DqAGhGWYf/EpGnI79MxKmBlHMhK26zx50vXb1TbvESw=,tag:Xix499XAcAmxhNuGr2ApcA==,type:str]
|
||||
mattermost:
|
||||
env: ENC[AES256_GCM,data:ftWpGl6+sUMzJJKgfcPLvbFGGn16AKUPzPn8X6DNVMLrxZIkQ23Tk3ekKLKFpQEUtQfFjVlrTfFZezWKs4nVNLg2LmQqJNGMCCax5PRwAgoAsJ7pa9ewNmHT+EIXtZEjQgVfN5786Yno5n/6JJ1lz6EiGmdn7/0rF5TLGjzig17azazS1+lkIYY=,iv:SZvGGKpVRI/odHbmgY8M6t6zCk8RgM+7EQEgRiizglA=,tag:cInsVo/QD85m+LxldyRlnA==,type:str]
|
||||
env: ENC[AES256_GCM,data:4GcV8UOYmVUjZoYc0Nq/vEWtxtYNV81zVTEyFnZIfY1k/Ar1MU+fn5A99JLIMc8U84/QupDU7TcneiN/wqPv2jYqGS7ixSNTk+x5uUPMarzKZ04ynav6FCWEvlSF0Sz4/5s/Pvp1Qi3zdv16ZVGUHbM8/wCcaZBkSS0ofwBTIXVsVYSRPFxLehtBgwjAnD46qS+YJmszmd7V5N/adWWF34vAdfLiO6Y7KDB3jnMLOPU6Drtw9L83AW6NuOtk8crZrI1dkTD/xUC07IvMhZpZVc9ktQJqIvlk/ADs5aIp/QYrjICdYvb8xC16oV7jC/7yzXzC/UuYbCvS5gnHGMK/CsBkmM9HXmQ6mWjrfuOJEkMHSefS7O8HyrNoNDSXq0ivCr6KJmwrz7NXNAE6a6xx9LMjs5DJ8H5fda1l5TGVAdA2tg==,iv:dG4cnEtUgUxw7zS2k15p+6//Bl19WquTfFIiz5Vi/0M=,tag:cMBU8CtFBBjfcfpO709Kpg==,type:str]
|
||||
mattermost-s4f:
|
||||
env: ENC[AES256_GCM,data:QFS3D/KXIZy9NJ7cocGKXRCvFLHIaLysnLr3OKWU4VoqRX/yykxGbVTOaC/li0s1bsbnm46xKKWzvnrZjMxj+xjItlpNcII4+Z0=,iv:Qj6+AFG/+HpTB8zBXcQF3PdfLo+ZybTRFCGIMpK3Tuw=,tag:BK7FaXUoWcEcttVE6crNhg==,type:str]
|
||||
tracktrain:
|
||||
env: ENC[AES256_GCM,data:W3+8qWomPgGJt5u50aAm9x/dilMpqKY11I2AdaIBTz5posc25ts0LB5S/Sxe1ROz4itpDK3QvjoFUTRhS39k4dwMr5lqXV8Ln4B+sPpvh7oBM8A5zydP8Jj1J1YqRt8++RTUmb4z41DIwb/yaZKMu6z0guXIu1yuYzcbCuk0xe/iOp6UUpfjOzzWTvxY54zY6kWcjHLiCSwD31Cd+MxMPfbUEkHt+0W+sBmYXGeEFI/6ULSB6FnGjNW6F9g=,iv:3ymah8HG+Yg6VYZZA/MRRjHDYvYJz01ezvhfQiftegg=,tag:trht+PRYfKgWJkg2wRwISQ==,type:str]
|
||||
env: ENC[AES256_GCM,data:jaq039FNxBrsPfG/q+InYpiyl1LBdY++DlLM6UpSAwKlINucooTrHz51QrdRWhAZDqXhVTHM55Q/Zm4wazweCABiNjkXDFoZgxc5YJX+pvBct6M533xl109yD6KiYOXDqPY03u71aop8OmOAnKDp1JlzPS1otdlaN8Vd56G+,iv:nYU2rgMMG4QcJo5DnZpYZm1zr82idd7r1uTsqNiXLdA=,tag:9rdxAneYUREacXNunpTuHw==,type:str]
|
||||
vaultwarden:
|
||||
env: ENC[AES256_GCM,data:hdm91tI8WBd3es+IUbdBO69kh1pNZTNvZNFIdSZO8lm4yYMPE+Jm7EzVqwOaZRbpQaVDBg7uh5P4ODc=,iv:no7U0wQCwZOeL2pwXf2pUIgrEsEOYwqOT04LvpCl614=,tag:AGSu5M7H69x6pDM062bC6g==,type:str]
|
||||
auamost:
|
||||
secrets.fish: ENC[AES256_GCM,data:QBteJdVPSWa4cmu1BVWJ3AMWWH4zIv2+G83fK0QsbA/fYoIU5jobCT3USyujNz+jQaAAxA45jmQbCWNAFLl1q8hP4i9EIikVECx0VKVXPXILBND+w7zPSLldAbOugRYt2iAt1dDADZPtulKlkz7usdafbB+2igLXdyFRLfIxDTOrBuqQ+5yeofQe5k0XWRcmQQ/1AV0JrRrmLmr69VKsR932JWD8XxmI/HFyZPzWdExBSOmvnj+m4K+DV4cVmN4t6XOY0dM3gRQ95DglEuGlp/V2o3GqwY0mXCvhM1eh81u8mPALKp6Pv2i2yU35F01Puf5t1FHGDfzp0bW0xuKEywfGjAOifFkSE/3JFir434B6G0DiJNpOIl6QJ6DA8rSKfuPdccm6Or0zX8iJGRHDJmREQ05V9l0jHAAxLNuNdbsxg+8kCWVVnW+d1YDn9KW7LbFlP+sx4Ef5leUYft/lYhF4Z5Xp3arqVrlebWjWIBEuZeJTnkE3y+TdUUCs360zzWHqsipGmo1+/88CEqL52FfUOlJ4VCR45/7nYZ3RaRBWDGFW8RvwmWSFSstEcEXQ01U8lCwyn40+blfltme3KJ1f+pWMrZAKhPlOlMHCYfjd7esWI2sYcQbTZqxH49GnW6dsW/W+eiLs3zlD/Deb2CugHe63zRdlivmVPOz4zD1PXcCVpEZHoTTiJl7Om9K2mPYq9wQN41wsDUrNL9p8m9UlhWKbjBh5UU7p6F6OhF5rKH/Fs8fIaPi6B8uamTvEmiOGTUWl3vmQjBvhM8fJWoIkRB8hgCisr9OZ,iv:8jVAImjeXbXfiLKg9G0PyLMTV8cAyDmukeittqjKFpQ=,tag:fLIcsWKbdFQ/vPCgi/W3Zw==,type:str]
|
||||
secrets.fish: ENC[AES256_GCM,data:Dyb0Byigh4tmkmdz7KxkgvudO830x8+1qNQBOT+ohydOY3OeuJseJQ/rjaYhMTfh6tcKpu1aSarKRINbJp2u0yu+eazVV69CRzu9OlsXaMD6Rbvw4Cn0LttJhjK1za8+fXm7IZsAhErrV6WmU1/JryQkZf18hxMrO5EBmFy4ONHNj3lc4pApMUqXLiVL6xaW+Mix+jx4gT8r0/0lpAdT5oObPPBo+HIDJEGj+QPBvxNBJaURKVRX5+8fe4+hFzqBjU7QJ/LLPBo2lp2BLgo39qCeLaHogkWMXEYPb4/eaW0SZ8/Z56gh7dsO5X1r8kSAEMDoYVCC6KrXDh2M48/lYT+biid8iALCphatpZzH9CbV0FWIcZ5s0q8fApTZ1ubtiVqRNN1niGajgLGe5TSQcPAQs1yCBQ+9BJSDro9qNNXXlVpHO59Dfs2w+f2FBBQOnOIqhxQPbyhzIep3kRuIH42rowGG66uOJaC7g1W5fCwkdBNDZK8D01nj1+PA17j3xExqTT4+m1oUSlROhDRgxf+nYWkuxaAM1z+FsTswFHzdBJ8wtK56z+dpBH2f3SNW/5bwMif00uS1z+6U4yuCl0sdh0SF/yLjbIyvMwPiy7xzaBEZ+bve6ps0yh1sYvyLN7vxs7tRhtN0yLs28ZeT5BEwJAiKP1+KWhK86XbKh3fMtfl5V06xyW4aBkeYC4cg2wSNlvlDrbIrtPsJMHQt/swsHvIde4AfEyzhrTs8ezuVRbm/9glTVh1mzw==,iv:MpaFGYbcTXdFabV+vlGyGxexpfP7LUpYYBjF6GVEN7c=,tag:n8qTOhnbBT7Xxz21bU0bYQ==,type:str]
|
||||
restic:
|
||||
s3creds.env: ENC[AES256_GCM,data:9WNu5S4KmdMXdshSpawEjIexAKH6vZCPwb9xyq6xmerly1lxSfFZzgg60M0L3L+I4joLTVi23YBB8Eh6Xfx9GgxNww7w7BjMCQs/X16ecDWlb346TKf+,iv:Gu4CbXXJAlQYXRqOjIAUYmn8EU4mrvcOVc2eCh1Ikzs=,tag:1xpVIonHiAGHsXTY9liPQQ==,type:str]
|
||||
system: ENC[AES256_GCM,data:RIgO0QHVjwp2D3LoU62vLzepASdsXxu0DqUTA6Voa3K1d4xFHX2u+UR8AcqR,iv:O0K8i5ivne7WU+ygDEUcrvKW6DIfXjVPY63gpfsxEFE=,tag:n/1atQ5qlyB0SMHrYiTCrA==,type:str]
|
||||
|
@ -98,8 +100,8 @@ sops:
|
|||
bndBTXJhQVE2OVlKeGNTbzJlL0duUzAKIWdesesYvBIN/m36fhzxq30+IT8qp/pF
|
||||
S6i7QqZF75y2BpEoupRCqNIAsHrouUE+U9ZQJZO8m9J591mWvbVJIw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2024-07-26T13:05:44Z"
|
||||
mac: ENC[AES256_GCM,data:9A8nX155dpCC1cvdH1hgeNKh0tt5FMaOKU7vZQ33jfWbiXOsJbp5iHKXxWOexFc70acyhdweoHwq61oJm2mzVufJIPA55ZAUItQcDXJCCeu6KswHug0tQtKHoCRSwdTdMTRNom4XjrpA/j4WWpuhoilyknycXqTpGHHVSdL2lYg=,iv:N0zwzGtGzAxhbmLzslbkXSr/iKmq5FeyT/iWeE4x2hQ=,tag:yIoLXpqlU2SlVRK5+S/qaw==,type:str]
|
||||
lastmodified: "2024-03-11T00:55:56Z"
|
||||
mac: ENC[AES256_GCM,data:JccZYv1R0dxH64o7imEcL+/lat1GpipChoOVpRhcQsjNteEkmhp8lzLto1+P7kQNiKtutsfNedLKw/THQMDk3MuTneOPO93PeQwzwBLqM3lDLVecIndUV9ARZ1B1W/687aUMbPGMYWODbe3loQMNrtT0WoPp8otWjUSfp0/W31E=,iv:UqFxIeGH3xXMdK9LJHyiQmC1AtiLfX+CAMBKfAhEBMg=,tag:9wBmdUaJOykcyFnxkFvJGw==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
||||
|
|
|
@ -11,8 +11,8 @@ default_language = "en"
|
|||
|
||||
# might be useful — this isn't a blog, obviously, but updates for new entries
|
||||
# could still be nice, I guess
|
||||
generate_feeds = true
|
||||
feed_filenames = [ "atom.xml" ]
|
||||
generate_feed = true
|
||||
feed_filename = "atom.xml"
|
||||
|
||||
build_search_index = true
|
||||
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
{ copyPathToStore, stdenvNoCC, zola, writeShellScriptBin }:
|
||||
{ stdenvNoCC, zola, writeScriptBin }:
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
name = "docs.hacc.space-static";
|
||||
|
||||
src = ./.;
|
||||
content = copyPathToStore ../../docs;
|
||||
# HINT: this is cursed. Nix flakes have no optimisation to deal with ${./.},
|
||||
# so we wind up having to do this to make the symlink to content/ work.
|
||||
# (we still need to manually adjust it — but at least this way we can find
|
||||
# its target without further hoops)
|
||||
#
|
||||
# This does also mean we now copy the entire flake into the Nix store twice.
|
||||
# Yay for flakes!
|
||||
src = "${../../.}/websites/docs.hacc.space";
|
||||
|
||||
phases = [ "buildPhase" ];
|
||||
buildInputs = [ zola ];
|
||||
buildPhase = ''
|
||||
cp -r $src/* .
|
||||
rm content
|
||||
ln -s $content content
|
||||
ln -s $src/../../docs content
|
||||
zola build --output-dir $out
|
||||
'';
|
||||
|
||||
watch = writeShellScriptBin "watch" ''
|
||||
watch = writeScriptBin "watch" ''
|
||||
cd $(git rev-parse --show-toplevel)/websites/docs.hacc.space
|
||||
${zola}/bin/zola serve --output-dir /tmp/hacc-docs "$@"
|
||||
'';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ stdenvNoCC, sfz, writeShellScriptBin }:
|
||||
{ stdenvNoCC, sfz, writeScriptBin }:
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
name = "hacc.earth-static";
|
||||
|
@ -13,7 +13,7 @@ stdenvNoCC.mkDerivation rec {
|
|||
rm $out/default.nix
|
||||
'';
|
||||
|
||||
watch = writeShellScriptBin "watch" ''
|
||||
watch = writeScriptBin "watch" ''
|
||||
cd $(git rev-parse --show-toplevel)/websites/hacc.earth
|
||||
${sfz}/bin/sfz "$@"
|
||||
'';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ stdenvNoCC, sfz, writeShellScriptBin }:
|
||||
{ stdenvNoCC, sfz, writeScriptBin }:
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
name = "muc.hacc.earth-static";
|
||||
|
@ -13,7 +13,7 @@ stdenvNoCC.mkDerivation rec {
|
|||
rm $out/default.nix
|
||||
'';
|
||||
|
||||
watch = writeShellScriptBin "watch" ''
|
||||
watch = writeScriptBin "watch" ''
|
||||
cd $(git rev-parse --show-toplevel)/websites/help.studentsforfuture.info
|
||||
${sfz}/bin/sfz "$@"
|
||||
'';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ jekyll, stdenvNoCC, writeShellScriptBin }:
|
||||
{ jekyll, stdenvNoCC, writeScriptBin }:
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
name = "infra4future.de-static";
|
||||
|
@ -11,7 +11,7 @@ stdenvNoCC.mkDerivation rec {
|
|||
${jekyll}/bin/jekyll build -d $out --disable-disk-cache
|
||||
'';
|
||||
|
||||
watch = writeShellScriptBin "watch" ''
|
||||
watch = writeScriptBin "watch" ''
|
||||
cd $(git rev-parse --show-toplevel)/websites/infra4future.de
|
||||
rm -rf /tmp/hacc-website
|
||||
${jekyll}/bin/jekyll serve --disable-disk-cache -d /tmp/hacc-website "$@"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ stdenvNoCC, sfz, writeShellScriptBin }:
|
||||
{ stdenvNoCC, sfz, writeScriptBin }:
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
name = "muc.hacc.earth-static";
|
||||
|
@ -13,7 +13,7 @@ stdenvNoCC.mkDerivation rec {
|
|||
rm $out/default.nix
|
||||
'';
|
||||
|
||||
watch = writeShellScriptBin "watch" ''
|
||||
watch = writeScriptBin "watch" ''
|
||||
cd $(git rev-parse --show-toplevel)/websites/muc.hacc.earth
|
||||
${sfz}/bin/sfz "$@"
|
||||
'';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ jekyll, stdenvNoCC, writeShellScriptBin }:
|
||||
{ jekyll, stdenvNoCC, writeScriptBin }:
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
name = "mumble.infra4future.de-static";
|
||||
|
@ -11,7 +11,7 @@ stdenvNoCC.mkDerivation rec {
|
|||
${jekyll}/bin/jekyll build -d $out --disable-disk-cache
|
||||
'';
|
||||
|
||||
watch = writeShellScriptBin "watch" ''
|
||||
watch = writeScriptBin "watch" ''
|
||||
cd $(git rev-parse --show-toplevel)/websites/mumble.infra4future.de
|
||||
rm -rf /tmp/hacc-website
|
||||
${jekyll}/bin/jekyll serve --disable-disk-cache -d /tmp/hacc-website "$@"
|
||||
|
|
Loading…
Reference in a new issue