forked from hacc/haccfiles
Compare commits
318 commits
nextcloud2
...
main
Author | SHA1 | Date | |
---|---|---|---|
6f70382ac1 | |||
656987563c | |||
37618af4da | |||
169a165a92 | |||
9ada0691dc | |||
dce974cab6 | |||
fdea9ee2c1 | |||
0e1f14957e | |||
69e51f1e76 | |||
8f81701589 | |||
849098c386 | |||
cb012aba67 | |||
aaf4e86da3 | |||
6c72210b0e | |||
243f091a49 | |||
3345eb97dc | |||
589499fbf5 | |||
0fa4849c3d | |||
c6dc74b3b7 | |||
60acc52ec7 | |||
7be555013a | |||
ca0c1192a0 | |||
0caa57a30e | |||
60c661317c | |||
a5dd06225b | |||
1d92eb6de9 | |||
2d99878838 | |||
da3795d35b | |||
41670c996f | |||
b409d603a9 | |||
6cd10a640c | |||
cb7975e778 | |||
697bbedd41 | |||
2ef1aeca1b | |||
d27d9e8722 | |||
c295604a13 | |||
4dc9cdac91 | |||
67da5a7c8a | |||
272b3e6e51 | |||
4d5e82a0d9 | |||
1cc938a0b8 | |||
c3c7fe44de | |||
eaa25de128 | |||
5d598bafaa | |||
79610d6adc | |||
ea2500ff79 | |||
34a27e9dc8 | |||
960426f68f | |||
87b1f4a0eb | |||
9e7f02ae7b | |||
47ee7ac1ab | |||
db2d353029 | |||
84dddea096 | |||
e88833120a | |||
d1e5820166 | |||
5fe7a12b74 | |||
fbeaf68490 | |||
2de13398e6 | |||
89dd5499a4 | |||
cabc8706a3 | |||
b314c296b2 | |||
8dcc83b017 | |||
7a05ceb813 | |||
5f982dad47 | |||
f045684f7a | |||
47869a3c8d | |||
1f871af807 | |||
cca5abe131 | |||
83d800164c | |||
4ffedfe532 | |||
285a8e6a8e | |||
ed667e15e9 | |||
75cc371c01 | |||
0a208223c8 | |||
8b6ce305d7 | |||
215bed6418 | |||
147fe172d9 | |||
2cd0de8eeb | |||
3e40d82579 | |||
f749f4ed48 | |||
679df4d856 | |||
05af3ac4f8 | |||
efadc5ada9 | |||
d933a6ef98 | |||
6e84a9f9f8 | |||
8c3d3bf6db | |||
972a26163a | |||
27b8ef6784 | |||
8662943183 | |||
f9005dd4d0 | |||
f654b33a56 | |||
3dc63acf52 | |||
208bcaa898 | |||
d4d3f6e5d2 | |||
f75169ce0a | |||
d99408486a | |||
d20acbfe58 | |||
281745d7a6 | |||
1ad0a7751c | |||
5e51d5f252 | |||
069236027c | |||
283aba0c2c | |||
faa83b6007 | |||
e81472cb87 | |||
1cee814e04 | |||
8da02ed645 | |||
8283162109 | |||
8f7f5448a3 | |||
319e5894e0 | |||
55b0b3558d | |||
3fb25aa016 | |||
7b9e423999 | |||
f29830ec93 | |||
e12cc7dbf5 | |||
cbc7827cb9 | |||
1042c90d8a | |||
ea230c34b0 | |||
62917423e3 | |||
0f678c5e80 | |||
0140b7a9fb | |||
39531f1c48 | |||
461cb01126 | |||
2988939be0 | |||
7427df5167 | |||
1ccc0ccbca | |||
5dd817796f | |||
a36d2a7617 | |||
c28a1f6e2e | |||
c681bb413c | |||
062e123046 | |||
93cc8b8172 | |||
816e175b33 | |||
a3c6479dbe | |||
abfc5618e9 | |||
c0f37da12f | |||
12e4cba3e6 | |||
68dc640257 | |||
41d82ae436 | |||
c2022d9c60 | |||
990d48a1c7 | |||
d011fcb56d | |||
b38e6a0ebc | |||
a72f35de35 | |||
4e17d6034c | |||
2008876dc6 | |||
910caf3485 | |||
226508d4b0 | |||
cb87d88a13 | |||
658e9046c5 | |||
c3457207cd | |||
4d91e1f591 | |||
01d972c9ed | |||
9d187d212a | |||
17149be4bd | |||
920ea9e8d4 | |||
f03a582345 | |||
641c59092c | |||
b5855fe379 | |||
0f19d712cb | |||
448ea1b831 | |||
ea5a77703e | |||
8186160c1b | |||
e03bf84d3a | |||
a4288d77ce | |||
3ce4b83464 | |||
9e7929ab5f | |||
a8f7ee667d | |||
eae84263f5 | |||
6586f0c552 | |||
f9d7496af7 | |||
a17cd69a52 | |||
54fe6bfce7 | |||
17ead057f4 | |||
3407e873ef | |||
4b40d665fe | |||
6529cb79a0 | |||
72ca5b2888 | |||
74654f2fc0 | |||
4fb06c3e10 | |||
d7d15f4b0b | |||
c18215f356 | |||
6a4ff47443 | |||
109aada070 | |||
2d542e9167 | |||
d8e937a91d | |||
57b6eac7c2 | |||
e5d57ebec9 | |||
6a51e74c73 | |||
5bd2c5ab4c | |||
3099798468 | |||
b5d4f76a1d | |||
003f2f7e44 | |||
0d75469590 | |||
49fa2325f3 | |||
a3689d1c76 | |||
eda184ee48 | |||
8d9df0e20e | |||
fb3c1b0a96 | |||
b30df7ea6d | |||
26f3f98a9c | |||
f91ea850bc | |||
a6d21f4fd9 | |||
7fd1c9ff80 | |||
ba91526fc8 | |||
72c16d9e1c | |||
aa62e616a3 | |||
30510a3194 | |||
dc1bdb2682 | |||
5fee4c445d | |||
9ac7307672 | |||
26f91fac20 | |||
9185f3e0ab | |||
2e74ca9b35 | |||
4c456eae1c | |||
7a3e65a3f5 | |||
9af819b4b8 | |||
82e2831d3a | |||
15c49c657f | |||
87fd563ad3 | |||
eb7183ac54 | |||
1a54dbd191 | |||
015f66d749 | |||
|
ba5bcf601c | ||
9363c9e004 | |||
34a147afe6 | |||
1720b7bf81 | |||
bb24ce8b87 | |||
7e00264911 | |||
c5a0f13884 | |||
bcc27eba11 | |||
c28e533257 | |||
84dab162c1 | |||
f75429781d | |||
5a28a55f01 | |||
3df1ec0436 | |||
b15f303107 | |||
0f4957d860 | |||
ea2d89fa84 | |||
7fa5939cf9 | |||
12da955842 | |||
0127b30566 | |||
5a0496a8f7 | |||
d11c388f31 | |||
79fb386395 | |||
fe2fd2e0eb | |||
eb13717e28 | |||
7b145988d2 | |||
1b09180b38 | |||
c09337c973 | |||
025d17c487 | |||
319f827aa0 | |||
d6d45685c7 | |||
b1974aa2d0 | |||
de1e7366f3 | |||
401898b284 | |||
380934299b | |||
13b81b37f4 | |||
f281c90da5 | |||
eb8807feff | |||
a8b3f4b16c | |||
4bd1430f0a | |||
daac7ebcb0 | |||
e29cd5f887 | |||
39a1719188 | |||
c12ae3231a | |||
4969444bc4 | |||
25e9fb85a3 | |||
63cf62849b | |||
acd051e4e0 | |||
620c1a30e4 | |||
55f17ad7c3 | |||
0e20c9ddfa | |||
1291d3c9f6 | |||
cde949ac5b | |||
052e1ac126 | |||
0686807690 | |||
e8d36fc259 | |||
2e92960390 | |||
e229538bde | |||
0fe3094853 | |||
f64b1f9534 | |||
52f9f2d64c | |||
714a8e5d73 | |||
55ffc7282e | |||
5821a58d23 | |||
86ff63683c | |||
35853d56e2 | |||
41c914991a | |||
f2c90e5601 | |||
77d7625315 | |||
|
04272968d0 | ||
7e615e6daa | |||
82e70e0151 | |||
6bba15faae | |||
9bf75b9c3d | |||
83cda0f44a | |||
97459d8177 | |||
6aa06aed18 | |||
639410011e | |||
|
7db9dbb4c2 | ||
|
856cd79c37 | ||
3ea537459b | |||
f53cb24d2e | |||
45ceeef189 | |||
e246563f57 | |||
a1c5832a51 | |||
c854e10980 | |||
b5a68e09fd | |||
f9f1eee6fd | |||
|
db5865fff2 | ||
|
65ec0779b7 | ||
4b53211130 | |||
|
86b9d3113c | ||
|
39aaf2e0bb | ||
|
8021685ec8 | ||
8f413da05a | |||
e9d2630ea9 | |||
445a974f97 |
119 changed files with 3059 additions and 26994 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@ result
|
||||||
ecdsa_host
|
ecdsa_host
|
||||||
secrets/
|
secrets/
|
||||||
.*.swp
|
.*.swp
|
||||||
|
.deploy-gc/*
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
stages:
|
|
||||||
- build
|
|
||||||
|
|
||||||
build-parsons:
|
|
||||||
tags:
|
|
||||||
- nix
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- nix-build -A deploy.parsons
|
|
1
.rgignore
Normal file
1
.rgignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
websites/*
|
23
.sops.yaml
Normal file
23
.sops.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
keys:
|
||||||
|
- &parsons age1yql8qaf7upraqy4cq397tt4vgs046hq0v59qymla8t3x0ujqvu4sesgsvw
|
||||||
|
- &hexchen-backup age1zgdegurzlr8cw9948wgf4q5qh3efltwhhzus5tt6az5xvvsux9us2v4tyd
|
||||||
|
- &stuebinm-ilex age18wkr3kjalalzrq9l05q32gnlaqr7t6rqqzde307m83rs9fp4xcfsdtj9gt
|
||||||
|
- &stuebinm-surltesh-echer age1q88az2y5hnx8naqsvrurllqj6y5gtehrpa9emmrxy5ghwsr7pvnqf7tfpx
|
||||||
|
- &stuebinm-abbenay age18nkru4pwvvapdw76nauv2xdtlj8cvyv3ugahe9kcxtvtsptx2eyqw7p0m6
|
||||||
|
- &octycs-m age1fm3e99tdyrsvztdchxxllt9nat35xzvd68d09y8scu9jfc7kvvuquhr49c
|
||||||
|
- &zauberberg-conway age16fk0m26n0fr2vmuxm2mjsmrawclde2mlyj6wg3ee9jvzmu5ru3ustgs5jq
|
||||||
|
- &moira-2022-06 age1l694a4xht7r0eza9r2vjncupmp6cxyk3k9x2ljwynnur4m2lc5jqmy3jut
|
||||||
|
- &moira-openpgp age1m374x78q9eykua32ldrqxh8rh36kz6jyre69a263krf28hcycsqsrmshl0
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: secrets.yaml
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *parsons
|
||||||
|
- *hexchen-backup
|
||||||
|
- *stuebinm-ilex
|
||||||
|
- *stuebinm-surltesh-echer
|
||||||
|
- *stuebinm-abbenay
|
||||||
|
- *octycs-m
|
||||||
|
- *zauberberg-conway
|
||||||
|
- *moira-2022-06
|
||||||
|
- *moira-openpgp
|
24
LICENSE
Normal file
24
LICENSE
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
80
README.md
80
README.md
|
@ -1,31 +1,64 @@
|
||||||
# hacc nixfiles
|
# hacc nixfiles
|
||||||
|
|
||||||
welcome to hacc nixfiles (haccfiles). this is the code describing our nix-based infrastructure.
|
Welcome to the hacc nixfiles (haccfiles). This is how we configure (most of)
|
||||||
|
our infrastructure.
|
||||||
|
|
||||||
## structure
|
## General layout
|
||||||
|
|
||||||
- `default.nix`: Entrypoint to the config
|
- `flake.nix`: Entrypoint & dependencies
|
||||||
- `common/`: configuration common to all hosts
|
|
||||||
- `desktop/`: desktop-relevant communication
|
|
||||||
- `modules/`: home-grown modules for hacc-specific services
|
- `modules/`: home-grown modules for hacc-specific services
|
||||||
- `nix/`: sources files, managed with niv
|
- `pkgs/`: packages we need which aren't in nixpkgs
|
||||||
- `pkgs/`: packages we built and don't want to upstream
|
- `websites/`: static websites hosted by us
|
||||||
- `hosts/`: configuration.nix per host
|
- `common/`: meta-level config, reusable across machines
|
||||||
- `services/`: all services we run; imported in appropriate host config
|
- `parsons/`: our sole server, its config & the services it runs
|
||||||
|
|
||||||
## working with the haccfiles
|
Right now, we only have a single host. We might add more again in the future.
|
||||||
|
|
||||||
deploy:
|
## Working with this repo
|
||||||
``` shell
|
|
||||||
nix build -f . deploy.$hostname && ./result switch
|
|
||||||
```
|
|
||||||
|
|
||||||
`$hostname` can be replaced with any hostname or group
|
You will need a flake-enabled nix installation, and have your ssh config set up
|
||||||
|
so that `ssh parsons` will connect to `parsons.hacc.space`.
|
||||||
|
|
||||||
|
### Deploying remotely
|
||||||
|
|
||||||
|
It's recommended to use [deploy_rs](https://github.com/serokell/deploy-rs):
|
||||||
|
~~~shell
|
||||||
|
deploy .#parsons -k [--dry-activate]
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Alternatively, using just `nixos-rebuild`:
|
||||||
|
~~~shell
|
||||||
|
nixos-rebuild --flake .#parsons --target-host parsons \
|
||||||
|
--use-remote-sudo --use-substitutes [test|switch|dry-activate]
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Re-deploying on parsons itself
|
||||||
|
|
||||||
|
Simply do:
|
||||||
|
~~~shell
|
||||||
|
nixos-rebuild --flake .#parsons [test|switch|dry-activate]
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Working on websites
|
||||||
|
|
||||||
|
Websites are exposed as flake outputs: if you're working on a website & want to
|
||||||
|
check it in a browser, do e.g.
|
||||||
|
|
||||||
|
~~~shell
|
||||||
|
nix run .#\"muc.hacc.earth\"
|
||||||
|
~~~
|
||||||
|
|
||||||
|
to start a local http server (note that some of our websites need a directory
|
||||||
|
to be built in; these use `/tmp/hacc-website`).
|
||||||
|
|
||||||
|
To add a new website, add a new subdirectory to `websites`; nix will generate a
|
||||||
|
vhost config based on that directory's name. Add a `default.nix` in your directory
|
||||||
|
describing how to build the website, and give its derivation a `watch` attribute
|
||||||
|
to make the `nix run` setup work.
|
||||||
|
|
||||||
## I don't want to build this long dependency / want a cached version!
|
## I don't want to build this long dependency / want a cached version!
|
||||||
|
|
||||||
If it's still available on parsons from a previous deploy, do:
|
If it's still available on parsons from a previous deploy, do:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
nix copy --from ssh://parsons /nix/store/...
|
nix copy --from ssh://parsons /nix/store/...
|
||||||
```
|
```
|
||||||
|
@ -36,12 +69,13 @@ don't know the actual outpath, look in the .drv file (should start with
|
||||||
`Derive([("out","[the path you want]"...`)
|
`Derive([("out","[the path you want]"...`)
|
||||||
|
|
||||||
## committing to haccfiles
|
## committing to haccfiles
|
||||||
- Golden Rule: DO NOT COMMIT TO MAIN
|
- Things on `main` should always reflect the config that's actually deployed on
|
||||||
- exceptions apply, if you are not sure where to commit, don't commit to main
|
parsons, except during testing / debugging sessions
|
||||||
- split up commits, every commit is one atomic change
|
- split up commits, every commit is one atomic change
|
||||||
- e.g. no big "did some changes" but instead "updated service x", "updated service y", "update service z"
|
- follow the commit format: "place: $change"
|
||||||
- follow the commit format: "$prefix$place: $change"
|
- place: e.g. `modules/$module`, `services/$service` ...
|
||||||
- prefix: one of fixup, nothing
|
- change: describe your change. Please wrap your lines sensibly (or configure
|
||||||
- place: one of "modules/$module", "$hostname/service", "common/($place)", "pkgs/$pkgs" or "sources"
|
your editor to do this for you)
|
||||||
- change: describe your change, don't go over the character limit where git starts hiding/wrapping
|
|
||||||
- Exception: autogenerated messages (merge commits, reverts, etc)
|
- Exception: autogenerated messages (merge commits, reverts, etc)
|
||||||
|
- don't overuse merge commits, try to rebase things if possible with reasonable
|
||||||
|
effort
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
{ config, lib, pkgs, modules, ... }:
|
{ config, lib, pkgs, modules, sources, ... }:
|
||||||
|
|
||||||
let
|
{
|
||||||
sources = import ../nix/sources.nix;
|
|
||||||
in {
|
|
||||||
imports = [
|
imports = [
|
||||||
../modules
|
../modules
|
||||||
./users.nix
|
./users.nix
|
||||||
(sources.home-manager + "/nixos")
|
|
||||||
modules.network.nftables
|
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages;
|
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages;
|
||||||
|
@ -19,20 +15,28 @@ in {
|
||||||
SystemMaxUse=512M
|
SystemMaxUse=512M
|
||||||
MaxRetentionSec=48h
|
MaxRetentionSec=48h
|
||||||
'';
|
'';
|
||||||
|
nix.package = pkgs.lix;
|
||||||
nix.gc.automatic = lib.mkDefault true;
|
nix.gc.automatic = lib.mkDefault true;
|
||||||
nix.gc.options = lib.mkDefault "--delete-older-than 1w";
|
nix.gc.options = lib.mkDefault "--delete-older-than 7d";
|
||||||
nix.trustedUsers = [ "root" "@wheel" ];
|
nix.settings.trusted-users = [ "root" "@wheel" ];
|
||||||
|
nix.extraOptions = ''
|
||||||
|
experimental-features = nix-command flakes
|
||||||
|
'';
|
||||||
environment.variables.EDITOR = "vim";
|
environment.variables.EDITOR = "vim";
|
||||||
|
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
ports = lib.mkDefault [ 62954 ];
|
ports = lib.mkDefault [ 62954 ];
|
||||||
passwordAuthentication = false;
|
settings = {
|
||||||
challengeResponseAuthentication = false;
|
X11Forwarding = true;
|
||||||
permitRootLogin = lib.mkDefault "prohibit-password";
|
PermitRootLogin = "prohibit-password";
|
||||||
extraConfig = "StreamLocalBindUnlink yes";
|
PasswordAuthentication = false;
|
||||||
forwardX11 = true;
|
KbdInteractiveAuthentication = false;
|
||||||
|
StreamLocalBindUnlink = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
programs.mosh.enable = true;
|
||||||
|
programs.fish.enable = true;
|
||||||
security.sudo.wheelNeedsPassword = lib.mkDefault false;
|
security.sudo.wheelNeedsPassword = lib.mkDefault false;
|
||||||
|
|
||||||
i18n.defaultLocale = "en_IE.UTF-8";
|
i18n.defaultLocale = "en_IE.UTF-8";
|
||||||
|
@ -57,7 +61,7 @@ in {
|
||||||
whois
|
whois
|
||||||
iperf
|
iperf
|
||||||
fd
|
fd
|
||||||
exa
|
eza
|
||||||
socat
|
socat
|
||||||
tmux
|
tmux
|
||||||
gnupg
|
gnupg
|
||||||
|
@ -71,9 +75,11 @@ in {
|
||||||
ffmpeg-full
|
ffmpeg-full
|
||||||
bat
|
bat
|
||||||
niv
|
niv
|
||||||
|
sqlite-interactive
|
||||||
|
hacc-scripts
|
||||||
];
|
];
|
||||||
|
|
||||||
security.acme.email = "info+acme@hacc.space";
|
security.acme.defaults.email = "info+acme@hacc.space";
|
||||||
security.acme.acceptTerms = true;
|
security.acme.acceptTerms = true;
|
||||||
|
|
||||||
services.nginx.appendHttpConfig = ''
|
services.nginx.appendHttpConfig = ''
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
{config, lib, pkgs, ...}:
|
|
||||||
|
|
||||||
let
|
|
||||||
sources = import ../nix/sources.nix;
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
(import sources.nix-hexchen {}).users.hexchen.base
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,11 +1,6 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
|
||||||
./hexchen.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
home-manager.useGlobalPkgs = true;
|
|
||||||
|
|
||||||
users.users = {
|
users.users = {
|
||||||
root = {
|
root = {
|
||||||
|
@ -17,14 +12,10 @@
|
||||||
uid = lib.mkForce 1000;
|
uid = lib.mkForce 1000;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
};
|
|
||||||
|
|
||||||
stuebinm = {
|
|
||||||
uid = 1005;
|
|
||||||
isNormalUser = true;
|
|
||||||
extraGroups = [ "wheel" ];
|
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDQtJQ8fUfwsC9Q39sNpZ41RRbW91QXDLKltsYK+TLidQ5IJj2KsG/lkd433Tod6PzSvB2PcfIfnvUz7GQuS1UwXHMdLEy0/kqeYrSi6QlAxFyFBSTsUZ4d+HHwBBoXhu1Iaoch/FJNI0FhfBciIii05UyYuPj5zGgvWhnfD53Ll8HA6XVXhSK09+9GRGq57Mix5N9AkzfEF83aRUF9Qfl7Jl16rOjIgtS8hbL0kXIKUeCxZA2xi/lNHEQRriCiriPmPGOhiPcNXzbekw7IbFfE3If1CHnj7KA4KnafHAd+uHvQAce5Y4v2vMOPfGVh1cm84VTzdSPEW5V1hFjOlSnnuCQtAzkQLv8zed2NLj73GgFlcUrYKERcH84wydD0gEednNKsW8T2NzgO2eNCBf0LrcFp17qmWLv51A3jofEX5tQ3PZ7zbtR4DMUmrizrsBWDYiHJOMVeMs/9TnmIc3PL17qvVvFI7OcYxl+SPPpPtaBzxXZAMIvGFppzYxRylBcBhNvE+bXXgLFXh5cbUcwgXjvrX0y8Gv/5S4E55+i2rQMqC55+O48snoSeNlQDZV+B9setXoC93K9fBurmCX8ObnNRvvghcwUl9OBSW5K9TBdl6FF3+Z3gOCIxOMGQQKJUS5/g/eLFJ+13Y5qAPS49XJzaBiTmDrRi8x22p7sU1Q== stuebinm@in.tum.de"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINJ0tCxsEilAzV6LaNpUpcjzyEn4ptw8kFz3R+Z3YjEF hexchen@backup"
|
||||||
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDI3T1eFS77URHZ/HVWkMOqx7W1U54zJtn9C7QWsHOtyH72i/4EVj8SxYqLllElh1kuKUXSUipPeEzVsipFVvfH0wEuTDgFffiSQ3a8lfUgdEBuoySwceEoPgc5deapkOmiDIDeeWlrRe3nqspLRrSWU1DirMxoFPbwqJXRvpl6qJPxRg+2IolDcXlZ6yxB4Vv48vzRfVzZNUz7Pjmy2ebU8PbDoFWL/S3m7yOzQpv3L7KYBz7+rkjuF3AU2vy6CAfIySkVpspZZLtkTGCIJF228ev0e8NvhuN6ZnjzXxVTQOy32HCdPdbBbicu0uHfZ5O7JX9DjGd8kk1r2dnZwwy/ hexchen@yubi5"
|
||||||
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4CLJ+mFfq5XiBXROKewmN9WYmj+79bj/AoaR6Iud2pirulot3tkrrLe2cMjiNWFX8CGVqrsAELKUA8EyUTJfStlcTE0/QNESTRmdDaC+lZL41pWUO9KOiD6/0axAhHXrSJ0ScvbqtD0CtpnCKKxtuOflVPoUGZsH9cLKJNRKfEka0H0GgeKb5Tp618R/WNAQOwaCcXzg/nG4Bgv3gJW4Nm9IKy/MwRZqtILi8Mtd+2diTqpMwyNRmbenmRHCQ1vRw46joYkledVqrmSlfSMFgIHI1zRSBXb/JkG2IvIyB5TGbTkC4N2fqJNpH8wnCKuOvs46xmgdiRA26P48C2em3 hexchen@yubi5c"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,7 +24,7 @@
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDobGLrA6YQAKdJkZMpAsqjlk744G/pCJEvAUNJDuT1Sr59BFKDchPT03exb0o39mjH4iqvw4JDI10RfylKbR1736Ji2yRLlbCzUdgv2CfZc28TAO0rscyT49RHJmzEEE5QD4Ge7MgvFBEmZKXAxntA8M8EbxxEVfzhWp3751BYkzrCbJiHMXcTb+BG9P6rmrraINmgUJxywym5PsMYt2sfHlVus3hSpWnCR/cu0nxmW9E6Tm6CzSkWOXOTdjVuc0Kgh5GXaKDROzJ9K7cJAhd5t8Yzqtpm2xfSU5FVVUH9i7PbXOo8FL82Xi6kWMgdFNLvKimxGqW+bCv3ROlyKWF4I+HQdfdL181KaOQ40jAvjmldrB/ZiEbuWYSBZ/XhxFkKrtBYPDFHq/a5lnH3OvcDm7+/LhwIKUnyZyQ2dXOLOTOEDsO/69xwNveCB8of9o/erDbOeb+d44cXUFpPMUTz4bHXEP6y+zz8TB8/aleGbLQCPUzRZfvazN95jGUDqkumi9B3Lf+W/KpjVUgu3NQsUuJn6khMYW9VefnJvHwzbWpqIzbzNePL4iZFECv4NHPQHO/katajnMbkCie9rfnLk1EjJnrSnZUInEygkW/7Eu4EQM2h7lU4HYfwP1c4ubCFdES0ELGqSuJRwd/ORDbgxbuKOQ7gZ3/lgHdr9KGqJQ== markus.amaseder@amaseder.de"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIQqFXSlqW+D4ZtVdCiN9IT461iwyqy2taBRD3qkvXqn m@octycs.eu"
|
||||||
];
|
];
|
||||||
hashedPassword = "$6$qQEbD8Ejx/y$6/nkX8CmFBtAlUP/UbFKVMVlA.ZvVbjQZRABqXQjU11tKpY25ww.MCGGMEKFv.7I/UH/126/q0S3ROTqePUEc.";
|
hashedPassword = "$6$qQEbD8Ejx/y$6/nkX8CmFBtAlUP/UbFKVMVlA.ZvVbjQZRABqXQjU11tKpY25ww.MCGGMEKFv.7I/UH/126/q0S3ROTqePUEc.";
|
||||||
};
|
};
|
||||||
|
@ -43,20 +34,53 @@
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" "cdrom" ];
|
extraGroups = [ "wheel" "cdrom" ];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCt34ou3NYWoUayWrJa5ISzihAAhFiwolJPmm2fF9llPUUA8DP3BQRiKeqDlkDzhWLwztb+dNIUuregiFJdRN5Q2JZBKlM7Gqb1QtPhtK+xe2pyZPX2SWKIsKA6j3VAThhXsQdj3slXu3dG8FF7j+IFg/eTgpeQIFQQkMIc204ha8OP2ASYAJqgJVbXq8Xh3KkAc1HSrjYJLntryvK10wyU8p3ug370dMu3vRUn44FEyDzXFM9rfsgysQTzVgp+sXdRfMLeyvf+SUrE8hiPjzevF2nsUP0Xf/rIaK5VayChPLXJkulognINzvuVWAdwNPDLpgGwkjglF2681Ag88bLX allesmoeglicheundvielmehr@hotmail.de"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfxXSy22k2EZwz1EtvIMwQKGWsswEBeLn5ClhuiI4Ma lukas@Conway.lan"
|
||||||
];
|
];
|
||||||
packages = with pkgs; [ ffmpeg ];
|
packages = with pkgs; [ ffmpeg ];
|
||||||
};
|
};
|
||||||
|
|
||||||
schweby = {
|
moira = {
|
||||||
uid = 1004;
|
uid = 1004;
|
||||||
shell = pkgs.fish;
|
shell = pkgs.fish;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" "cdrom" ];
|
extraGroups = [ "wheel" "cdrom" ];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKqj9RRfthjBl4+y4YH7aWetx5qs2KOE2B0oOw3pjRrQ schweby 2022-05-22"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJrcJRF71+XM5YZj+SaSiGcdVZ0IDxGBXIWssDtHiTtr moira_2022_06"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINUa7NLrRqQ3j4KSGIw0vSvLMTO0gSZeCypQnJ/Viqm8 openpgp:0xBE0BE8A3"
|
||||||
];
|
];
|
||||||
hashedPassword = "$6$zkAsaVdmIduqZxez$GY9aBlYeP41F0it/VbbZzLLLRQhHAbDdFsa3e/1GS9McTuSimMHODg6HqNVEH1zSqD3afhK/0UHfqbtF5qpi90";
|
hashedPassword = "$6$zkAsaVdmIduqZxez$GY9aBlYeP41F0it/VbbZzLLLRQhHAbDdFsa3e/1GS9McTuSimMHODg6HqNVEH1zSqD3afhK/0UHfqbtF5qpi90";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
stuebinm = {
|
||||||
|
uid = 1005;
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" ];
|
||||||
|
shell = pkgs.fish;
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG7J3peZGB4XGJKI1dV5PdpQS+TzmoJ7qL//ipCG7G5K stuebinm@surltesh-echer"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKPB74xA2GBXnDwPEEaxWLONdQyBwjDoJHYagKRQXwO2 stuebinm@abbenay"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH8e9WrHsknoFwBm/YaigOSz9VI8dXRRR5G9BX4kKt9/ stuebinm@ilex"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
leah2 = {
|
||||||
|
uid = 1006;
|
||||||
|
shell = pkgs.fish;
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" "cdrom" ];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK4o/ncaQUorp/BeZesPnVhzvfoqLJW3WZHtz+CWQvFU"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
floppy = {
|
||||||
|
uid = 1007;
|
||||||
|
shell = pkgs.fish;
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" "cdrom" ];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDyVQhFDcoMnoYivQu1h8NCTWa+2WriZ1m5BilkuUk4u"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
11
default.nix
11
default.nix
|
@ -1,11 +0,0 @@
|
||||||
rec {
|
|
||||||
sources = import ./nix/sources.nix;
|
|
||||||
pkgs = import ./pkgs {};
|
|
||||||
inherit (pkgs) lib;
|
|
||||||
inherit (import (sources.nix-hexchen + "/lib/hosts.nix") {
|
|
||||||
inherit pkgs sources;
|
|
||||||
inherit ((import sources.nix-hexchen) {}) modules;
|
|
||||||
hostsDir = ./hosts; commonImports = [./common]; pkgsPath = ./pkgs;
|
|
||||||
}) hosts groups;
|
|
||||||
deploy = import (sources.nix-hexchen + "/lib/deploy.nix") { inherit pkgs hosts groups; };
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
boot.plymouth.enable = true;
|
|
||||||
nixpkgs.config = {
|
|
||||||
mumble.speechdSupport = true;
|
|
||||||
allowUnfree = true;
|
|
||||||
};
|
|
||||||
# boot.plymouth.splashBeforeUnlock = true;
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
pulsemixer pavucontrol
|
|
||||||
firefox kitty j4-dmenu-desktop bemenu
|
|
||||||
breeze-qt5 mako
|
|
||||||
mpv youtube-dl
|
|
||||||
wl-clipboard mumble
|
|
||||||
xdg_utils
|
|
||||||
slurp grim libnotify
|
|
||||||
_1password-gui
|
|
||||||
gimp
|
|
||||||
# gnome3.nautilus
|
|
||||||
] ++ (with pkgs; [ alacritty picom feh copyq polybar cinnamon.nemo rofi arandr notepadqq nomacs imv gthumb ]);
|
|
||||||
|
|
||||||
sound.enable = true;
|
|
||||||
time.timeZone = "Europe/Berlin";
|
|
||||||
hardware.pulseaudio = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.pulseaudioFull;
|
|
||||||
};
|
|
||||||
networking.useDHCP = lib.mkDefault true;
|
|
||||||
hardware.opengl.enable = true;
|
|
||||||
services.xserver = {
|
|
||||||
windowManager.bspwm.enable = true;
|
|
||||||
layout = "de";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
{config, lib, pkgs, ...}:
|
|
||||||
|
|
||||||
{
|
|
||||||
services.xserver.displayManager.lightdm = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
services.xserver = {
|
|
||||||
enable = true;
|
|
||||||
# videoDrivers = [ "nvidia" ];
|
|
||||||
};
|
|
||||||
# hardware.nvidia.modesetting.enable = true;
|
|
||||||
|
|
||||||
services.xserver.desktopManager.plasma5.enable = true;
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
{ config, pkgs, ...}:
|
|
||||||
|
|
||||||
{
|
|
||||||
boot = {
|
|
||||||
extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
|
|
||||||
kernelModules = [ "v4l2loopback" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ obs-studio ];
|
|
||||||
}
|
|
7
docs/_index.md
Normal file
7
docs/_index.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
+++
|
||||||
|
title = "hacc infra documentation"
|
||||||
|
page_template = "doc-page.html"
|
||||||
|
sort_by="title"
|
||||||
|
+++
|
||||||
|
|
||||||
|
|
10
docs/auth.md
Normal file
10
docs/auth.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
+++
|
||||||
|
title = "Authentication"
|
||||||
|
categories = [ "services", "uffd" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
We use [uffd](https://git.cccv.de/uffd/uffd) for our SSO, for better or worse.
|
||||||
|
Mostly for worse.
|
||||||
|
|
||||||
|
|
||||||
|
|
20
docs/domains.md
Normal file
20
docs/domains.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
+++
|
||||||
|
title = "Domains"
|
||||||
|
categories = [ "domains", "meta" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
Perhaps too many of them.
|
||||||
|
|
||||||
|
## Domains
|
||||||
|
|
||||||
|
| domain | mc | status | date | reseller | owner | custody |
|
||||||
|
| :------------------- | :-: | :-----: | :------: | :---------- | :--------- | :-----: |
|
||||||
|
| 4future.dev | yes | | | | | hacc e.V. |
|
||||||
|
| infra4future.de | yes | | | | | hacc e.V. |
|
||||||
|
| hacc.space | yes | | | | | hacc e.V. |
|
||||||
|
| hacc.earth | yes | | | | | hacc e.V. |
|
||||||
|
| hacc.media | yes | | | | | hacc e.V. |
|
||||||
|
| hacc.wiki | no | | | | | |
|
||||||
|
|
||||||
|
mc = managed by cloudflare
|
||||||
|
status = (renewl | autorenewl | expires)
|
16
docs/hostnames.md
Normal file
16
docs/hostnames.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
+++
|
||||||
|
title = "Hostname schema"
|
||||||
|
+++
|
||||||
|
|
||||||
|
[Badass Anarchist Women](https://listverse.com/2018/09/27/10-absolutely-badass-anarchist-women-who-challenged-the-system/)
|
||||||
|
- keller
|
||||||
|
- deCleyre
|
||||||
|
- davidNeel
|
||||||
|
- leGuin
|
||||||
|
- [parsons](../parsons)
|
||||||
|
- ohair
|
||||||
|
- berneri
|
||||||
|
- michel
|
||||||
|
- sanger
|
||||||
|
- goldman
|
||||||
|
|
17
docs/lxc.md
Normal file
17
docs/lxc.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
+++
|
||||||
|
title = "LXC"
|
||||||
|
categories = [ "lxc" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
Some things don't easily run on NixOS. For these we have LXC containers running
|
||||||
|
debian.
|
||||||
|
|
||||||
|
Right now, only onlyoffice is left.
|
||||||
|
|
||||||
|
## Useful commands
|
||||||
|
- login to a container as root with a usable shell
|
||||||
|
`lxc-attach -n <name> -- /usr/bin/sudo -i`
|
||||||
|
- restarting the keycloak and ldap containers
|
||||||
|
`lxc-stop -n <name> && lxc-start -n <name>`
|
||||||
|
- restarting their network bridge:
|
||||||
|
`systemctl restart lxcbr0-netdev.services`
|
18
docs/rebooting.md
Normal file
18
docs/rebooting.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
+++
|
||||||
|
title = "Rebooting Parsons"
|
||||||
|
categories = [ "nix" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
## Check integrity after unexpected shutdown
|
||||||
|
These steps are only required if the server shut down unexpectedly or you suspect tampering.
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## Unlock full disk encryption
|
||||||
|
Connection to the server via the command listed in the shared password manager.
|
||||||
|
Only the Vorstand has access to it!
|
||||||
|
|
||||||
|
Enter the passwords for dpool and zroot.
|
||||||
|
|
||||||
|
If both are correct, you will be disconnected and the server continues the boot sequence.
|
||||||
|
The server should be up after about minute. Please check all services for availability.
|
21
docs/secrets.md
Normal file
21
docs/secrets.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
+++
|
||||||
|
title = "Secrets"
|
||||||
|
categories = [ "services", "sops" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
## Secret management
|
||||||
|
|
||||||
|
We use [sops-nix](https://github.com/Mic92/sops-nix) to manage secrets which we'd
|
||||||
|
like to have in Git but don't want to be public. Entries in `secrets.yaml` are
|
||||||
|
encrypted for each of the age keys listed in `.sops.yaml`, which are themselves
|
||||||
|
derived from ssh keys.
|
||||||
|
|
||||||
|
For the initial set up, please take a look at the sops-nix Readme file.
|
||||||
|
|
||||||
|
To edit the secrets file, run `sops secrets.yaml`, which will decrypt the
|
||||||
|
file & open it in your $EDITOR, then re-encrypt it when you're done.
|
||||||
|
|
||||||
|
To add a new key, use `ssh-to-age` to convert your ssh key to age, and add it to
|
||||||
|
`sops.yaml`. Then do `sops updatekeys secrets.yaml` to re-encrypt the file for
|
||||||
|
the new set of keys.
|
||||||
|
|
5
docs/services/_index.md
Normal file
5
docs/services/_index.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
+++
|
||||||
|
title = "Services"
|
||||||
|
sort_by = "title"
|
||||||
|
page_template = "doc-page.html"
|
||||||
|
+++
|
19
docs/services/acme.md
Normal file
19
docs/services/acme.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
+++
|
||||||
|
title = "ACME / letsencrypt"
|
||||||
|
categories = [ "domain", "https", "ssl", "tls", "Certificates" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
We use the ACME module's nginx integration for basically everything. Beware of
|
||||||
|
rate limits when redeploying lots of things at once! Let's Encrypt is a little
|
||||||
|
picky about those.
|
||||||
|
|
||||||
|
|
||||||
|
## Workarounds & peculiar configuration choices
|
||||||
|
|
||||||
|
Certs live under `/var/lib/acme/`
|
||||||
|
|
||||||
|
If you need to remove a cert for whatever reason, be aware that there is a
|
||||||
|
hidden `.lego` folder, that contains state as well
|
68
docs/services/hedgedoc.md
Normal file
68
docs/services/hedgedoc.md
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
+++
|
||||||
|
title = "hedgedoc"
|
||||||
|
taxonomies.categories = [ "services" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
|
||||||
|
hegedoc was once called codiMD, so container, config and users are still called codimd.
|
||||||
|
|
||||||
|
**Do NOT change this** unless you're sure what you're doing.
|
||||||
|
|
||||||
|
We have two instances:
|
||||||
|
- `pad-hacc`/pad.hacc.space is connected to our SSO/uffd
|
||||||
|
- `pad-i4f`/pad.infra4future.de is not connected to our SSO and meant to be more public
|
||||||
|
|
||||||
|
## Basic Troubleshooting
|
||||||
|
|
||||||
|
Usually if hedgedoc dies, it's because postgresql wasn't there yet. Just restart
|
||||||
|
hedgedoc.
|
||||||
|
|
||||||
|
## More Troubles
|
||||||
|
log into the container and take a look at the logs
|
||||||
|
|
||||||
|
~~~shell
|
||||||
|
sudo nixos-container root-login codimd
|
||||||
|
journalctl -e
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### fixing failed database upgrades
|
||||||
|
|
||||||
|
see https://docs.hedgedoc.org/guides/migration-troubleshooting/ (copied below
|
||||||
|
for convenience?):
|
||||||
|
|
||||||
|
In some cases, HedgeDoc might apply migrations without correctly saving the
|
||||||
|
progress. It will then refuse to start with "already exists"-errors like
|
||||||
|
ERROR: type "enum_Notes_permission" already exists.
|
||||||
|
|
||||||
|
Get the name of the failing migration and append .js to it. For example, if
|
||||||
|
you encounter this error:
|
||||||
|
|
||||||
|
~~~
|
||||||
|
== 20180306150303-fix-enum: migrating =======
|
||||||
|
|
||||||
|
ERROR: type "enum_Notes_permission" already exists
|
||||||
|
~~~
|
||||||
|
|
||||||
|
the name of the failed migration would be 20180306150303-fix-enum.js.
|
||||||
|
|
||||||
|
The SQL-statement may look like this:
|
||||||
|
|
||||||
|
~~~
|
||||||
|
INSERT INTO "SequelizeMeta" (name) VALUES ('20180306150303-fix-enum.js');
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Make sure HedgeDoc does not run and insert the name into the SequelizeMeta table.
|
||||||
|
Enter the container switch to the postgres user, open psql and commect to the
|
||||||
|
codimd database:
|
||||||
|
|
||||||
|
~~~shell
|
||||||
|
su postgres
|
||||||
|
psql
|
||||||
|
\l
|
||||||
|
\c codimd
|
||||||
|
UN adjusted SQL STAMEMENT from above ]
|
||||||
|
\q
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Start HedgeDoc again and observe if it starts correctly. It may be necessary to
|
||||||
|
repeat this process and insert multiple migrations into the SequelizeMeta table.
|
65
docs/services/mail.md
Normal file
65
docs/services/mail.md
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
+++
|
||||||
|
title = "mail"
|
||||||
|
taxonomies.categories = [ "services" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
Mail is not connected to our SSO!
|
||||||
|
|
||||||
|
## adding a mail account
|
||||||
|
- We use `@hacc.space` for our mails
|
||||||
|
- `@infra4future.de` is reserved for services, old user accounts will be
|
||||||
|
forwarded & logins disabled
|
||||||
|
- choose a name (no aliases or other names can be the same)
|
||||||
|
- generate a sha-512 password hash ```mkpasswd -m sha-512``` - **never add an
|
||||||
|
unhashed password!**
|
||||||
|
- add your account to `loginAccounts =` in `//parsons/mail.nix`
|
||||||
|
- build and redeploy parsons
|
||||||
|
|
||||||
|
**example:**
|
||||||
|
```
|
||||||
|
zwoelfontheshelf@hacc.space" = {
|
||||||
|
hashedPassword = "$6$ISAaU8X6D$oGKe9WXDWrRpGzHUEdxrxdtgvzuGOkBMuDc82IZhegpsv1bqd550FhZZrI40IjZTA5Hy2MZ8j/0efpnQ4fOQH0";
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## adding to a forward address
|
||||||
|
- add the mail address to the corresponding `extraVirtualAliases =`
|
||||||
|
- build and redeploy parsons
|
||||||
|
|
||||||
|
## adding a forward address
|
||||||
|
- add the address to `extraVirtualAliases =`
|
||||||
|
- add the addresses it should forward to
|
||||||
|
- build and redeploy parsons
|
||||||
|
|
||||||
|
**example:**
|
||||||
|
```
|
||||||
|
"himmel@hacc.space" = [
|
||||||
|
"hexchen@hacc.space"
|
||||||
|
"zauberberg@hacc.space"
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
## sending & receiving mail
|
||||||
|
|
||||||
|
### as a user
|
||||||
|
- Your mail client should auto configure correctly
|
||||||
|
|
||||||
|
~~~
|
||||||
|
mailserver: mail.hacc.space (everywhere)
|
||||||
|
username: $your_mail_address
|
||||||
|
sending via smtp: port 587 or 465
|
||||||
|
recieving
|
||||||
|
imap: port 993
|
||||||
|
TLS and STARTTLS are supported
|
||||||
|
~~~
|
||||||
|
|
||||||
|
- You can send mail as you and any alias you receive mail from. Set a second Identity in your e-mail client
|
||||||
|
|
||||||
|
### as an application
|
||||||
|
- mailserver: `mail.hacc.space`
|
||||||
|
- Do **not** use port 25. It's for server to server communication only.
|
||||||
|
- Use smtp ports `587` or `465`
|
||||||
|
- enable TLS if possible
|
||||||
|
- only send mail from `noreply@infra4future.de`
|
||||||
|
- Password is somewhere (TODO!)
|
||||||
|
|
40
docs/services/mumble.md
Normal file
40
docs/services/mumble.md
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
+++
|
||||||
|
title = "mumble"
|
||||||
|
taxonomies.categories = [ "mumble" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
|
||||||
|
[offical Docmuentation](https://wiki.mumble.info/wiki/Main_Page)
|
||||||
|
|
||||||
|
Mumble's server is called murmur, but the naming is inconsistent. Sometimes
|
||||||
|
it's also just called mumble server.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
## registration
|
||||||
|
Users need to be registered to join any other channel than public.
|
||||||
|
An already registered user has to register them with the server.
|
||||||
|
1. right click on the username
|
||||||
|
2. choose register in the menu. Done.
|
||||||
|
|
||||||
|
## restricted channels
|
||||||
|
Every channel in the hacc category except for plenum can only be accessed by
|
||||||
|
members of the hacc group.
|
||||||
|
|
||||||
|
## adding users to a group
|
||||||
|
Only admins can edit groups, and only registered users can be added to groups.
|
||||||
|
1. right click on the Root channel
|
||||||
|
2. select Edit...
|
||||||
|
2. In Groups select $groupname
|
||||||
|
3. make the change you want to make
|
||||||
|
4. click "OK"
|
||||||
|
|
||||||
|
# Config details
|
||||||
|
- the server is not registered with mumble & not on the public server list
|
||||||
|
- the bitrate is set to 128kb/s; otherwise the client would complain that the
|
||||||
|
server bitrate is less then the configured (default) in its local settings
|
||||||
|
|
||||||
|
# Hacks
|
||||||
|
- murmur needs a TLS cert, which we get via the ACME module
|
||||||
|
- there's a funny group setup so that hopefully murmurd can read the cert
|
||||||
|
- this seems to work fine now, but was some source of trouble in the past
|
18
docs/services/service.template.md
Normal file
18
docs/services/service.template.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
+++
|
||||||
|
title = "$Service Name"
|
||||||
|
draft = true ## Remove this line to make file appear on website
|
||||||
|
+++
|
||||||
|
|
||||||
|
<general information & pointers to official documentation>
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
<usage from an admin's perspective>
|
||||||
|
|
||||||
|
# Config Notes
|
||||||
|
<what should one keep in mind when reading the nix file?>
|
||||||
|
|
||||||
|
## Updating
|
||||||
|
<anything to keep in mind?>
|
||||||
|
|
||||||
|
# Hacks
|
||||||
|
<ugly things which might break or cause general ???? states>
|
24
docs/snapshots.md
Normal file
24
docs/snapshots.md
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
+++
|
||||||
|
title = "Use ZFS snapshot"
|
||||||
|
taxonomies.categories = [ "zfs", "snapshot", "filesystem", "backup", "update", "upgrade" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
## Make a ZFS snapshot
|
||||||
|
~~~shell
|
||||||
|
sudo zfs snapshot zroot/safe/persist@<name>
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Rollback
|
||||||
|
|
||||||
|
### single files
|
||||||
|
The snapshots can be accessed under `<mountpoint>/.zfs/snapshot/...`
|
||||||
|
|
||||||
|
### fully
|
||||||
|
~~~shell
|
||||||
|
sudo zfs rollback zroot/safe/persist@<name>
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Delete a ZFS snapshot
|
||||||
|
~~~shell
|
||||||
|
sudo zfs destroy zroot/safe/persist@<name>
|
||||||
|
~~~
|
229
flake.lock
Normal file
229
flake.lock
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"blobs": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1604995301,
|
||||||
|
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
|
||||||
|
"owner": "simple-nixos-mailserver",
|
||||||
|
"repo": "blobs",
|
||||||
|
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
|
||||||
|
"type": "gitlab"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "simple-nixos-mailserver",
|
||||||
|
"repo": "blobs",
|
||||||
|
"type": "gitlab"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deploy-rs": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"utils": "utils"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1727447169,
|
||||||
|
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=",
|
||||||
|
"owner": "serokell",
|
||||||
|
"repo": "deploy-rs",
|
||||||
|
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "serokell",
|
||||||
|
"repo": "deploy-rs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1696426674,
|
||||||
|
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixos-mailserver": {
|
||||||
|
"inputs": {
|
||||||
|
"blobs": "blobs",
|
||||||
|
"flake-compat": [
|
||||||
|
"deploy-rs",
|
||||||
|
"flake-compat"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs-unstable"
|
||||||
|
],
|
||||||
|
"nixpkgs-24_05": "nixpkgs-24_05"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1734370678,
|
||||||
|
"narHash": "sha256-a8zkti1QM5Oxkdfnzr/NjrFlyqI36/kYV/X8G1jOmB4=",
|
||||||
|
"owner": "simple-nixos-mailserver",
|
||||||
|
"repo": "nixos-mailserver",
|
||||||
|
"rev": "c43d8c4a3ce84a7bebd110b06e69365484db6208",
|
||||||
|
"type": "gitlab"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "simple-nixos-mailserver",
|
||||||
|
"ref": "master",
|
||||||
|
"repo": "nixos-mailserver",
|
||||||
|
"type": "gitlab"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1734298236,
|
||||||
|
"narHash": "sha256-aWhhqY44xBjMoO9r5fyPp5u8tqUNWRZ/m/P+abMSs5c=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "eb919d9300b6a18f8583f58aef16db458fbd7bec",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-24.11-small",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-24_05": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731797254,
|
||||||
|
"narHash": "sha256-df3dJApLPhd11AlueuoN0Q4fHo/hagP75LlM5K1sz9g=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e8c38b73aeb218e27163376a2d617e61a2ad9b59",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-24.05",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-oldstable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1678761643,
|
||||||
|
"narHash": "sha256-tapXZvg6Kg5Fm7Fm6i+7cRC5Exp2lX7cgMrqsfrGhuc=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "c4aec3c021620d98861639946123214207e98344",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "c4aec3c021620d98861639946123214207e98344",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-unstable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1734318609,
|
||||||
|
"narHash": "sha256-VPbVfHSvFs58T+kbseS7wa9WP6p2z7RJmjTnV4pAPQ0=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "66cdf593c0041cf1efc9b2889d80c9a5c497b284",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-unstable-small",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"deploy-rs": "deploy-rs",
|
||||||
|
"nixos-mailserver": "nixos-mailserver",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"nixpkgs-oldstable": "nixpkgs-oldstable",
|
||||||
|
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||||
|
"sops-nix": "sops-nix",
|
||||||
|
"tracktrain": "tracktrain"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sops-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs-unstable"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1733965552,
|
||||||
|
"narHash": "sha256-GZ4YtqkfyTjJFVCub5yAFWsHknG1nS/zfk7MuHht4Fs=",
|
||||||
|
"owner": "Mic92",
|
||||||
|
"repo": "sops-nix",
|
||||||
|
"rev": "2d73fc6ac4eba4b9a83d3cb8275096fbb7ab4004",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Mic92",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tracktrain": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1720213096,
|
||||||
|
"narHash": "sha256-GrSXD6WvyiXcHx1s+48PEZVn/MTtBJAXpgds+NdEL2g=",
|
||||||
|
"ref": "main",
|
||||||
|
"rev": "2943327863bfe5c6e793e5c40e473a2755d45642",
|
||||||
|
"revCount": 126,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://stuebinm.eu/git/tracktrain"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"ref": "main",
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://stuebinm.eu/git/tracktrain"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1701680307,
|
||||||
|
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
88
flake.nix
Normal file
88
flake.nix
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
{
|
||||||
|
description = "hacc infra stuff";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "nixpkgs/nixos-24.11-small";
|
||||||
|
nixpkgs-unstable.url = "nixpkgs/nixos-unstable-small";
|
||||||
|
nixpkgs-oldstable.url = "github:/NixOS/nixpkgs?rev=c4aec3c021620d98861639946123214207e98344";
|
||||||
|
|
||||||
|
nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master";
|
||||||
|
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";
|
||||||
|
|
||||||
|
# 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";
|
||||||
|
flake-compat.follows = "/deploy-rs/flake-compat";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, deploy-rs, sops-nix, ... }@inputs:
|
||||||
|
let modules = {
|
||||||
|
bindMounts = import ./modules/bindmounts.nix;
|
||||||
|
nopersist = import ./modules/nopersist.nix;
|
||||||
|
encboot = import ./modules/encboot.nix;
|
||||||
|
};
|
||||||
|
profiles = {
|
||||||
|
container = import ./modules/container-profile.nix;
|
||||||
|
};
|
||||||
|
pkgs = import ./pkgs {
|
||||||
|
sources = inputs;
|
||||||
|
system = "x86_64-linux";
|
||||||
|
config.allowUnfree = true;
|
||||||
|
};
|
||||||
|
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; }
|
||||||
|
];
|
||||||
|
specialArgs = {
|
||||||
|
sources = inputs;
|
||||||
|
inherit modules profiles;
|
||||||
|
inherit (nixpkgs.lib) nixosSystem;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
deploy.nodes.parsons = {
|
||||||
|
hostname = "parsons";
|
||||||
|
profiles.system = {
|
||||||
|
user = "root";
|
||||||
|
autoRollback = false;
|
||||||
|
path = deploy-rs.lib.x86_64-linux.activate.nixos
|
||||||
|
self.nixosConfigurations.parsons;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# This is highly advised, and will prevent many possible mistakes
|
||||||
|
checks = builtins.mapAttrs
|
||||||
|
(system: deployLib: deployLib.deployChecks self.deploy)
|
||||||
|
deploy-rs.lib;
|
||||||
|
|
||||||
|
apps.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;
|
||||||
|
in
|
||||||
|
{ docs = websites."docs.hacc.space"; } // websites;
|
||||||
|
|
||||||
|
packages.x86_64-linux = {
|
||||||
|
inherit (pkgs) mattermost hacc-scripts;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,80 +0,0 @@
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports =
|
|
||||||
[ # Include the results of the hardware scan.
|
|
||||||
./hardware-config.nix
|
|
||||||
../../common
|
|
||||||
../../desktop
|
|
||||||
../../desktop/streaming.nix
|
|
||||||
../../desktop/gnome.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.loader.grub ={
|
|
||||||
enable = true;
|
|
||||||
version = 2;
|
|
||||||
efiSupport = true;
|
|
||||||
device = "nodev";
|
|
||||||
};
|
|
||||||
boot.loader.efi = {
|
|
||||||
canTouchEfiVariables = true;
|
|
||||||
efiSysMountPoint = "/boot";
|
|
||||||
};
|
|
||||||
|
|
||||||
hardware.decklink.enable = true;
|
|
||||||
|
|
||||||
networking.hostName = "nixda"; # Define your hostname.
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ blackmagicDesktopVideo blender companion ];
|
|
||||||
|
|
||||||
networking.wg-quick.interfaces.cornbox = {
|
|
||||||
privateKeyFile = "/etc/wireguard/cornbox.key";
|
|
||||||
address = [ "195.39.247.67/28" "2a0f:4ac0:1337::12/64" ];
|
|
||||||
postUp = "/run/wrappers/bin/ping -c5 195.39.247.65";
|
|
||||||
peers = [
|
|
||||||
{
|
|
||||||
persistentKeepalive = 25;
|
|
||||||
allowedIPs = [ "2a0f:4ac0:1337::/48" "195.39.247.64/27" ];
|
|
||||||
publicKey = "8IWyiQL3wKP9CD/4UdS9b8mcbL67mkUyeSPORgEPvV0=";
|
|
||||||
endpoint = "cornbox.hetzner.chaoswit.ch:51821";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.xserver = {
|
|
||||||
enable = true;
|
|
||||||
videoDrivers = [ "nvidia" ];
|
|
||||||
};
|
|
||||||
hardware.nvidia.modesetting.enable = true;
|
|
||||||
|
|
||||||
boot.kernelPackages = pkgs.linuxPackages;
|
|
||||||
boot.blacklistedKernelModules = [ "snd_blackmagic_io" ];
|
|
||||||
|
|
||||||
users.users.stream = {
|
|
||||||
isNormalUser = true;
|
|
||||||
password = "hacchacc";
|
|
||||||
extraGroups = [ "audio" "video" ];
|
|
||||||
openssh.authorizedKeys.keys = with pkgs.lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
|
|
||||||
};
|
|
||||||
|
|
||||||
services.pipewire.enable = true;
|
|
||||||
services.pipewire.pulse.enable = true;
|
|
||||||
hardware.pulseaudio.enable = lib.mkForce false;
|
|
||||||
|
|
||||||
services.udev.extraRules = ''
|
|
||||||
SUBSYSTEM=="input", GROUP="input", MODE="0666"
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006?", MODE:="666", GROUP="plugdev"
|
|
||||||
KERNEL=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006?", MODE:="666", GROUP="plugdev"
|
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="ffff", ATTRS{idProduct}=="1f4?", MODE:="666", GROUP="plugdev"
|
|
||||||
KERNEL=="hidraw", ATTRS{idVendor}=="ffff", ATTRS{idProduct}=="1f4?", MODE:="666", GROUP="plugdev"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# 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 = "20.09"; # Did you read the comment?
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports =
|
|
||||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "nvme" "ehci_pci" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
|
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ "kvm-amd" ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
fileSystems."/" =
|
|
||||||
{ device = "/dev/disk/by-uuid/dfbfee26-c2c0-4c0c-b145-6362c7650ac9";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [ "subvol=@nix" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/home" =
|
|
||||||
{ device = "/dev/disk/by-uuid/dfbfee26-c2c0-4c0c-b145-6362c7650ac9";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [ "subvol=@home" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/boot" =
|
|
||||||
{ device = "/dev/disk/by-uuid/A358-97BC";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [ ];
|
|
||||||
}
|
|
28
modules/bindmounts.nix
Normal file
28
modules/bindmounts.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let cfg = config.hacc;
|
||||||
|
|
||||||
|
in {
|
||||||
|
|
||||||
|
options.hacc.bindMounts = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
example = { "/etc/asdf" = "/persist/asdf"; };
|
||||||
|
};
|
||||||
|
options.hacc.bindToPersist = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = [ "postgres" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
config.fileSystems = mapAttrs (_: device: {
|
||||||
|
inherit device;
|
||||||
|
options = [ "bind" ];
|
||||||
|
}) cfg.bindMounts;
|
||||||
|
|
||||||
|
config.hacc.bindMounts = listToAttrs
|
||||||
|
(map (name: { inherit name; value = "/persist${name}"; })
|
||||||
|
cfg.bindToPersist);
|
||||||
|
}
|
29
modules/buildinfo.nix
Normal file
29
modules/buildinfo.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{ 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;
|
||||||
|
}
|
18
modules/container-profile.nix
Normal file
18
modules/container-profile.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{ lib, ...}:
|
||||||
|
|
||||||
|
{
|
||||||
|
boot.isContainer = true;
|
||||||
|
networking.useDHCP = false;
|
||||||
|
users.users.root.hashedPassword = "";
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
services.coredns = {
|
||||||
|
enable = true;
|
||||||
|
config = ''
|
||||||
|
.:53 {
|
||||||
|
forward . 1.1.1.1
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = lib.mkDefault "21.05";
|
||||||
|
}
|
95
modules/containers.nix
Normal file
95
modules/containers.nix
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
{ 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));
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.hardware.decklink;
|
|
||||||
kernelPackages = config.boot.kernelPackages;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.hardware.decklink.enable = mkEnableOption "Enable hardware support for the Blackmagic Design Decklink audio/video interfaces.";
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
boot.kernelModules = [ "blackmagic" "blackmagic-io" "snd_blackmagic-io" ];
|
|
||||||
boot.extraModulePackages = [ kernelPackages.decklink ];
|
|
||||||
systemd.services."DecklinkVideoHelper" = {
|
|
||||||
after = [ "syslog.target" "local-fs.target" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig.ExecStart = "${pkgs.blackmagicDesktopVideo}/bin/DesktopVideoHelper -n";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,16 +1,7 @@
|
||||||
{ ... }:
|
{ ... }:
|
||||||
let
|
|
||||||
sources = import ../nix/sources.nix;
|
{
|
||||||
in {
|
|
||||||
imports = [
|
imports = [
|
||||||
./nftnat
|
|
||||||
./decklink.nix
|
|
||||||
./websites.nix
|
./websites.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# disabled since vaultwarden defines a dummy bitwarden_rs option that
|
|
||||||
# shows a deprication warning, which conflicts with this module
|
|
||||||
disabledModules = [
|
|
||||||
"services/security/bitwarden_rs/default.nix"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
45
modules/encboot.nix
Normal file
45
modules/encboot.nix
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let cfg = config.hacc.encboot;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
hacc.encboot = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
networkDrivers = mkOption { type = with types; listOf str; };
|
||||||
|
dataset = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "zroot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
boot.initrd.kernelModules = cfg.networkDrivers;
|
||||||
|
|
||||||
|
boot.initrd.network = {
|
||||||
|
enable = true;
|
||||||
|
ssh = {
|
||||||
|
enable = true;
|
||||||
|
port = 2222;
|
||||||
|
authorizedKeys = with lib;
|
||||||
|
concatLists (mapAttrsToList (name: user:
|
||||||
|
if elem "wheel" user.extraGroups then
|
||||||
|
user.openssh.authorizedKeys.keys
|
||||||
|
else
|
||||||
|
[ ]) config.users.users);
|
||||||
|
hostKeys = [ /etc/ssh/encboot_host ];
|
||||||
|
};
|
||||||
|
|
||||||
|
postCommands = ''
|
||||||
|
zpool import ${cfg.dataset}
|
||||||
|
echo "zfs load-key -a; killall zfs && exit" >> /root/.profile
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,255 +0,0 @@
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
|
|
||||||
cfg = config.services.mattermost-patched;
|
|
||||||
|
|
||||||
defaultConfig = builtins.fromJSON (builtins.replaceStrings [ "\\u0026" ] [ "&" ]
|
|
||||||
(readFile "${pkgs.mattermost}/config/config.json")
|
|
||||||
);
|
|
||||||
|
|
||||||
database = "postgres://${cfg.localDatabaseUser}:${cfg.localDatabasePassword}@localhost:5432/${cfg.localDatabaseName}?sslmode=disable&connect_timeout=10";
|
|
||||||
|
|
||||||
mattermostConf = foldl recursiveUpdate defaultConfig
|
|
||||||
[ { ServiceSettings.SiteURL = cfg.siteUrl;
|
|
||||||
ServiceSettings.ListenAddress = cfg.listenAddress;
|
|
||||||
TeamSettings.SiteName = cfg.siteName;
|
|
||||||
}
|
|
||||||
cfg.extraConfig
|
|
||||||
];
|
|
||||||
|
|
||||||
mattermostConfJSON = pkgs.writeText "mattermost-config-raw.json" (builtins.toJSON mattermostConf);
|
|
||||||
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
services.mattermost-patched = {
|
|
||||||
enable = mkEnableOption "Mattermost chat server";
|
|
||||||
|
|
||||||
statePath = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/var/lib/mattermost";
|
|
||||||
description = "Mattermost working directory";
|
|
||||||
};
|
|
||||||
|
|
||||||
siteUrl = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "https://chat.example.com";
|
|
||||||
description = ''
|
|
||||||
URL this Mattermost instance is reachable under, without trailing slash.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
siteName = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "Mattermost";
|
|
||||||
description = "Name of this Mattermost site.";
|
|
||||||
};
|
|
||||||
|
|
||||||
listenAddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = ":8065";
|
|
||||||
example = "[::1]:8065";
|
|
||||||
description = ''
|
|
||||||
Address and port this Mattermost instance listens to.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
mutableConfig = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Whether the Mattermost config.json is writeable by Mattermost.
|
|
||||||
|
|
||||||
Most of the settings can be edited in the system console of
|
|
||||||
Mattermost if this option is enabled. A template config using
|
|
||||||
the options specified in services.mattermost will be generated
|
|
||||||
but won't be overwritten on changes or rebuilds.
|
|
||||||
|
|
||||||
If this option is disabled, changes in the system console won't
|
|
||||||
be possible (default). If an config.json is present, it will be
|
|
||||||
overwritten!
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.attrs;
|
|
||||||
default = { };
|
|
||||||
description = ''
|
|
||||||
Addtional configuration options as Nix attribute set in config.json schema.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
secretConfig = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Path to a json file containing secret config values, which should
|
|
||||||
not be written into the Nix store. If it is not null (the default)
|
|
||||||
and mutableConfig is set to false, then the mattermost service will
|
|
||||||
join the file at this path into its config.
|
|
||||||
|
|
||||||
Note that this file cannot be used to overwrite values already
|
|
||||||
specified by the other options of this module.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
localDatabaseCreate = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Create a local PostgreSQL database for Mattermost automatically.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
localDatabaseName = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "mattermost";
|
|
||||||
description = ''
|
|
||||||
Local Mattermost database name.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
localDatabaseUser = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "mattermost";
|
|
||||||
description = ''
|
|
||||||
Local Mattermost database username.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
localDatabasePassword = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "mmpgsecret";
|
|
||||||
description = ''
|
|
||||||
Password for local Mattermost database user.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "mattermost";
|
|
||||||
description = ''
|
|
||||||
User which runs the Mattermost service.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "mattermost";
|
|
||||||
description = ''
|
|
||||||
Group which runs the Mattermost service.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
matterircd = {
|
|
||||||
enable = mkEnableOption "Mattermost IRC bridge";
|
|
||||||
parameters = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
example = [ "-mmserver chat.example.com" "-bind [::]:6667" ];
|
|
||||||
description = ''
|
|
||||||
Set commandline parameters to pass to matterircd. See
|
|
||||||
https://github.com/42wim/matterircd#usage for more information.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkMerge [
|
|
||||||
(mkIf cfg.enable {
|
|
||||||
users.users = optionalAttrs (cfg.user == "mattermost") {
|
|
||||||
mattermost = {
|
|
||||||
group = cfg.group;
|
|
||||||
uid = config.ids.uids.mattermost;
|
|
||||||
home = cfg.statePath;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups = optionalAttrs (cfg.group == "mattermost") {
|
|
||||||
mattermost.gid = config.ids.gids.mattermost;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.postgresql.enable = cfg.localDatabaseCreate;
|
|
||||||
|
|
||||||
# The systemd service will fail to execute the preStart hook
|
|
||||||
# if the WorkingDirectory does not exist
|
|
||||||
system.activationScripts.mattermost = ''
|
|
||||||
mkdir -p ${cfg.statePath}
|
|
||||||
'';
|
|
||||||
|
|
||||||
systemd.services.mattermost = {
|
|
||||||
description = "Mattermost chat service";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "network.target" "postgresql.service" ];
|
|
||||||
|
|
||||||
preStart = ''
|
|
||||||
mkdir -p ${cfg.statePath}/{data,config,logs}
|
|
||||||
ln -sf ${pkgs.mattermost}/{bin,fonts,i18n,templates,client} ${cfg.statePath}
|
|
||||||
'' + lib.optionalString (!cfg.mutableConfig) ''
|
|
||||||
rm -f ${cfg.statePath}/config/config.json
|
|
||||||
'' + (if cfg.secretConfig == null
|
|
||||||
then ''
|
|
||||||
cp ${mattermostConfJSON} ${cfg.statePath}/config/config.json
|
|
||||||
''
|
|
||||||
else ''
|
|
||||||
${pkgs.jq}/bin/jq -s ".[1] * .[0]" ${cfg.secretConfig} ${mattermostConfJSON} > ${cfg.statePath}/config/config.json
|
|
||||||
'')
|
|
||||||
+ ''
|
|
||||||
${pkgs.mattermost}/bin/mattermost config migrate ${cfg.statePath}/config/config.json ${database}
|
|
||||||
'' + lib.optionalString cfg.mutableConfig ''
|
|
||||||
if ! test -e "${cfg.statePath}/config/.initial-created"; then
|
|
||||||
rm -f ${cfg.statePath}/config/config.json
|
|
||||||
cp ${mattermostConfJSON} ${cfg.statePath}/config/config.json
|
|
||||||
touch ${cfg.statePath}/config/.initial-created
|
|
||||||
fi
|
|
||||||
'' + lib.optionalString cfg.localDatabaseCreate ''
|
|
||||||
if ! test -e "${cfg.statePath}/.db-created"; then
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} \
|
|
||||||
${config.services.postgresql.package}/bin/psql postgres -c \
|
|
||||||
"CREATE ROLE ${cfg.localDatabaseUser} WITH LOGIN NOCREATEDB NOCREATEROLE ENCRYPTED PASSWORD '${cfg.localDatabasePassword}'"
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} \
|
|
||||||
${config.services.postgresql.package}/bin/createdb \
|
|
||||||
--owner ${cfg.localDatabaseUser} ${cfg.localDatabaseName}
|
|
||||||
touch ${cfg.statePath}/.db-created
|
|
||||||
fi
|
|
||||||
'' + ''
|
|
||||||
chown ${cfg.user}:${cfg.group} -R ${cfg.statePath}
|
|
||||||
chmod u+rw,g+r,o-rwx -R ${cfg.statePath}
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
PermissionsStartOnly = true;
|
|
||||||
User = cfg.user;
|
|
||||||
Group = cfg.group;
|
|
||||||
ExecStart = "${pkgs.mattermost}/bin/mattermost" +
|
|
||||||
(if cfg.mutableConfig then " -c ${database}" else " -c ${cfg.statePath}/config/config.json");
|
|
||||||
WorkingDirectory = "${cfg.statePath}";
|
|
||||||
Restart = "always";
|
|
||||||
RestartSec = "10";
|
|
||||||
LimitNOFILE = "49152";
|
|
||||||
};
|
|
||||||
unitConfig.JoinsNamespaceOf = mkIf cfg.localDatabaseCreate "postgresql.service";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(mkIf cfg.matterircd.enable {
|
|
||||||
systemd.services.matterircd = {
|
|
||||||
description = "Mattermost IRC bridge service";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nobody";
|
|
||||||
Group = "nogroup";
|
|
||||||
ExecStart = "${pkgs.matterircd}/bin/matterircd ${concatStringsSep " " cfg.matterircd.parameters}";
|
|
||||||
WorkingDirectory = "/tmp";
|
|
||||||
PrivateTmp = true;
|
|
||||||
Restart = "always";
|
|
||||||
RestartSec = "5";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,755 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.nextcloud-patched;
|
|
||||||
fpm = config.services.phpfpm.pools.nextcloud;
|
|
||||||
|
|
||||||
phpPackage =
|
|
||||||
let
|
|
||||||
base = pkgs.php74;
|
|
||||||
in
|
|
||||||
base.buildEnv {
|
|
||||||
extensions = { enabled, all }: with all;
|
|
||||||
enabled ++ [
|
|
||||||
apcu redis memcached imagick
|
|
||||||
];
|
|
||||||
extraConfig = phpOptionsStr;
|
|
||||||
};
|
|
||||||
|
|
||||||
toKeyValue = generators.toKeyValue {
|
|
||||||
mkKeyValue = generators.mkKeyValueDefault {} " = ";
|
|
||||||
};
|
|
||||||
|
|
||||||
phpOptions = {
|
|
||||||
upload_max_filesize = cfg.maxUploadSize;
|
|
||||||
post_max_size = cfg.maxUploadSize;
|
|
||||||
memory_limit = cfg.maxUploadSize;
|
|
||||||
} // cfg.phpOptions
|
|
||||||
// optionalAttrs cfg.caching.apcu {
|
|
||||||
"apc.enable_cli" = "1";
|
|
||||||
};
|
|
||||||
phpOptionsStr = toKeyValue phpOptions;
|
|
||||||
|
|
||||||
occ = pkgs.writeScriptBin "nextcloud-occ" ''
|
|
||||||
#! ${pkgs.runtimeShell}
|
|
||||||
cd ${cfg.package}
|
|
||||||
sudo=exec
|
|
||||||
if [[ "$USER" != nextcloud ]]; then
|
|
||||||
sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR --preserve-env=OC_PASS'
|
|
||||||
fi
|
|
||||||
export NEXTCLOUD_CONFIG_DIR="${cfg.home}/config"
|
|
||||||
$sudo \
|
|
||||||
${phpPackage}/bin/php \
|
|
||||||
occ $*
|
|
||||||
'';
|
|
||||||
|
|
||||||
inherit (config.system) stateVersion;
|
|
||||||
|
|
||||||
in {
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
(mkRemovedOptionModule [ "services" "nextcloud-patched" "nginx" "enable" ] ''
|
|
||||||
The nextcloud module supports `nginx` as reverse-proxy by default and doesn't
|
|
||||||
support other reverse-proxies officially.
|
|
||||||
|
|
||||||
However it's possible to use an alternative reverse-proxy by
|
|
||||||
|
|
||||||
* disabling nginx
|
|
||||||
* setting `listen.owner` & `listen.group` in the phpfpm-pool to a different value
|
|
||||||
|
|
||||||
Further details about this can be found in the `Nextcloud`-section of the NixOS-manual
|
|
||||||
(which can be openend e.g. by running `nixos-help`).
|
|
||||||
'')
|
|
||||||
];
|
|
||||||
|
|
||||||
options.services.nextcloud-patched = {
|
|
||||||
enable = mkEnableOption "nextcloud";
|
|
||||||
hostName = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "FQDN for the nextcloud instance.";
|
|
||||||
};
|
|
||||||
home = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/var/lib/nextcloud";
|
|
||||||
description = "Storage path of nextcloud.";
|
|
||||||
};
|
|
||||||
logLevel = mkOption {
|
|
||||||
type = types.ints.between 0 4;
|
|
||||||
default = 2;
|
|
||||||
description = "Log level value between 0 (DEBUG) and 4 (FATAL).";
|
|
||||||
};
|
|
||||||
https = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Use https for generated links.";
|
|
||||||
};
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
description = "Which package to use for the Nextcloud instance.";
|
|
||||||
relatedPackages = [ "nextcloud18" "nextcloud19" "nextcloud20" "nextcloud21" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
maxUploadSize = mkOption {
|
|
||||||
default = "512M";
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Defines the upload limit for files. This changes the relevant options
|
|
||||||
in php.ini and nginx if enabled.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
skeletonDirectory = mkOption {
|
|
||||||
default = "";
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
The directory where the skeleton files are located. These files will be
|
|
||||||
copied to the data directory of new users. Leave empty to not copy any
|
|
||||||
skeleton files.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
webfinger = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Enable this option if you plan on using the webfinger plugin.
|
|
||||||
The appropriate nginx rewrite rules will be added to your configuration.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
phpOptions = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
default = {
|
|
||||||
short_open_tag = "Off";
|
|
||||||
expose_php = "Off";
|
|
||||||
error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT";
|
|
||||||
display_errors = "stderr";
|
|
||||||
"opcache.enable_cli" = "1";
|
|
||||||
"opcache.interned_strings_buffer" = "8";
|
|
||||||
"opcache.max_accelerated_files" = "10000";
|
|
||||||
"opcache.memory_consumption" = "128";
|
|
||||||
"opcache.revalidate_freq" = "1";
|
|
||||||
"opcache.fast_shutdown" = "1";
|
|
||||||
"openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt";
|
|
||||||
catch_workers_output = "yes";
|
|
||||||
};
|
|
||||||
description = ''
|
|
||||||
Options for PHP's php.ini file for nextcloud.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
poolSettings = mkOption {
|
|
||||||
type = with types; attrsOf (oneOf [ str int bool ]);
|
|
||||||
default = {
|
|
||||||
"pm" = "dynamic";
|
|
||||||
"pm.max_children" = "32";
|
|
||||||
"pm.start_servers" = "2";
|
|
||||||
"pm.min_spare_servers" = "2";
|
|
||||||
"pm.max_spare_servers" = "4";
|
|
||||||
"pm.max_requests" = "500";
|
|
||||||
};
|
|
||||||
description = ''
|
|
||||||
Options for nextcloud's PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
poolConfig = mkOption {
|
|
||||||
type = types.nullOr types.lines;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Options for nextcloud's PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
dbtype = mkOption {
|
|
||||||
type = types.enum [ "sqlite" "pgsql" "mysql" ];
|
|
||||||
default = "sqlite";
|
|
||||||
description = "Database type.";
|
|
||||||
};
|
|
||||||
dbname = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = "nextcloud";
|
|
||||||
description = "Database name.";
|
|
||||||
};
|
|
||||||
dbuser = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = "nextcloud";
|
|
||||||
description = "Database user.";
|
|
||||||
};
|
|
||||||
dbpass = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Database password. Use <literal>dbpassFile</literal> to avoid this
|
|
||||||
being world-readable in the <literal>/nix/store</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
dbpassFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
The full path to a file that contains the database password.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
dbhost = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = "localhost";
|
|
||||||
description = ''
|
|
||||||
Database host.
|
|
||||||
|
|
||||||
Note: for using Unix authentication with PostgreSQL, this should be
|
|
||||||
set to <literal>/run/postgresql</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
dbport = mkOption {
|
|
||||||
type = with types; nullOr (either int str);
|
|
||||||
default = null;
|
|
||||||
description = "Database port.";
|
|
||||||
};
|
|
||||||
dbtableprefix = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Table prefix in Nextcloud database.";
|
|
||||||
};
|
|
||||||
adminuser = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "root";
|
|
||||||
description = "Admin username.";
|
|
||||||
};
|
|
||||||
adminpass = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Admin password. Use <literal>adminpassFile</literal> to avoid this
|
|
||||||
being world-readable in the <literal>/nix/store</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
adminpassFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
The full path to a file that contains the admin's password. Must be
|
|
||||||
readable by user <literal>nextcloud</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraTrustedDomains = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Trusted domains, from which the nextcloud installation will be
|
|
||||||
acessible. You don't need to add
|
|
||||||
<literal>services.nextcloud.hostname</literal> here.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
trustedProxies = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Trusted proxies, to provide if the nextcloud installation is being
|
|
||||||
proxied to secure against e.g. spoofing.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
overwriteProtocol = mkOption {
|
|
||||||
type = types.nullOr (types.enum [ "http" "https" ]);
|
|
||||||
default = null;
|
|
||||||
example = "https";
|
|
||||||
|
|
||||||
description = ''
|
|
||||||
Force Nextcloud to always use HTTPS i.e. for link generation. Nextcloud
|
|
||||||
uses the currently used protocol by default, but when behind a reverse-proxy,
|
|
||||||
it may use <literal>http</literal> for everything although Nextcloud
|
|
||||||
may be served via HTTPS.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultPhoneRegion = mkOption {
|
|
||||||
default = null;
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
example = "DE";
|
|
||||||
description = ''
|
|
||||||
<warning>
|
|
||||||
<para>This option exists since Nextcloud 21! If older versions are used,
|
|
||||||
this will throw an eval-error!</para>
|
|
||||||
</warning>
|
|
||||||
|
|
||||||
<link xlink:href="https://www.iso.org/iso-3166-country-codes.html">ISO 3611-1</link>
|
|
||||||
country codes for automatic phone-number detection without a country code.
|
|
||||||
|
|
||||||
With e.g. <literal>DE</literal> set, the <literal>+49</literal> can be omitted for
|
|
||||||
phone-numbers.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
defaultapp = mkOption {
|
|
||||||
default = null;
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
example = "files";
|
|
||||||
description = ''
|
|
||||||
This options sets the app that opens as default.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
caching = {
|
|
||||||
apcu = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Whether to load the APCu module into PHP.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
redis = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Whether to load the Redis module into PHP.
|
|
||||||
You still need to enable Redis in your config.php.
|
|
||||||
See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
memcached = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Whether to load the Memcached module into PHP.
|
|
||||||
You still need to enable Memcached in your config.php.
|
|
||||||
See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
autoUpdateApps = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Run regular auto update of all apps installed from the nextcloud app store.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
startAt = mkOption {
|
|
||||||
type = with types; either str (listOf str);
|
|
||||||
default = "05:00:00";
|
|
||||||
example = "Sun 14:00:00";
|
|
||||||
description = ''
|
|
||||||
When to run the update. See `systemd.services.<name>.startAt`.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
occ = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = occ;
|
|
||||||
internal = true;
|
|
||||||
description = ''
|
|
||||||
The nextcloud-occ program preconfigured to target this Nextcloud instance.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraOptions = mkOption {
|
|
||||||
type = types.attrs;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
Extra options which should be appended to nextcloud's config.php file
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
secretFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Secret options which will be appended to nextcloud's config.php file (written in JSON, in the same
|
|
||||||
form as the `extraOptions` option).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable (mkMerge [
|
|
||||||
{ assertions = let acfg = cfg.config; in [
|
|
||||||
{ assertion = !(acfg.dbpass != null && acfg.dbpassFile != null);
|
|
||||||
message = "Please specify no more than one of dbpass or dbpassFile";
|
|
||||||
}
|
|
||||||
{ assertion = ((acfg.adminpass != null || acfg.adminpassFile != null)
|
|
||||||
&& !(acfg.adminpass != null && acfg.adminpassFile != null));
|
|
||||||
message = "Please specify exactly one of adminpass or adminpassFile";
|
|
||||||
}
|
|
||||||
{ assertion = versionOlder cfg.package.version "21" -> cfg.config.defaultPhoneRegion == null;
|
|
||||||
message = "The `defaultPhoneRegion'-setting is only supported for Nextcloud >=21!";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
warnings = []
|
|
||||||
++ (optional (cfg.poolConfig != null) ''
|
|
||||||
Using config.services.nextcloud.poolConfig is deprecated and will become unsupported in a future release.
|
|
||||||
Please migrate your configuration to config.services.nextcloud.poolSettings.
|
|
||||||
'')
|
|
||||||
++ (optional (versionOlder cfg.package.version "18") ''
|
|
||||||
A legacy Nextcloud install (from before NixOS 20.03) may be installed.
|
|
||||||
|
|
||||||
You're currently deploying an older version of Nextcloud. This may be needed
|
|
||||||
since Nextcloud doesn't allow major version upgrades that skip multiple
|
|
||||||
versions (i.e. an upgrade from 16 is possible to 17, but not 16 to 18).
|
|
||||||
|
|
||||||
It is assumed that Nextcloud will be upgraded from version 16 to 17.
|
|
||||||
|
|
||||||
* If this is a fresh install, there will be no upgrade to do now.
|
|
||||||
|
|
||||||
* If this server already had Nextcloud installed, first deploy this to your
|
|
||||||
server, and wait until the upgrade to 17 is finished.
|
|
||||||
|
|
||||||
Then, set `services.nextcloud.package` to `pkgs.nextcloud18` to upgrade to
|
|
||||||
Nextcloud version 18. Please note that Nextcloud 19 is already out and it's
|
|
||||||
recommended to upgrade to nextcloud19 after that.
|
|
||||||
'')
|
|
||||||
++ (optional (versionOlder cfg.package.version "19") ''
|
|
||||||
A legacy Nextcloud install (from before NixOS 20.09) may be installed.
|
|
||||||
|
|
||||||
If/After nextcloud18 is installed successfully, you can safely upgrade to
|
|
||||||
nextcloud19. If not, please upgrade to nextcloud18 first since Nextcloud doesn't
|
|
||||||
support upgrades that skip multiple versions (i.e. an upgrade from 17 to 19 isn't
|
|
||||||
possible, but an upgrade from 18 to 19).
|
|
||||||
'')
|
|
||||||
++ (optional (versionOlder cfg.package.version "21") ''
|
|
||||||
The latest Nextcloud release is v21 which can be installed by setting
|
|
||||||
`services.nextcloud.package` to `pkgs.nextcloud21`. Please note that if you're
|
|
||||||
on `pkgs.nextcloud19`, you'll have to install `pkgs.nextcloud20` first.
|
|
||||||
'');
|
|
||||||
|
|
||||||
services.nextcloud-patched.package = with pkgs;
|
|
||||||
mkDefault (
|
|
||||||
if pkgs ? nextcloud
|
|
||||||
then throw ''
|
|
||||||
The `pkgs.nextcloud`-attribute has been removed. If it's supposed to be the default
|
|
||||||
nextcloud defined in an overlay, please set `services.nextcloud.package` to
|
|
||||||
`pkgs.nextcloud`.
|
|
||||||
''
|
|
||||||
else if versionOlder stateVersion "20.03" then nextcloud17
|
|
||||||
else if versionOlder stateVersion "20.09" then nextcloud18
|
|
||||||
else nextcloud19
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
{ systemd.timers.nextcloud-cron = {
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig.OnBootSec = "5m";
|
|
||||||
timerConfig.OnUnitActiveSec = "15m";
|
|
||||||
timerConfig.Unit = "nextcloud-cron.service";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services = {
|
|
||||||
# When upgrading the Nextcloud package, Nextcloud can report errors such as
|
|
||||||
# "The files of the app [all apps in /var/lib/nextcloud/apps] were not replaced correctly"
|
|
||||||
# Restarting phpfpm on Nextcloud package update fixes these issues (but this is a workaround).
|
|
||||||
phpfpm-nextcloud.restartTriggers = [ cfg.package ];
|
|
||||||
|
|
||||||
nextcloud-setup = let
|
|
||||||
c = cfg.config;
|
|
||||||
writePhpArrary = a: "[${concatMapStringsSep "," (val: ''"${toString val}"'') a}]";
|
|
||||||
overrideConfig = pkgs.writeText "nextcloud-config.php" ''
|
|
||||||
<?php
|
|
||||||
${optionalString (c.dbpassFile != null) ''
|
|
||||||
function nix_read_pwd() {
|
|
||||||
$file = "${c.dbpassFile}";
|
|
||||||
if (!file_exists($file)) {
|
|
||||||
throw new \RuntimeException(sprintf(
|
|
||||||
"Cannot start Nextcloud, dbpass file %s set by NixOS doesn't exist!",
|
|
||||||
$file
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return trim(file_get_contents($file));
|
|
||||||
}
|
|
||||||
''}
|
|
||||||
${optionalString (cfg.secretFile != null) ''
|
|
||||||
function nix_read_secrets() {
|
|
||||||
$file = "${cfg.secretFile}";
|
|
||||||
if (!file_exists($file)) {
|
|
||||||
throw new \RuntimeException(sprintf(
|
|
||||||
"Cannot start Nextcloud, secrets file %s set by NixOS doesn't exist!",
|
|
||||||
$file
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return json_decode(file_get_contents($file));
|
|
||||||
}
|
|
||||||
''}
|
|
||||||
$CONFIG = [
|
|
||||||
'apps_paths' => [
|
|
||||||
[ 'path' => '${cfg.home}/apps', 'url' => '/apps', 'writable' => false ],
|
|
||||||
[ 'path' => '${cfg.home}/store-apps', 'url' => '/store-apps', 'writable' => true ],
|
|
||||||
],
|
|
||||||
'datadirectory' => '${cfg.home}/data',
|
|
||||||
'skeletondirectory' => '${cfg.skeletonDirectory}',
|
|
||||||
${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"}
|
|
||||||
'log_type' => 'syslog',
|
|
||||||
'log_level' => '${builtins.toString cfg.logLevel}',
|
|
||||||
${optionalString (c.defaultapp != null) "'defaultapp' => '${c.defaultapp}',"}
|
|
||||||
${optionalString (c.overwriteProtocol != null) "'overwriteprotocol' => '${c.overwriteProtocol}',"}
|
|
||||||
${optionalString (c.dbname != null) "'dbname' => '${c.dbname}',"}
|
|
||||||
${optionalString (c.dbhost != null) "'dbhost' => '${c.dbhost}',"}
|
|
||||||
${optionalString (c.dbport != null) "'dbport' => '${toString c.dbport}',"}
|
|
||||||
${optionalString (c.dbuser != null) "'dbuser' => '${c.dbuser}',"}
|
|
||||||
${optionalString (c.dbtableprefix != null) "'dbtableprefix' => '${toString c.dbtableprefix}',"}
|
|
||||||
${optionalString (c.dbpass != null) "'dbpassword' => '${c.dbpass}',"}
|
|
||||||
${optionalString (c.dbpassFile != null) "'dbpassword' => nix_read_pwd(),"}
|
|
||||||
'dbtype' => '${c.dbtype}',
|
|
||||||
'trusted_domains' => ${writePhpArrary ([ cfg.hostName ] ++ c.extraTrustedDomains)},
|
|
||||||
'trusted_proxies' => ${writePhpArrary (c.trustedProxies)},
|
|
||||||
${optionalString (c.defaultPhoneRegion != null) "'default_phone_region' => '${c.defaultPhoneRegion}',"}
|
|
||||||
];
|
|
||||||
|
|
||||||
$EXTRACONFIG = json_decode('${builtins.toJSON cfg.extraOptions}', true);
|
|
||||||
|
|
||||||
array_push($CONFIG, $EXTRACONFIG);
|
|
||||||
${optionalString (cfg.secretFile != null) "array_push($CONFIG, nix_read_secrets());"}
|
|
||||||
'';
|
|
||||||
occInstallCmd = let
|
|
||||||
dbpass = if c.dbpassFile != null
|
|
||||||
then ''"$(<"${toString c.dbpassFile}")"''
|
|
||||||
else if c.dbpass != null
|
|
||||||
then ''"${toString c.dbpass}"''
|
|
||||||
else ''""'';
|
|
||||||
adminpass = if c.adminpassFile != null
|
|
||||||
then ''"$(<"${toString c.adminpassFile}")"''
|
|
||||||
else ''"${toString c.adminpass}"'';
|
|
||||||
installFlags = concatStringsSep " \\\n "
|
|
||||||
(mapAttrsToList (k: v: "${k} ${toString v}") {
|
|
||||||
"--database" = ''"${c.dbtype}"'';
|
|
||||||
# The following attributes are optional depending on the type of
|
|
||||||
# database. Those that evaluate to null on the left hand side
|
|
||||||
# will be omitted.
|
|
||||||
${if c.dbname != null then "--database-name" else null} = ''"${c.dbname}"'';
|
|
||||||
${if c.dbhost != null then "--database-host" else null} = ''"${c.dbhost}"'';
|
|
||||||
${if c.dbport != null then "--database-port" else null} = ''"${toString c.dbport}"'';
|
|
||||||
${if c.dbuser != null then "--database-user" else null} = ''"${c.dbuser}"'';
|
|
||||||
"--database-pass" = dbpass;
|
|
||||||
${if c.dbtableprefix != null
|
|
||||||
then "--database-table-prefix" else null} = ''"${toString c.dbtableprefix}"'';
|
|
||||||
"--admin-user" = ''"${c.adminuser}"'';
|
|
||||||
"--admin-pass" = adminpass;
|
|
||||||
"--data-dir" = ''"${cfg.home}/data"'';
|
|
||||||
});
|
|
||||||
in ''
|
|
||||||
${occ}/bin/nextcloud-occ maintenance:install \
|
|
||||||
${installFlags}
|
|
||||||
'';
|
|
||||||
occSetTrustedDomainsCmd = concatStringsSep "\n" (imap0
|
|
||||||
(i: v: ''
|
|
||||||
${occ}/bin/nextcloud-occ config:system:set trusted_domains \
|
|
||||||
${toString i} --value="${toString v}"
|
|
||||||
'') ([ cfg.hostName ] ++ cfg.config.extraTrustedDomains));
|
|
||||||
|
|
||||||
in {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
before = [ "phpfpm-nextcloud.service" ];
|
|
||||||
path = [ occ ];
|
|
||||||
script = ''
|
|
||||||
chmod og+x ${cfg.home}
|
|
||||||
|
|
||||||
${optionalString (c.dbpassFile != null) ''
|
|
||||||
if [ ! -r "${c.dbpassFile}" ]; then
|
|
||||||
echo "dbpassFile ${c.dbpassFile} is not readable by nextcloud:nextcloud! Aborting..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ -z "$(<${c.dbpassFile})" ]; then
|
|
||||||
echo "dbpassFile ${c.dbpassFile} is empty!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
''}
|
|
||||||
${optionalString (c.adminpassFile != null) ''
|
|
||||||
if [ ! -r "${c.adminpassFile}" ]; then
|
|
||||||
echo "adminpassFile ${c.adminpassFile} is not readable by nextcloud:nextcloud! Aborting..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ -z "$(<${c.adminpassFile})" ]; then
|
|
||||||
echo "adminpassFile ${c.adminpassFile} is empty!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
''}
|
|
||||||
|
|
||||||
ln -sf ${cfg.package}/apps ${cfg.home}/
|
|
||||||
|
|
||||||
# create nextcloud directories.
|
|
||||||
# if the directories exist already with wrong permissions, we fix that
|
|
||||||
for dir in ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps; do
|
|
||||||
if [ ! -e $dir ]; then
|
|
||||||
install -o nextcloud -g nextcloud -d $dir
|
|
||||||
elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then
|
|
||||||
chgrp -R nextcloud $dir
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php
|
|
||||||
|
|
||||||
# Do not install if already installed
|
|
||||||
if [[ ! -e ${cfg.home}/config/config.php ]]; then
|
|
||||||
${occInstallCmd}
|
|
||||||
fi
|
|
||||||
|
|
||||||
${occ}/bin/nextcloud-occ upgrade
|
|
||||||
|
|
||||||
${occ}/bin/nextcloud-occ config:system:delete trusted_domains
|
|
||||||
${occSetTrustedDomainsCmd}
|
|
||||||
'';
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
serviceConfig.User = "nextcloud";
|
|
||||||
};
|
|
||||||
nextcloud-cron = {
|
|
||||||
environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
serviceConfig.User = "nextcloud";
|
|
||||||
serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php";
|
|
||||||
};
|
|
||||||
nextcloud-update-plugins = mkIf cfg.autoUpdateApps.enable {
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
serviceConfig.ExecStart = "${occ}/bin/nextcloud-occ app:update --all";
|
|
||||||
serviceConfig.User = "nextcloud";
|
|
||||||
startAt = cfg.autoUpdateApps.startAt;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.phpfpm = {
|
|
||||||
pools.nextcloud = {
|
|
||||||
user = "nextcloud";
|
|
||||||
group = "nextcloud";
|
|
||||||
phpOptions = phpOptionsStr;
|
|
||||||
phpPackage = phpPackage;
|
|
||||||
phpEnv = {
|
|
||||||
NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
|
|
||||||
PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin";
|
|
||||||
};
|
|
||||||
settings = mapAttrs (name: mkDefault) {
|
|
||||||
"listen.owner" = config.services.nginx.user;
|
|
||||||
"listen.group" = config.services.nginx.group;
|
|
||||||
} // cfg.poolSettings;
|
|
||||||
extraConfig = cfg.poolConfig;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.nextcloud = {
|
|
||||||
home = "${cfg.home}";
|
|
||||||
group = "nextcloud";
|
|
||||||
createHome = true;
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ];
|
|
||||||
|
|
||||||
environment.systemPackages = [ occ ];
|
|
||||||
|
|
||||||
services.nginx.enable = mkDefault true;
|
|
||||||
|
|
||||||
services.nginx.virtualHosts.${cfg.hostName} = let
|
|
||||||
major = toInt (versions.major cfg.package.version);
|
|
||||||
in {
|
|
||||||
root = cfg.package;
|
|
||||||
locations = {
|
|
||||||
"= /robots.txt" = {
|
|
||||||
priority = 100;
|
|
||||||
extraConfig = ''
|
|
||||||
allow all;
|
|
||||||
log_not_found off;
|
|
||||||
access_log off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"= /" = {
|
|
||||||
priority = 100;
|
|
||||||
extraConfig = ''
|
|
||||||
if ( $http_user_agent ~ ^DavClnt ) {
|
|
||||||
return 302 /remote.php/webdav/$is_args$args;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"/" = {
|
|
||||||
priority = 900;
|
|
||||||
extraConfig = "rewrite ^ /index.php;";
|
|
||||||
};
|
|
||||||
"~ ^/store-apps" = {
|
|
||||||
priority = 201;
|
|
||||||
extraConfig = "root ${cfg.home};";
|
|
||||||
};
|
|
||||||
"^~ /.well-known" = {
|
|
||||||
priority = 210;
|
|
||||||
extraConfig = ''
|
|
||||||
absolute_redirect off;
|
|
||||||
location = /.well-known/carddav {
|
|
||||||
return 301 /remote.php/dav;
|
|
||||||
}
|
|
||||||
location = /.well-known/caldav {
|
|
||||||
return 301 /remote.php/dav;
|
|
||||||
}
|
|
||||||
location ~ ^/\.well-known/(?!acme-challenge|pki-validation) {
|
|
||||||
return 301 /index.php$request_uri;
|
|
||||||
}
|
|
||||||
try_files $uri $uri/ =404;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)".extraConfig = ''
|
|
||||||
return 404;
|
|
||||||
'';
|
|
||||||
"~ ^/(?:\\.(?!well-known)|autotest|occ|issue|indie|db_|console)".extraConfig = ''
|
|
||||||
return 404;
|
|
||||||
'';
|
|
||||||
"~ ^\\/(?:index|remote|public|cron|core\\/ajax\\/update|status|ocs\\/v[12]|updater\\/.+|oc[ms]-provider\\/.+|.+\\/richdocumentscode\\/proxy)\\.php(?:$|\\/)" = {
|
|
||||||
priority = 500;
|
|
||||||
extraConfig = ''
|
|
||||||
include ${config.services.nginx.package}/conf/fastcgi.conf;
|
|
||||||
fastcgi_split_path_info ^(.+?\.php)(\\/.*)$;
|
|
||||||
set $path_info $fastcgi_path_info;
|
|
||||||
try_files $fastcgi_script_name =404;
|
|
||||||
fastcgi_param PATH_INFO $path_info;
|
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
||||||
fastcgi_param HTTPS ${if cfg.https then "on" else "off"};
|
|
||||||
fastcgi_param modHeadersAvailable true;
|
|
||||||
fastcgi_param front_controller_active true;
|
|
||||||
fastcgi_pass unix:${fpm.socket};
|
|
||||||
fastcgi_intercept_errors on;
|
|
||||||
fastcgi_request_buffering off;
|
|
||||||
fastcgi_read_timeout 120s;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"~ \\.(?:css|js|woff2?|svg|gif|map)$".extraConfig = ''
|
|
||||||
try_files $uri /index.php$request_uri;
|
|
||||||
expires 6M;
|
|
||||||
access_log off;
|
|
||||||
'';
|
|
||||||
"~ ^\\/(?:updater|ocs-provider|ocm-provider)(?:$|\\/)".extraConfig = ''
|
|
||||||
try_files $uri/ =404;
|
|
||||||
index index.php;
|
|
||||||
'';
|
|
||||||
"~ \\.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$".extraConfig = ''
|
|
||||||
try_files $uri /index.php$request_uri;
|
|
||||||
access_log off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
extraConfig = ''
|
|
||||||
index index.php index.html /index.php$request_uri;
|
|
||||||
expires 1m;
|
|
||||||
add_header X-Content-Type-Options nosniff;
|
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
|
||||||
add_header X-Robots-Tag none;
|
|
||||||
add_header X-Download-Options noopen;
|
|
||||||
add_header X-Permitted-Cross-Domain-Policies none;
|
|
||||||
add_header X-Frame-Options sameorigin;
|
|
||||||
add_header Referrer-Policy no-referrer;
|
|
||||||
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
|
|
||||||
client_max_body_size ${cfg.maxUploadSize};
|
|
||||||
fastcgi_buffers 64 4K;
|
|
||||||
fastcgi_hide_header X-Powered-By;
|
|
||||||
gzip on;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_comp_level 4;
|
|
||||||
gzip_min_length 256;
|
|
||||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
|
||||||
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
|
||||||
|
|
||||||
${optionalString cfg.webfinger ''
|
|
||||||
rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
|
|
||||||
rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.hacc.nftables.nat;
|
|
||||||
nats = config.networking.nat;
|
|
||||||
in {
|
|
||||||
options.hacc.nftables.nat = {
|
|
||||||
enable = mkEnableOption "Wrap NAT into nftables.";
|
|
||||||
forwardPorts = mkOption {
|
|
||||||
type = with types; listOf (submodule {
|
|
||||||
options = {
|
|
||||||
ports = mkOption {
|
|
||||||
type = types.listOf (types.either types.int (types.strMatching "[[:digit:]]+-[[:digit:]]+"));
|
|
||||||
};
|
|
||||||
destination = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "10.0.0.1";
|
|
||||||
};
|
|
||||||
proto = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "tcp";
|
|
||||||
example = "udp";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
default = [];
|
|
||||||
example = [{ ports = [ 8080 "9100-9200" ]; destination = "192.168.100.2"; proto = "udp"; }];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.nat.enable = mkOverride 99 false;
|
|
||||||
|
|
||||||
boot = {
|
|
||||||
kernelModules = [ "nf_nat_ftp" ];
|
|
||||||
kernel.sysctl = {
|
|
||||||
"net.ipv4.conf.all.forwarding" = mkOverride 90 true;
|
|
||||||
"net.ipv4.conf.default.forwarding" = mkOverride 90 true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.nftables = {
|
|
||||||
extraConfig = ''
|
|
||||||
table ip nat {
|
|
||||||
chain prerouting {
|
|
||||||
type nat hook prerouting priority -100
|
|
||||||
${concatMapStringsSep "\n" (rule: "iif ${nats.externalInterface} ${rule.proto} dport { ${concatStringsSep ", " (map (x: toString x) rule.ports)} } dnat ${rule.destination}") cfg.forwardPorts}
|
|
||||||
}
|
|
||||||
chain postrouting {
|
|
||||||
type nat hook postrouting priority 100
|
|
||||||
${concatMapStringsSep "\n" (iface: "iifname ${replaceStrings ["+"] ["*"] iface} oifname ${nats.externalInterface} masquerade") nats.internalInterfaces}
|
|
||||||
${concatMapStringsSep "\n" (addr: "ip saddr ${addr} oifname ${nats.externalInterface} masquerade") nats.internalIPs}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
52
modules/nopersist.nix
Normal file
52
modules/nopersist.nix
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
{ config, lib, pkgs, modules, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ modules.bindMounts ];
|
||||||
|
|
||||||
|
users.mutableUsers = false;
|
||||||
|
|
||||||
|
boot.initrd = mkIf (config.fileSystems."/".fsType or "notzfs" == "zfs") {
|
||||||
|
network.ssh.hostKeys = mkIf config.hacc.encboot.enable
|
||||||
|
(mkForce [ /persist/ssh/encboot_host ]);
|
||||||
|
|
||||||
|
postDeviceCommands = mkIf (!config.boot.initrd.systemd.enable)
|
||||||
|
(mkAfter ''
|
||||||
|
zfs rollback -r ${config.fileSystems."/".device}@blank
|
||||||
|
'');
|
||||||
|
|
||||||
|
systemd = mkIf config.boot.initrd.systemd.enable {
|
||||||
|
storePaths = [ pkgs.zfs ];
|
||||||
|
services.rollback = {
|
||||||
|
description = "Rollback ZFS datasets to a pristine state";
|
||||||
|
wantedBy = [ "initrd.target" ];
|
||||||
|
after = [ "zfs-import-${head (splitString "/" config.fileSystems."/".device)}.service" ];
|
||||||
|
before = [ "sysroot.mount" ];
|
||||||
|
path = [ pkgs.zfs ];
|
||||||
|
unitConfig.DefaultDependencies = "no";
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
script = ''
|
||||||
|
zfs rollback -r ${config.fileSystems."/".device}@blank && echo "rollback complete"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
hostKeys = [
|
||||||
|
{
|
||||||
|
path = "/persist/ssh/ssh_host_ed25519_key";
|
||||||
|
type = "ed25519";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
path = "/persist/ssh/ssh_host_rsa_key";
|
||||||
|
type = "rsa";
|
||||||
|
bits = 4096;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql.dataDir =
|
||||||
|
"/persist/postgresql/${config.services.postgresql.package.psqlSchema}";
|
||||||
|
}
|
|
@ -21,33 +21,42 @@ in
|
||||||
default = [];
|
default = [];
|
||||||
description = "subdirectories that shouldn't be published";
|
description = "subdirectories that shouldn't be published";
|
||||||
};
|
};
|
||||||
|
builders = mkOption {
|
||||||
|
type = types.lazyAttrsOf types.package;
|
||||||
|
default = {};
|
||||||
|
description = "exposes website builders, for use with nix run";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = let
|
||||||
|
subdirs =
|
||||||
|
let dirAttrs = filterAttrs
|
||||||
|
(n: v: v == "directory" || lists.elem n cfg.ignore)
|
||||||
|
(builtins.readDir cfg.directory);
|
||||||
|
in mapAttrsToList (n: v: n) dirAttrs;
|
||||||
|
mkWebsiteDrv = subdir:
|
||||||
|
pkgs.callPackage "${cfg.directory}/${subdir}" {};
|
||||||
|
mkWebsiteVHost = subdir: {
|
||||||
|
name = subdir;
|
||||||
|
# the nginx virtualhost config (for all sites) goes in here
|
||||||
|
value = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
|
||||||
|
locations."/".root =
|
||||||
|
(mkWebsiteDrv subdir).outPath;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in mkIf cfg.enable {
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
virtualHosts =
|
virtualHosts =
|
||||||
let
|
listToAttrs (map mkWebsiteVHost subdirs);
|
||||||
subdirs =
|
|
||||||
let dirAttrs = filterAttrs
|
|
||||||
(n: v: v == "directory" || lists.elem n cfg.ignore)
|
|
||||||
(builtins.readDir cfg.directory);
|
|
||||||
in mapAttrsToList (n: v: n) dirAttrs;
|
|
||||||
|
|
||||||
mkWebsite = subdir: {
|
|
||||||
name = subdir;
|
|
||||||
# the nginx virtualhost config (for all sites) goes in here
|
|
||||||
value = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
|
|
||||||
# naive string interpolation is safe here since nix will always immediately
|
|
||||||
# resolve relative paths to absolute paths; it's not lazy about that.
|
|
||||||
locations."/".root =
|
|
||||||
(pkgs.callPackage "${cfg.directory}/${subdir}" {}).outPath;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in listToAttrs (map mkWebsite subdirs);
|
|
||||||
};
|
};
|
||||||
|
hacc.websites.builders =
|
||||||
|
listToAttrs (map (subdir: {
|
||||||
|
name = subdir;
|
||||||
|
value = if (mkWebsiteDrv subdir) ? watch then (mkWebsiteDrv subdir).watch else null;
|
||||||
|
}) subdirs);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
102
nix/sources.json
102
nix/sources.json
|
@ -1,102 +0,0 @@
|
||||||
{
|
|
||||||
"haccmap": {
|
|
||||||
"branch": "master",
|
|
||||||
"repo": "https://gitlab.infra4future.de/hacc/haccspace-rc3-map",
|
|
||||||
"rev": "9490ebf656ef379e51cb518ec0038e15d6aeaac6",
|
|
||||||
"type": "git"
|
|
||||||
},
|
|
||||||
"home-manager": {
|
|
||||||
"branch": "release-21.11",
|
|
||||||
"description": "Manage a user environment using Nix [maintainer=@rycee] ",
|
|
||||||
"homepage": "https://nix-community.github.io/home-manager/",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "home-manager",
|
|
||||||
"rev": "d93d56ab8c1c6aa575854a79b9d2f69d491db7d0",
|
|
||||||
"sha256": "1fi27zabvqlyc2ggg7wr01j813gs46rswg1i897h9hqkbgqsjkny",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://github.com/nix-community/home-manager/archive/d93d56ab8c1c6aa575854a79b9d2f69d491db7d0.tar.gz",
|
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
|
||||||
},
|
|
||||||
"mattermost-server": {
|
|
||||||
"branch": "master",
|
|
||||||
"description": "Open source Slack-alternative in Golang and React - Mattermost",
|
|
||||||
"homepage": "https://mattermost.com",
|
|
||||||
"owner": "mattermost",
|
|
||||||
"repo": "mattermost-server",
|
|
||||||
"rev": "71cdd9e486399f20039eaf147cb12dbcbff002a6",
|
|
||||||
"sha256": "1hgcclf7g18kma9vfbiwgxzpzw26qmckmi0g5wympqc9dbc3y25v",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://github.com/mattermost/mattermost-server/archive/refs/tags/v6.7.0.tar.gz",
|
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/refs/tags/v<version>.tar.gz",
|
|
||||||
"version": "6.7.0"
|
|
||||||
},
|
|
||||||
"mattermost-webapp": {
|
|
||||||
"sha256": "15lj6xid2fizcp046h1kv3mls0p166zk04n3jw2zddm1kymndplp",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://releases.mattermost.com/6.7.0/mattermost-6.7.0-linux-amd64.tar.gz",
|
|
||||||
"url_template": "https://releases.mattermost.com/<version>/mattermost-<version>-linux-amd64.tar.gz",
|
|
||||||
"version": "6.7.0"
|
|
||||||
},
|
|
||||||
"niv": {
|
|
||||||
"branch": "master",
|
|
||||||
"description": "Easy dependency management for Nix projects",
|
|
||||||
"homepage": "https://github.com/nmattia/niv",
|
|
||||||
"owner": "nmattia",
|
|
||||||
"repo": "niv",
|
|
||||||
"rev": "82e5cd1ad3c387863f0545d7591512e76ab0fc41",
|
|
||||||
"sha256": "090l219mzc0gi33i3psgph6s2pwsc8qy4lyrqjdj4qzkvmaj65a7",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://github.com/nmattia/niv/archive/82e5cd1ad3c387863f0545d7591512e76ab0fc41.tar.gz",
|
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
|
||||||
},
|
|
||||||
"nix-hexchen": {
|
|
||||||
"branch": "main",
|
|
||||||
"ref": "main",
|
|
||||||
"repo": "https://gitlab.com/hexchen/nixfiles",
|
|
||||||
"rev": "ef358992030e9a6fa975a24bf4d9aa133bc72424",
|
|
||||||
"sha256": "01hcdrpfc8g1bbc96h7gi04zmyxi9vd7392ncadwfkx5xfd2fp17",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://gitlab.com/hexchen/nixfiles/-/archive/ef358992030e9a6fa975a24bf4d9aa133bc72424.tar.gz",
|
|
||||||
"url_template": "<repo>/-/archive/<rev>.tar.gz"
|
|
||||||
},
|
|
||||||
"nixos-mailserver": {
|
|
||||||
"branch": "nixos-21.11",
|
|
||||||
"ref": "nixos-21.11",
|
|
||||||
"repo": "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver",
|
|
||||||
"rev": "6e3a7b2ea6f0d68b82027b988aa25d3423787303",
|
|
||||||
"sha256": "1i56llz037x416bw698v8j6arvv622qc0vsycd20lx3yx8n77n44",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/6e3a7b2ea6f0d68b82027b988aa25d3423787303.tar.gz",
|
|
||||||
"url_template": "<repo>/-/archive/<rev>.tar.gz"
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"branch": "nixos-21.11",
|
|
||||||
"description": "Nix Packages collection",
|
|
||||||
"homepage": "",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "4dbec24ea806d348dd8f8e8e80051bbda708726a",
|
|
||||||
"sha256": "0jjg6cr6jg16fy368p49vpq4al86084jhls135jqqvnf778q43cf",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://github.com/nixos/nixpkgs/archive/4dbec24ea806d348dd8f8e8e80051bbda708726a.tar.gz",
|
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
|
||||||
},
|
|
||||||
"nixpkgs-unstable": {
|
|
||||||
"branch": "nixos-unstable",
|
|
||||||
"description": "Nix Packages collection",
|
|
||||||
"homepage": "",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "e0169d7a9d324afebf5679551407756c77af8930",
|
|
||||||
"sha256": "1nr7ih856ca2vl0blim4bz2yxz6cg7jfsx4z096hg0qa5i04zg95",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://github.com/nixos/nixpkgs/archive/e0169d7a9d324afebf5679551407756c77af8930.tar.gz",
|
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
|
||||||
},
|
|
||||||
"workadventure": {
|
|
||||||
"branch": "master",
|
|
||||||
"repo": "https://stuebinm.eu/git/workadventure-nix",
|
|
||||||
"rev": "8db4bbc5eccaac218c68fb0853f1972dadd7a40c",
|
|
||||||
"type": "git"
|
|
||||||
}
|
|
||||||
}
|
|
174
nix/sources.nix
174
nix/sources.nix
|
@ -1,174 +0,0 @@
|
||||||
# This file has been generated by Niv.
|
|
||||||
|
|
||||||
let
|
|
||||||
|
|
||||||
#
|
|
||||||
# The fetchers. fetch_<type> fetches specs of type <type>.
|
|
||||||
#
|
|
||||||
|
|
||||||
fetch_file = pkgs: name: spec:
|
|
||||||
let
|
|
||||||
name' = sanitizeName name + "-src";
|
|
||||||
in
|
|
||||||
if spec.builtin or true then
|
|
||||||
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
|
|
||||||
else
|
|
||||||
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
|
|
||||||
|
|
||||||
fetch_tarball = pkgs: name: spec:
|
|
||||||
let
|
|
||||||
name' = sanitizeName name + "-src";
|
|
||||||
in
|
|
||||||
if spec.builtin or true then
|
|
||||||
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
|
|
||||||
else
|
|
||||||
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
|
|
||||||
|
|
||||||
fetch_git = name: spec:
|
|
||||||
let
|
|
||||||
ref =
|
|
||||||
if spec ? ref then spec.ref else
|
|
||||||
if spec ? branch then "refs/heads/${spec.branch}" else
|
|
||||||
if spec ? tag then "refs/tags/${spec.tag}" else
|
|
||||||
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
|
|
||||||
in
|
|
||||||
builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; };
|
|
||||||
|
|
||||||
fetch_local = spec: spec.path;
|
|
||||||
|
|
||||||
fetch_builtin-tarball = name: throw
|
|
||||||
''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.
|
|
||||||
$ niv modify ${name} -a type=tarball -a builtin=true'';
|
|
||||||
|
|
||||||
fetch_builtin-url = name: throw
|
|
||||||
''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.
|
|
||||||
$ niv modify ${name} -a type=file -a builtin=true'';
|
|
||||||
|
|
||||||
#
|
|
||||||
# Various helpers
|
|
||||||
#
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
|
|
||||||
sanitizeName = name:
|
|
||||||
(
|
|
||||||
concatMapStrings (s: if builtins.isList s then "-" else s)
|
|
||||||
(
|
|
||||||
builtins.split "[^[:alnum:]+._?=-]+"
|
|
||||||
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
# The set of packages used when specs are fetched using non-builtins.
|
|
||||||
mkPkgs = sources: system:
|
|
||||||
let
|
|
||||||
sourcesNixpkgs =
|
|
||||||
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
|
|
||||||
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
|
|
||||||
hasThisAsNixpkgsPath = <nixpkgs> == ./.;
|
|
||||||
in
|
|
||||||
if builtins.hasAttr "nixpkgs" sources
|
|
||||||
then sourcesNixpkgs
|
|
||||||
else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
|
|
||||||
import <nixpkgs> {}
|
|
||||||
else
|
|
||||||
abort
|
|
||||||
''
|
|
||||||
Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
|
|
||||||
add a package called "nixpkgs" to your sources.json.
|
|
||||||
'';
|
|
||||||
|
|
||||||
# The actual fetching function.
|
|
||||||
fetch = pkgs: name: spec:
|
|
||||||
|
|
||||||
if ! builtins.hasAttr "type" spec then
|
|
||||||
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
|
|
||||||
else if spec.type == "file" then fetch_file pkgs name spec
|
|
||||||
else if spec.type == "tarball" then fetch_tarball pkgs name spec
|
|
||||||
else if spec.type == "git" then fetch_git name spec
|
|
||||||
else if spec.type == "local" then fetch_local spec
|
|
||||||
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
|
|
||||||
else if spec.type == "builtin-url" then fetch_builtin-url name
|
|
||||||
else
|
|
||||||
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
|
|
||||||
|
|
||||||
# If the environment variable NIV_OVERRIDE_${name} is set, then use
|
|
||||||
# the path directly as opposed to the fetched source.
|
|
||||||
replace = name: drv:
|
|
||||||
let
|
|
||||||
saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name;
|
|
||||||
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
|
|
||||||
in
|
|
||||||
if ersatz == "" then drv else
|
|
||||||
# this turns the string into an actual Nix path (for both absolute and
|
|
||||||
# relative paths)
|
|
||||||
if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}";
|
|
||||||
|
|
||||||
# Ports of functions for older nix versions
|
|
||||||
|
|
||||||
# a Nix version of mapAttrs if the built-in doesn't exist
|
|
||||||
mapAttrs = builtins.mapAttrs or (
|
|
||||||
f: set: with builtins;
|
|
||||||
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
|
|
||||||
);
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
|
|
||||||
range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1);
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
|
|
||||||
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
|
|
||||||
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
|
|
||||||
concatMapStrings = f: list: concatStrings (map f list);
|
|
||||||
concatStrings = builtins.concatStringsSep "";
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
|
|
||||||
optionalAttrs = cond: as: if cond then as else {};
|
|
||||||
|
|
||||||
# fetchTarball version that is compatible between all the versions of Nix
|
|
||||||
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
|
|
||||||
let
|
|
||||||
inherit (builtins) lessThan nixVersion fetchTarball;
|
|
||||||
in
|
|
||||||
if lessThan nixVersion "1.12" then
|
|
||||||
fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
|
|
||||||
else
|
|
||||||
fetchTarball attrs;
|
|
||||||
|
|
||||||
# fetchurl version that is compatible between all the versions of Nix
|
|
||||||
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
|
|
||||||
let
|
|
||||||
inherit (builtins) lessThan nixVersion fetchurl;
|
|
||||||
in
|
|
||||||
if lessThan nixVersion "1.12" then
|
|
||||||
fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
|
|
||||||
else
|
|
||||||
fetchurl attrs;
|
|
||||||
|
|
||||||
# Create the final "sources" from the config
|
|
||||||
mkSources = config:
|
|
||||||
mapAttrs (
|
|
||||||
name: spec:
|
|
||||||
if builtins.hasAttr "outPath" spec
|
|
||||||
then abort
|
|
||||||
"The values in sources.json should not have an 'outPath' attribute"
|
|
||||||
else
|
|
||||||
spec // { outPath = replace name (fetch config.pkgs name spec); }
|
|
||||||
) config.sources;
|
|
||||||
|
|
||||||
# The "config" used by the fetchers
|
|
||||||
mkConfig =
|
|
||||||
{ sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
|
|
||||||
, sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile)
|
|
||||||
, system ? builtins.currentSystem
|
|
||||||
, pkgs ? mkPkgs sources system
|
|
||||||
}: rec {
|
|
||||||
# The sources, i.e. the attribute set of spec name to spec
|
|
||||||
inherit sources;
|
|
||||||
|
|
||||||
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
|
|
||||||
inherit pkgs;
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }
|
|
|
@ -2,48 +2,46 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
../../common
|
../common
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
modules.encboot
|
modules.encboot
|
||||||
modules.network.nftables modules.nftnat
|
modules.nopersist
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
./nftables.nix
|
||||||
|
./nextcloud.nix
|
||||||
../../services/nextcloud
|
./mattermost.nix
|
||||||
../../services/mattermost.nix
|
./murmur.nix
|
||||||
../../services/thelounge.nix
|
./hedgedoc-hacc.nix
|
||||||
../../services/murmur.nix
|
./hedgedoc-i4f.nix
|
||||||
../../services/hedgedoc-hacc.nix
|
./mail.nix
|
||||||
../../services/hedgedoc-i4f.nix
|
./forgejo.nix
|
||||||
../../services/mail.nix
|
./nginx-pages.nix
|
||||||
../../services/syncthing.nix
|
./vaultwarden.nix
|
||||||
../../services/gitlab.nix
|
./tracktrain.nix
|
||||||
../../services/nginx-pages.nix
|
./uffd.nix
|
||||||
../../services/gitlab-runner.nix
|
|
||||||
../../services/lantifa.nix
|
|
||||||
../../services/vaultwarden.nix
|
|
||||||
../../services/uffd.nix
|
|
||||||
# ../../services/workadventure.nix
|
|
||||||
|
|
||||||
./lxc.nix
|
./lxc.nix
|
||||||
|
./monit.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
hexchen.encboot = {
|
hacc.bindToPersist = [ "/var/lib/acme" ];
|
||||||
|
|
||||||
|
hacc.encboot = {
|
||||||
enable = true;
|
enable = true;
|
||||||
dataset = "-a";
|
dataset = "-a";
|
||||||
networkDrivers = [ "igb" ];
|
networkDrivers = [ "igb" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sops.defaultSopsFile = ../secrets.yaml;
|
||||||
|
sops.age.sshKeyPaths = [ "/persist/ssh/ssh_host_ed25519_key" ];
|
||||||
|
|
||||||
boot.loader.grub.enable = true;
|
boot.loader.grub.enable = true;
|
||||||
boot.loader.grub.version = 2;
|
|
||||||
boot.loader.grub.devices = [ "/dev/nvme0n1" "/dev/nvme1n1" ];
|
boot.loader.grub.devices = [ "/dev/nvme0n1" "/dev/nvme1n1" ];
|
||||||
boot.supportedFilesystems = [ "zfs" ];
|
boot.supportedFilesystems = [ "zfs" ];
|
||||||
|
|
||||||
networking.hostId = "b2867696";
|
networking.hostId = "b2867696";
|
||||||
networking.useDHCP = true;
|
networking.useDHCP = true;
|
||||||
networking.nftables.enable = true;
|
networking.nftables.enable = true;
|
||||||
hexchen.nftables.nat.enable = true;
|
|
||||||
networking.nat.internalInterfaces = ["ve-+"];
|
networking.hostName = "parsons";
|
||||||
networking.nat.externalInterface = "enp35s0";
|
|
||||||
|
|
||||||
networking.interfaces.enp35s0.ipv6.addresses = [{
|
networking.interfaces.enp35s0.ipv6.addresses = [{
|
||||||
address = "2a01:4f9:3a:2ddb::1";
|
address = "2a01:4f9:3a:2ddb::1";
|
||||||
|
@ -53,13 +51,6 @@
|
||||||
address = "fe80::1";
|
address = "fe80::1";
|
||||||
interface = "enp35s0";
|
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 = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -79,8 +70,8 @@
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
|
||||||
services.restic.backups.tardis = {
|
services.restic.backups.tardis = {
|
||||||
passwordFile = "/persist/restic/system";
|
passwordFile = "/run/secrets/restic/system";
|
||||||
environmentFile = "/persist/restic/system.s3creds";
|
environmentFile = "/run/secrets/restic/s3creds.env";
|
||||||
paths = [
|
paths = [
|
||||||
"/home"
|
"/home"
|
||||||
"/persist"
|
"/persist"
|
||||||
|
@ -93,5 +84,10 @@
|
||||||
repository = "b2:tardis-parsons:system";
|
repository = "b2:tardis-parsons:system";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sops.secrets = {
|
||||||
|
"restic/system" = {};
|
||||||
|
"restic/s3creds.env" = {};
|
||||||
|
};
|
||||||
|
|
||||||
system.stateVersion = "21.05";
|
system.stateVersion = "21.05";
|
||||||
}
|
}
|
86
parsons/forgejo.nix
Normal file
86
parsons/forgejo.nix
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
hacc.containers.forgejo = {
|
||||||
|
config = { lib, pkgs, ... }: {
|
||||||
|
system.stateVersion = "21.11";
|
||||||
|
|
||||||
|
environment.systemPackages = [ pkgs.forgejo ];
|
||||||
|
|
||||||
|
hacc.bindMounts."/var/lib/forgejo" = "/persist/forgejo";
|
||||||
|
|
||||||
|
services.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.forgejo;
|
||||||
|
lfs.enable = true;
|
||||||
|
database.type = "postgres";
|
||||||
|
settings = {
|
||||||
|
repository = {
|
||||||
|
DEFAULT_PRIVATE = "public";
|
||||||
|
PREFERRED_LICENSES = "Unlicense";
|
||||||
|
DEFAULT_BRANCH = "main";
|
||||||
|
};
|
||||||
|
oauth2_client = {
|
||||||
|
ACCOUNT_LINKING = "auto";
|
||||||
|
ENABLE_AUTO_REGISTRATION = true;
|
||||||
|
};
|
||||||
|
"repository.pull-requests" = {
|
||||||
|
DEFAULT_MERGE_STYLE = "merge";
|
||||||
|
DEFAULT_MERGE_MESSAGE_ALL_AUTHORS = true;
|
||||||
|
};
|
||||||
|
"repository.upload".FILE_MAX_SIZE = 1024;
|
||||||
|
server = {
|
||||||
|
LANDING_PAGE = "explore";
|
||||||
|
OFFLINE_MODE = true;
|
||||||
|
ROOT_URL = "https://git.infra4future.de";
|
||||||
|
HTTP_PORT = 3000;
|
||||||
|
HTTP_ADDR = "0.0.0.0";
|
||||||
|
};
|
||||||
|
security = { INSTALL_LOCK = true; };
|
||||||
|
other = {
|
||||||
|
SHOW_FOOTER_VERSION = false;
|
||||||
|
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false;
|
||||||
|
};
|
||||||
|
cron = {
|
||||||
|
ENABLED = true;
|
||||||
|
NOTICE_ON_SUCCESS = true;
|
||||||
|
};
|
||||||
|
"cron.update_mirrors" = {
|
||||||
|
SCHEDULE = "@every 12h";
|
||||||
|
PULL_LIMIT = "-1";
|
||||||
|
PUSH_LIMIT = "-1";
|
||||||
|
};
|
||||||
|
"cron.git_gc_repos".ENABLED = true;
|
||||||
|
"cron.delete_old_actions".ENABLED = true;
|
||||||
|
log.LEVEL = "Info";
|
||||||
|
service.DISABLE_REGISTRATION = true;
|
||||||
|
session.COOKIE_SECURE = true;
|
||||||
|
default.APP_NAME = "0x0: git for all creatures";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.postgresql.package = pkgs.postgresql_15;
|
||||||
|
|
||||||
|
services.postgresqlBackup = {
|
||||||
|
enable = true;
|
||||||
|
databases = [ "forgejo" ];
|
||||||
|
startAt = "*-*-* 23:45:00";
|
||||||
|
location = "/persist/backups/postgres";
|
||||||
|
};
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
AcceptEnv = "GIT_PROTOCOL";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."git.infra4future.de" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://${config.containers.forgejo.localAddress}:3000";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -28,6 +28,7 @@
|
||||||
fileSystems."/persist" =
|
fileSystems."/persist" =
|
||||||
{ device = "zroot/safe/persist";
|
{ device = "zroot/safe/persist";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/home" =
|
fileSystems."/home" =
|
||||||
|
@ -55,11 +56,6 @@
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/var/lib/docker" =
|
|
||||||
{ device = "zroot/local/docker";
|
|
||||||
fsType = "zfs";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [ ];
|
swapDevices = [ ];
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,43 +1,19 @@
|
||||||
{ config, lib, pkgs, profiles, modules, evalConfig, sources, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
containers.pad-hacc = {
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.5";
|
|
||||||
autoStart = true;
|
|
||||||
bindMounts = {
|
|
||||||
"/persist" = {
|
|
||||||
hostPath = "/persist/containers/pad-hacc";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
sops.secrets = {
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
"hedgedoc-hacc/env" = {};
|
||||||
];
|
};
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
containers.pad-hacc.bindMounts = {
|
||||||
networking.firewall.enable = false;
|
"/secrets".hostPath = "/run/secrets/hedgedoc-hacc";
|
||||||
networking.defaultGateway = {
|
};
|
||||||
address = "192.168.100.1";
|
hacc.containers.pad-hacc = {
|
||||||
interface = "eth0";
|
config = { config, lib, ... }: {
|
||||||
};
|
|
||||||
services.coredns = {
|
|
||||||
enable = true;
|
|
||||||
config = ''
|
|
||||||
.:53 {
|
|
||||||
forward . 1.1.1.1
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
services.hedgedoc = {
|
services.hedgedoc = {
|
||||||
enable = true;
|
enable = true;
|
||||||
configuration = {
|
settings = {
|
||||||
allowAnonymous = true;
|
allowAnonymous = true;
|
||||||
allowFreeURL = true;
|
allowFreeURL = true;
|
||||||
allowGravatar = false;
|
allowGravatar = false;
|
||||||
|
@ -58,9 +34,11 @@
|
||||||
authorizationURL = "https://login.infra4future.de/oauth2/authorize";
|
authorizationURL = "https://login.infra4future.de/oauth2/authorize";
|
||||||
tokenURL = "https://login.infra4future.de/oauth2/token";
|
tokenURL = "https://login.infra4future.de/oauth2/token";
|
||||||
clientID = "hedgedoc";
|
clientID = "hedgedoc";
|
||||||
clientSecret = "1a730af1-4d6e-4c1d-8f7e-72375c9b8d62";
|
# must be set to make the NixOS module happy, but env var takes precedence
|
||||||
|
clientSecret = "lol nope";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
environmentFile = "/secrets/env";
|
||||||
};
|
};
|
||||||
systemd.services.hedgedoc.environment = {
|
systemd.services.hedgedoc.environment = {
|
||||||
"CMD_LOGLEVEL" = "warn";
|
"CMD_LOGLEVEL" = "warn";
|
||||||
|
@ -70,20 +48,19 @@
|
||||||
"CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR" = "email";
|
"CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR" = "email";
|
||||||
"CMD_OAUTH2_PROVIDERNAME" = "Infra4Future";
|
"CMD_OAUTH2_PROVIDERNAME" = "Infra4Future";
|
||||||
};
|
};
|
||||||
|
|
||||||
services.postgresql = {
|
services.postgresql = {
|
||||||
enable = true;
|
enable = true;
|
||||||
ensureDatabases = [ "codimd" ];
|
ensureDatabases = [ "codimd" ];
|
||||||
ensureUsers = [{
|
ensureUsers = [{
|
||||||
name = "codimd";
|
name = "codimd";
|
||||||
ensurePermissions = {
|
ensureDBOwnership = true;
|
||||||
"DATABASE codimd" = "ALL PRIVILEGES";
|
|
||||||
};
|
|
||||||
}];
|
}];
|
||||||
authentication = ''
|
authentication = ''
|
||||||
local all all trust
|
local all all trust
|
||||||
host codimd codimd 127.0.0.1/32 trust
|
host codimd codimd 127.0.0.1/32 trust
|
||||||
'';
|
'';
|
||||||
package = pkgs.postgresql_11;
|
package = pkgs.postgresql_15;
|
||||||
};
|
};
|
||||||
services.postgresqlBackup = {
|
services.postgresqlBackup = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -91,7 +68,8 @@
|
||||||
startAt = "*-*-* 23:45:00";
|
startAt = "*-*-* 23:45:00";
|
||||||
location = "/persist/backups/postgres";
|
location = "/persist/backups/postgres";
|
||||||
};
|
};
|
||||||
})).config.system.build.toplevel;
|
hacc.bindToPersist = [ "/var/lib/hedgedoc" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
services.nginx.virtualHosts."pad.hacc.earth" = {
|
services.nginx.virtualHosts."pad.hacc.earth" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
|
@ -1,43 +1,11 @@
|
||||||
{ config, lib, pkgs, modules, evalConfig, sources, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
containers.pad-i4f = {
|
hacc.containers.pad-i4f = {
|
||||||
privateNetwork = true;
|
config = { config, lib, ... }: {
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.6";
|
|
||||||
autoStart = true;
|
|
||||||
bindMounts = {
|
|
||||||
"/persist" = {
|
|
||||||
hostPath = "/persist/containers/pad-i4f";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
services.coredns = {
|
|
||||||
enable = true;
|
|
||||||
config = ''
|
|
||||||
.:53 {
|
|
||||||
forward . 1.1.1.1
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
services.hedgedoc = {
|
services.hedgedoc = {
|
||||||
enable = true;
|
enable = true;
|
||||||
configuration = {
|
settings = {
|
||||||
allowAnonymous = true;
|
allowAnonymous = true;
|
||||||
allowFreeURL = true;
|
allowFreeURL = true;
|
||||||
allowGravatar = false;
|
allowGravatar = false;
|
||||||
|
@ -60,7 +28,7 @@
|
||||||
};
|
};
|
||||||
services.postgresql = {
|
services.postgresql = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.postgresql_11;
|
package = pkgs.postgresql_15;
|
||||||
authentication = ''
|
authentication = ''
|
||||||
local all all trust
|
local all all trust
|
||||||
host hedgedoc hedgedoc 127.0.0.1/32 trust
|
host hedgedoc hedgedoc 127.0.0.1/32 trust
|
||||||
|
@ -68,9 +36,7 @@
|
||||||
ensureDatabases = [ "hedgedoc" ];
|
ensureDatabases = [ "hedgedoc" ];
|
||||||
ensureUsers = [{
|
ensureUsers = [{
|
||||||
name = "hedgedoc";
|
name = "hedgedoc";
|
||||||
ensurePermissions = {
|
ensureDBOwnership = true;
|
||||||
"DATABASE hedgedoc" = "ALL PRIVILEGES";
|
|
||||||
};
|
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
services.postgresqlBackup = {
|
services.postgresqlBackup = {
|
||||||
|
@ -79,7 +45,8 @@
|
||||||
startAt = "*-*-* 23:45:00";
|
startAt = "*-*-* 23:45:00";
|
||||||
location = "/persist/backups/postgres";
|
location = "/persist/backups/postgres";
|
||||||
};
|
};
|
||||||
})).config.system.build.toplevel;
|
hacc.bindToPersist = [ "/var/lib/hedgedoc" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."pad.infra4future.de" = {
|
services.nginx.virtualHosts."pad.infra4future.de" = {
|
|
@ -8,7 +8,6 @@
|
||||||
prefixLength = 24;
|
prefixLength = 24;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
networking.nat.internalInterfaces = [ "lxcbr0" ];
|
|
||||||
|
|
||||||
virtualisation.lxc.enable = true;
|
virtualisation.lxc.enable = true;
|
||||||
virtualisation.lxc.systemConfig = ''
|
virtualisation.lxc.systemConfig = ''
|
||||||
|
@ -27,10 +26,4 @@
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."auth.infra4future.de" = {
|
|
||||||
locations."/".proxyPass = "http://10.1.2.104:8080";
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
}
|
}
|
208
parsons/mail.nix
Normal file
208
parsons/mail.nix
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
{ config, options, pkgs, lib, sources, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ sources.nixos-mailserver.outPath ];
|
||||||
|
|
||||||
|
# reduce log spam
|
||||||
|
systemd.services.rspamd.serviceConfig.LogLevelMax =
|
||||||
|
3; # this is set to error because rspamd regularly complains about not enough learns
|
||||||
|
systemd.services.dovecot2.serviceConfig.LogLevelMax = 5; # = notice
|
||||||
|
|
||||||
|
# stop postfix from dying if rspamd hiccups
|
||||||
|
systemd.services.postfix.unitConfig = {
|
||||||
|
Requires = lib.mkForce "dovecot2.service opendkim.service";
|
||||||
|
};
|
||||||
|
|
||||||
|
mailserver = {
|
||||||
|
mailDirectory = "/persist/mail";
|
||||||
|
enable = true;
|
||||||
|
fqdn = "mail.hacc.space";
|
||||||
|
monitoring = {
|
||||||
|
enable = true;
|
||||||
|
alertAddress = "admin@hacc.space";
|
||||||
|
};
|
||||||
|
domains = [
|
||||||
|
"hacc.space"
|
||||||
|
"muc.hacc.space"
|
||||||
|
"hacc.earth"
|
||||||
|
"4future.dev"
|
||||||
|
"4futu.re"
|
||||||
|
"infra4future.de"
|
||||||
|
];
|
||||||
|
|
||||||
|
loginAccounts = {
|
||||||
|
"hexchen@hacc.space".hashedPassword =
|
||||||
|
"$6$x9skYtRp4dgxC$1y8gPC2BuVqG3kJVSMGgzZv0Bg1T9qxcnBWLIDbANy1d//SQ23Y7s3IMYcEPd1/l/MYWD9Y/Qse6HbT5w5Xwq/";
|
||||||
|
|
||||||
|
"octycs@hacc.space".hashedPassword =
|
||||||
|
"$6$KceTivtJ$58jxhYF6ULfivNsb3Z0J7PnGea0Hs2wTWh3c9FrKRIAmuOD96u2IDgZRCn6P5NrXA0BL.n6HC2RS3r.4JnOmg.";
|
||||||
|
"octycs@hacc.space".aliases = [ "markus@hacc.space" ];
|
||||||
|
|
||||||
|
"raphael@hacc.space".hashedPassword =
|
||||||
|
"$6$QveHpwMcp9mkFVAU$EFuahOrJIxPg.c.WGFHtrP3.onwJYwvP7fiBHHGb9jhosewZ2tEUP.2D3uyDLhd9Cfny6Yp4jDk/Hkjk7/ME1/";
|
||||||
|
|
||||||
|
"moira@hacc.space".hashedPassword =
|
||||||
|
"$6$BpYhwcZNrkLhVqK$6FMqA/vUkdV4GBlHLSqS5DRCb/CaLDNeIsBcZ8G30heytS/tJj2Ag7b1ovSltTA4PUfhee3pJrz1BkwkA93vN1";
|
||||||
|
|
||||||
|
"zauberberg@hacc.space".hashedPassword =
|
||||||
|
"$6$ISAaU8X6D$oGKe9WXDWrRpGzHUTdxrxdtg9zuGOlBMuDc82IZhegpsv1bqd550FhZZrI40IjZTA5Hy2MZ8j/0efpnQ4fOQH0";
|
||||||
|
"zauberberg@hacc.space".aliases = [ "lukas@hacc.space" ];
|
||||||
|
|
||||||
|
"stuebinm@hacc.space".hashedPassword =
|
||||||
|
"$6$mjrMQG5smqLRlm$WzmbiZnGlEXGT7hj/n2qz0nvVzGyZfMToCyLRi0wErfVEHI7y7jtWoHqIWnpcHAM29UocsIFFsUCb3XqQCwwB.";
|
||||||
|
|
||||||
|
"lenny@hacc.space".hashedPassword =
|
||||||
|
"$6$EZpv9XImv5F3$p2NSoo5gLxh6NnB3/C6wF8knRTuMHqDXYF3BEscaQuk7qok2Z13xKT/6mFvvSKKBnFCuYptgnfGswmoqIzm/1/";
|
||||||
|
"lenny@hacc.space".aliases = [ "rinderhacc@hacc.space" ];
|
||||||
|
|
||||||
|
"peter@hacc.space".hashedPassword =
|
||||||
|
"$6$yvpfTC.7DDpqpsYy$7TrfmLvz/fRl.k5mSHhI67CNquJa3yEFbLuTJvpyJ8Dj7SaD2eoOHWqef.CNo.T08kYzaqMcM73whAxjXVEmc.";
|
||||||
|
"peter@hacc.space".aliases = [ "linmob@hacc.space" ];
|
||||||
|
|
||||||
|
"finance@muc.hacc.space".hashedPassword =
|
||||||
|
"$6$R3GRmvXwqnMM6q.R$Y9mrUAmMnCScsM6pKjxo2a2XPM7lHrV8FIgK0PzhYvZbxWczo7.O4dk1onYeV1mRx/nXZfkZNjqNCruCn0S2m.";
|
||||||
|
|
||||||
|
"noreply@hacc.space" = {
|
||||||
|
hashedPassword =
|
||||||
|
"$6$YsqMoItITZUzI5wo$5Lejf8XBHRx4LW4VuZ9wJCiBbT4kOV/EZaCdWQ07eVIrkRTZwXWZ5zfsh.olXEFwvpNWN.DBnU.dQc.cC0/ra/";
|
||||||
|
};
|
||||||
|
|
||||||
|
"noreply@infra4future.de" = {
|
||||||
|
hashedPassword =
|
||||||
|
"$6$uaD8bRcT1$gFqhFyu5RUsyUUOG5b.kN.JAJ1rVHvaYhpeRHoMvrERAMgBu1FHu2oDnjTsy.5NKoLc5xpI5uv4Gpy4YbmDmV.";
|
||||||
|
};
|
||||||
|
|
||||||
|
"mattermost@hacc.space" = {
|
||||||
|
hashedPassword =
|
||||||
|
"$6$uaD8bRcT1$gFqhFyu5RUsyUUOG5b.kN.JAJ1rVHvaYhpeRHoMvrERAMgBu1FHu2oDnjTsy.5NKoLc5xpI5uv4Gpy4YbmDmV.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraVirtualAliases = {
|
||||||
|
# address = forward address;
|
||||||
|
|
||||||
|
# -- International --
|
||||||
|
# info/contact: main entrypoint, anyone can read or reply to this.
|
||||||
|
"info@hacc.space" = [
|
||||||
|
"hexchen@hacc.space"
|
||||||
|
"octycs@hacc.space"
|
||||||
|
"raphael@hacc.space"
|
||||||
|
"moira@hacc.space"
|
||||||
|
"zauberberg@hacc.space"
|
||||||
|
"stuebinm@hacc.space"
|
||||||
|
"lenny@hacc.space"
|
||||||
|
"peter@hacc.space"
|
||||||
|
];
|
||||||
|
|
||||||
|
# admin: current people with access to the mail server and knowledge on how to use it™
|
||||||
|
"admin@hacc.space" = [
|
||||||
|
"hexchen@hacc.space"
|
||||||
|
"moira@hacc.space"
|
||||||
|
"zauberberg@hacc.space"
|
||||||
|
"stuebinm@hacc.space"
|
||||||
|
];
|
||||||
|
|
||||||
|
# voc: hacc video operation center, various streaming-related things
|
||||||
|
"voc@hacc.space" = [
|
||||||
|
"hexchen@hacc.space"
|
||||||
|
"moira@hacc.space"
|
||||||
|
"octycs@hacc.space"
|
||||||
|
"stuebinm@hacc.space"
|
||||||
|
"zauberberg@hacc.space"
|
||||||
|
"lenny@hacc.space"
|
||||||
|
"raphael@hacc.space"
|
||||||
|
];
|
||||||
|
|
||||||
|
# -- Regional: Germany --
|
||||||
|
# board of hacc e.V.
|
||||||
|
"vorstand@hacc.space" =
|
||||||
|
[ "raphael@hacc.space" "moira@hacc.space" "peter@hacc.space" ];
|
||||||
|
|
||||||
|
# members of hacc e.V.
|
||||||
|
"mitglieder@hacc.space" = [
|
||||||
|
"hexchen@hacc.space"
|
||||||
|
"raphael@hacc.space"
|
||||||
|
"moira@hacc.space"
|
||||||
|
"zauberberg@hacc.space"
|
||||||
|
"lenny@hacc.space"
|
||||||
|
"octycs@hacc.space"
|
||||||
|
"stuebinm@hacc.space"
|
||||||
|
"peter@hacc.space"
|
||||||
|
];
|
||||||
|
|
||||||
|
# -- Regional: Munich --
|
||||||
|
"muc@hacc.space" = [
|
||||||
|
"hexchen@hacc.space"
|
||||||
|
"octycs@hacc.space"
|
||||||
|
"raphael@hacc.space"
|
||||||
|
"moira@hacc.space"
|
||||||
|
"zauberberg@hacc.space"
|
||||||
|
"stuebinm@hacc.space"
|
||||||
|
"lenny@hacc.space"
|
||||||
|
"peter@hacc.space"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Use Let's Encrypt certificates. Note that this needs to set up a stripped
|
||||||
|
# down nginx and opens port 80.
|
||||||
|
certificateScheme = "acme-nginx";
|
||||||
|
|
||||||
|
# Only allow implict TLS
|
||||||
|
enableImap = false;
|
||||||
|
enablePop3 = false;
|
||||||
|
|
||||||
|
# Enable the ManageSieve protocol
|
||||||
|
enableManageSieve = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postfix.submissionOptions.smtpd_sender_restrictions =
|
||||||
|
lib.mkForce "reject_non_fqdn_sender,reject_unknown_sender_domain,permit";
|
||||||
|
services.postfix.submissionsOptions.smtpd_sender_restrictions =
|
||||||
|
lib.mkForce "reject_non_fqdn_sender,reject_unknown_sender_domain,permit";
|
||||||
|
|
||||||
|
services.postfix.virtual = ''
|
||||||
|
postmaster@hacc.space admin@hacc.space
|
||||||
|
abuse@hacc.space admin@hacc.space
|
||||||
|
contact@hacc.space info@hacc.space
|
||||||
|
hello@hacc.space info@hacc.space
|
||||||
|
haccvoc@hacc.space voc@hacc.space
|
||||||
|
@4future.dev @hacc.space
|
||||||
|
@4futu.re @hacc.space
|
||||||
|
@hacc.earth @hacc.space
|
||||||
|
@infra4future.de @hacc.space
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.alps = {
|
||||||
|
enable = true;
|
||||||
|
theme = "alps";
|
||||||
|
smtps = {
|
||||||
|
port = 465;
|
||||||
|
host = "mail.hacc.space";
|
||||||
|
};
|
||||||
|
imaps = {
|
||||||
|
port = 993;
|
||||||
|
host = "mail.hacc.space";
|
||||||
|
};
|
||||||
|
bindIP = "[::1]";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.alps.after = [ "dovecot2.service" "postfix.service" ];
|
||||||
|
systemd.services.alps.bindsTo = [ "dovecot2.service" "postfix.service" ];
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."mail.hacc.space" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/".proxyPass = "http://[::1]:1323";
|
||||||
|
};
|
||||||
|
|
||||||
|
hacc.bindToPersist = [
|
||||||
|
"/var/lib/rspamd"
|
||||||
|
"/var/lib/opendkim"
|
||||||
|
"/var/lib/postfix"
|
||||||
|
"/var/lib/dovecot"
|
||||||
|
"/var/sieve"
|
||||||
|
"/var/lib/redis-rspamd"
|
||||||
|
"/var/dkim"
|
||||||
|
];
|
||||||
|
}
|
|
@ -1,50 +1,26 @@
|
||||||
{config, pkgs, lib, profiles, modules, evalConfig, sources, ...}:
|
{ config, pkgs, lib, ...}:
|
||||||
|
|
||||||
let
|
{
|
||||||
mattermost = pkgs.mattermost;
|
sops.secrets = {
|
||||||
in {
|
"mattermost/env" = {};
|
||||||
containers.mattermost = {
|
};
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.3";
|
|
||||||
|
|
||||||
bindMounts = {
|
hacc.containers.mattermost = {
|
||||||
"/persist" = {
|
bindSecrets = true;
|
||||||
hostPath = "/persist/containers/mattermost";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
config = { config, lib, pkgs, ... }: {
|
||||||
boot.isContainer = true;
|
environment.systemPackages = [ pkgs.morph pkgs.pgloader ];
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
systemd.services.mattermost.serviceConfig.EnvironmentFile =
|
||||||
../modules/mattermost.nix
|
lib.mkForce "/secrets/env";
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.overlays = [ (self: super: { inherit mattermost; }) ];
|
services.mattermost = {
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
|
|
||||||
# couldn't figure out how to actually overwrite modules, so now
|
|
||||||
# there's two mattermost modules ...
|
|
||||||
services.mattermost-patched = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
siteUrl = "https://mattermost.infra4future.de";
|
siteUrl = "https://mattermost.infra4future.de";
|
||||||
siteName = "Mattermost for Future";
|
siteName = "Mattermost for Future";
|
||||||
listenAddress = "0.0.0.0:3000";
|
listenAddress = "0.0.0.0:3000";
|
||||||
mutableConfig = false;
|
mutableConfig = false;
|
||||||
|
|
||||||
secretConfig = "/persist/mattermost/secrets.json";
|
|
||||||
statePath = "/persist/mattermost";
|
statePath = "/persist/mattermost";
|
||||||
|
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
|
@ -122,12 +98,21 @@ in {
|
||||||
EnableSMTPAuth = true;
|
EnableSMTPAuth = true;
|
||||||
SMTPUsername = "noreply@infra4future.de";
|
SMTPUsername = "noreply@infra4future.de";
|
||||||
SMTPServer = "mail.hacc.space";
|
SMTPServer = "mail.hacc.space";
|
||||||
|
SMTPPort = "465";
|
||||||
|
SMTPServerTimeout = 10;
|
||||||
|
ConnectionSecurity = "TLS";
|
||||||
};
|
};
|
||||||
RateLimitSettings.Enable = false;
|
RateLimitSettings.Enable = false;
|
||||||
PrivacySettings = {
|
PrivacySettings = {
|
||||||
ShowEmailAddress = false;
|
ShowEmailAddress = false;
|
||||||
ShowFullName = true;
|
ShowFullName = true;
|
||||||
};
|
};
|
||||||
|
# to disable the extra landing page advertising the app
|
||||||
|
NativeAppSettings = {
|
||||||
|
AppDownloadLink = "";
|
||||||
|
AndroidAppDownloadLink = "";
|
||||||
|
IosAppDownloadLink = "";
|
||||||
|
};
|
||||||
SupportSettings = {
|
SupportSettings = {
|
||||||
TermsOfServiceLink = "https://infra4future.de/nutzungsbedingungen.html";
|
TermsOfServiceLink = "https://infra4future.de/nutzungsbedingungen.html";
|
||||||
PrivacyPolicyLink = "https://infra4future.de/nutzungsbedingungen.html";
|
PrivacyPolicyLink = "https://infra4future.de/nutzungsbedingungen.html";
|
||||||
|
@ -159,18 +144,12 @@ in {
|
||||||
Enable = true;
|
Enable = true;
|
||||||
EnableUploads = true;
|
EnableUploads = true;
|
||||||
Plugins = {
|
Plugins = {
|
||||||
bigbluebutton = {
|
|
||||||
adminonly = false;
|
|
||||||
base_url = "https://bbb.infra4future.de/bigbluebutton/api";
|
|
||||||
salt = "zKCsNeaEniC115ynHOsZopgA4iTiJjzgeiPNoCEc";
|
|
||||||
};
|
|
||||||
"com.github.matterpoll.matterpoll" = {
|
"com.github.matterpoll.matterpoll" = {
|
||||||
experimentalui = true;
|
experimentalui = true;
|
||||||
trigger = "poll";
|
trigger = "poll";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
PluginStates = {
|
PluginStates = {
|
||||||
bigbluebutton.Enable = true;
|
|
||||||
"com.github.matterpoll.matterpoll".Enable = true;
|
"com.github.matterpoll.matterpoll".Enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -179,6 +158,8 @@ in {
|
||||||
MetricsSettings.Enable = false;
|
MetricsSettings.Enable = false;
|
||||||
GuestAccountsSettings.Enable = false;
|
GuestAccountsSettings.Enable = false;
|
||||||
FeatureFlags.CollapsedThreads = true;
|
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
|
# turn of the weirder parts of this module (which insist on passwords
|
||||||
|
@ -189,44 +170,28 @@ in {
|
||||||
localDatabaseCreate = false;
|
localDatabaseCreate = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.mysql = {
|
|
||||||
enable = true;
|
|
||||||
ensureDatabases = [ "mattermost" ];
|
|
||||||
ensureUsers = [ {
|
|
||||||
name = "mattermost";
|
|
||||||
ensurePermissions = { "mattermost.*" = "ALL PRIVILEGES"; };
|
|
||||||
} ];
|
|
||||||
package = pkgs.mysql80;
|
|
||||||
dataDir = "/persist/mysql";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.postgresql = {
|
services.postgresql = {
|
||||||
enable = lib.mkForce true; # mattermost sets this to false. wtf.
|
enable = lib.mkForce true; # mattermost sets this to false. wtf.
|
||||||
package = pkgs.postgresql_11;
|
package = pkgs.postgresql_15;
|
||||||
ensureDatabases = [ "mattermost" ];
|
ensureDatabases = [ "mattermost" ];
|
||||||
ensureUsers = [ {
|
ensureUsers = [ {
|
||||||
name = "mattermost";
|
name = "mattermost";
|
||||||
ensurePermissions = { "DATABASE mattermost" = "ALL PRIVILEGES"; };
|
ensureDBOwnership = true;
|
||||||
} ];
|
} ];
|
||||||
|
|
||||||
authentication = lib.mkForce ''
|
authentication = lib.mkForce ''
|
||||||
# Generated file; do not edit!
|
# Generated file; do not edit!
|
||||||
local all all trust
|
local all all trust
|
||||||
host mattermost mattermost ::1/128 trust
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 3000 ];
|
services.postgresqlBackup = {
|
||||||
|
|
||||||
services.coredns = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
config = ''
|
databases = [ "mattermost" ];
|
||||||
.:53 {
|
startAt = "*-*-* 23:45:00";
|
||||||
forward . 1.1.1.1
|
location = "/persist/backups/postgres";
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
})).config.system.build.toplevel;
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."mattermost.infra4future.de" = {
|
services.nginx.virtualHosts."mattermost.infra4future.de" = {
|
64
parsons/monit.nix
Normal file
64
parsons/monit.nix
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
{ 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,12 +1,13 @@
|
||||||
{ config, lib, pkgs, sources, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
hexchen.bindmounts."/var/lib/murmur" = "/persist/var/lib/murmur";
|
|
||||||
|
|
||||||
services.murmur = {
|
services.murmur = {
|
||||||
enable = true;
|
enable = true;
|
||||||
logDays = -1;
|
logDays = -1;
|
||||||
welcometext = "Welcome to mumble4future! Brought to you by infra4future. The server is now reachable under mumble.hacc.space, please update your bookmarks.";
|
registerName = "hackers against climate change";
|
||||||
|
welcometext = ''
|
||||||
|
<br>Welcome to <b>mumble4future</b>!<br>Brought to you by <b style="color:red">infra4future</b>.<br>On <a href=https://mumble.hacc.space>mumble.hacc.space</a><br>Not confusing at all!
|
||||||
|
'';
|
||||||
sslKey = "/var/lib/acme/mumble.hacc.space/key.pem";
|
sslKey = "/var/lib/acme/mumble.hacc.space/key.pem";
|
||||||
sslCert = "/var/lib/acme/mumble.hacc.space/fullchain.pem";
|
sslCert = "/var/lib/acme/mumble.hacc.space/fullchain.pem";
|
||||||
bandwidth = 128000;
|
bandwidth = 128000;
|
||||||
|
@ -16,8 +17,14 @@
|
||||||
networking.firewall.allowedUDPPorts = [ config.services.murmur.port ];
|
networking.firewall.allowedUDPPorts = [ config.services.murmur.port ];
|
||||||
|
|
||||||
# the mumble cert has its own group so that both nginx and murmur can read it
|
# the mumble cert has its own group so that both nginx and murmur can read it
|
||||||
users.groups.mumblecert = {};
|
users.groups.mumblecert = { };
|
||||||
security.acme.certs."mumble.hacc.space".group = "mumblecert";
|
security.acme.certs."mumble.hacc.space" = {
|
||||||
|
group = "mumblecert";
|
||||||
|
extraDomainNames = [ "mumble.infra4future.de" ];
|
||||||
|
reloadServices = [ "murmur" ];
|
||||||
|
};
|
||||||
users.users.nginx.extraGroups = [ "mumblecert" ];
|
users.users.nginx.extraGroups = [ "mumblecert" ];
|
||||||
users.users.murmur.extraGroups = [ "mumblecert" ];
|
users.users.murmur.extraGroups = [ "mumblecert" ];
|
||||||
|
|
||||||
|
hacc.bindToPersist = [ "/var/lib/murmur" ];
|
||||||
}
|
}
|
89
parsons/nextcloud.nix
Normal file
89
parsons/nextcloud.nix
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
containers.nextcloud.timeoutStartSec = "10 min";
|
||||||
|
hacc.containers.nextcloud = {
|
||||||
|
config = { config, lib, pkgs, ... }: {
|
||||||
|
environment.systemPackages = [ pkgs.htop ];
|
||||||
|
|
||||||
|
services.nextcloud = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# must be set manually; may not be incremented by more than one at
|
||||||
|
# a time, otherwise nextcloud WILL break
|
||||||
|
package = pkgs.nextcloud30;
|
||||||
|
|
||||||
|
home = "/persist/nextcloud";
|
||||||
|
https = true;
|
||||||
|
|
||||||
|
hostName = "cloud.infra4future.de";
|
||||||
|
config = {
|
||||||
|
dbtype = "pgsql";
|
||||||
|
dbuser = "nextcloud";
|
||||||
|
dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
|
||||||
|
dbname = "nextcloud";
|
||||||
|
# socket auth does not needs this, but the module insists it does
|
||||||
|
adminpassFile = "/persist/adminpassfile";
|
||||||
|
adminuser = "root";
|
||||||
|
};
|
||||||
|
|
||||||
|
# multiple pools may be doable using services.phpfpm.pools,
|
||||||
|
# but i have not tried this yet. The nextcloud module defines a
|
||||||
|
# pool "nextcloud"
|
||||||
|
poolSettings = {
|
||||||
|
pm = "dynamic";
|
||||||
|
"pm.max_children" = "32";
|
||||||
|
"pm.max_requests" = "500";
|
||||||
|
"pm.max_spare_servers" = "4";
|
||||||
|
"pm.min_spare_servers" = "2";
|
||||||
|
"pm.start_servers" = "2";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
instanceid = "ocxlphb7fbju";
|
||||||
|
datadirectory = "/persist/nextcloud/data";
|
||||||
|
loglevel = 0;
|
||||||
|
"overwrite.cli.url" = "https://cloud.infra4future.de";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.postgresql_15;
|
||||||
|
ensureDatabases = [ "nextcloud" ];
|
||||||
|
ensureUsers = [
|
||||||
|
{ # by default, postgres has unix sockets enabled, and allows a
|
||||||
|
# system user `nextcloud` to log in without other authentication
|
||||||
|
name = "nextcloud";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresqlBackup = {
|
||||||
|
enable = true;
|
||||||
|
databases = [ "nextcloud" ];
|
||||||
|
startAt = "*-*-* 23:45:00";
|
||||||
|
location = "/persist/backups/postgres";
|
||||||
|
};
|
||||||
|
|
||||||
|
# ensure that postgres is running *before* running the setup
|
||||||
|
systemd.services."nextcloud-setup" = {
|
||||||
|
requires = ["postgresql.service"];
|
||||||
|
after = ["postgresql.service"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."cloud.infra4future.de" = {
|
||||||
|
locations."/".proxyPass = "http://${config.containers.nextcloud.localAddress}:80";
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_buffering off;
|
||||||
|
client_max_body_size 0;
|
||||||
|
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
23
parsons/nftables.nix
Normal file
23
parsons/nftables.nix
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
networking.firewall.enable = true;
|
||||||
|
networking.firewall.logRefusedConnections = false;
|
||||||
|
networking.nat.enable = 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
|
||||||
|
}
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority 100
|
||||||
|
iifname lxcbr0 oifname enp35s0 masquerade
|
||||||
|
iifname ve-* oifname enp35s0 masquerade
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
16
parsons/nginx-pages.nix
Normal file
16
parsons/nginx-pages.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
hacc.websites = {
|
||||||
|
enable = true;
|
||||||
|
directory = "${../.}/websites";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."parsons.hacc.space" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/~stuebinm/".root = "/persist/www/";
|
||||||
|
};
|
||||||
|
}
|
137
parsons/s4f-conference.nix
Normal file
137
parsons/s4f-conference.nix
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
}
|
105
parsons/tracktrain.nix
Normal file
105
parsons/tracktrain.nix
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
tracktrain-config = ''
|
||||||
|
dbstring: "dbname=tracktrain"
|
||||||
|
gtfs: /persist/gtfs.zip
|
||||||
|
assets: ${pkgs.tracktrain}/assets
|
||||||
|
|
||||||
|
warp:
|
||||||
|
port: 4000
|
||||||
|
|
||||||
|
login:
|
||||||
|
enable: true
|
||||||
|
url: https://login.infra4future.de
|
||||||
|
clientName: tracktrain
|
||||||
|
# clientSecret defined in env file
|
||||||
|
|
||||||
|
logging:
|
||||||
|
ntfyTopic: ping.stuebinm.eu/monit
|
||||||
|
name: ilztalbahn
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sops.secrets = {
|
||||||
|
"tracktrain/env" = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."tracktrain.ilztalbahn.eu" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://${config.containers.tracktrain.localAddress}: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";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
extraConfig = ''
|
||||||
|
rewrite ^/metrics/(.*) /$1 break;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
hacc.containers.tracktrain = {
|
||||||
|
bindSecrets = true;
|
||||||
|
|
||||||
|
config = { config, lib, pkgs, ... }: {
|
||||||
|
|
||||||
|
systemd.services.tracktrain = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
description = "tracks trains, hopefully";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
requires = [ "network.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
EnvironmentFile = "/secrets/env";
|
||||||
|
DynamicUser = true;
|
||||||
|
};
|
||||||
|
path = [ pkgs.wget pkgs.ntfy-sh ];
|
||||||
|
script = ''
|
||||||
|
cd /tmp
|
||||||
|
ln -sf ${pkgs.writeText "tracktrain-config.yaml" tracktrain-config} config.yaml
|
||||||
|
sleep 3
|
||||||
|
${pkgs.tracktrain}/bin/tracktrain +RTS -T
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.postgresql.wantedBy = [ "tracktrain.service" ];
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.postgresql_15;
|
||||||
|
ensureDatabases = [ "tracktrain" ];
|
||||||
|
ensureUsers = [ {
|
||||||
|
name = "tracktrain";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
} ];
|
||||||
|
authentication = ''
|
||||||
|
local all all trust
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.prometheus = {
|
||||||
|
enable = true;
|
||||||
|
port = 9001;
|
||||||
|
scrapeConfigs = [ {
|
||||||
|
job_name = "tracktrain";
|
||||||
|
static_configs = [{
|
||||||
|
targets = [ "0.0.0.0:4000" ];
|
||||||
|
}];
|
||||||
|
} ];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.grafana.serviceConfig.EnvironmentFile =
|
||||||
|
"/secrets/env";
|
||||||
|
hacc.bindToPersist = [ "/var/lib/grafana" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
66
parsons/uffd.nix
Normal file
66
parsons/uffd.nix
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
hacc.containers.uffd = {
|
||||||
|
config = { config, lib, pkgs, ... }: {
|
||||||
|
services.uwsgi = {
|
||||||
|
enable = true;
|
||||||
|
plugins = [ "python3" ];
|
||||||
|
instance = {
|
||||||
|
type = "normal";
|
||||||
|
pythonPackages = _: [ pkgs.uffd ];
|
||||||
|
module = "uffd:create_app()";
|
||||||
|
# socket = "${config.services.uwsgi.runDir}/uwsgi.sock";
|
||||||
|
http = ":8080";
|
||||||
|
env = [
|
||||||
|
"CONFIG_PATH=/persist/uffd/uffd.conf"
|
||||||
|
];
|
||||||
|
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;
|
||||||
|
forceSSL = true;
|
||||||
|
locations = {
|
||||||
|
"/".proxyPass = "http://${config.containers.uffd.localAddress}:8080";
|
||||||
|
"/static".root = "${pkgs.uffd}/lib/python3.10/site-packages/uffd";
|
||||||
|
"/static/hacc.png".return = "302 https://infra4future.de/assets/img/logo_vernetzung.png";
|
||||||
|
"/static/infra4future.svg".return = "302 https://infra4future.de/assets/img/infra4future.svg";
|
||||||
|
"/static/hedgedoc.svg".return = "302 https://infra4future.de/assets/img/icons/hedgedoc.svg";
|
||||||
|
"/static/mattermost.svg".return = "302 https://infra4future.de/assets/img/icons/mattermost.svg";
|
||||||
|
"/static/nextcloud.svg".return = "302 https://infra4future.de/assets/img/icons/nextcloud.svg";
|
||||||
|
"/static/hot_shit.svg".return = "302 https://infra4future.de/assets/img/icons/hot_shit.svg";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.auamost = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
description = "mattermost aua gruppensync";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets."auamost/secrets.fish" = { };
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [ curl jq ];
|
||||||
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
sops.secrets = {
|
||||||
|
"vaultwarden/env" = {};
|
||||||
|
};
|
||||||
|
|
||||||
services.vaultwarden = {
|
services.vaultwarden = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = {
|
config = {
|
||||||
|
@ -27,7 +31,7 @@
|
||||||
SMTP_USERNAME="noreply@infra4future.de";
|
SMTP_USERNAME="noreply@infra4future.de";
|
||||||
|
|
||||||
};
|
};
|
||||||
environmentFile = "/persist/var/lib/vaultwarden/vaultwarden.env"; #contains SMTP_PASSWORD
|
environmentFile = "/run/secrets/vaultwarden/env";
|
||||||
dbBackend = "sqlite";
|
dbBackend = "sqlite";
|
||||||
backupDir = "/persist/data/vaultwarden_backups/";
|
backupDir = "/persist/data/vaultwarden_backups/";
|
||||||
};
|
};
|
|
@ -1,25 +0,0 @@
|
||||||
{ lib, buildGoModule }:
|
|
||||||
|
|
||||||
buildGoModule rec {
|
|
||||||
pname = "alps";
|
|
||||||
version = "0.0.1";
|
|
||||||
|
|
||||||
src = fetchGit {
|
|
||||||
url = "https://git.sr.ht/~migadu/alps";
|
|
||||||
rev = "51498a2dc37987f55b022efb961b68a282be17ed";
|
|
||||||
};
|
|
||||||
|
|
||||||
vendorSha256 = "0wc8fb03zlc1gl4nxlsh149gvpvrs3lc0smzrnam9smigg9gw4in";
|
|
||||||
|
|
||||||
subPackages = [ "cmd/alps" ];
|
|
||||||
|
|
||||||
postInstall = ''
|
|
||||||
mkdir -p $out/share/alps
|
|
||||||
cp -r $src/themes $out/share/alps/
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description = "A simple and extensible webmail.";
|
|
||||||
homepage = "https://git.sr.ht/~migadu/alps";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
{ stdenv, requireFile, lib,
|
|
||||||
libcxx, libcxxabi
|
|
||||||
}:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "blackmagic-desktop-video";
|
|
||||||
version = "12.2.2";
|
|
||||||
|
|
||||||
buildInputs = [
|
|
||||||
libcxx libcxxabi
|
|
||||||
];
|
|
||||||
|
|
||||||
src = requireFile {
|
|
||||||
name = "Blackmagic_Desktop_Video_Linux_12.2.2.tar.gz";
|
|
||||||
url = "https://www.blackmagicdesign.com/support/";
|
|
||||||
sha256 = "8bca946bd3f002d2d404a74210c881935351e1a0d03f750559b180fdb439ef35";
|
|
||||||
};
|
|
||||||
|
|
||||||
setSourceRoot = ''
|
|
||||||
tar xf Blackmagic_Desktop_Video_Linux_12.2.2/other/x86_64/desktopvideo-12.2.2a6-x86_64.tar.gz
|
|
||||||
sourceRoot=$NIX_BUILD_TOP/desktopvideo-12.2.2a6-x86_64
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
mkdir -p $out/{bin,share/doc,lib}
|
|
||||||
cp -r $sourceRoot/usr/share/doc/desktopvideo $out/share/doc
|
|
||||||
cp $sourceRoot/usr/lib/*.so $out/lib
|
|
||||||
ln -s ${libcxx}/lib/* ${libcxxabi}/lib/* $out/lib
|
|
||||||
cp $sourceRoot/usr/lib/blackmagic/DesktopVideo/libgcc_s.so.1 $out/lib/
|
|
||||||
cp $sourceRoot/usr/lib/blackmagic/DesktopVideo/DesktopVideoHelper $out/bin/
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
postFixup = ''
|
|
||||||
patchelf --set-interpreter ${stdenv.cc.bintools.dynamicLinker} \
|
|
||||||
--set-rpath "$out/lib:${lib.makeLibraryPath [ libcxx libcxxabi ]}" \
|
|
||||||
$out/bin/DesktopVideoHelper
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
homepage = "https://www.blackmagicdesign.com/support/family/capture-and-playback";
|
|
||||||
maintainers = [ maintainers.hexchen ];
|
|
||||||
license = licenses.unfree;
|
|
||||||
description = "Supporting applications for Blackmagic Decklink. Doesn't include the desktop applications, only the helper required to make the driver work.";
|
|
||||||
platforms = platforms.linux;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
{ stdenv, mkYarnPackage, mkYarnModules, fetchFromGitHub, libsass, python, python3, pkg-config, libusb, fetchurl, nodejs, electron, writeText, makeWrapper, udev, nodePackages, libvips }:
|
|
||||||
|
|
||||||
let
|
|
||||||
version = "2.1.3";
|
|
||||||
source = fetchFromGitHub {
|
|
||||||
owner = "bitfocus";
|
|
||||||
repo = "companion";
|
|
||||||
# rev = "v${version}";
|
|
||||||
rev = "1cc51029a19d7263a09058f73922277ca53a1583";
|
|
||||||
sha256 = "0305wwdic3n20whzhh9zqcd3dwj7hc4fpycs645ncc3sk48azmj0";
|
|
||||||
};
|
|
||||||
nodeHeaders = fetchurl {
|
|
||||||
url = "https://nodejs.org/download/release/v${nodejs.version}/node-v${nodejs.version}-headers.tar.gz";
|
|
||||||
sha256 = "19b0dg8292cjx758wlrvpb3jf520bpyvjal2n7r4fyvk38x9flik";
|
|
||||||
};
|
|
||||||
webui = mkYarnPackage rec {
|
|
||||||
inherit version;
|
|
||||||
pname = "bitfocus-companion-webui";
|
|
||||||
|
|
||||||
src = "${source}/webui";
|
|
||||||
|
|
||||||
configurePhase = "
|
|
||||||
cp -r $node_modules node_modules
|
|
||||||
chmod -R u+w node_modules
|
|
||||||
";
|
|
||||||
buildPhase = "PUBLIC_URL=. yarn build";
|
|
||||||
installPhase = "mv build $out";
|
|
||||||
distPhase = "true";
|
|
||||||
|
|
||||||
yarnNix = ./yarn-webui.nix;
|
|
||||||
|
|
||||||
pkgConfig = {
|
|
||||||
node-sass = {
|
|
||||||
buildInputs = [ libsass python ];
|
|
||||||
postInstall = "node scripts/build.js --tarball=${nodeHeaders}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
yarnModulesNoWorkspace = args: (mkYarnModules args).overrideAttrs(old: {
|
|
||||||
buildPhase = builtins.replaceStrings [" ./package.json"] [" /dev/null; cp deps/*/package.json ."] old.buildPhase;
|
|
||||||
});
|
|
||||||
|
|
||||||
modules = yarnModulesNoWorkspace rec {
|
|
||||||
inherit version;
|
|
||||||
pname = "companion-modules";
|
|
||||||
name = "${pname}-${version}";
|
|
||||||
yarnNix = ./yarn.nix;
|
|
||||||
packageJSON = "${source}/package.json";
|
|
||||||
yarnLock = "${source}/yarn.lock";
|
|
||||||
|
|
||||||
pkgConfig = {
|
|
||||||
node-hid = {
|
|
||||||
buildInputs = [ udev libusb python3 pkg-config ];
|
|
||||||
postInstall = "${nodePackages.node-gyp}/bin/node-gyp rebuild --tarball=${nodeHeaders}";
|
|
||||||
};
|
|
||||||
sharp = {
|
|
||||||
buildInputs = [ libvips pkg-config ];
|
|
||||||
postInstall = ''
|
|
||||||
sed -i "s|<!(node -p \"require(\\\\'./lib/libvips\\\\').minimumLibvipsVersion\")|${libvips.version}|" binding.gyp
|
|
||||||
sed -i "s|<!(node -p \"require(\\\\'./lib/libvips\\\\').pkgConfigPath()\")||" binding.gyp
|
|
||||||
sed -i "s|<!(node -p \"Boolean(require(\\\\'./lib/libvips\\\\').useGlobalLibvips()).toString()\")|true|" binding.gyp
|
|
||||||
sed -i "s|PKG_CONFIG_PATH=\"<(pkg_config_path)\" ||" binding.gyp
|
|
||||||
${nodePackages.node-gyp}/bin/node-gyp rebuild --tarball=${nodeHeaders}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in stdenv.mkDerivation rec {
|
|
||||||
inherit version webui modules;
|
|
||||||
pname = "bitfocus-companion";
|
|
||||||
|
|
||||||
src = source;
|
|
||||||
|
|
||||||
nativeBuildInputs = [ makeWrapper ];
|
|
||||||
|
|
||||||
configurePhase = "";
|
|
||||||
buildPhase = "";
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/share
|
|
||||||
cp --no-preserve=mode -r $src "$out/share/companion"
|
|
||||||
echo "nixos-f00baa-0" > $out/share/companion/BUILD
|
|
||||||
ln -s '${webui}' "$out/share/companion/static"
|
|
||||||
cp -r '${modules}/node_modules' "$out/share/companion/node_modules"
|
|
||||||
|
|
||||||
sed -i "s|process.resourcesPath|\"$out/share/companion\"|" $out/share/companion/lib/server_http.js
|
|
||||||
sed -i "s|require('app-root-path')|\"$out/share/companion\"|" $out/share/companion/{app,lib/{schedule,help,instance}}.js
|
|
||||||
|
|
||||||
makeWrapper '${electron}/bin/electron' "$out/bin/companion" \
|
|
||||||
--add-flags "$out/share/companion"
|
|
||||||
'';
|
|
||||||
}
|
|
|
@ -1,478 +0,0 @@
|
||||||
{
|
|
||||||
"name": "companion",
|
|
||||||
"version": "2.2.0",
|
|
||||||
"description": "Companion",
|
|
||||||
"main": "electron.js",
|
|
||||||
"build": {
|
|
||||||
"productName": "Companion",
|
|
||||||
"appId": "companion.bitfocus.no",
|
|
||||||
"remoteBuild": false,
|
|
||||||
"dmg": {
|
|
||||||
"artifactName": "companion-mac-${arch}.dmg",
|
|
||||||
"sign": true
|
|
||||||
},
|
|
||||||
"mac": {
|
|
||||||
"target": "dmg",
|
|
||||||
"category": "no.bitfocus.companion",
|
|
||||||
"extendInfo": {
|
|
||||||
"LSBackgroundOnly": 1,
|
|
||||||
"LSUIElement": 1
|
|
||||||
},
|
|
||||||
"extraFiles": [
|
|
||||||
{
|
|
||||||
"from": "./node_modules/sharp/vendor/8.10.6/lib",
|
|
||||||
"to": "Frameworks",
|
|
||||||
"filter": [
|
|
||||||
"!glib-2.0/**/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"win": {
|
|
||||||
"target": "nsis",
|
|
||||||
"extraFiles": [
|
|
||||||
{
|
|
||||||
"from": "./node_modules/sharp/build/Release",
|
|
||||||
"to": ".",
|
|
||||||
"filter": [
|
|
||||||
"lib*.dll"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"nsis": {
|
|
||||||
"artifactName": "companion-win64.exe",
|
|
||||||
"createStartMenuShortcut": true,
|
|
||||||
"perMachine": true,
|
|
||||||
"oneClick": false,
|
|
||||||
"allowElevation": true,
|
|
||||||
"allowToChangeInstallationDirectory": true,
|
|
||||||
"installerIcon": "icon.ico",
|
|
||||||
"installerSidebar": "compinst.bmp",
|
|
||||||
"uninstallerSidebar": "compinst.bmp"
|
|
||||||
},
|
|
||||||
"directories": {
|
|
||||||
"buildResources": "assets/",
|
|
||||||
"output": "electron-output/"
|
|
||||||
},
|
|
||||||
"linux": {
|
|
||||||
"target": "dir",
|
|
||||||
"extraFiles": [
|
|
||||||
{
|
|
||||||
"from": "./node_modules/sharp/vendor/8.10.6/lib",
|
|
||||||
"to": ".",
|
|
||||||
"filter": [
|
|
||||||
"libvips*.so.*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"**/*",
|
|
||||||
"assets/icon.png",
|
|
||||||
"assets/bitfocus-logo.png",
|
|
||||||
"assets/trayTemplate.png",
|
|
||||||
"assets/trayTemplate@2x.png",
|
|
||||||
"!webui/**/*",
|
|
||||||
"!font/*",
|
|
||||||
"!tools/*",
|
|
||||||
"!*.md",
|
|
||||||
"!node_modules/sharp/vendor/lib"
|
|
||||||
],
|
|
||||||
"extraResources": [
|
|
||||||
{
|
|
||||||
"from": "webui/build",
|
|
||||||
"to": "static"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"prod": "./tools/build_writefile.sh && electron .",
|
|
||||||
"dev": "./tools/build_writefile.sh && cross-env DEVELOPER=1 electron .",
|
|
||||||
"update": "./tools/update.sh",
|
|
||||||
"pack": "electron-builder --dir",
|
|
||||||
"dist:webui": "yarn --cwd webui build",
|
|
||||||
"dist:prepare": "./tools/build_writefile.sh ; rm -rf electron-output && yarn dist:webui",
|
|
||||||
"dist": "yarn dist:prepare && yarn electron-rebuild && electron-builder",
|
|
||||||
"electron-rebuild": "yarn dist:prepare:sharp && electron-builder install-app-deps",
|
|
||||||
"testprod": "./node_modules/electron/cli.js .",
|
|
||||||
"macdist": "yarn dist:prepare && yarn dist:prepare:mac-x64 && electron-builder --publish=never --x64 --mac",
|
|
||||||
"macarmdist": "yarn dist:prepare && yarn dist:prepare:mac-arm64 && electron-builder --publish=never --arm64 --mac",
|
|
||||||
"windist": "yarn dist:prepare && yarn dist:prepare:win && electron-builder --publish=never --x64 --win",
|
|
||||||
"lindist": "yarn dist:prepare && yarn dist:prepare:linux && electron-builder --publish=never --x64 --linux",
|
|
||||||
"rpidist": "yarn dist:prepare && yarn dist:prepare:rpi && electron-builder --publish=never --armv7l --linux",
|
|
||||||
"dist:prepare:sharp": "cd node_modules/sharp && rimraf vendor && node install/libvips && node install/dll-copy",
|
|
||||||
"dist:prepare:win": "cross-env npm_config_platform=win32 npm_config_arch=x64 yarn dist:prepare:sharp",
|
|
||||||
"dist:prepare:mac-x64": "cross-env npm_config_platform=darwin npm_config_arch=x64 yarn dist:prepare:sharp",
|
|
||||||
"dist:prepare:mac-arm64": "cross-env npm_config_platform=darwin npm_config_arch=arm64 yarn dist:prepare:sharp",
|
|
||||||
"dist:prepare:linux": "cross-env npm_config_platform=linux npm_config_arch=x64 yarn dist:prepare:sharp",
|
|
||||||
"dist:prepare:rpi": "cross-env npm_config_platform=linux npm_config_arch=arm yarn dist:prepare:sharp",
|
|
||||||
"test": "mocha",
|
|
||||||
"postinstall": "./tools/build_writefile.sh",
|
|
||||||
"headless": "nodemon --ignore './webui/' headless.js",
|
|
||||||
"dev-headless": "./tools/build_writefile.sh && cross-env DEVELOPER=1 nodemon --ignore './webui/' headless.js",
|
|
||||||
"dev-webui": "yarn --cwd webui dev",
|
|
||||||
"format": "prettier --write ."
|
|
||||||
},
|
|
||||||
"repository": "https://github.com/bitfocus/companion",
|
|
||||||
"keywords": [
|
|
||||||
"bitfocus",
|
|
||||||
"companion"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"npm": "please-use-yarn",
|
|
||||||
"yarn": "^1.22",
|
|
||||||
"node": "^14.16"
|
|
||||||
},
|
|
||||||
"managed_node_version": "14",
|
|
||||||
"author": "Bitfocus AS",
|
|
||||||
"license": "MIT",
|
|
||||||
"devDependencies": {
|
|
||||||
"asar": "^3.0.3",
|
|
||||||
"aws-sdk": "^2.931.0",
|
|
||||||
"chai": "^4.3.4",
|
|
||||||
"chai-fs": "^2.0.0",
|
|
||||||
"cross-env": "^7.0.3",
|
|
||||||
"electron": "^13.1.2",
|
|
||||||
"electron-builder": "22.11.7",
|
|
||||||
"mocha": "^6.2.3",
|
|
||||||
"nodemon": "^2.0.7",
|
|
||||||
"p-all": "^3.0.0",
|
|
||||||
"prettier": "^2.3.1",
|
|
||||||
"rimraf": "^3.0.2",
|
|
||||||
"s3-upload-stream": "^1.0.7"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@sentry/electron": "^2.5.0",
|
|
||||||
"app-root-path": "^3.0.0",
|
|
||||||
"binopsy": "^0.0.0",
|
|
||||||
"check-ip": "^1.1.1",
|
|
||||||
"companion-module-7thsensedesign-delta": "github:bitfocus/companion-module-7thsensedesign-delta#v1.0.1",
|
|
||||||
"companion-module-agf-characterworks": "github:bitfocus/companion-module-agf-characterworks#v1.0.3",
|
|
||||||
"companion-module-aja-helo": "github:bitfocus/companion-module-aja-helo#v1.0.2",
|
|
||||||
"companion-module-aja-kipro": "github:bitfocus/companion-module-aja-kipro#v2.0.11",
|
|
||||||
"companion-module-aja-kumo": "github:bitfocus/companion-module-aja-kumo#v1.0.5",
|
|
||||||
"companion-module-allenheath-dlive-ilive": "github:bitfocus/companion-module-allenheath-dlive-ilive#v1.3.7",
|
|
||||||
"companion-module-allenheath-qu": "github:bitfocus/companion-module-allenheath-qu#v1.0.7",
|
|
||||||
"companion-module-allenheath-sq": "github:bitfocus/companion-module-allenheath-sq#v1.3.8",
|
|
||||||
"companion-module-analogway-eks500": "github:bitfocus/companion-module-analogway-eks500#v1.0.1",
|
|
||||||
"companion-module-analogway-livecore": "github:bitfocus/companion-module-analogway-livecore#v1.1.1",
|
|
||||||
"companion-module-analogway-livepremier": "github:bitfocus/companion-module-analogway-livepremier#v1.0.2",
|
|
||||||
"companion-module-analogway-midra": "github:bitfocus/companion-module-analogway-midra#v1.0.2",
|
|
||||||
"companion-module-analogway-picturall": "github:bitfocus/companion-module-analogway-picturall#v1.2.1",
|
|
||||||
"companion-module-analogway-pls300": "github:bitfocus/companion-module-analogway-pls300#v1.0.3",
|
|
||||||
"companion-module-analogway-vertige": "github:bitfocus/companion-module-analogway-vertige#v1.0.0",
|
|
||||||
"companion-module-analogway-vio": "github:bitfocus/companion-module-analogway-vio#v1.0.1",
|
|
||||||
"companion-module-anomes-millumin": "github:bitfocus/companion-module-anomes-millumin#v1.0.6",
|
|
||||||
"companion-module-arkaos-mediamaster": "github:bitfocus/companion-module-arkaos-mediamaster#v1.0.1",
|
|
||||||
"companion-module-aten-matrix": "github:bitfocus/companion-module-aten-matrix#v1.0.0",
|
|
||||||
"companion-module-audiostrom-liveprofessor": "github:bitfocus/companion-module-audiostrom-liveprofessor#v1.0.0",
|
|
||||||
"companion-module-audivero-unityintercom-client": "github:bitfocus/companion-module-audivero-unityintercom-client#v1.0.2",
|
|
||||||
"companion-module-avishop-hdbaset-matrix": "github:bitfocus/companion-module-avishop-hdbaset-matrix#v1.0.1",
|
|
||||||
"companion-module-avolites-ai": "github:bitfocus/companion-module-avolites-ai#v1.0.1",
|
|
||||||
"companion-module-avolites-titan": "github:bitfocus/companion-module-avolites-titan#v1.1.0",
|
|
||||||
"companion-module-avproconnect-acmx1616-auhd": "github:bitfocus/companion-module-avproconnect-acmx1616-auhd#v1.0.0",
|
|
||||||
"companion-module-avstumpfl-pixera": "github:bitfocus/companion-module-avstumpfl-pixera#v1.0.2",
|
|
||||||
"companion-module-axis-ptz": "github:bitfocus/companion-module-axis-ptz#v1.0.1",
|
|
||||||
"companion-module-barco-dcs": "github:bitfocus/companion-module-barco-dcs#v1.0.4",
|
|
||||||
"companion-module-barco-dp": "github:bitfocus/companion-module-barco-dp#v1.1.2",
|
|
||||||
"companion-module-barco-encore": "github:bitfocus/companion-module-barco-encore#v1.0.1",
|
|
||||||
"companion-module-barco-eventmaster": "github:bitfocus/companion-module-barco-eventmaster#v1.3.6",
|
|
||||||
"companion-module-barco-eventmaster-xml": "github:bitfocus/companion-module-barco-eventmaster-xml#v1.2.4",
|
|
||||||
"companion-module-barco-hdx": "github:bitfocus/companion-module-barco-hdx#v1.1.5",
|
|
||||||
"companion-module-barco-imagepro": "github:bitfocus/companion-module-barco-imagepro#v1.0.1",
|
|
||||||
"companion-module-barco-matrixpro": "github:bitfocus/companion-module-barco-matrixpro#v1.1.0",
|
|
||||||
"companion-module-barco-pds": "github:bitfocus/companion-module-barco-pds#v1.1.5",
|
|
||||||
"companion-module-barco-pulse": "github:bitfocus/companion-module-barco-pulse#v1.1.2",
|
|
||||||
"companion-module-bbc-raven": "github:bitfocus/companion-module-bbc-raven#v1.0.1",
|
|
||||||
"companion-module-behringer-wing": "github:bitfocus/companion-module-behringer-wing#v1.0.5",
|
|
||||||
"companion-module-behringer-x32": "github:bitfocus/companion-module-behringer-x32#v2.7.0",
|
|
||||||
"companion-module-behringer-xair": "github:bitfocus/companion-module-behringer-xair#v1.6.7",
|
|
||||||
"companion-module-biamp-audia": "github:bitfocus/companion-module-biamp-audia#v1.0.1",
|
|
||||||
"companion-module-birddog-studio": "github:bitfocus/companion-module-birddog-studio#v1.0.0",
|
|
||||||
"companion-module-birddog-visca": "github:bitfocus/companion-module-birddog-visca#v1.0.4",
|
|
||||||
"companion-module-bitfocus-companion": "github:bitfocus/companion-module-bitfocus-companion#v1.5.3",
|
|
||||||
"companion-module-bitfocus-snapshot": "github:bitfocus/companion-module-bitfocus-snapshot#v0.0.4",
|
|
||||||
"companion-module-blackbox-boxilla": "github:bitfocus/companion-module-blackbox-boxilla#v1.0.2",
|
|
||||||
"companion-module-blackdiamondvideo-phantom800": "github:bitfocus/companion-module-blackdiamondvideo-phantom800#v1.0.0",
|
|
||||||
"companion-module-bmd-atem": "github:bitfocus/companion-module-bmd-atem#v2.13.0",
|
|
||||||
"companion-module-bmd-audiomonitor": "github:bitfocus/companion-module-bmd-audiomonitor#v1.0.0",
|
|
||||||
"companion-module-bmd-hyperdeck": "github:bitfocus/companion-module-bmd-hyperdeck#v1.2.2",
|
|
||||||
"companion-module-bmd-multiview16": "github:bitfocus/companion-module-bmd-multiview16#v1.0.1",
|
|
||||||
"companion-module-bmd-multiview4": "github:bitfocus/companion-module-bmd-multiview4#v1.3.2",
|
|
||||||
"companion-module-bmd-smartview": "github:bitfocus/companion-module-bmd-smartview#v1.1.3",
|
|
||||||
"companion-module-bmd-teranex": "github:bitfocus/companion-module-bmd-teranex#v1.0.4",
|
|
||||||
"companion-module-bmd-videohub": "github:bitfocus/companion-module-bmd-videohub#v1.3.0",
|
|
||||||
"companion-module-bmd-webpresenterhd": "github:bitfocus/companion-module-bmd-webpresenterhd#v1.0.1",
|
|
||||||
"companion-module-boinx-mimolive": "github:bitfocus/companion-module-boinx-mimolive#v1.0.1",
|
|
||||||
"companion-module-borealsystems-director": "github:bitfocus/companion-module-borealsystems-director#v1.0.0",
|
|
||||||
"companion-module-brightsign-player": "github:bitfocus/companion-module-brightsign-player#v1.1.1",
|
|
||||||
"companion-module-brompton-tessera": "github:bitfocus/companion-module-brompton-tessera#v1.0.0",
|
|
||||||
"companion-module-canon-xf": "github:bitfocus/companion-module-canon-xf#v1.0.0",
|
|
||||||
"companion-module-casparcg-server": "github:bitfocus/companion-module-casparcg-server#v1.0.2",
|
|
||||||
"companion-module-chamsys-magicq-osc": "github:bitfocus/companion-module-chamsys-magicq-osc#v1.0.1",
|
|
||||||
"companion-module-chamsys-magicq-udp": "github:bitfocus/companion-module-chamsys-magicq-udp#v1.0.2",
|
|
||||||
"companion-module-christie-pandorasbox": "github:bitfocus/companion-module-christie-pandorasbox#v2.0.2",
|
|
||||||
"companion-module-christie-projector": "github:bitfocus/companion-module-christie-projector#v2.0.3",
|
|
||||||
"companion-module-christie-spyder": "github:bitfocus/companion-module-christie-spyder#v1.0.0",
|
|
||||||
"companion-module-christie-wd": "github:bitfocus/companion-module-christie-wd#v1.0.6",
|
|
||||||
"companion-module-cisco-cms": "github:bitfocus/companion-module-cisco-cms#v1.0.1",
|
|
||||||
"companion-module-cisco-webex-websocket": "github:bitfocus/companion-module-cisco-webex-websocket#v1.1.0",
|
|
||||||
"companion-module-cockos-reaper": "github:bitfocus/companion-module-cockos-reaper#v1.1.0",
|
|
||||||
"companion-module-connect-webcaster": "github:bitfocus/companion-module-connect-webcaster#v1.0.0",
|
|
||||||
"companion-module-crystal-scte": "github:bitfocus/companion-module-crystal-scte#v1.0.0",
|
|
||||||
"companion-module-dahuasecurity-ptz": "github:bitfocus/companion-module-dahuasecurity-ptz#v1.0.1",
|
|
||||||
"companion-module-dalite-scb": "github:bitfocus/companion-module-dalite-scb#v1.0.0",
|
|
||||||
"companion-module-dashare-multiplay": "github:bitfocus/companion-module-dashare-multiplay#v1.0.1",
|
|
||||||
"companion-module-datapath-fx4": "github:bitfocus/companion-module-datapath-fx4#v1.0.0",
|
|
||||||
"companion-module-dataton-watchout": "github:bitfocus/companion-module-dataton-watchout#v1.2.0",
|
|
||||||
"companion-module-datavideo-dvip": "github:bitfocus/companion-module-datavideo-dvip#v1.0.0",
|
|
||||||
"companion-module-datavideo-visca": "github:bitfocus/companion-module-datavideo-visca#v1.0.3",
|
|
||||||
"companion-module-dcc-ex-commandstation": "github:bitfocus/companion-module-dcc-ex-commandstation#v1.0.0",
|
|
||||||
"companion-module-denon-dn-500bd-mkii": "github:bitfocus/companion-module-denon-dn-500bd-mkii#v1.0.2",
|
|
||||||
"companion-module-denon-receiver": "github:bitfocus/companion-module-denon-receiver#v1.0.1",
|
|
||||||
"companion-module-denon-recorder": "github:bitfocus/companion-module-denon-recorder#v1.0.1",
|
|
||||||
"companion-module-depili-clock-8001": "github:bitfocus/companion-module-depili-clock-8001#v5.1.1",
|
|
||||||
"companion-module-dexon-dimax": "github:bitfocus/companion-module-dexon-dimax#v1.0.3",
|
|
||||||
"companion-module-dexon-divip": "github:bitfocus/companion-module-dexon-divip#v1.0.2",
|
|
||||||
"companion-module-dexon-matrix": "github:bitfocus/companion-module-dexon-matrix#v1.0.1",
|
|
||||||
"companion-module-digico-osc": "github:bitfocus/companion-module-digico-osc#v1.0.2",
|
|
||||||
"companion-module-digitalprojection-highlight": "github:bitfocus/companion-module-digitalprojection-highlight#v1.0.2",
|
|
||||||
"companion-module-disguise": "github:bitfocus/companion-module-disguise#v1.1.0",
|
|
||||||
"companion-module-disguise-mtc": "github:bitfocus/companion-module-disguise-mtc#v1.0.2",
|
|
||||||
"companion-module-dolby-cinemaprocessor": "github:bitfocus/companion-module-dolby-cinemaprocessor#v1.1.0",
|
|
||||||
"companion-module-draco-tera": "github:bitfocus/companion-module-draco-tera#v1.0.4",
|
|
||||||
"companion-module-dsan-limitimer": "github:bitfocus/companion-module-dsan-limitimer#v1.1.1",
|
|
||||||
"companion-module-dsan-perfectcue": "github:bitfocus/companion-module-dsan-perfectcue#v1.0.0",
|
|
||||||
"companion-module-dtvideolabs-playbackproplus": "github:bitfocus/companion-module-dtvideolabs-playbackproplus#v1.0.2",
|
|
||||||
"companion-module-elgato-keylight": "github:bitfocus/companion-module-elgato-keylight#v1.2.2",
|
|
||||||
"companion-module-epiphan-pearl": "github:bitfocus/companion-module-epiphan-pearl#v1.0.7",
|
|
||||||
"companion-module-etc-eos": "github:bitfocus/companion-module-etc-eos#v1.2.1",
|
|
||||||
"companion-module-extron-dxp": "github:bitfocus/companion-module-extron-dxp#v1.0.8",
|
|
||||||
"companion-module-extron-in1604": "github:bitfocus/companion-module-extron-in1604#v1.0.3",
|
|
||||||
"companion-module-extron-ipl-t-pcs4": "github:bitfocus/companion-module-extron-ipl-t-pcs4#v1.0.2",
|
|
||||||
"companion-module-extron-smp111": "github:bitfocus/companion-module-extron-smp111#v1.0.4",
|
|
||||||
"companion-module-extron-smp351": "github:bitfocus/companion-module-extron-smp351#v1.2.0",
|
|
||||||
"companion-module-extron-smx": "github:bitfocus/companion-module-extron-smx#v1.0.4",
|
|
||||||
"companion-module-faithchapel-videoplayoutserver": "github:bitfocus/companion-module-faithchapel-videoplayoutserver#v1.0.1",
|
|
||||||
"companion-module-figure53-go-button": "github:bitfocus/companion-module-figure53-go-button#v1.2.4",
|
|
||||||
"companion-module-figure53-qlab": "github:bitfocus/companion-module-figure53-qlab#v1.2.5",
|
|
||||||
"companion-module-figure53-qlab-advance": "github:bitfocus/companion-module-figure53-qlab-advance#v1.3.8",
|
|
||||||
"companion-module-figure53-qview": "github:bitfocus/companion-module-figure53-qview#v1.0.0",
|
|
||||||
"companion-module-folivora-btt": "github:bitfocus/companion-module-folivora-btt#v1.0.2",
|
|
||||||
"companion-module-fora-hvs": "github:bitfocus/companion-module-fora-hvs#v1.2.4",
|
|
||||||
"companion-module-foscam-ptz": "github:bitfocus/companion-module-foscam-ptz#v1.0.1",
|
|
||||||
"companion-module-gallery-virtualvtrpro": "github:bitfocus/companion-module-gallery-virtualvtrpro#v1.0.1",
|
|
||||||
"companion-module-gammacontrol-gmaestro": "github:bitfocus/companion-module-gammacontrol-gmaestro#v1.0.2",
|
|
||||||
"companion-module-gefen-dvimatrix": "github:bitfocus/companion-module-gefen-dvimatrix#v1.0.1",
|
|
||||||
"companion-module-generic-artnet": "github:bitfocus/companion-module-generic-artnet#v1.0.2",
|
|
||||||
"companion-module-generic-emberplus": "github:bitfocus/companion-module-generic-emberplus#v1.1.1",
|
|
||||||
"companion-module-generic-http": "github:bitfocus/companion-module-generic-http#v1.0.8",
|
|
||||||
"companion-module-generic-mqtt": "github:bitfocus/companion-module-generic-mqtt#v1.2.0",
|
|
||||||
"companion-module-generic-osc": "github:bitfocus/companion-module-generic-osc#v1.0.4",
|
|
||||||
"companion-module-generic-pjlink": "github:bitfocus/companion-module-generic-pjlink#v1.0.5",
|
|
||||||
"companion-module-generic-sacn": "github:bitfocus/companion-module-generic-sacn#v1.0.0",
|
|
||||||
"companion-module-generic-swp08": "github:bitfocus/companion-module-generic-swp08#v1.0.3",
|
|
||||||
"companion-module-generic-tcp-serial": "github:bitfocus/companion-module-generic-tcp-serial#v1.0.2",
|
|
||||||
"companion-module-generic-tcp-udp": "github:bitfocus/companion-module-generic-tcp-udp#v1.0.6",
|
|
||||||
"companion-module-generic-wakeonlan": "github:bitfocus/companion-module-generic-wakeonlan#v1.0.4",
|
|
||||||
"companion-module-generic-websocket": "github:bitfocus/companion-module-generic-websocket#v1.0.0",
|
|
||||||
"companion-module-globalcache-itac-cc": "github:bitfocus/companion-module-globalcache-itac-cc#v1.0.1",
|
|
||||||
"companion-module-globalcache-itac-ir": "github:bitfocus/companion-module-globalcache-itac-ir#v1.0.5",
|
|
||||||
"companion-module-globalcache-itac-sl": "github:bitfocus/companion-module-globalcache-itac-sl#v1.0.3",
|
|
||||||
"companion-module-grassvalley-amp": "github:bitfocus/companion-module-grassvalley-amp#v1.1.3",
|
|
||||||
"companion-module-greenhippo-hippotizer": "github:bitfocus/companion-module-greenhippo-hippotizer#v1.0.2",
|
|
||||||
"companion-module-h2r-graphics": "github:bitfocus/companion-module-h2r-graphics#v1.1.2",
|
|
||||||
"companion-module-haivision-connectdvr": "github:bitfocus/companion-module-haivision-connectdvr#v1.0.9",
|
|
||||||
"companion-module-haivision-kbencoder": "github:bitfocus/companion-module-haivision-kbencoder#v1.0.0",
|
|
||||||
"companion-module-highend-hog4": "github:bitfocus/companion-module-highend-hog4#v1.1.0",
|
|
||||||
"companion-module-hologfx-holographics": "github:bitfocus/companion-module-hologfx-holographics#v1.0.0",
|
|
||||||
"companion-module-homeassistant-server": "github:bitfocus/companion-module-homeassistant-server#v0.6.1",
|
|
||||||
"companion-module-ifelseware-avkey": "github:bitfocus/companion-module-ifelseware-avkey#v1.0.0",
|
|
||||||
"companion-module-ifelseware-avplayback": "github:bitfocus/companion-module-ifelseware-avplayback#v1.0.2",
|
|
||||||
"companion-module-imimot-mitti": "github:bitfocus/companion-module-imimot-mitti#v1.0.8",
|
|
||||||
"companion-module-interactivetechnologies-cueserver": "github:bitfocus/companion-module-interactivetechnologies-cueserver#v1.0.1",
|
|
||||||
"companion-module-irisdown-countdowntimer": "github:bitfocus/companion-module-irisdown-countdowntimer#v1.1.3",
|
|
||||||
"companion-module-irisdown-remoteshowcontrol": "github:bitfocus/companion-module-irisdown-remoteshowcontrol#v1.0.2",
|
|
||||||
"companion-module-jamesholt-x32tc": "github:bitfocus/companion-module-jamesholt-x32tc#v1.0.6",
|
|
||||||
"companion-module-joy-playdeck": "github:bitfocus/companion-module-joy-playdeck#v1.0.1",
|
|
||||||
"companion-module-justmacros-lua": "github:bitfocus/companion-module-justmacros-lua#v1.0.1",
|
|
||||||
"companion-module-jvc-ptz": "github:bitfocus/companion-module-jvc-ptz#v1.0.9",
|
|
||||||
"companion-module-kiloview-ndi": "github:bitfocus/companion-module-kiloview-ndi#v1.0.0",
|
|
||||||
"companion-module-kramer-matrix": "github:bitfocus/companion-module-kramer-matrix#v1.2.1",
|
|
||||||
"companion-module-kramer-vp727": "github:bitfocus/companion-module-kramer-vp727#v1.0.1",
|
|
||||||
"companion-module-kramer-vp734": "github:bitfocus/companion-module-kramer-vp734#v1.0.0",
|
|
||||||
"companion-module-kramer-vp773a": "github:bitfocus/companion-module-kramer-vp773a#v1.0.0",
|
|
||||||
"companion-module-kramer-vs41h": "github:bitfocus/companion-module-kramer-vs41h#v1.0.0",
|
|
||||||
"companion-module-leafcoders-titler": "github:bitfocus/companion-module-leafcoders-titler#v1.0.0",
|
|
||||||
"companion-module-lectrosonics-aspen": "github:bitfocus/companion-module-lectrosonics-aspen#v1.0.0",
|
|
||||||
"companion-module-lightware-lw2": "github:bitfocus/companion-module-lightware-lw2#v1.0.2",
|
|
||||||
"companion-module-lightware-lw3": "github:bitfocus/companion-module-lightware-lw3#v1.0.1",
|
|
||||||
"companion-module-liminalet-zoomosc": "github:bitfocus/companion-module-liminalet-zoomosc#v1.0.8",
|
|
||||||
"companion-module-linkbox-remote": "github:bitfocus/companion-module-linkbox-remote#v1.2.1",
|
|
||||||
"companion-module-livingasone-decoders": "github:bitfocus/companion-module-livingasone-decoders#v1.1.2",
|
|
||||||
"companion-module-ltn-schedule": "github:bitfocus/companion-module-ltn-schedule#v1.0.0",
|
|
||||||
"companion-module-lumens-mediaprocessor": "github:bitfocus/companion-module-lumens-mediaprocessor#v1.0.0",
|
|
||||||
"companion-module-lumens-visca": "github:bitfocus/companion-module-lumens-visca#v1.0.2",
|
|
||||||
"companion-module-lyntec-rpc-breaker": "github:bitfocus/companion-module-lyntec-rpc-breaker#v1.0.3",
|
|
||||||
"companion-module-magewell-proconvert-decoder": "github:bitfocus/companion-module-magewell-proconvert-decoder#v1.0.0",
|
|
||||||
"companion-module-magewell-ultrastream": "github:bitfocus/companion-module-magewell-ultrastream#v0.0.3",
|
|
||||||
"companion-module-magicsoft-recorder": "github:bitfocus/companion-module-magicsoft-recorder#v1.0.0",
|
|
||||||
"companion-module-malighting-grandma2": "github:bitfocus/companion-module-malighting-grandma2#v1.0.10",
|
|
||||||
"companion-module-malighting-msc": "github:bitfocus/companion-module-malighting-msc#v0.2.1",
|
|
||||||
"companion-module-matrox-monarch": "github:bitfocus/companion-module-matrox-monarch#v1.0.0",
|
|
||||||
"companion-module-media-player-classic": "github:bitfocus/companion-module-media-player-classic#v1.0.0",
|
|
||||||
"companion-module-metus-ingest": "github:bitfocus/companion-module-metus-ingest#v1.2.1",
|
|
||||||
"companion-module-middleatlantic-racklink": "github:bitfocus/companion-module-middleatlantic-racklink#v1.0.0",
|
|
||||||
"companion-module-middlethings-middlecontrol": "github:bitfocus/companion-module-middlethings-middlecontrol#v1.0.1",
|
|
||||||
"companion-module-modelighting-edin": "github:bitfocus/companion-module-modelighting-edin#v1.0.0",
|
|
||||||
"companion-module-modulo": "github:bitfocus/companion-module-modulo#v1.0.1",
|
|
||||||
"companion-module-motu-avb": "github:bitfocus/companion-module-motu-avb#v1.0.2",
|
|
||||||
"companion-module-msc-router": "github:bitfocus/companion-module-msc-router#v1.0.2",
|
|
||||||
"companion-module-multicamsystems-multicamsuite": "github:bitfocus/companion-module-multicamsystems-multicamsuite#v1.0.1",
|
|
||||||
"companion-module-muxlab-kvm": "github:bitfocus/companion-module-muxlab-kvm#v1.0.0",
|
|
||||||
"companion-module-neodarque-stagetimer2": "github:bitfocus/companion-module-neodarque-stagetimer2#v1.2.6",
|
|
||||||
"companion-module-netio-powerbox": "github:bitfocus/companion-module-netio-powerbox#v1.0.0",
|
|
||||||
"companion-module-nevion-mrp": "github:bitfocus/companion-module-nevion-mrp#v2.0.2",
|
|
||||||
"companion-module-newbluefx-titler": "github:bitfocus/companion-module-newbluefx-titler#v1.0.1",
|
|
||||||
"companion-module-newtek-ndistudiomonitor": "github:bitfocus/companion-module-newtek-ndistudiomonitor#v1.0.1",
|
|
||||||
"companion-module-newtek-tricaster": "github:bitfocus/companion-module-newtek-tricaster#v1.1.4",
|
|
||||||
"companion-module-nexo-nxamp": "github:bitfocus/companion-module-nexo-nxamp#v1.0.0",
|
|
||||||
"companion-module-nobe-omniscope": "github:bitfocus/companion-module-nobe-omniscope#v1.0.0",
|
|
||||||
"companion-module-noismada-octopuslistener": "github:bitfocus/companion-module-noismada-octopuslistener#v1.0.2",
|
|
||||||
"companion-module-noismada-octopusshowcontrol": "github:bitfocus/companion-module-noismada-octopusshowcontrol#v1.2.0",
|
|
||||||
"companion-module-novastar-controller": "github:bitfocus/companion-module-novastar-controller#v1.0.6",
|
|
||||||
"companion-module-obs-studio": "github:bitfocus/companion-module-obs-studio#v1.0.24",
|
|
||||||
"companion-module-obsidiancontrol-onyx": "github:bitfocus/companion-module-obsidiancontrol-onyx#v1.0.3",
|
|
||||||
"companion-module-octava-pro-dsx": "github:bitfocus/companion-module-octava-pro-dsx#v0.0.1",
|
|
||||||
"companion-module-openlp-http": "github:bitfocus/companion-module-openlp-http#v0.1.1",
|
|
||||||
"companion-module-opensong-api": "github:bitfocus/companion-module-opensong-api#v1.0.1",
|
|
||||||
"companion-module-openweather-rest": "github:bitfocus/companion-module-openweather-rest#v1.0.2",
|
|
||||||
"companion-module-opticis-omm-1000": "github:bitfocus/companion-module-opticis-omm-1000#v1.0.2",
|
|
||||||
"companion-module-optoma-z28s": "github:bitfocus/companion-module-optoma-z28s#v1.0.2",
|
|
||||||
"companion-module-orfast-ndi": "github:bitfocus/companion-module-orfast-ndi#v1.0.0",
|
|
||||||
"companion-module-panasonic-avhs": "github:bitfocus/companion-module-panasonic-avhs#v1.0.4",
|
|
||||||
"companion-module-panasonic-camera-controller": "github:bitfocus/companion-module-panasonic-camera-controller#v1.0.6",
|
|
||||||
"companion-module-panasonic-projector": "github:bitfocus/companion-module-panasonic-projector#v1.0.1",
|
|
||||||
"companion-module-panasonic-ptz": "github:bitfocus/companion-module-panasonic-ptz#v1.0.19",
|
|
||||||
"companion-module-panasonic-tv-th": "github:bitfocus/companion-module-panasonic-tv-th#v0.0.1",
|
|
||||||
"companion-module-pangolin-beyond": "github:bitfocus/companion-module-pangolin-beyond#v1.0.2",
|
|
||||||
"companion-module-phillips-hue": "github:bitfocus/companion-module-phillips-hue#v0.0.4",
|
|
||||||
"companion-module-pixap-pixtimerpro": "github:bitfocus/companion-module-pixap-pixtimerpro#v1.0.6",
|
|
||||||
"companion-module-planningcenter-serviceslive": "github:bitfocus/companion-module-planningcenter-serviceslive#v1.0.5",
|
|
||||||
"companion-module-presentationtools-aps": "github:bitfocus/companion-module-presentationtools-aps#v1.1.0",
|
|
||||||
"companion-module-presentationtools-cuetimer": "github:bitfocus/companion-module-presentationtools-cuetimer#v1.0.0",
|
|
||||||
"companion-module-protopie-bridge": "github:bitfocus/companion-module-protopie-bridge#v1.0.2",
|
|
||||||
"companion-module-prsi-ipower": "github:bitfocus/companion-module-prsi-ipower#v1.0.2",
|
|
||||||
"companion-module-ptzoptics-visca": "github:bitfocus/companion-module-ptzoptics-visca#v1.1.6",
|
|
||||||
"companion-module-qsys-remote-control": "github:bitfocus/companion-module-qsys-remote-control#v1.0.3",
|
|
||||||
"companion-module-radiodj-rest": "github:bitfocus/companion-module-radiodj-rest#v1.0.0",
|
|
||||||
"companion-module-rationalacoustics-smaart3": "github:bitfocus/companion-module-rationalacoustics-smaart3#v1.0.3",
|
|
||||||
"companion-module-renewedvision-propresenter": "github:bitfocus/companion-module-renewedvision-propresenter#v2.4.0",
|
|
||||||
"companion-module-renewedvision-pvp": "github:bitfocus/companion-module-renewedvision-pvp#v1.0.7",
|
|
||||||
"companion-module-resolume-arena": "github:bitfocus/companion-module-resolume-arena#v1.0.5",
|
|
||||||
"companion-module-rocosoft-ptzjoy": "github:bitfocus/companion-module-rocosoft-ptzjoy#v1.0.1",
|
|
||||||
"companion-module-roku-tv": "github:bitfocus/companion-module-roku-tv#v1.0.1",
|
|
||||||
"companion-module-roland-m5000": "github:bitfocus/companion-module-roland-m5000#v1.0.2",
|
|
||||||
"companion-module-roland-v1200hd": "github:bitfocus/companion-module-roland-v1200hd#v1.0.0",
|
|
||||||
"companion-module-roland-v600uhd": "github:bitfocus/companion-module-roland-v600uhd#v1.0.1",
|
|
||||||
"companion-module-roland-v60hd": "github:bitfocus/companion-module-roland-v60hd#v1.0.10",
|
|
||||||
"companion-module-roland-vp42h": "github:bitfocus/companion-module-roland-vp42h#v1.0.0",
|
|
||||||
"companion-module-roland-vr50hd-mk2": "github:bitfocus/companion-module-roland-vr50hd-mk2#v1.0.0",
|
|
||||||
"companion-module-roland-xs42h": "github:bitfocus/companion-module-roland-xs42h#v1.0.0",
|
|
||||||
"companion-module-roland-xs62s": "github:bitfocus/companion-module-roland-xs62s#v1.0.1",
|
|
||||||
"companion-module-roland-xs84h": "github:bitfocus/companion-module-roland-xs84h#v1.0.0",
|
|
||||||
"companion-module-rossvideo-caprica": "github:bitfocus/companion-module-rossvideo-caprica#v1.0.0",
|
|
||||||
"companion-module-rossvideo-nkrouter": "github:bitfocus/companion-module-rossvideo-nkrouter#v1.0.2",
|
|
||||||
"companion-module-rossvideo-rosstalk": "github:bitfocus/companion-module-rossvideo-rosstalk#v1.2.8",
|
|
||||||
"companion-module-rossvideo-xpression": "github:bitfocus/companion-module-rossvideo-xpression#v1.0.2",
|
|
||||||
"companion-module-sain-smart-relay": "github:bitfocus/companion-module-sain-smart-relay#v1.0.0",
|
|
||||||
"companion-module-seervision-suite": "github:bitfocus/companion-module-seervision-suite#v1.1.0",
|
|
||||||
"companion-module-sharp-tv": "github:bitfocus/companion-module-sharp-tv#v1.0.0",
|
|
||||||
"companion-module-showcuesystems-scs": "github:bitfocus/companion-module-showcuesystems-scs#v1.0.1",
|
|
||||||
"companion-module-shure-dis-ccu": "github:bitfocus/companion-module-shure-dis-ccu#v1.0.1",
|
|
||||||
"companion-module-shure-psm1000": "github:bitfocus/companion-module-shure-psm1000#v1.0.0",
|
|
||||||
"companion-module-shure-scm820": "github:bitfocus/companion-module-shure-scm820#v1.0.0",
|
|
||||||
"companion-module-shure-wireless": "github:bitfocus/companion-module-shure-wireless#v1.2.0",
|
|
||||||
"companion-module-sienna-ndimonitor": "github:bitfocus/companion-module-sienna-ndimonitor#v1.0.0",
|
|
||||||
"companion-module-singularlive-studio": "github:bitfocus/companion-module-singularlive-studio#v1.0.7",
|
|
||||||
"companion-module-slack-webhooks": "github:bitfocus/companion-module-slack-webhooks#v1.0.1",
|
|
||||||
"companion-module-softron-movierecorder": "github:bitfocus/companion-module-softron-movierecorder#v1.0.1",
|
|
||||||
"companion-module-softron-ontheairvideo": "github:bitfocus/companion-module-softron-ontheairvideo#v1.0.0",
|
|
||||||
"companion-module-sononum-horae": "github:bitfocus/companion-module-sononum-horae#v1.0.1",
|
|
||||||
"companion-module-sonoran-coyote": "github:bitfocus/companion-module-sonoran-coyote#v1.0.0",
|
|
||||||
"companion-module-sonos-speakers": "github:bitfocus/companion-module-sonos-speakers#v0.2.0",
|
|
||||||
"companion-module-sony-bravia": "github:bitfocus/companion-module-sony-bravia#v1.0.0",
|
|
||||||
"companion-module-sony-visca": "github:bitfocus/companion-module-sony-visca#v1.2.8",
|
|
||||||
"companion-module-soundcraft-ui": "github:bitfocus/companion-module-soundcraft-ui#v2.0.3",
|
|
||||||
"companion-module-sounddevices-pixnet": "github:bitfocus/companion-module-sounddevices-pixnet#v1.0.0",
|
|
||||||
"companion-module-spotify-remote": "github:bitfocus/companion-module-spotify-remote#v1.0.7",
|
|
||||||
"companion-module-spx-gc": "github:bitfocus/companion-module-spx-gc#v1.0.2",
|
|
||||||
"companion-module-studiocoast-vmix": "github:bitfocus/companion-module-studiocoast-vmix#v1.2.22",
|
|
||||||
"companion-module-symetrix-dsp": "github:bitfocus/companion-module-symetrix-dsp#v1.3.0",
|
|
||||||
"companion-module-tallyma-wirelesstally": "github:bitfocus/companion-module-tallyma-wirelesstally#v1.0.1",
|
|
||||||
"companion-module-tascam-bdmp1": "github:bitfocus/companion-module-tascam-bdmp1#v0.1.5",
|
|
||||||
"companion-module-tascam-cd": "github:bitfocus/companion-module-tascam-cd#v1.0.2",
|
|
||||||
"companion-module-techministry-midirelay": "github:bitfocus/companion-module-techministry-midirelay#v2.0.4",
|
|
||||||
"companion-module-techministry-protally": "github:bitfocus/companion-module-techministry-protally#v1.0.0",
|
|
||||||
"companion-module-techministry-tallyarbiter": "github:bitfocus/companion-module-techministry-tallyarbiter#v1.0.2",
|
|
||||||
"companion-module-teracom-tcw181b": "github:bitfocus/companion-module-teracom-tcw181b#v1.0.2",
|
|
||||||
"companion-module-teradek-vidiu": "github:bitfocus/companion-module-teradek-vidiu#v1.0.2",
|
|
||||||
"companion-module-tesla-smart": "github:bitfocus/companion-module-tesla-smart#v1.0.3",
|
|
||||||
"companion-module-thelightingcontroller": "github:bitfocus/companion-module-thelightingcontroller#v1.1.2",
|
|
||||||
"companion-module-thingm-blink1": "github:bitfocus/companion-module-thingm-blink1#v1.2.3",
|
|
||||||
"companion-module-tplink-kasasmartplug": "github:bitfocus/companion-module-tplink-kasasmartplug#v1.0.1",
|
|
||||||
"companion-module-tslproducts-umd": "github:bitfocus/companion-module-tslproducts-umd#v1.2.1",
|
|
||||||
"companion-module-tvone-corio": "github:bitfocus/companion-module-tvone-corio#v1.0.0",
|
|
||||||
"companion-module-twitch-api": "github:bitfocus/companion-module-twitch-api#v1.0.0",
|
|
||||||
"companion-module-ubiquiti-unifi": "github:bitfocus/companion-module-ubiquiti-unifi#v1.0.1",
|
|
||||||
"companion-module-vaddio-ptz": "github:bitfocus/companion-module-vaddio-ptz#v1.0.1",
|
|
||||||
"companion-module-vicreo-hotkey": "github:bitfocus/companion-module-vicreo-hotkey#v2.0.5",
|
|
||||||
"companion-module-vicreo-variablelistener": "github:bitfocus/companion-module-vicreo-variablelistener#v1.0.7",
|
|
||||||
"companion-module-videolan-vlc": "github:bitfocus/companion-module-videolan-vlc#v1.1.12",
|
|
||||||
"companion-module-visualproductions-bstation2": "github:bitfocus/companion-module-visualproductions-bstation2#v1.0.6",
|
|
||||||
"companion-module-vivitek-projector": "github:bitfocus/companion-module-vivitek-projector#v1.0.3",
|
|
||||||
"companion-module-vizio-smartcast": "github:bitfocus/companion-module-vizio-smartcast#v1.1.4",
|
|
||||||
"companion-module-vyv-photon": "github:bitfocus/companion-module-vyv-photon#v1.0.4",
|
|
||||||
"companion-module-wyrestorm-sw0402mv": "github:bitfocus/companion-module-wyrestorm-sw0402mv#v1.0.1",
|
|
||||||
"companion-module-xiamen-sprolink-vd-series": "github:bitfocus/companion-module-xiamen-sprolink-vd-series#v1.0.1",
|
|
||||||
"companion-module-yamaha-rcp": "github:bitfocus/companion-module-yamaha-rcp#v1.6.0",
|
|
||||||
"companion-module-youtube-live": "github:bitfocus/companion-module-youtube-live#v1.1.2",
|
|
||||||
"companion-module-zenvideo-ndirouter": "github:bitfocus/companion-module-zenvideo-ndirouter#v1.0.1",
|
|
||||||
"debug": "^4.2.0",
|
|
||||||
"elgato-stream-deck": "^4.1.0",
|
|
||||||
"emberplus-connection": "^0.0.4",
|
|
||||||
"express": "^4.16.3",
|
|
||||||
"find-process": "1.4.4",
|
|
||||||
"fs-extra": "^10.0.0",
|
|
||||||
"infinitton-idisplay": "^1.0.5",
|
|
||||||
"lodash": "^4.17.20",
|
|
||||||
"mkdirp": "^1.0.4",
|
|
||||||
"moment": "^2.29.1",
|
|
||||||
"network": "^0.4.1",
|
|
||||||
"node-fetch": "^2.6.1",
|
|
||||||
"node-rest-client": "^3.1.0",
|
|
||||||
"osc": "^2.4.1",
|
|
||||||
"pngjs": "^3.3.3",
|
|
||||||
"sharp": "^0.28.3",
|
|
||||||
"shortid": "^2.2.16",
|
|
||||||
"socket.io": "^4.1.2",
|
|
||||||
"strip-ansi": "^5.2.0",
|
|
||||||
"websocket": "^1.0.34",
|
|
||||||
"node-hid": "^2.1.1",
|
|
||||||
"serialport": "^9.2.0",
|
|
||||||
"ws": "^7.4.6"
|
|
||||||
},
|
|
||||||
"collective": {
|
|
||||||
"type": "donorbox",
|
|
||||||
"url": "https://donorbox.org/bitfocus-opensource"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"@julusian/jpeg-turbo": "^1.1.1"
|
|
||||||
},
|
|
||||||
"resolutions": {
|
|
||||||
"infinitton-idisplay/node-hid": "^2.1.1",
|
|
||||||
"**/osc/serialport": "^9.2.0",
|
|
||||||
"**/osc/ws": "^7.4.6"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
10067
pkgs/companion/yarn.nix
10067
pkgs/companion/yarn.nix
File diff suppressed because it is too large
Load diff
|
@ -1,48 +0,0 @@
|
||||||
{ stdenv, requireFile, fetchpatch, kernel, lib }:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "decklink";
|
|
||||||
version = "12.2.2";
|
|
||||||
|
|
||||||
src = requireFile {
|
|
||||||
name = "Blackmagic_Desktop_Video_Linux_12.2.2.tar.gz";
|
|
||||||
url = "https://www.blackmagicdesign.com/support/";
|
|
||||||
sha256 = "8bca946bd3f002d2d404a74210c881935351e1a0d03f750559b180fdb439ef35";
|
|
||||||
};
|
|
||||||
|
|
||||||
KERNELDIR = "${kernel.dev}/lib/modules/${kernel.modDirVersion}/build";
|
|
||||||
INSTALL_MOD_PATH = placeholder "out";
|
|
||||||
|
|
||||||
nativeBuildInputs = kernel.moduleBuildDependencies;
|
|
||||||
|
|
||||||
setSourceRoot = ''
|
|
||||||
tar xf Blackmagic_Desktop_Video_Linux_12.2.2/other/x86_64/desktopvideo-12.2.2a6-x86_64.tar.gz
|
|
||||||
sourceRoot=$NIX_BUILD_TOP/desktopvideo-12.2.2a6-x86_64/usr/src
|
|
||||||
'';
|
|
||||||
|
|
||||||
buildPhase = ''
|
|
||||||
runHook preBuild
|
|
||||||
|
|
||||||
make -C $sourceRoot/blackmagic-12.2.2a6 -j$NIX_BUILD_CORES
|
|
||||||
make -C $sourceRoot/blackmagic-io-12.2.2a6 -j$NIX_BUILD_CORES
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
make -C $KERNELDIR M=$sourceRoot/blackmagic-12.2.2a6 modules_install
|
|
||||||
make -C $KERNELDIR M=$sourceRoot/blackmagic-io-12.2.2a6 modules_install
|
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
homepage = "https://www.blackmagicdesign.com/support/family/capture-and-playback";
|
|
||||||
maintainers = [ maintainers.hexchen ];
|
|
||||||
license = licenses.unfree;
|
|
||||||
description = "Kernel module for the Blackmagic Design Decklink cards";
|
|
||||||
platforms = platforms.linux;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,68 +1,32 @@
|
||||||
{ config ? {}, system ? builtins.currentSystem, ... }@args:
|
{ sources, ... }@args:
|
||||||
|
|
||||||
let
|
let
|
||||||
sources = import ../nix/sources.nix;
|
|
||||||
pkgs = import sources.nixpkgs args;
|
pkgs = import sources.nixpkgs args;
|
||||||
|
oldstable = import sources.nixpkgs-oldstable args;
|
||||||
unstable = import sources.nixpkgs-unstable args;
|
unstable = import sources.nixpkgs-unstable args;
|
||||||
|
|
||||||
callPackage = pkgs.lib.callPackageWith (pkgs // newpkgs);
|
callPackage = pkgs.lib.callPackageWith (pkgs // newpkgs);
|
||||||
|
|
||||||
newpkgs = {
|
newpkgs = {
|
||||||
alps = callPackage ./alps {};
|
|
||||||
|
|
||||||
companion = callPackage ./companion {};
|
mattermost = callPackage ./mattermost.nix {
|
||||||
libvips = callPackage ./libvips {};
|
buildGoModule = unstable.buildGo122Module;
|
||||||
|
|
||||||
docker = pkgs.docker.overrideAttrs (super: {
|
|
||||||
moby = super.moby.overrideAttrs (super: {
|
|
||||||
extraPath = super.extraPath + ":${pkgs.zfs}/bin";
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
linuxPackagesFor = kernel: (pkgs.linuxPackagesFor kernel).extend (_: ksuper: {
|
|
||||||
decklink = callPackage ./decklink { kernel = ksuper.kernel; };
|
|
||||||
});
|
|
||||||
|
|
||||||
blackmagicDesktopVideo = callPackage ./blackmagic-desktop-video { };
|
|
||||||
|
|
||||||
obs-studio = unstable.obs-studio.overrideAttrs (_: rec {
|
|
||||||
wrapLibraries = with (pkgs // newpkgs); [
|
|
||||||
xorg.libX11.out
|
|
||||||
libvlc
|
|
||||||
blackmagicDesktopVideo
|
|
||||||
libcxx
|
|
||||||
libcxxabi
|
|
||||||
];
|
|
||||||
postInstall = ''
|
|
||||||
wrapProgram $out/bin/obs \
|
|
||||||
--prefix "LD_LIBRARY_PATH" : "${pkgs.lib.makeLibraryPath wrapLibraries}"
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
|
|
||||||
mattermost = callPackage ./mattermost {};
|
|
||||||
|
|
||||||
# a version of the lounge with some extra css that
|
|
||||||
# hides things the hacc-voc doesn't need
|
|
||||||
thelounge-hacked = pkgs.stdenv.mkDerivation {
|
|
||||||
name = "thelounge-hacked";
|
|
||||||
src = pkgs.thelounge;
|
|
||||||
|
|
||||||
phases = [ "buildPhase" "installPhase" ];
|
|
||||||
buildPhase = ''
|
|
||||||
cp $src/* -r .
|
|
||||||
chmod 777 lib/node_modules/thelounge/public/css/style.css
|
|
||||||
cat ${./thelounge/css-patch.css} >> lib/node_modules/thelounge/public/css/style.css
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out
|
|
||||||
cp * -r $out
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uffd = callPackage ./uffd {};
|
morph = callPackage ./morph.nix {
|
||||||
|
buildGoModule = unstable.buildGo122Module;
|
||||||
|
};
|
||||||
|
|
||||||
inherit (unstable) bottom vaultwarden vaultwarden-vault;
|
tracktrain = import sources.tracktrain {
|
||||||
|
nixpkgs = unstable;
|
||||||
|
compiler = "default";
|
||||||
|
};
|
||||||
|
|
||||||
|
uffd = oldstable.callPackage ./uffd { };
|
||||||
|
|
||||||
|
hacc-scripts = callPackage ./scripts {};
|
||||||
|
|
||||||
|
inherit (oldstable) uwsgi flask;
|
||||||
};
|
};
|
||||||
|
|
||||||
in pkgs.extend(_: _: newpkgs)
|
in pkgs.extend(_: _: newpkgs)
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
stdenv, fetchurl, pkg-config, glib, expat,
|
|
||||||
libjpeg_turbo, libexif, librsvg, libtiff, libpng
|
|
||||||
}:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "libvips";
|
|
||||||
version = "8.11.3";
|
|
||||||
|
|
||||||
src = fetchurl {
|
|
||||||
url = "https://github.com/libvips/libvips/releases/download/v${version}/vips-${version}.tar.gz";
|
|
||||||
sha256 = "00fz7h7vb0qqsc9i2smp3aljwjyb5cin2fiqillv8vvx8wpis2lv";
|
|
||||||
};
|
|
||||||
|
|
||||||
propagatedBuildInputs = [ glib ];
|
|
||||||
buildInputs = [ expat libjpeg_turbo libexif librsvg libtiff libpng ];
|
|
||||||
nativeBuildInputs = [ pkg-config ];
|
|
||||||
}
|
|
85
pkgs/mattermost.nix
Normal file
85
pkgs/mattermost.nix
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
{ lib
|
||||||
|
, buildGoModule
|
||||||
|
, fetchFromGitHub
|
||||||
|
, nix-update-script
|
||||||
|
, fetchurl
|
||||||
|
, nixosTests
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildGoModule rec {
|
||||||
|
pname = "mattermost";
|
||||||
|
# ESR releases only.
|
||||||
|
# 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";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "mattermost";
|
||||||
|
repo = "mattermost";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-bLZFeG6kBVP0ws50wtBam/bO206sQnz6va8PATAoRAQ=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Needed because buildGoModule does not support go workspaces yet.
|
||||||
|
# We use go 1.22's workspace vendor command, which is not yet available
|
||||||
|
# in the default version of go used in nixpkgs, nor is it used by upstream:
|
||||||
|
# https://github.com/mattermost/mattermost/issues/26221#issuecomment-1945351597
|
||||||
|
overrideModAttrs = (_: {
|
||||||
|
buildPhase = ''
|
||||||
|
make setup-go-work
|
||||||
|
go work vendor -e
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
webapp = fetchurl {
|
||||||
|
url = "https://releases.mattermost.com/${version}/mattermost-${version}-linux-amd64.tar.gz";
|
||||||
|
hash = "sha256-jyaJUN8wpuBivKNdm7f1mYwygO8xC+Zxy0SdkDovdsA=";
|
||||||
|
};
|
||||||
|
|
||||||
|
vendorHash = "sha256-Gwv6clnq7ihoFC8ox8iEM5xp/us9jWUrcmqA9/XbxBE=";
|
||||||
|
|
||||||
|
modRoot = "./server";
|
||||||
|
preBuild = ''
|
||||||
|
make setup-go-work
|
||||||
|
'';
|
||||||
|
|
||||||
|
subPackages = [ "cmd/mattermost" ];
|
||||||
|
offlineCache = webapp;
|
||||||
|
|
||||||
|
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"
|
||||||
|
];
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
tar --strip 1 --directory $out -xf $webapp \
|
||||||
|
mattermost/{client,i18n,fonts,templates,config}
|
||||||
|
|
||||||
|
# For some reason a bunch of these files are executable
|
||||||
|
find $out/{client,i18n,fonts,templates,config} -type f -exec chmod -x {} \;
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
updateScript = nix-update-script {
|
||||||
|
extraArgs = [ "--version-regex" "^v(9\.11\.([0-9.]+))" ];
|
||||||
|
};
|
||||||
|
tests.mattermost = nixosTests.mattermost;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 ];
|
||||||
|
maintainers = with maintainers; [ ryantm numinit kranzes mgdelacroix ];
|
||||||
|
mainProgram = "mattermost";
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,49 +0,0 @@
|
||||||
{ stdenv, fetchurl, fetchFromGitHub, buildGoPackage, buildEnv, lib }:
|
|
||||||
|
|
||||||
let
|
|
||||||
sources = import ../../nix/sources.nix;
|
|
||||||
version = sources.mattermost-webapp.version;
|
|
||||||
|
|
||||||
mattermost-server = buildGoPackage rec {
|
|
||||||
pname = "mattermost-server";
|
|
||||||
inherit version;
|
|
||||||
|
|
||||||
src = sources.mattermost-server.outPath;
|
|
||||||
|
|
||||||
goPackagePath = "github.com/mattermost/mattermost-server";
|
|
||||||
|
|
||||||
ldflags = [
|
|
||||||
"-X ${goPackagePath}/model.BuildNumber=nixpkgs-${version}"
|
|
||||||
];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
mattermost-webapp = stdenv.mkDerivation {
|
|
||||||
pname = "mattermost-webapp";
|
|
||||||
inherit version;
|
|
||||||
|
|
||||||
src = sources.mattermost-webapp;
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out
|
|
||||||
cp -r client $out
|
|
||||||
cp -r i18n $out
|
|
||||||
cp -r fonts $out
|
|
||||||
cp -r templates $out
|
|
||||||
cp -r config $out
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
buildEnv {
|
|
||||||
name = "mattermost-${version}";
|
|
||||||
paths = [ mattermost-server mattermost-webapp ];
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description = "Open-source, self-hosted Slack-alternative";
|
|
||||||
homepage = "https://www.mattermost.org";
|
|
||||||
license = with licenses; [ agpl3 asl20 ];
|
|
||||||
maintainers = with maintainers; [ fpletz ryantm ];
|
|
||||||
platforms = platforms.unix;
|
|
||||||
};
|
|
||||||
}
|
|
33
pkgs/morph.nix
Normal file
33
pkgs/morph.nix
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{ 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"
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
16
pkgs/scripts/default.nix
Normal file
16
pkgs/scripts/default.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{ 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/*
|
||||||
|
'';
|
||||||
|
}
|
47
pkgs/scripts/uffd-sync-mattermost-groups.fish
Normal file
47
pkgs/scripts/uffd-sync-mattermost-groups.fish
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#!/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
|
121
pkgs/scripts/uffd-unused-accounts-notification.scm
Normal file
121
pkgs/scripts/uffd-unused-accounts-notification.scm
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
#!/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
|
||||||
|
"))
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
|
|
||||||
/* Hides extra fields on connect screen */
|
|
||||||
.connect-row:nth-of-type(4) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.connect-row:nth-of-type(2) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.connect-row:nth-of-type(5) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Hides side panel button */
|
|
||||||
.header > button:first-child {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hides channel options button (includes leave option) */
|
|
||||||
.header > button:nth-last-child(2) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
|
@ -3,14 +3,14 @@
|
||||||
python3Packages.buildPythonPackage rec {
|
python3Packages.buildPythonPackage rec {
|
||||||
pname = "uffd";
|
pname = "uffd";
|
||||||
version = "2.0.1";
|
version = "2.0.1";
|
||||||
|
PACKAGE_VERSION = version;
|
||||||
|
|
||||||
src = fetchzip {
|
src = fetchzip {
|
||||||
url =
|
url = "https://git.cccv.de/uffd/uffd/-/archive/v${version}/uffd-v${version}.tar.gz";
|
||||||
"https://git.cccv.de/uffd/uffd/-/archive/v${version}/uffd-v${version}.tar.gz";
|
|
||||||
hash = "sha256-KP4J1bw5u7MklaPu2SBFRNyGgkKOBOpft5MMH+em5M4=";
|
hash = "sha256-KP4J1bw5u7MklaPu2SBFRNyGgkKOBOpft5MMH+em5M4=";
|
||||||
};
|
};
|
||||||
|
|
||||||
patches = [ ./fix-setuppy.patch ./fix-userinfo.patch ];
|
patches = [ ./forgejo-magic.patch ./fix-setuppy.patch ./fix-userinfo.patch ];
|
||||||
|
|
||||||
propagatedBuildInputs = with python3Packages; [
|
propagatedBuildInputs = with python3Packages; [
|
||||||
flask
|
flask
|
||||||
|
|
32
pkgs/uffd/forgejo-magic.patch
Normal file
32
pkgs/uffd/forgejo-magic.patch
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
From e3c0995160a653ef6cd8784b255036585b273b82 Mon Sep 17 00:00:00 2001
|
||||||
|
From: stuebinm <stuebinm@disroot.org>
|
||||||
|
Date: Wed, 20 Jul 2022 18:02:15 +0200
|
||||||
|
Subject: [PATCH] magic gitea patch
|
||||||
|
|
||||||
|
---
|
||||||
|
uffd/oauth2/views.py | 9 +++++++++
|
||||||
|
1 file changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/uffd/oauth2/views.py b/uffd/oauth2/views.py
|
||||||
|
index d13fd42..94352be 100644
|
||||||
|
--- a/uffd/oauth2/views.py
|
||||||
|
+++ b/uffd/oauth2/views.py
|
||||||
|
@@ -230,6 +230,15 @@ def oauth_required(*scopes):
|
||||||
|
@oauth_required('profile')
|
||||||
|
def userinfo():
|
||||||
|
user = request.oauth.user
|
||||||
|
+ client = request.oauth.client_id
|
||||||
|
+ if client == "forgejo":
|
||||||
|
+ return jsonify(
|
||||||
|
+ id=user.unix_uid,
|
||||||
|
+ full_name=user.displayname,
|
||||||
|
+ login=user.loginname,
|
||||||
|
+ email=user.mail,
|
||||||
|
+ groups=[group.name for group in user.groups]
|
||||||
|
+ )
|
||||||
|
return jsonify(
|
||||||
|
id=user.unix_uid,
|
||||||
|
name=user.displayname,
|
||||||
|
--
|
||||||
|
2.36.0
|
||||||
|
|
105
secrets.yaml
Normal file
105
secrets.yaml
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
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]
|
||||||
|
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]
|
||||||
|
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]
|
||||||
|
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]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age1yql8qaf7upraqy4cq397tt4vgs046hq0v59qymla8t3x0ujqvu4sesgsvw
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHd0Rrem03aWMwUGgwMlM2
|
||||||
|
dmRJdVYrRVNBTXZrVk5CdEFYcDRyN3VlcUhvCmE5L0lpbzdxanNBWFU1dEprUC9Y
|
||||||
|
eUZqdHVmWks2V1g0SHZRN1BsSU96OU0KLS0tIGl1ZUg2aDNtREZWeUE5UXlPeHNG
|
||||||
|
STcwOFgwK1lpWjdyTkd3c0dBTlAyK28KAKL7rPPH0DNRgL3qqCelAoUPnOy8MydL
|
||||||
|
t2ft9ZmzkoiSdSt0Ad1U5IImQt9ZzhPtYYnYbiEVNcfuFCnGcqdoPw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1zgdegurzlr8cw9948wgf4q5qh3efltwhhzus5tt6az5xvvsux9us2v4tyd
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvT0M2SmdwNmNyWWZ1V2o5
|
||||||
|
OHZ4RDlIbTZONXc5Z0FPMm03V3UzVWhaRnhBCjU5dzZlbkZHRkdacG1nUng4S0p6
|
||||||
|
Q1I5Vjg0Vk5wRzNGZTNONXdCMnpUTEEKLS0tIFo5K0tGdDZpLzNPb0llb0dJdk9u
|
||||||
|
c3p5UVBjZWlNVkxFMlVaQ3VMVFdhZVUKxcIL/JMBEojPRlDLHUIuxKcMPMEEsTkS
|
||||||
|
0zLjYVZL7YDS0dKdaZjaExHKrRzRpsY0qpDBHyhcyzRae1sWA4e5Kw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age18wkr3kjalalzrq9l05q32gnlaqr7t6rqqzde307m83rs9fp4xcfsdtj9gt
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwUmFJc24xV2JGS3dzK25F
|
||||||
|
SVVXTjBaRUxJQ3hXZXlHYTRzaXZVNjVObEFZCmpPQUV1b0lySkUvcURObm1xNSt4
|
||||||
|
WVQrbnlvZkQrbzloQzc4NlJCWnlPeGMKLS0tIDBVa2lpUmcrWURwWW8rc3ZmUUU1
|
||||||
|
U0pGQjJackNhT0d4L2ZIOTdTUjBwcjQKCRWcpevMcv2HsWC4jyc/GzxxjkTEm+UF
|
||||||
|
4QdXjJAHh2QLxV9aXF/k/KogebCFkBTirmyOhRKtBRkt87d1D9FKUA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1q88az2y5hnx8naqsvrurllqj6y5gtehrpa9emmrxy5ghwsr7pvnqf7tfpx
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzWnZFOVFuTnFTMmpVMDFU
|
||||||
|
dkw4UFlUenZzNkRuNy90NWk4aVNEd2J2Ukc0Cm9mM2dpZEJpVVY4TVB0WUxmTjEw
|
||||||
|
VFJ3aHB6ZFh5YWptYTZ5cXVjTUNBVkEKLS0tIEx0dVRPVVVacHFCMDhFNE1NMnZy
|
||||||
|
cUxicklTUGtPeTlnSFV1TUZqR1VmRnMKtJ+Q80SgqW/Jad8aF7pViGANHCsTMNEM
|
||||||
|
7TbhITW+zWIhnviVS0xOqXrvQs4iBbMfiNnQbFS7tEX08AT2oAg6cw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age18nkru4pwvvapdw76nauv2xdtlj8cvyv3ugahe9kcxtvtsptx2eyqw7p0m6
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzT3ZNenJKWTZ3NjdqNWpR
|
||||||
|
Zk9Ya3lsT1Jqd0RIWm8xdm16UjFzcFV1aGlBCkRuMllGSFVIUCs4UEJEQVVGQUxK
|
||||||
|
L1FGNGJwYkFIdU4wOXdFQWt6RSsyR28KLS0tIEgya2xORURncHlvNHJNTnIrb2da
|
||||||
|
emRETSt4WGFYeXR5UmNSajNpUStKUzAKxgDME0M1ewNE/BrL/wFjF4Yj7GupjRPF
|
||||||
|
Fuxae5U3phphzOkflQtreM1ScbUGge8WeiSVWY3Pl1azsYo/yqg8Ew==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1fm3e99tdyrsvztdchxxllt9nat35xzvd68d09y8scu9jfc7kvvuquhr49c
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwVEdpZmdSdnBaYnV2RWhT
|
||||||
|
MmMxQW9PUUJ4enRqNjFIZ25kUEkvdHBpOXdRCmJkSTJyWklhTU5neUlybzR1Nkp6
|
||||||
|
YlVHczNwRzl0d0hGalpvTFdEUlV3UHMKLS0tIGhQZXEvd2F0aTlna0FNL2wyaEdC
|
||||||
|
U1oyWXcza08rTG1DS0dUYkZOVWZ4L1kKgpt6jG0lNBMdk/isa1A/tfKYjprnnIo5
|
||||||
|
pi4t1c7CktFBkhMlOv6VPJCsQlP0YtZUh/uut70Kecv48+YH5gC/8A==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age16fk0m26n0fr2vmuxm2mjsmrawclde2mlyj6wg3ee9jvzmu5ru3ustgs5jq
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHRzc5WHAzcWhGSU1kdE1E
|
||||||
|
Z1B0aFhqYUQzQ2ptK09YMm9odWh3U0w3bmtvCi9IcWFhOFhvYU5ISlVpTURMY2hX
|
||||||
|
RG5mL1gvNkZ1SDdMZTR4QWxtRG1VUlkKLS0tIFl5UUdIR0JOSmF4OWx1OHBuaFJj
|
||||||
|
N0FDY2xYRlpmaTgxWURGZWxWWktPV00KAHNeeqhzql4LInlJoD9u7ptFWZBgktvp
|
||||||
|
tju4cZ/78VgdZIfEfnlzw8lsqpRx1z5Fw8K4CcXRJJLRVfHuj2CHTA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1l694a4xht7r0eza9r2vjncupmp6cxyk3k9x2ljwynnur4m2lc5jqmy3jut
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBscDFuL0ZsdWxoUFJBd2xr
|
||||||
|
ZXh3K0lSUnFmTVFTVHB5bGR2TC9lREdUczJrCnFSaGoyUnJjbXJ5d1lQd0RUcFJt
|
||||||
|
REkvdEY2NzcveHpQRWZ1STBSemx0SkkKLS0tIGtyN0svS3lYcmxUbVJiU1RaK21l
|
||||||
|
Ukh0VkVaeVBoOXQ1cmZ6WHNkYjQvTmsKG4914d+pSt1seoKiejoCvATOTaVFN4ih
|
||||||
|
Y74W+WXyaKoQP3Q9QrbSURpE+ICfblxHmkbsPB/agNzZVWrfyBaX1A==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1m374x78q9eykua32ldrqxh8rh36kz6jyre69a263krf28hcycsqsrmshl0
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqR01XampvRE92VnZ3OTZs
|
||||||
|
YmJYaEN2eVJOVWt1OHE1bTdua1ArSC9oVm1ZClBsVFBSWWtLRUoyNDF0NlUwaUpo
|
||||||
|
b0kyazNwRUFhS0RYd1pGNHNENWxQb28KLS0tIDhzdHhRN1FYczZBMksrM09UWUtJ
|
||||||
|
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]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.8.1
|
|
@ -1,64 +0,0 @@
|
||||||
{config, pkgs, lib, ...}:
|
|
||||||
|
|
||||||
{
|
|
||||||
services.gitlab-runner = {
|
|
||||||
enable = true;
|
|
||||||
concurrent = 4;
|
|
||||||
services = {
|
|
||||||
infra4future = {
|
|
||||||
buildsDir = "/persist/var/lib/gitlab-runner/builds";
|
|
||||||
dockerImage = "nixos/nix";
|
|
||||||
executor = "docker";
|
|
||||||
registrationConfigFile = "/persist/var/lib/gitlab-runner/gitlab-runner.env";
|
|
||||||
};
|
|
||||||
nix = {
|
|
||||||
limit = 1; # don't run multiple jobs
|
|
||||||
registrationConfigFile = "/persist/var/lib/gitlab-runner/gitlab-runner.env";
|
|
||||||
dockerImage = "alpine";
|
|
||||||
dockerVolumes = [
|
|
||||||
"/nix/store:/nix/store:ro"
|
|
||||||
"/nix/var/nix/db:/nix/var/nix/db:ro"
|
|
||||||
"/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket:ro"
|
|
||||||
];
|
|
||||||
dockerDisableCache = true;
|
|
||||||
preBuildScript = pkgs.writeScript "setup-container" ''
|
|
||||||
mkdir -p -m 0755 /nix/var/log/nix/drvs
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/gcroots
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/profiles
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/temproots
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/userpool
|
|
||||||
mkdir -p -m 1777 /nix/var/nix/gcroots/per-user
|
|
||||||
mkdir -p -m 1777 /nix/var/nix/profiles/per-user
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/profiles/per-user/root
|
|
||||||
mkdir -p -m 0700 "$HOME/.nix-defexpr"
|
|
||||||
. ${pkgs.nix}/etc/profile.d/nix.sh
|
|
||||||
${pkgs.nix}/bin/nix-env -i ${lib.concatStringsSep " " (with pkgs; [ nix cacert git openssh ])}
|
|
||||||
${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixpkgs-unstable
|
|
||||||
${pkgs.nix}/bin/nix-channel --update nixpkgs
|
|
||||||
'';
|
|
||||||
environmentVariables = {
|
|
||||||
ENV = "/etc/profile";
|
|
||||||
USER = "root";
|
|
||||||
NIX_REMOTE = "daemon";
|
|
||||||
PATH = "/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin";
|
|
||||||
NIX_SSL_CERT_FILE = "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt";
|
|
||||||
};
|
|
||||||
tagList = [ "nix" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.gitlab-runner.serviceConfig = {
|
|
||||||
DynamicUser = lib.mkForce false;
|
|
||||||
User = "gitlab-runner";
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.gitlab-runner = {
|
|
||||||
home = "/persist/var/lib/gitlab-runner";
|
|
||||||
extraGroups = [ "docker" ];
|
|
||||||
isSystemUser = true;
|
|
||||||
group = "nogroup";
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation.docker.storageDriver = "zfs";
|
|
||||||
}
|
|
|
@ -1,165 +0,0 @@
|
||||||
{config, pkgs, lib, profiles, modules, evalConfig, sources, ...}:
|
|
||||||
|
|
||||||
{
|
|
||||||
containers.gitlab = {
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.7";
|
|
||||||
|
|
||||||
bindMounts = {
|
|
||||||
"/persist" = {
|
|
||||||
hostPath = "/persist/containers/gitlab";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
../modules/mattermost.nix
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.gitlab = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
databaseCreateLocally = true;
|
|
||||||
|
|
||||||
host = "gitlab.infra4future.de";
|
|
||||||
https = true;
|
|
||||||
port = 443;
|
|
||||||
|
|
||||||
statePath = "/persist/gitlab";
|
|
||||||
user = "git";
|
|
||||||
databaseUsername = "git";
|
|
||||||
|
|
||||||
initialRootPasswordFile = "/persist/secrets/gitlab-root";
|
|
||||||
secrets.secretFile = "/persist/secrets/gitlab-secret";
|
|
||||||
secrets.dbFile = "/persist/secrets/gitlab-db";
|
|
||||||
secrets.otpFile = "/persist/secrets/gitlab-otp";
|
|
||||||
secrets.jwsFile = "/persist/secrets/gitlab-jws";
|
|
||||||
|
|
||||||
smtp = {
|
|
||||||
enable = true;
|
|
||||||
address = "mail.hacc.space";
|
|
||||||
port = 587;
|
|
||||||
authentication = "plain";
|
|
||||||
domain = "gitlab.infra4future.de";
|
|
||||||
enableStartTLSAuto = true;
|
|
||||||
username = "noreply@infra4future.de";
|
|
||||||
passwordFile = "/persist/secrets/noreply-pass";
|
|
||||||
};
|
|
||||||
|
|
||||||
pagesExtraArgs = [ "-listen-proxy" "0.0.0.0:8090" ];
|
|
||||||
extraConfig = {
|
|
||||||
pages = {
|
|
||||||
enabled = true;
|
|
||||||
host = "4future.dev";
|
|
||||||
port = 443;
|
|
||||||
https = true;
|
|
||||||
};
|
|
||||||
omniauth = {
|
|
||||||
enabled = true;
|
|
||||||
auto_sign_in_with_provider = "oauth2_generic";
|
|
||||||
allow_single_sign_on = ["oauth2_generic"];
|
|
||||||
block_auto_created_users = false;
|
|
||||||
providers = [
|
|
||||||
{
|
|
||||||
name = "oauth2_generic";
|
|
||||||
label = "infra4future Login";
|
|
||||||
app_id = "gitlab";
|
|
||||||
app_secret = { _secret = "/persist/secrets/oidc-clientsecret"; };
|
|
||||||
args = {
|
|
||||||
client_options = {
|
|
||||||
site = "https://login.infra4future.de";
|
|
||||||
user_info_url = "/oauth2/userinfo";
|
|
||||||
authorize_url = "/oauth2/authorize";
|
|
||||||
token_url = "/oauth2/token";
|
|
||||||
};
|
|
||||||
strategy_class ="OmniAuth::Strategies::OAuth2Generic";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.redis.enable = true;
|
|
||||||
services.postgresql.package = pkgs.postgresql_13;
|
|
||||||
|
|
||||||
services.nginx = {
|
|
||||||
enable = true;
|
|
||||||
recommendedGzipSettings = true;
|
|
||||||
recommendedOptimisation = true;
|
|
||||||
recommendedTlsSettings = true;
|
|
||||||
virtualHosts."gitlab.infra4future.de" = {
|
|
||||||
default = true;
|
|
||||||
locations."/".proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket";
|
|
||||||
locations."/".extraConfig = ''
|
|
||||||
proxy_redirect off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.openssh.enable = true;
|
|
||||||
services.openssh.passwordAuthentication = false;
|
|
||||||
|
|
||||||
users.users.git = {
|
|
||||||
isSystemUser = true;
|
|
||||||
group = "gitlab";
|
|
||||||
home = "/persist/gitlab/home";
|
|
||||||
uid = 165;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.coredns = {
|
|
||||||
enable = true;
|
|
||||||
config = ''
|
|
||||||
.:53 {
|
|
||||||
forward . 1.1.1.1
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
})).config.system.build.toplevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
hexchen.nftables.nat.forwardPorts = [{
|
|
||||||
ports = [ 22 ];
|
|
||||||
destination = "${config.containers.gitlab.localAddress}:22";
|
|
||||||
proto = "tcp";
|
|
||||||
}];
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."gitlab.infra4future.de" = {
|
|
||||||
locations."/".proxyPass = "http://${config.containers.gitlab.localAddress}:80";
|
|
||||||
locations."/".extraConfig = ''
|
|
||||||
proxy_set_header X-Nginx-Proxy true;
|
|
||||||
proxy_redirect off;
|
|
||||||
'';
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."4future.dev" = {
|
|
||||||
locations."/".proxyPass = "http://${config.containers.gitlab.localAddress}:8090";
|
|
||||||
serverName = "~^((.*)\.)?4future\.dev$";
|
|
||||||
useACMEHost = "4future.dev";
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
security.acme.certs."4future.dev" = {
|
|
||||||
dnsProvider = "cloudflare";
|
|
||||||
credentialsFile = "/var/lib/acme/cloudflare.pass";
|
|
||||||
extraDomainNames = [ "*.4future.dev" ];
|
|
||||||
group = config.services.nginx.group;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
{ config, lib, pkgs, profiles, modules, evalConfig, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
containers.lantifa = {
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.8";
|
|
||||||
bindMounts = {
|
|
||||||
"/persist" = {
|
|
||||||
hostPath = "/persist/containers/lantifa";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
hexchen.bindmounts."/var/lib/mediawiki" = "/persist/var/lib/mediawiki";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.hosts."127.0.0.1" = [ "wiki.lantifa.org" ];
|
|
||||||
users.users.mediawiki.extraGroups = [ "keys" ];
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.mediawiki = {
|
|
||||||
enable = true;
|
|
||||||
name = "LANtifa";
|
|
||||||
database.createLocally = true;
|
|
||||||
passwordFile = "/var/lib/mediawiki/mediawiki-password";
|
|
||||||
extraConfig = let
|
|
||||||
wikidb = pkgs.fetchzip {
|
|
||||||
url = "https://www.kennel17.co.uk/uploads/testwiki/e/e9/WikiDB.zip";
|
|
||||||
sha256 = "0pns9fk1ws54m7rgbfsrxqh6ayab16mmnvzba8m4malljgrbil8b";
|
|
||||||
};
|
|
||||||
in ''
|
|
||||||
// Configure short URLs
|
|
||||||
$wgScriptPath = "";
|
|
||||||
$wgArticlePath = "/wiki/$1";
|
|
||||||
$wgUsePathInfo = true;
|
|
||||||
|
|
||||||
require_once('${wikidb}/WikiDB.php');
|
|
||||||
$wgExtraNamespaces = array( 100 => "Table", 101 => "Table_Talk",);
|
|
||||||
$wgWikiDBNamespaces = 100;
|
|
||||||
$wgGroupPermissions['user']['writeapi'] = true;
|
|
||||||
$wgDefaultUserOptions['visualeditor-enable'] = 1;
|
|
||||||
$wgLogo = "images/c/c5/LantifaLogoFem0.3.png";
|
|
||||||
|
|
||||||
// PageForms config
|
|
||||||
$wgGroupPermissions['*']['viewedittab'] = false;
|
|
||||||
$wgGroupPermissions['user']['viewedittab'] = true;
|
|
||||||
|
|
||||||
// Moderation setting
|
|
||||||
$wgModerationNotificationEnable = true;
|
|
||||||
$wgModerationEmail = "wiki_mod@lantifa.org";
|
|
||||||
$wgLogRestrictions["newusers"] = 'moderation';
|
|
||||||
|
|
||||||
// intersection / DynamicPageList config
|
|
||||||
$wgDLPMaxCacheTime = 5 * 60;
|
|
||||||
'';
|
|
||||||
|
|
||||||
extensions = {
|
|
||||||
TemplateData = null;
|
|
||||||
VisualEditor = null;
|
|
||||||
InputBox = null;
|
|
||||||
Moderation = pkgs.fetchzip {
|
|
||||||
url = "https://github.com/edwardspec/mediawiki-moderation/archive/v1.4.20.tar.gz";
|
|
||||||
sha256 = "1k0z44jfqsxzwy6jjz3yfibiq8wi845d5iwwh8j3yijn2854fj0i";
|
|
||||||
};
|
|
||||||
intersection = pkgs.fetchzip { # This is the DynamicPageList extension
|
|
||||||
url = "https://extdist.wmflabs.org/dist/extensions/intersection-REL1_36-4a70dbd.tar.gz";
|
|
||||||
sha256 = "0s70fqkf5ylpsxy1h3hljic8708j6099mz12b6k03hgwc582yywi";
|
|
||||||
};
|
|
||||||
PageForms = pkgs.fetchzip {
|
|
||||||
url = "https://github.com/wikimedia/mediawiki-extensions-PageForms/archive/5.0.1.zip";
|
|
||||||
sha256 = "172m7p941fbkl29h5bhanx3dn42jfmzgyvgmgm2lgdbmkawwly96";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualHost = {
|
|
||||||
hostName = "wiki.lantifa.org";
|
|
||||||
listen = [ { port = 80; } ];
|
|
||||||
adminAddr = "admin@hacc.space";
|
|
||||||
extraConfig = ''
|
|
||||||
RewriteEngine On
|
|
||||||
RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/index.php [L]
|
|
||||||
RewriteRule ^/*$ %{DOCUMENT_ROOT}/index.php [L]
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.mysql.dataDir = "/persist/mysql";
|
|
||||||
services.mysqlBackup = {
|
|
||||||
enable = true;
|
|
||||||
databases = [ "mediawiki" ];
|
|
||||||
calendar = "*-*-* 23:45:00";
|
|
||||||
};
|
|
||||||
})).config.system.build.toplevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."wiki.lantifa.org" = {
|
|
||||||
locations."/".proxyPass = "http://" + config.containers.lantifa.localAddress + "";
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,169 +0,0 @@
|
||||||
{ config, pkgs, lib, sources, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
sources.nixos-mailserver.outPath
|
|
||||||
];
|
|
||||||
|
|
||||||
# reduce log spam
|
|
||||||
systemd.services.rspamd.serviceConfig.LogLevelMax = 3; # this is set to error because rspamd regularly complains about not enough learns
|
|
||||||
systemd.services.postfix.serviceConfig.LogLevelMax = 5; # = notice
|
|
||||||
systemd.services.dovecot2.serviceConfig.LogLevelMax = 5; # = notice
|
|
||||||
|
|
||||||
# stop postfix from dying if rspamd hiccups
|
|
||||||
systemd.services.postfix.unitConfig = {
|
|
||||||
Requires = lib.mkForce "dovecot2.service opendkim.service";
|
|
||||||
};
|
|
||||||
|
|
||||||
mailserver = {
|
|
||||||
mailDirectory = "/persist/mail";
|
|
||||||
enable = true;
|
|
||||||
fqdn = "mail.hacc.space";
|
|
||||||
domains = [ "hacc.space" "muc.hacc.space" "hacc.earth" "4future.dev" "4futu.re" "infra4future.de" "discuss.infra4future.de" ];
|
|
||||||
|
|
||||||
loginAccounts = {
|
|
||||||
"hexchen@hacc.space".hashedPassword = "$6$x9skYtRp4dgxC$1y8gPC2BuVqG3kJVSMGgzZv0Bg1T9qxcnBWLIDbANy1d//SQ23Y7s3IMYcEPd1/l/MYWD9Y/Qse6HbT5w5Xwq/";
|
|
||||||
"hexchen@hacc.space".aliases = [ "postmaster@hacc.space" "abuse@hacc.space" "hexchen@infra4future.de" ];
|
|
||||||
|
|
||||||
"octycs@hacc.space".hashedPassword = "$6$KceTivtJ$58jxhYF6ULfivNsb3Z0J7PnGea0Hs2wTWh3c9FrKRIAmuOD96u2IDgZRCn6P5NrXA0BL.n6HC2RS3r.4JnOmg.";
|
|
||||||
"octycs@hacc.space".aliases = [ "markus@hacc.space" ];
|
|
||||||
|
|
||||||
"raphael@hacc.space".hashedPassword = "$6$QveHpwMcp9mkFVAU$EFuahOrJIxPg.c.WGFHtrP3.onwJYwvP7fiBHHGb9jhosewZ2tEUP.2D3uyDLhd9Cfny6Yp4jDk/Hkjk7/ME1/";
|
|
||||||
|
|
||||||
"schweby@hacc.space".hashedPassword = "$6$BpYhwcZNrkLhVqK$6FMqA/vUkdV4GBlHLSqS5DRCb/CaLDNeIsBcZ8G30heytS/tJj2Ag7b1ovSltTA4PUfhee3pJrz1BkwkA93vN1";
|
|
||||||
|
|
||||||
"zauberberg@hacc.space".hashedPassword = "$6$ISAaU8X6D$oGKe9WXDWrRpGzHUTdxrxdtg9zuGOlBMuDc82IZhegpsv1bqd550FhZZrI40IjZTA5Hy2MZ8j/0efpnQ4fOQH0";
|
|
||||||
"zauberberg@hacc.space".aliases = [ "lukas@hacc.space" ];
|
|
||||||
|
|
||||||
"stuebinm@hacc.space".hashedPassword = "$6$mjrMQG5smqLRlm$WzmbiZnGlEXGT7hj/n2qz0nvVzGyZfMToCyLRi0wErfVEHI7y7jtWoHqIWnpcHAM29UocsIFFsUCb3XqQCwwB.";
|
|
||||||
|
|
||||||
"lenny@hacc.space".hashedPassword = "$6$EZpv9XImv5F3$p2NSoo5gLxh6NnB3/C6wF8knRTuMHqDXYF3BEscaQuk7qok2Z13xKT/6mFvvSKKBnFCuYptgnfGswmoqIzm/1/";
|
|
||||||
"lenny@hacc.space".aliases = [ "rinderhacc@hacc.space" ];
|
|
||||||
|
|
||||||
"finance@muc.hacc.space".hashedPassword = "$6$R3GRmvXwqnMM6q.R$Y9mrUAmMnCScsM6pKjxo2a2XPM7lHrV8FIgK0PzhYvZbxWczo7.O4dk1onYeV1mRx/nXZfkZNjqNCruCn0S2m.";
|
|
||||||
|
|
||||||
# service accounts
|
|
||||||
"noreply@hacc.space".hashedPassword = "$6$YsqMoItITZUzI5wo$5Lejf8XBHRx4LW4VuZ9wJCiBbT4kOV/EZaCdWQ07eVIrkRTZwXWZ5zfsh.olXEFwvpNWN.DBnU.dQc.cC0/ra/";
|
|
||||||
"newsletter@hacc.space".hashedPassword = "$6$f0xKnQxBInd$zbVIi1lTKWauqW.c8sMNLHNwzn81oQrVOiIfJwPa98n9xWz/NkjuWLYuFpK.MSZwNwP7Yv/a/qaOb9v8qv/.N1";
|
|
||||||
"gitlab@infra4future.de".hashedPassword = "$6$8vvkYuxv$9xV5WktsqfgM3cWSxonjtaohm7oqvDC5qsgJCJBATwesjTRxd/QTLa7t7teK8Nzyl.Py26xz.NvYowCZQ4aBE1";
|
|
||||||
"noreply@infra4future.de".hashedPassword = "$6$uaD8bRcT1$gFqhFyu5RUsyUUOG5b.kN.JAJ1rVHvaYhpeRHoMvrERAMgBu1FHu2oDnjTsy.5NKoLc5xpI5uv4Gpy4YbmDmV.";
|
|
||||||
"discuss@infra4future.de".hashedPassword = "$6$8x8/OlMFjq1$S54jdBh7WjrdC6UtbYAHHzMJak7Ai/CjwmWBBbqh7yRHuZt.mfZrsfBNiL3JKBHE7seQ7JYRU99lJKCU6Aujg/";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraVirtualAliases = {
|
|
||||||
# address = forward address;
|
|
||||||
|
|
||||||
# -- International --
|
|
||||||
# info/contact: main entrypoint, anyone can read or reply to this.
|
|
||||||
"info@hacc.space" = [
|
|
||||||
"hexchen@hacc.space"
|
|
||||||
"octycs@hacc.space"
|
|
||||||
"raphael@hacc.space"
|
|
||||||
"schweby@hacc.space"
|
|
||||||
"zauberberg@hacc.space"
|
|
||||||
"stuebinm@hacc.space"
|
|
||||||
"lenny@hacc.space"
|
|
||||||
];
|
|
||||||
# admin: current people with access to the mail server and knowledge on how to use it
|
|
||||||
"admin@hacc.space" = [
|
|
||||||
"hexchen@hacc.space"
|
|
||||||
"schweby@hacc.space"
|
|
||||||
"zauberberg@hacc.space"
|
|
||||||
];
|
|
||||||
# voc: hacc video operation center, various streaming-related things
|
|
||||||
"voc@hacc.space" = [
|
|
||||||
"hexchen@hacc.space"
|
|
||||||
"schweby@hacc.space"
|
|
||||||
"octycs@hacc.space"
|
|
||||||
"stuebinm@hacc.space"
|
|
||||||
"zauberberg@hacc.space"
|
|
||||||
"lenny@hacc.space"
|
|
||||||
"raphael@hacc.space"
|
|
||||||
];
|
|
||||||
|
|
||||||
# -- Regional: Germany --
|
|
||||||
# board of hacc e.V.
|
|
||||||
"vorstand@hacc.space" = [
|
|
||||||
"raphael@hacc.space"
|
|
||||||
"schweby@hacc.space"
|
|
||||||
"zauberberg@hacc.space"
|
|
||||||
];
|
|
||||||
# members of hacc e.V.
|
|
||||||
"mitglieder@hacc.space" = [
|
|
||||||
"hexchen@hacc.space"
|
|
||||||
"raphael@hacc.space"
|
|
||||||
"schweby@hacc.space"
|
|
||||||
"zauberberg@hacc.space"
|
|
||||||
"lenny@hacc.space"
|
|
||||||
"octycs@hacc.space"
|
|
||||||
"stuebinm@hacc.space"
|
|
||||||
];
|
|
||||||
|
|
||||||
# -- Regional: Munich --
|
|
||||||
"muc@hacc.space" = [
|
|
||||||
"hexchen@hacc.space"
|
|
||||||
"octycs@hacc.space"
|
|
||||||
"raphael@hacc.space"
|
|
||||||
"schweby@hacc.space"
|
|
||||||
"zauberberg@hacc.space"
|
|
||||||
"stuebinm@hacc.space"
|
|
||||||
"lenny@hacc.space"
|
|
||||||
];
|
|
||||||
|
|
||||||
# -- c3 world operation centre --
|
|
||||||
"world@muc.hacc.space" = [
|
|
||||||
"hexchen@hacc.space"
|
|
||||||
"stuebinm@hacc.space"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Use Let's Encrypt certificates. Note that this needs to set up a stripped
|
|
||||||
# down nginx and opens port 80.
|
|
||||||
certificateScheme = 3;
|
|
||||||
|
|
||||||
# Enable IMAP and POP3
|
|
||||||
enableImap = true;
|
|
||||||
enablePop3 = true;
|
|
||||||
enableImapSsl = true;
|
|
||||||
enablePop3Ssl = true;
|
|
||||||
|
|
||||||
# Enable the ManageSieve protocol
|
|
||||||
enableManageSieve = true;
|
|
||||||
|
|
||||||
# whether to scan inbound emails for viruses (note that this requires at least
|
|
||||||
# 1 Gb RAM for the server. Without virus scanning 256 MB RAM should be plenty)
|
|
||||||
virusScanning = false;
|
|
||||||
};
|
|
||||||
services.postfix.submissionOptions.smtpd_sender_restrictions = lib.mkForce "reject_non_fqdn_sender,reject_unknown_sender_domain,permit";
|
|
||||||
services.postfix.submissionsOptions.smtpd_sender_restrictions = lib.mkForce "reject_non_fqdn_sender,reject_unknown_sender_domain,permit";
|
|
||||||
services.postfix.virtual = ''
|
|
||||||
@4future.dev @hacc.space
|
|
||||||
@4futu.re @hacc.space
|
|
||||||
@hacc.earth @hacc.space
|
|
||||||
@discuss.infra4future.de discuss@infra4future.de
|
|
||||||
admin@infra4future.de admin@hacc.space
|
|
||||||
noreply@infra4future.de admin@hacc.space
|
|
||||||
lukas@infra4future.de zauberberg@hacc.space
|
|
||||||
info@infra4future.de admin@hacc.space
|
|
||||||
postmaster@infra4future.de admin@hacc.space
|
|
||||||
voc@infra4future.de voc@hacc.space
|
|
||||||
haccvoc@infra4future.de voc@hacc.space
|
|
||||||
contact@hacc.space info@hacc.space
|
|
||||||
himmel@hacc.space admin@hacc.space
|
|
||||||
divoc-patches@muc.hacc.space world@muc.hacc.space
|
|
||||||
'';
|
|
||||||
|
|
||||||
systemd.services.alps = {
|
|
||||||
enable = true;
|
|
||||||
script = "${pkgs.alps}/bin/alps -theme alps imaps://mail.hacc.space:993 smtps://mail.hacc.space:465";
|
|
||||||
serviceConfig.WorkingDirectory = "${pkgs.alps}/share/alps";
|
|
||||||
serviceConfig.Restart = "always";
|
|
||||||
requiredBy = [ "multi-user.target" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."mail.hacc.space" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/".proxyPass = "http://[::1]:1323";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,144 +0,0 @@
|
||||||
{ config, lib, pkgs, profiles, modules, evalConfig, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
containers.nextcloud = {
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.2";
|
|
||||||
bindMounts = {
|
|
||||||
"/persist" = {
|
|
||||||
hostPath = "/persist/containers/nextcloud";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
../../modules/nextcloud.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.htop ];
|
|
||||||
|
|
||||||
services.nextcloud-patched = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
# must be set manually; may not be incremented by more than one at
|
|
||||||
# a time, otherwise nextcloud WILL break
|
|
||||||
package = pkgs.nextcloud24;
|
|
||||||
|
|
||||||
home = "/persist/nextcloud";
|
|
||||||
https = true;
|
|
||||||
|
|
||||||
hostName = "cloud.infra4future.de";
|
|
||||||
config = {
|
|
||||||
dbtype = "pgsql";
|
|
||||||
dbuser = "nextcloud";
|
|
||||||
dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
|
|
||||||
dbname = "nextcloud";
|
|
||||||
adminpassFile = "/persist/nextcloud/config/admin_pw";
|
|
||||||
adminuser = "root";
|
|
||||||
defaultapp = "apporder";
|
|
||||||
};
|
|
||||||
|
|
||||||
caching.redis = true;
|
|
||||||
|
|
||||||
# multiple pools may be doable using services.phpfpm.pools,
|
|
||||||
# but i have not tried this yet. The nextcloud module defines a
|
|
||||||
# pool "nextcloud"
|
|
||||||
poolSettings = {
|
|
||||||
pm = "dynamic";
|
|
||||||
"pm.max_children" = "32";
|
|
||||||
"pm.max_requests" = "500";
|
|
||||||
"pm.max_spare_servers" = "4";
|
|
||||||
"pm.min_spare_servers" = "2";
|
|
||||||
"pm.start_servers" = "2";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraOptions = {
|
|
||||||
instanceid = "ocxlphb7fbju";
|
|
||||||
redis = {
|
|
||||||
host = "/run/redis/redis.sock";
|
|
||||||
port = 0;
|
|
||||||
dbindex = 0;
|
|
||||||
password = "secret";
|
|
||||||
timeout = 1.5;
|
|
||||||
};
|
|
||||||
datadirectory = "/persist/data/ncdata";
|
|
||||||
mail_smtpmode = "smtp";
|
|
||||||
mail_smtpsecure = "ssl";
|
|
||||||
mail_sendmailmode = "smtp";
|
|
||||||
mail_from_address = "noreply";
|
|
||||||
mail_domain = "infra4future.de";
|
|
||||||
mail_smtpauthtype = "PLAIN";
|
|
||||||
mail_smtpauth = 1;
|
|
||||||
mail_smtphost = "mail.hacc.space";
|
|
||||||
mail_smtpport = 465;
|
|
||||||
mail_smtpname = "noreply@infra4future.de";
|
|
||||||
loglevel = 0;
|
|
||||||
"overwrite.cli.url" = "https://cloud.infra4future.de";
|
|
||||||
};
|
|
||||||
|
|
||||||
# passwordsalt, secret, and mail_smtppassword go in here
|
|
||||||
secretFile = "/persist/secrets.json";
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
services.redis = {
|
|
||||||
enable = true;
|
|
||||||
unixSocket = "/var/run/redis/redis.sock";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.postgresql = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.postgresql_11;
|
|
||||||
ensureDatabases = [ "nextcloud" ];
|
|
||||||
ensureUsers = [
|
|
||||||
{ # by default, postgres has unix sockets enabled, and allows a
|
|
||||||
# system user `nextcloud` to log in without other authentication
|
|
||||||
name = "nextcloud";
|
|
||||||
ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# ensure that postgres is running *before* running the setup
|
|
||||||
systemd.services."nextcloud-setup" = {
|
|
||||||
requires = ["postgresql.service"];
|
|
||||||
after = ["postgresql.service"];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.coredns = {
|
|
||||||
enable = true;
|
|
||||||
config = ''
|
|
||||||
.:53 {
|
|
||||||
forward . 1.1.1.1
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
})).config.system.build.toplevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."cloud.infra4future.de" = {
|
|
||||||
locations."/".proxyPass = "http://${config.containers.nextcloud.localAddress}:80";
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_buffering off;
|
|
||||||
client_max_body_size 0;
|
|
||||||
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{ config, pkgs, ... }:
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
hacc.websites = {
|
|
||||||
enable = true;
|
|
||||||
directory = ../websites;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
{
|
|
||||||
services.syncthing = {
|
|
||||||
enable = true;
|
|
||||||
relay.enable = false;
|
|
||||||
openDefaultPorts = true;
|
|
||||||
configDir = "/persist/var/lib/syncthing/";
|
|
||||||
dataDir = "/persist/data/syncthing/";
|
|
||||||
devices = {
|
|
||||||
schweby = {
|
|
||||||
addresses = []; # empty = dynamic
|
|
||||||
id = "YF7DNNS-B63GERK-YFQ7G7Q-2DG7557-VIWFOTK-R3JOS63-T76POBQ-F6MO6AH";
|
|
||||||
};
|
|
||||||
raphael-laptop = {
|
|
||||||
addresses = []; # empty = dynamic
|
|
||||||
id = "72B3T74-NOMJV3X-EVJXTJF-5GGAEZB-ZDKBHXQ-VQNRYEU-YCPA2JP-L6NGAAG";
|
|
||||||
};
|
|
||||||
# zauberberg
|
|
||||||
conway = {
|
|
||||||
addresses = []; # empty = dynamic
|
|
||||||
id = "HV7IU2N-Q4W3A7F-BSASR43-OB575SM-47FY2UW-7N5GMFM-PX3LWRN-HXBXMQF";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
folders = {
|
|
||||||
"/persist/data/syncthing/hacc/" = {
|
|
||||||
id = "qt2ly-xvvvs";
|
|
||||||
devices = [ "schweby" "conway" "raphael-laptop"];
|
|
||||||
type = "receiveonly";
|
|
||||||
versioning = {
|
|
||||||
type = "simple";
|
|
||||||
params.keep = "10";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"/persist/data/syncthing/hacc_eV_vorstand/" = {
|
|
||||||
id = "twwt7-fxrsr";
|
|
||||||
devices = [ "schweby" "conway" "raphael-laptop"];
|
|
||||||
# type = "receiveencrypted"; # no yet implemented
|
|
||||||
};
|
|
||||||
};
|
|
||||||
overrideFolders = false; # enables workaround for recieveencrypted
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
{ config, lib, pkgs, evalConfig, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
# necessary since overlays won't propagate into the
|
|
||||||
# container's config
|
|
||||||
thelounge = pkgs.thelounge-hacked;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
containers.thelounge = {
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.4";
|
|
||||||
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.thelounge = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
extraConfig = {
|
|
||||||
public = true;
|
|
||||||
# respect X-Forwarded-For
|
|
||||||
reverseProxy = true;
|
|
||||||
defaults = {
|
|
||||||
name = "libera chat";
|
|
||||||
host = "irc.eu.libera.chat";
|
|
||||||
port = 6697;
|
|
||||||
# encrypt things!
|
|
||||||
tls = true;
|
|
||||||
# yes, please do actually check the cert …
|
|
||||||
rejectUnauthorized = true;
|
|
||||||
nick = "haccGuest%%%%";
|
|
||||||
join = "#hacc-webchat";
|
|
||||||
};
|
|
||||||
lockNetwork = true;
|
|
||||||
|
|
||||||
# don't log messages (default is text / sqlite)
|
|
||||||
messageStorage = [];
|
|
||||||
|
|
||||||
# darker theme
|
|
||||||
#theme = "morning";
|
|
||||||
|
|
||||||
# these three should result in having link previews
|
|
||||||
# which are fetched only by the server, then proxied
|
|
||||||
# (i.e. clients won't directly connect to arbitrary
|
|
||||||
# domains to get previews)
|
|
||||||
prefetch = true;
|
|
||||||
prefetchStorage = true;
|
|
||||||
disableMediaPreview = true;
|
|
||||||
|
|
||||||
leaveMessage = "happy haccing";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# override the package we use
|
|
||||||
systemd.services.thelounge.serviceConfig.ExecStart =
|
|
||||||
pkgs.lib.mkForce "${thelounge}/bin/thelounge start";
|
|
||||||
|
|
||||||
services.coredns = {
|
|
||||||
enable = true;
|
|
||||||
config = ''
|
|
||||||
.:53 {
|
|
||||||
forward . 1.1.1.1
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
})).config.system.build.toplevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."webchat.voc.hacc.space" = {
|
|
||||||
locations."/".proxyPass =
|
|
||||||
"http://${config.containers.thelounge.localAddress}:9000";
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
{ config, lib, pkgs, profiles, modules, evalConfig, sources, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
uffd = pkgs.uffd;
|
|
||||||
in {
|
|
||||||
containers.uffd = {
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.9";
|
|
||||||
autoStart = true;
|
|
||||||
bindMounts = {
|
|
||||||
"/persist" = {
|
|
||||||
hostPath = "/persist/containers/uffd";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
services.coredns = {
|
|
||||||
enable = true;
|
|
||||||
config = ''
|
|
||||||
.:53 {
|
|
||||||
forward . 1.1.1.1
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
services.uwsgi = {
|
|
||||||
enable = true;
|
|
||||||
plugins = [ "python3" ];
|
|
||||||
instance = {
|
|
||||||
type = "normal";
|
|
||||||
pythonPackages = self: with self; [ uffd ];
|
|
||||||
module = "uffd:create_app()";
|
|
||||||
# socket = "${config.services.uwsgi.runDir}/uwsgi.sock";
|
|
||||||
http = ":8080";
|
|
||||||
env = [
|
|
||||||
"CONFIG_PATH=/persist/uffd/uffd.conf"
|
|
||||||
];
|
|
||||||
hook-pre-app = "exec:FLASK_APP=${uffd}/lib/python3.9/site-packages/uffd flask db upgrade";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})).config.system.build.toplevel;
|
|
||||||
};
|
|
||||||
services.nginx.virtualHosts."login.infra4future.de" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
locations = {
|
|
||||||
"/".proxyPass = "http://${config.containers.uffd.localAddress}:8080";
|
|
||||||
"/static".root = "${uffd}/lib/python3.9/site-packages/uffd";
|
|
||||||
"/static/hacc.png".return = "302 https://infra4future.de/assets/img/logo_vernetzung.png";
|
|
||||||
"/static/infra4future.svg".return = "302 https://infra4future.de/assets/img/infra4future.svg";
|
|
||||||
"/static/hedgedoc.svg".return = "302 https://infra4future.de/assets/img/icons/hedgedoc.svg";
|
|
||||||
"/static/mattermost.svg".return = "302 https://infra4future.de/assets/img/icons/mattermost.svg";
|
|
||||||
"/static/nextcloud.svg".return = "302 https://infra4future.de/assets/img/icons/nextcloud.svg";
|
|
||||||
"/static/hot_shit.svg".return = "302 https://infra4future.de/assets/img/icons/hot_shit.svg";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,87 +0,0 @@
|
||||||
{ config, lib, pkgs, modules, profiles, evalConfig, sources, ... }:
|
|
||||||
let
|
|
||||||
wapkgs = "${sources.workadventure}/wapkgs.nix";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.coturn = {
|
|
||||||
enable = true;
|
|
||||||
realm = "void.hacc.space";
|
|
||||||
no-cli = true;
|
|
||||||
lt-cred-mech = true;
|
|
||||||
|
|
||||||
extraConfig = ''
|
|
||||||
user=turn:a4c9ad080dc51146611eabd15a27b07fc92850a9ae90c53e7745fce6c5a2c457
|
|
||||||
fingerprint
|
|
||||||
external-ip=135.181.215.233
|
|
||||||
server-name=void.hacc.space
|
|
||||||
prometheus
|
|
||||||
'';
|
|
||||||
|
|
||||||
cert = config.security.acme.certs."void.hacc.space".directory + "full.pem";
|
|
||||||
pkey = config.security.acme.certs."void.hacc.space".directory + "key.pem";
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall = with config.services.coturn;
|
|
||||||
let
|
|
||||||
ports = [ listening-port tls-listening-port ];
|
|
||||||
in {
|
|
||||||
allowedTCPPorts = ports ++ [ 9641 ]; # 9641 is the port for the prometheus endpoint
|
|
||||||
allowedUDPPorts = ports;
|
|
||||||
allowedUDPPortRanges = [
|
|
||||||
{ from = min-port; to = max-port; }
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."void.hacc.space" = {
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://192.168.150.3";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
containers.wa-void = {
|
|
||||||
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.150.1";
|
|
||||||
localAddress = "192.168.150.3";
|
|
||||||
|
|
||||||
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
"${sources.workadventure.outPath}/default.nix"
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
];
|
|
||||||
|
|
||||||
services.workadventure."void" = {
|
|
||||||
|
|
||||||
packageset = (import wapkgs {inherit pkgs;}).workadventure-xce;
|
|
||||||
|
|
||||||
nginx = {
|
|
||||||
default = true;
|
|
||||||
domain = "https://void.hacc.space";
|
|
||||||
maps.path = "${sources.haccmap.outPath}/";
|
|
||||||
maps.serve = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
frontend.startRoomUrl = "/_/global/void.hacc.space/maps/main.json";
|
|
||||||
commonConfig = {
|
|
||||||
webrtc.stun.url = "stun:void.hacc.space:3478";
|
|
||||||
webrtc.turn = {
|
|
||||||
url = "turn:135.181.215.233";
|
|
||||||
user = "turn";
|
|
||||||
password = "a4c9ad080dc51146611eabd15a27b07fc92850a9ae90c53e7745fce6c5a2c457";
|
|
||||||
};
|
|
||||||
jitsi.url = "meet.ffmuc.net";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})).config.system.build.toplevel;
|
|
||||||
};
|
|
||||||
}
|
|
44
websites/docs.hacc.space/Readme.md
Normal file
44
websites/docs.hacc.space/Readme.md
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Markdown docs with zola.
|
||||||
|
|
||||||
|
[Zola](https://www.getzola.org/) is a static site generated written in Rust
|
||||||
|
(which you'll notice since sometimes it panics).
|
||||||
|
|
||||||
|
To run the site locally:
|
||||||
|
|
||||||
|
```
|
||||||
|
zola serve
|
||||||
|
```
|
||||||
|
|
||||||
|
## Directory Layout
|
||||||
|
|
||||||
|
All the important stuff goes into `content`. If you create subdirectories, make
|
||||||
|
sure you remembered to also create an `_index.md` file for it (if in doubt, just
|
||||||
|
copy the one at `content/_index.md`); otherwise pages in there won't work.
|
||||||
|
|
||||||
|
`templates` is *not* for site templates, but specifies how markdown files should
|
||||||
|
be turned into html. If an autogenerated link broke, you'll probably have to
|
||||||
|
change something in there. `sass` and `static` do exactly what they sound like.
|
||||||
|
|
||||||
|
It usually shouldn't be necessary to change `config.toml`, but if it is, [here
|
||||||
|
is the list of all available options](https://www.getzola.org/documentation/getting-started/configuration/).
|
||||||
|
|
||||||
|
|
||||||
|
## File Layout
|
||||||
|
|
||||||
|
Markdown files start with a frontmatter that should look something like so:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
+++
|
||||||
|
title = "blåhaj"
|
||||||
|
taxonomies.categories = [ "flausch" ]
|
||||||
|
+++
|
||||||
|
|
||||||
|
[actual markdown goes here]
|
||||||
|
```
|
||||||
|
|
||||||
|
The frontmatter is TOML; the `taxonomies.*` keys are special and can be used to
|
||||||
|
aggregate posts if enabled in `config.toml` (currently that's only the case for
|
||||||
|
`categories`, though). See also the [list of all available keys](https://www.getzola.org/documentation/content/page/).
|
||||||
|
|
||||||
|
Please don't repeat the page's title in markdown, otherwise it'll appear twice
|
||||||
|
in the html.
|
35
websites/docs.hacc.space/config.toml
Normal file
35
websites/docs.hacc.space/config.toml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# Zola's configuration file,
|
||||||
|
#
|
||||||
|
# see https://www.getzola.org/documentation/getting-started/configuration/
|
||||||
|
# for available keys.
|
||||||
|
|
||||||
|
# The URL the site will be built for
|
||||||
|
base_url = "https://docs.hacc.space"
|
||||||
|
|
||||||
|
compile_sass = true
|
||||||
|
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" ]
|
||||||
|
|
||||||
|
build_search_index = true
|
||||||
|
|
||||||
|
taxonomies = [
|
||||||
|
{ name = "categories", feed = false},
|
||||||
|
]
|
||||||
|
|
||||||
|
[markdown]
|
||||||
|
highlight_code = true
|
||||||
|
|
||||||
|
[extra] # user-defined keys
|
||||||
|
|
||||||
|
# site title text
|
||||||
|
main_title = "haccfiles documentation"
|
||||||
|
|
||||||
|
# navbar entries
|
||||||
|
main_menu = [
|
||||||
|
{url = "$BASE_URL", name = "Home"},
|
||||||
|
{url = "$BASE_URL/categories", name = "Categories"}
|
||||||
|
]
|
1
websites/docs.hacc.space/content
Symbolic link
1
websites/docs.hacc.space/content
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../docs
|
22
websites/docs.hacc.space/default.nix
Normal file
22
websites/docs.hacc.space/default.nix
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{ copyPathToStore, stdenvNoCC, zola, writeShellScriptBin }:
|
||||||
|
|
||||||
|
stdenvNoCC.mkDerivation rec {
|
||||||
|
name = "docs.hacc.space-static";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
content = copyPathToStore ../../docs;
|
||||||
|
|
||||||
|
phases = [ "buildPhase" ];
|
||||||
|
buildInputs = [ zola ];
|
||||||
|
buildPhase = ''
|
||||||
|
cp -r $src/* .
|
||||||
|
rm content
|
||||||
|
ln -s $content content
|
||||||
|
zola build --output-dir $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
watch = writeShellScriptBin "watch" ''
|
||||||
|
cd $(git rev-parse --show-toplevel)/websites/docs.hacc.space
|
||||||
|
${zola}/bin/zola serve --output-dir /tmp/hacc-docs "$@"
|
||||||
|
'';
|
||||||
|
}
|
168
websites/docs.hacc.space/sass/style.scss
Normal file
168
websites/docs.hacc.space/sass/style.scss
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'share-tech';
|
||||||
|
src: url('ShareTech-Regular.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
font-family: 'share-tech';
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
max-width: 60em;
|
||||||
|
font-size: 16pt;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.subtitle {
|
||||||
|
font-size: 14pt;
|
||||||
|
font-style: normal;
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
margin-bottom: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchresults {
|
||||||
|
width: 90%;
|
||||||
|
text-align: right;
|
||||||
|
right: 0;
|
||||||
|
position: absolute;
|
||||||
|
background-color: black;
|
||||||
|
top: 5em;
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchresults div {
|
||||||
|
padding: 0.5em;
|
||||||
|
border-top: 1px dashed gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchresults div:last-child {
|
||||||
|
border-bottom: 1px dashed gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchresultprevtext {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: inline-block;
|
||||||
|
width: 40em;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer.content {
|
||||||
|
top: 50px;
|
||||||
|
color: #cccccc;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer a {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.logo > img {
|
||||||
|
width: 300px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 32pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#headernav {
|
||||||
|
text-align: right;
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#headernav > a {
|
||||||
|
padding: 0.2em;
|
||||||
|
font-size: 20pt;
|
||||||
|
font-family: share-tech;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6{
|
||||||
|
font-weight: 600;
|
||||||
|
display: inline;
|
||||||
|
font-family: share-tech;
|
||||||
|
background: rgb(59,115,185);
|
||||||
|
background: linear-gradient(90deg, rgb(59, 115, 185) 0%, rgb(229, 35, 33) 100%);
|
||||||
|
background-clip: border-box;
|
||||||
|
color: transparent;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
h4 {
|
||||||
|
//font-weight: 600;
|
||||||
|
//display: inline;
|
||||||
|
font-family: share-tech;
|
||||||
|
//background: rgb(59,115,185);
|
||||||
|
//background: linear-gradient(90deg, rgb(59, 115, 185) 0%, rgb(229, 35, 33) 100%);
|
||||||
|
//background-clip: border-box;
|
||||||
|
color: #fff;
|
||||||
|
//-webkit-background-clip: text;
|
||||||
|
//background-clip: text;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #3b73b9;
|
||||||
|
transition: color .1s linear;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
/*color: #e52321;*/
|
||||||
|
color: #4e9af9;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pre {
|
||||||
|
padding: 1rem;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
// The line numbers already provide some kind of left/right padding
|
||||||
|
pre[data-linenos] {
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
pre table td {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
// The line number cells
|
||||||
|
pre table td:nth-of-type(1) {
|
||||||
|
text-align: center;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
pre mark {
|
||||||
|
// If you want your highlights to take the full width.
|
||||||
|
display: block;
|
||||||
|
// The default background colour of a mark is bright yellow
|
||||||
|
background-color: rgba(254, 252, 232, 0.9);
|
||||||
|
}
|
||||||
|
pre table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
BIN
websites/docs.hacc.space/static/ShareTech-Regular.ttf
Normal file
BIN
websites/docs.hacc.space/static/ShareTech-Regular.ttf
Normal file
Binary file not shown.
BIN
websites/docs.hacc.space/static/favicon.png
Normal file
BIN
websites/docs.hacc.space/static/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
BIN
websites/docs.hacc.space/static/favicon_color.png
Normal file
BIN
websites/docs.hacc.space/static/favicon_color.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
52
websites/docs.hacc.space/static/search.js
Normal file
52
websites/docs.hacc.space/static/search.js
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
function mkDiv (res) {
|
||||||
|
let div = document.createElement("div");
|
||||||
|
let a = document.createElement("a");
|
||||||
|
a.innerText = res.doc.title;
|
||||||
|
a.href = res.ref;
|
||||||
|
let text = document.createElement("span");
|
||||||
|
text.innerText = res.doc.body.slice(0,400).replaceAll("\n", " ");
|
||||||
|
text.classList.add("searchresultprevtext");
|
||||||
|
|
||||||
|
div.appendChild(text);
|
||||||
|
div.appendChild(a);
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = () => {
|
||||||
|
console.log("hello!")
|
||||||
|
let searchbox = document.getElementById("searchbox");
|
||||||
|
searchbox.innerHTML =
|
||||||
|
"<input id='searchinput' placeholder='search ...'></input> \
|
||||||
|
<div id='searchresults' style='display:none'></div>";
|
||||||
|
|
||||||
|
let searchinput = document.getElementById("searchinput");
|
||||||
|
let searchresults = document.getElementById("searchresults");
|
||||||
|
|
||||||
|
let index = elasticlunr.Index.load(window.searchIndex);
|
||||||
|
|
||||||
|
searchinput.addEventListener("keyup", () => {
|
||||||
|
let term = searchinput.value.trim();
|
||||||
|
let results = [];
|
||||||
|
if (term !== "") {
|
||||||
|
results = index.search(term, {});
|
||||||
|
console.log(results);
|
||||||
|
|
||||||
|
while (searchresults.lastChild) {
|
||||||
|
searchresults.removeChild(searchresults.lastChild)
|
||||||
|
}
|
||||||
|
if (results.length !== 0) {
|
||||||
|
let resultdivs = results.map(mkDiv);
|
||||||
|
resultdivs.map((div) => searchresults.appendChild(div));
|
||||||
|
} else {
|
||||||
|
searchresults.innerHTML =
|
||||||
|
term.length <= 4 ?
|
||||||
|
"<div>Need at least four characters to search.</div>"
|
||||||
|
: "<div>No results here.</div>";
|
||||||
|
}
|
||||||
|
searchresults.style.display = "initial";
|
||||||
|
} else {
|
||||||
|
searchresults.style.display = "none";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue