Compare commits

..

304 commits

Author SHA1 Message Date
35853d56e2 re-add infra4future.de faq
(contains info about how groups work)
2022-09-25 19:20:20 +02:00
41c914991a
Merge remote-tracking branch 'origin/fix/mattermost' 2022-09-24 18:05:44 +02:00
f2c90e5601 websites: remove mentions of gitlab.infra4future.de
(one remains for now, will do that later once anyone from students
for future says what to do in that case)
2022-09-24 17:46:48 +02:00
77d7625315
remove gitlab 2022-09-24 17:29:42 +02:00
hexchen
04272968d0 update and fix mattermost 2022-09-24 14:59:52 +00:00
7e615e6daa
Merge branch 'infra4future.de-update' 2022-09-19 18:12:54 +02:00
82e70e0151
change name 2022-09-19 18:11:54 +02:00
6bba15faae
gitea: git protocol v2 over ssh
cf. https://docs.gitea.io/en-us/config-cheat-sheet/#git-git, entry for
option ENABLE_AUTO_GIT_WIRE_PROTOCOL
2022-09-19 18:11:54 +02:00
9bf75b9c3d
git ssh: switch to gitea (instead of gitlab) 2022-09-19 18:11:54 +02:00
83cda0f44a
gitea: save state under /persist 2022-09-19 18:11:54 +02:00
97459d8177
gitea: enable offline mode 2022-09-19 18:11:54 +02:00
6aa06aed18
gitea: fix uffd login
(note that this actually has to patch uffd)
2022-09-19 18:11:54 +02:00
639410011e
update lantifa source urls & hashes 2022-09-19 18:11:54 +02:00
schweby
7db9dbb4c2
!fixup add missing settings section 2022-09-19 18:11:53 +02:00
schweby
856cd79c37
init basic untested config 2022-09-19 18:11:53 +02:00
3ea537459b
change name 2022-09-12 19:29:51 +02:00
f53cb24d2e update infra4future.de index website 2022-09-07 22:08:36 +02:00
45ceeef189
gitea: git protocol v2 over ssh
cf. https://docs.gitea.io/en-us/config-cheat-sheet/#git-git, entry for
option ENABLE_AUTO_GIT_WIRE_PROTOCOL
2022-08-03 11:26:05 +02:00
e246563f57 git ssh: switch to gitea (instead of gitlab) 2022-08-01 20:54:17 +02:00
a1c5832a51 gitea: save state under /persist 2022-08-01 18:39:46 +02:00
c854e10980
gitea: enable offline mode 2022-07-27 23:26:13 +02:00
b5a68e09fd
gitea: fix uffd login
(note that this actually has to patch uffd)
2022-07-27 23:26:13 +02:00
f9f1eee6fd
update lantifa source urls & hashes 2022-07-27 23:26:13 +02:00
schweby
db5865fff2
!fixup add missing settings section 2022-07-27 23:26:13 +02:00
schweby
65ec0779b7
init basic untested config 2022-07-27 23:26:13 +02:00
4b53211130
mattermost: minor upgrade (6.7.0 -> 6.7.2) 2022-07-27 23:25:46 +02:00
schweby
86b9d3113c
parsons/mail: readd noreply@infra4ure 2022-07-17 19:36:42 +02:00
schweby
39aaf2e0bb
!fixup make virtual addresses actually work
also fix typo
2022-07-10 19:02:45 +02:00
schweby
8021685ec8
update mail config 2022-07-09 20:56:46 +02:00
8f413da05a services/nextcloud: remove mail & redis
(both of these have lots of options, which either do nothing at all or
are misconfigured in some way and don't work. If we want redis-caching,
we can re-add it later, but the current state suggest it's already
working, which it isn't, which is worse)
2022-07-09 20:27:46 +02:00
e9d2630ea9 fix auamost path 2022-07-09 19:11:30 +02:00
445a974f97 magic mattermost group sync 2022-07-09 11:00:57 +02:00
4eecd1bad4 update nextcloud to 24
(apparently we forget to commit this??)
2022-07-09 10:56:58 +02:00
schweby
430efbc0a5
update sources 2022-06-09 14:56:38 +02:00
schweby
3dc6b5e3e9
common/users: update schwebys ssh key 2022-05-22 15:08:42 +02:00
hexchen
507a144165 Add uffd application icons 2022-05-02 16:28:37 +00:00
hexchen
7015386cd6 Fix uffd brand icon 2022-05-02 15:53:27 +00:00
schweby
440076bae9
services/nextcloud: make login work reliably 2022-04-30 23:35:19 +02:00
hexchen
27cc65fb14 feat: new SSO!!!! 🎉 2022-04-30 20:43:12 +00:00
287cb84d82
services/mattermost: bump to 6.6.0 2022-04-16 20:31:58 +02:00
schweby
3ee3c37ccb
sources: updates
CVE-2022-1162
2022-04-06 09:05:25 +02:00
39bec9fbd0
services/mattermost: bump to 6.5.0 2022-03-18 19:28:43 +01:00
5c85431847
mattermost: bump to 6.4.2 (security update) 2022-03-11 14:01:53 +01:00
schweby
2cf0119ec1
sources: updates
update kernel to proteced against CVE-2022-0847
2022-03-07 20:44:33 +01:00
schweby
a92ae39d65
gitlab-ci.yml: disable nixda build
It's known broken. No need to waste time and resources.
Reenable when fixed.
2022-02-27 12:22:30 +01:00
schweby
f1c3a2d082
sources: updates 2022-02-27 12:19:36 +01:00
schweby
93c13debe6
services/mattermost: bump to 6.4.1 2022-02-27 11:57:52 +01:00
3e95d6c222
bump nix/sources.json 2022-02-17 19:49:53 +01:00
ca19774c9e
services/mattermost: bump to 6.4.0 2022-02-17 19:49:38 +01:00
032c49c375
comment out services/workadventure
(we're not using it and it's eating build times, so I've disabled it for
now)
2022-02-17 19:48:45 +01:00
4b71a216ba
services/mattermost: bump to 6.1.3
(another security update)
2022-02-05 01:08:46 +01:00
schweby
17d695c00b
common: add niv 2022-02-04 08:51:39 +01:00
schweby
7815e32f9f
services/mail: reduce logspam
reduce logspam by out mail services by seeting them to logleven 5
(notice) and 3 (error)
2022-02-01 17:07:52 +01:00
99811b6711 bump update nixos-mailserver to 21.11 2022-02-01 14:44:47 +01:00
1aebabe8a0 parsons/restics: s3CredentialsFile is deprecated
This is untested, but the documentation on the s3CredentialsFile option
seems to suggest this should be correct.
2022-02-01 14:03:40 +01:00
10942ca464 bump home manager to 21.11 2022-02-01 14:00:35 +01:00
schweby
2d429492fe
services/mail: stop postfix from dying by rspamd 2022-01-31 21:43:25 +01:00
schweby
4bf804c025
services/syncthing: add Vorstands share
currently the receiveencrypted type is not supported by the nixos module
so we have to set it via the webinterface
2022-01-27 22:53:17 +01:00
schweby
8716f2b308
services/syncthing: update config format 2022-01-27 22:52:49 +01:00
hexchen
6de0b91beb fixer tous les things 2022-01-27 20:20:25 +00:00
9937d5ff94
fixing pad.hacc.space (hopefully)
(I haven't tested this, since I don't want to try the upgrade-adventure
a second time today, but I think this should fix it)
2022-01-27 20:38:06 +01:00
4ff0bdf3ec
whoops, apparently some rebase went wrong
(fixing it back into a buildable state)
2022-01-27 20:38:04 +01:00
676ba4fc31
services/hedgedocs: use socket auth for postgres 2022-01-27 20:37:42 +01:00
schweby
569c5652f2
sources: update 2022-01-27 20:37:40 +01:00
schweby
238c1b2c92
mediawiki cleanup 2022-01-27 20:36:34 +01:00
c2c0bd366a
bump nixpkgs to 21.11
This simply updates nixpkgs to 21.11 (along with a general update of
other sources), then follows the hints given out in the build process
until everything (on parsons) ran through fine.

Some things to note:
 - syncthing's declarative config is gone. Instead, declarative and
   non-declarative configuration can now be mixed, but with
   `overrideDevices` set to true, it _should_ ignore non-declarative
   settings and basically behave the same as before (or at least that's
   how I understood the documentation on that)
 - some postfix options now require a lib.mkForce, since the mail module
   also wants to set them — we should probably look into if the mail
   module has nicer ways of handling our settings now (which I didn't
   do)
 - we no longer import the vaultwarden module from unstable, since it's
   included in nixos 21.11 as-is. We _do_ still import the vaultwarden
   package from unstable, since downgrading sounds like a bad idea.
 - nix build will print a warning that `literalExample` is now
   depricated, but we don't seem to use that — I guess at some point
   we'll have to search through our sources if it doesn't go away

This was not yet deployed, and should probably considered a
work-in-progress.

Building Nixda currently fails decklink seems to have disappeared.
2022-01-27 20:36:17 +01:00
68afbe01b3 services/mattermost: bump to 6.1.2 (security update)
cf. https://mattermost.com/blog/mattermost-security-updates-6-3-1-6-2-2-6-1-2-5-37-7-released/

this supposedly fixes a "medium-level security vulnerability", but
they're not telling us what it is (for now …) :rolls_eyes:

anyways, seems to run fine on parsons.
2022-01-25 02:08:40 +01:00
schweby
fa347008fa
common/default.nix: add vgrep 2022-01-19 22:11:10 +01:00
schweby
c21b1b8ddf
services/syncthing: cleanup clients
remove no longer needed clients due to "new" password sharing
2022-01-19 21:35:03 +01:00
schweby
02a64a6f31
services/hedgedoc: lower loglevel to warn 2022-01-19 21:22:32 +01:00
b9aa3050d7 fix mumble website
This does two things:
 - add a group "mumblecert" which is allowed to read the mumble.hacc.space
   cert, and add both nginx and murmur's users to it
 - remove the website's derivation from services/murmur.nix and instead
   add it to the websites/ dir and handle it the same as all our other sites
2022-01-18 09:08:27 +01:00
schweby
6f0d8a6af9
hotfix: disable mumble website
disable the mumble website because of cert permission issues causes by ad9c1f4481
nginx doesn't start because it can read the cert of the website
2022-01-17 22:37:43 +01:00
ad9c1f4481
security/acme: mumble cert readable by murmur group
the postRun thing doesn't seem to work at all anymore?
2022-01-12 23:51:31 +01:00
f800057478
services/hedgedocs: remove unused module imports 2022-01-12 19:31:31 +01:00
ae67b38304 add the rest of our stativ web pages
however, for some reason, ACME still fails. Hopefully it's just the
rate limit, but it does look suspicious; there' still a
"www.muc.hacc.space" in the log that oughtn't be there …
2022-01-10 23:45:21 +01:00
eb07f34672 modules/website.nix init
idea is to have a directory `websites/` which contains all our static
sites, with the name of each subdirectory also being their domain. Then
Nix can just read that directory during build-time and automatically
generate nginx virtualHosts for all of them (note that the
subdirectories have to contain a `default.nix` specifying how to build
the site for that to work).

Thus we could avoid the dependency on gitlab pages.
2022-01-10 22:57:09 +01:00
c08ca5f85f
update readme
its incompleteness annoys me
2022-01-07 18:16:31 +01:00
a7896e718f
services/workadventure: re-add the hacc assembly map as default map 2022-01-07 17:29:10 +01:00
16245e830f
remove truelove-specific workadventure
This removes the special configuration to make our workadventure useable
for the truelove event and reverts it to just run at void.hacc.space
without authentication etc.

Tbh, not sure if that's actually what we want — do we need a running
workadventure instance at all? Or should we just remove the entire container?
2022-01-01 20:03:32 +01:00
schweby
9b38e5fba1 update sources 2021-12-30 22:58:23 +01:00
schweby
8c527ea552 enable ssh for stream user 2021-12-30 22:30:25 +01:00
schweby
b96a026565 cleanup default apps 2021-12-30 22:30:17 +01:00
schweby
ba60e3cf76 pkgs/blackmagic-desktop-video: update to 12.2.2 2021-12-19 17:13:51 +01:00
schweby
2a1e692522 services/lantifa: set mediawiki-version from 21.11
due to a wikiDB issue the mediawiki version in unstable (37) is not
compatible.
switching to 21.05 would mean a downgrade, so this is the hack until we
fully upgrade to 21.11
2021-12-11 13:20:42 +01:00
schweby
af8b16117f sources: add 21.11 as nixpkgs-new 2021-12-11 13:20:15 +01:00
schweby
bde7afa9ca sources: update 2021-12-11 12:54:02 +01:00
928d44fb95 Added stuebinm@hacc.space to mitglieder@hacc.space 2021-12-01 21:25:27 +00:00
3ad6a0d2df raphael@hacc.space added to voc@hacc.space 2021-12-01 21:22:53 +00:00
schweby
277d4a1fa7 services/nextcloud: fix downloads >1GB
should also gernerally improve performance when large(r) amounts of data
are exchanged
2021-11-22 20:58:39 +01:00
schweby
668a3fa4ee replace stdenv.lib with lib because deprecated 2021-11-19 19:54:19 +01:00
fccb150d3c
bump mattermost: 5.39.2 → 6.1.0 2021-11-17 12:48:56 +01:00
schweby
e10545d1f8 update sources
did not update nixpkgs-unstabele due to a compliler version problem
vaultwarden 2.23 needs rustc 1.57, only rustc 1.56.1 is available
2021-11-16 17:42:52 +01:00
6563e0ccfa add services/workadventure for true-love event 2021-11-09 17:02:43 +00:00
schweby
5432503397 services/mattermost: set MaxUsersPerTeam to 250 2021-11-06 18:11:08 +01:00
6d6a2aff67
bump mattermost 5.39.0 → 5.39.1 (security update)
really, i probably should've just jumped straight to 6.0.2, but whatever 🤷
2021-11-04 17:01:45 +01:00
schweby
144bd0d5f5 remove services/unifi
no longer needed
2021-11-03 15:36:03 +01:00
1b94984486
unbreak vaultwarden backup 2021-10-31 22:22:48 +01:00
schweby
6a7e836d22 pkgs/companion: update hash 2021-10-31 21:37:50 +01:00
schweby
f78ae0e50a sources: updates 2021-10-31 19:40:30 +01:00
schweby
13567e0152 sources: remove pbb-nixfiles
no longer available, also unused
2021-10-31 19:39:32 +01:00
schweby
232a90aaf1 services/nextcloud: replace password with file 2021-10-31 09:19:45 +01:00
schweby
0652afa761 services/nextcloud: set defaultapp to apporder 2021-10-31 08:28:10 +01:00
schweby
34eb8651d8 modules/nextcloud: add option for defaultapp 2021-10-31 08:27:40 +01:00
hexchen
750b069420 services/nginx-pages: fix acme bullshit 2021-10-28 19:02:38 +00:00
schweby
939d7adbb6 pkgs/companion: fix hash
who needs consistent links anyway
should fix nixda not building on parsons
2021-10-27 09:20:20 +02:00
schweby
09d6d6838d service/lantifa: update intersection plugin 2021-10-15 22:27:22 +02:00
schweby
5138da6805 sources: update 2021-10-13 20:31:40 +02:00
schweby
ad5d21cba5 sources: updates 2021-10-01 19:32:27 +02:00
octycs
f125de8342 services/nginx-pages: readd help.studentsforfuture.info 2021-09-28 21:28:54 +02:00
56cbb7601b services/vaultwarden: init vaultwarden 2021-09-28 11:13:25 +00:00
schweby
2044b77401 sources: update 2021-09-19 16:45:18 +02:00
schweby
3c3e4c0c83 pkgs/companion: fix hash of nodeHeaders 2021-09-19 16:37:18 +02:00
schweby
dbf8d74a24 set timezones
default is UTC no need to force it
A desktop shoud be in the commonly used timezone.
Forcing UTC has caused trouble multiple times.
2021-09-19 16:35:38 +02:00
schweby
f4089803ff sources: update mattermost to 5.39 2021-09-18 21:53:25 +02:00
schweby
e63af3984c sources: update 2021-09-18 21:37:57 +02:00
schweby
35a563185d parsons/lantifa: update intersection plugin 2021-09-18 21:36:39 +02:00
schweby
982546f73a sources: update 2021-08-30 15:12:30 +02:00
schweby
b9eb988aa0 parsons/murmur: fix acme
credits for ${pkgs.acl} go to stuebinm
2021-08-30 15:12:30 +02:00
hexchen
a113c05025 pkgs: init bitfocus companion for streamdeck 2021-08-28 14:31:14 +00:00
System administrator
20398cf2c8 stuff 2021-08-25 16:23:34 +00:00
schweby
56ad0ed886 nixda/decklink: bump version of bmv to 12.1
bmv = blackmagicvideo
2021-08-23 19:54:18 +00:00
hexchen
fd9e8941c7 get rid of hainich. migration done. 2021-08-23 19:32:02 +00:00
schweby
95a0e9f04a parsons: init lantifa wiki 2021-08-23 19:32:02 +00:00
hexchen
41acbdd3e0 parsons: deploy unifi controller 2021-08-23 19:32:02 +00:00
hexchen
d367269e87 thelounge: foo 2021-08-23 19:32:02 +00:00
hexchen
7dbc22929b parsons/nginx-pages: add muc.hacc.earth hacc 2021-08-23 19:32:02 +00:00
hexchen
35cd963f8c services/gitlab-runner: init on parsons
also disable ci for hainich
2021-08-23 19:32:02 +00:00
hexchen
6121acabd7 maintenance: update sources, fix mattermost 2021-08-23 19:32:02 +00:00
hexchen
275d3a16f0 parsons: init lxc 2021-08-23 19:32:02 +00:00
hexchen
69e49a0020 services/gitlab: init ssh 2021-08-23 19:32:02 +00:00
hexchen
373926e33b services/gitlab: init on parsons 2021-08-23 19:32:02 +00:00
schweby
7881b444ba parsons: init syncthing 2021-08-23 19:32:02 +00:00
hexchen
cdeb52f808 services/mail: migrate to parsons 2021-08-23 19:32:02 +00:00
schweby
f5579bc98e parsons: config nginx 2021-08-23 19:32:02 +00:00
hexchen
a5063ae960 parsons: small fixes 2021-08-23 19:32:02 +00:00
schweby
632bf21200 parsons: fix hegedocs 2021-08-23 19:32:02 +00:00
schweby
76c9b07d56 parsons: init hegedocs 2021-08-23 19:32:02 +00:00
hexchen
172d0869b3 services/murmur: migrate to parsons 2021-08-23 19:32:02 +00:00
hexchen
4b11dbf1d4 services/thelounge: move to parsons 2021-08-23 19:32:02 +00:00
84ac81435e hainich: hacky version of thelounge as webchat
Intended for KontraIAA; requirements were that it should be a simple and
non-confusing as possible.

I tried both KiwiIRC and thelounge, and found both horrible to
package (a fact not helped by the somewhat opaque structure of
nixpkgs.nodePackages, which does contain a version of thelounge but
will apparently ignore overrides of the src attribute).

Instead, this now contains a very hacky version of thelounge, which
merely takes the already-built version from nixpkgs and glues some extra
css to it which hides potentially confusing fields.

Things hidden on the "connect" screen:
 - the "name" field (since thelounge offers "nick" "name" and "realname"
   by default, which seems too much for something embedded on a website)
 - the "I have a password" checkbox

Things hidden on the general view:
 - the button to open the side panel (the panel itself is not hidden,
   and will appear by itself on wider layouts), so that users will only
   see that one channel
 - the "channel options" menu (which includes a "leave channel" option
   which would effectively break the webchat)

Things not addressed:
 - thelounge has autocompletion for /join /leave, etc. Do we want to
   disable that as well?
 - It would probably useful to suppress all the "x joined the channel"
   messages. Thelounge supports this, but apparently doesn't support
   setting it as default?

Misc:
 - for now, users will be connected to #thelounge on libera.chat, which
   appears to be okay with being used as an experimental channel
 - I allowed prefetching link previews, but only on the server's side
   (i.e. users' browsers won't fetch content from arbitrary sites)
 - not yet tested on hainich, but should work (tested in a NixOS
   container)
 - currently assumes a "webchat.voc.hacc.space" domain (I think we had a
   voc domain? but I forgot where it is …)
2021-08-23 19:32:02 +00:00
schweby
b23582a52f services/mattermost: init on parsons 2021-08-23 19:32:02 +00:00
hexchen
1c65805589 parsons: init backups 2021-08-07 12:05:26 +00:00
hexchen
da7beff2fe services/nextcloud: init on parsons 2021-08-07 12:05:26 +00:00
hexchen
3541d14c76 parsons: add nftables 2021-08-07 12:05:26 +00:00
hexchen
479d119b8b ci: add parsons 2021-08-07 12:05:26 +00:00
hexchen
0b30d81d13 hosts/parsons: init minimal config 2021-08-07 12:05:25 +00:00
hexchen
cf5062adfd sources: update nixpkgs to 21.05
this caused various other changes related to nftables, we are now using
hexchen's fork of pbb's module.
2021-08-07 12:05:25 +00:00
hexchen
cbeb0e86c1 mail: emergency alias 2021-08-03 17:13:46 +00:00
schweby
d3e08e0247
sources: update packages 2021-07-28 22:31:23 +02:00
2d0a5b9c22
Merge branch 'mattermost-reply-threads' of https://gitlab.infra4future.de/hacc/infra/haccfiles into mattermost-reply-threads 2021-07-18 21:28:28 +02:00
20bafd66c5
mattermost: add recommended proxy settings
This unbreaks the keycloak login
2021-07-18 21:26:14 +02:00
schweby
2c0abd0cc4
sources: set template for mattermost-server 2021-07-16 23:45:43 +02:00
32e13edee1
fix hashes
apparently I changed the url but not the hash at some point while
fiddling with the sources.json file.

have I mentioned how much I like niv yet?
2021-07-16 18:14:22 +02:00
69f5448aa3
mattermost 5.34.3 → 5.37.0
Among other things, this contains the "collapsable reply threads" feature
which makes it behave similar to slack.

Also, after spending thirty minutes or so attempting to teach niv that
it should really only fetch the tag "5.37.0" from the mattermost-server
repository and not any other commit, branch, or similar (there is a
"release-5.37" branch, but that seems to be for active development), I
have temporarily given up on it and typed in the urls manually.

Unfortunately, this means that any kind of `niv update` will now break
things. If anyone knows how to use niv correctly for this please patch
this; otherwise I guess we can extract mattermost out from niv again.
2021-07-16 17:45:18 +02:00
schweby
bfaa6a54ab
sources: update packages 2021-07-14 22:36:17 +02:00
schweby
04375f8152
hainich: remove websites
websites are now back on gitlab again
2021-07-14 22:15:03 +02:00
schweby
725517a035
sources: pin hexchen repo 2021-07-01 18:55:12 +02:00
schweby
6a408db9c1
hotfix: add websites to hainich
because gitlab broke websites AGAIN, they are now running on hainich
directly
While this is only a temporary solution, I think it will be as permanent
as they come
2021-06-25 11:38:47 +02:00
schweby
776c4d2f0f
sources: update packages 2021-06-23 23:16:54 +02:00
schweby
f6bf8c7c00
hainich: remove A20 ghost 2021-06-23 23:06:49 +02:00
octycs
df6f0baa71 hainich/mediawiki: Fix broken URL to plugin 2021-06-11 19:08:22 +02:00
schweby
b092919a53 nixda:update desktopvideo to 12.0 2021-06-09 21:58:06 +00:00
schweby
ab68332e2b sources: update packages 2021-06-09 22:30:19 +02:00
schweby
d37899698c
hainich: remove minecraft
nixos and its concepts/service management/update mechanism don't play nice with minecraft
In general some things I wanted to do (e.g. a map) are to spikiely resource intensive to run on a server meant to provide other services consistently
A replacement will be provided soon™
2021-06-06 18:22:24 +02:00
schweby
fec87aa59d
sources: update packages 2021-06-03 17:25:47 +02:00
Lukas
378c79f93e hainich:add hedgedoc for i4f 2021-06-02 19:08:54 +00:00
schweby
e9eb76c2b5
update sources 2021-05-26 22:31:06 +02:00
schweby
8506265060
sources: update packages 2021-05-12 21:41:53 +02:00
schweby
644c433809 hainich: init ghost A20 2021-05-12 19:37:15 +00:00
7d2e5f7576 ci: split up pipelines by host
Rationale: if one build fails, the other one will still continue running.
Especially since we already have some (and will presumably add more)
proprietary software to nixda which may require manual intervention
using nix-prefetch-url, this seems like a good idea.

An alternative would be to just specifiy `--keep-going`, but this seems
likely to lead to unreadable output.

However, I'm not sure what exactly happens when we try to run builds for
both hosts at once on the same nix store — it may be that this isn't the
best idea, but I guess we can just make the pipelines sequential instead
if necessary.

pipeline: fix mistake in build command

(previous commit contained two builds for nixda, none for hainich)
2021-05-10 14:41:42 +00:00
hexchen
3b39b0f316 hainich/gitlab-runner: limit nix builds to 1
running concurrent builds might cause stuff to be redownloaded/rebuilt.
2021-05-10 14:39:51 +00:00
3d8db75c48
mail: add addresses for c3wooc
Assuming I've understood the format of this config correctly, this
should add two new addresses for the c3wooc (one for general contact,
one for patches); both forwarding to its members (currently only hxchn
and me).
2021-05-08 20:06:00 +02:00
schweby
1e57204b7a
sources: update packages 2021-05-01 18:48:15 +02:00
9e7a277b6a workadventure: fix turn ipv4 address
apparently I missed changing that; it still pointed to my own
server (flora.stuebinm.eu) instead of hainich.
2021-04-29 22:20:10 +00:00
schweby
ae8bf7c8f6
sources: manage mattermost with niv
also reenables mattermost
also updated to version 5.34.2
2021-04-28 22:29:31 +02:00
schweby
148741f4c3
sources: update packages 2021-04-28 22:01:02 +02:00
schweby
3067d1b8fb
hainich/mediawiki: set static URL for WikiDB 2021-04-27 11:09:42 +02:00
hexchen
bc684b1626 services/mail: clean up the config file 2021-04-26 17:08:34 +00:00
schweby
908d6df2da
sources: update sources
this also disables mattermost-beta because of a version mismatch with
the development branch
will be readded with MR
2021-04-20 21:52:18 +02:00
schweby
9770b4089a
sources.json: replace refs with branches
refs are the old way of referring to what niv tracks for updates
niv actively encourages to switch to branches or tags so this is done
here
2021-04-20 21:39:17 +02:00
schweby
df31a3da35
hainich/minecraft: get server.jar via sources.json 2021-04-17 17:19:52 +02:00
schweby
3473603f91
sources: add papermc 2021-04-17 17:16:04 +02:00
schweby
243d0bf14d
hainich/minecraft: fix & reorder config
fixes a formatting error in jvmOpts and slightly reoders the config
2021-04-17 17:15:49 +02:00
schweby
75ec36dda2
hainich/mumble: import website from sources.json 2021-04-16 15:54:25 +02:00
schweby
18ed88727f
sources: add mumble-website 2021-04-16 15:52:17 +02:00
6e36ff58e2 workadventure: update and manage sources with niv
Changes:
 - workadventure is now pulled from stuebinm.eu/git via niv, and
   should be updated automatically along with the other sources
 - the same is true for the default map, which gets pulled directly from
   its gitlab sources.
 - this setup may potentially break things if I decide to rename an
   option upstream, but I don't think that'll happen too often
 - made the code a little nicer
 - uses workadventure-xce now, since the tabascoeye version is now gone

Open for discussion:
 - afaik know, the current version of workadventure-xce now contains
   fediventure-specific patches. Do we want that, or should we switch
   to the unfederated version?
2021-04-15 20:12:32 +00:00
hexchen
c3c3bca114 hainich/mail: update mailing lists, remove unused 2021-04-15 20:09:49 +00:00
schweby
1c446bec8d
hainich/hedgedoc: redirect pad.hacc.earth to pad.hacc.space 2021-04-15 14:13:15 +02:00
schweby
25568db129
hainich/nginx: disable interest cohort globally 2021-04-15 10:16:20 +02:00
schweby
0c55ccb47b
hainich: reduce backup retention 2021-04-15 06:37:12 +02:00
schweby
ccb4469922
hainich: Set more sensible snapshot retention time 2021-04-15 06:35:31 +02:00
schweby
b136ca090f
hainich: remove hasenloch 2021-04-15 06:18:26 +02:00
schweby
1f40f1f142
hainich: disable workadventure 2021-04-14 22:47:25 +02:00
schweby
caa45759a1
hainich/minecraft: update to paper 1.16.5-592 2021-04-14 22:43:35 +02:00
schweby
289c82e529
sources: update sources 2021-04-14 22:43:19 +02:00
schweby
7c04319456
hainich/minecraft: update to paper 1.16.5-583 2021-04-07 09:38:09 +02:00
schweby
2112e6e40e
sources: update packages 2021-04-07 09:38:05 +02:00
L3D ワッフルマイスター
b2d2235d4d remove newline in murmur.nix 😉 2021-04-05 06:46:34 +00:00
schweby
ee53d85b94
hainich/mumble: switch to updated site 2021-04-05 08:39:34 +02:00
schweby
6f7c79f93e
sources: update packages 2021-04-04 12:37:40 +02:00
schweby
87b3518ebd
hainich/minecraft: update to paper 1.16.5-576 2021-04-03 21:17:21 +02:00
schweby
cfb0cd5013
hainich/minecraft: add optimised GC options 2021-04-03 21:17:21 +02:00
schweby
d48c7cdcac
pkgs: set jre_headless to jdk11_headless
this is a workaround to be able to use java 11 with the
minecraft-server module
minecraft calls for jre_headless, which is still java 8
newer java version don't ship jre, which now have to be custom built or
the jdk used
2021-04-03 21:07:02 +02:00
schweby
5b37fde996
Merge branch 'mattermost-upgrade' 2021-04-03 10:23:00 +02:00
schweby
6db58c4a01
hasenloch: add FAQ and Contact 2021-04-03 08:00:59 +02:00
schweby
2974b9688b
hasenloch: update to newer version 2021-04-02 16:38:31 +02:00
schweby
a2bd7880b4
hainich/docker: stop docker from loading iptables 2021-03-30 23:59:05 +02:00
schweby
c10caa5b0f
hainich/mattermost: disable container firewall 2021-03-30 23:57:52 +02:00
schweby
78e607a28d
hainich: block x_tables module
this also blocks the x_tables module to prent it from loading
ip_tables
2021-03-30 17:59:26 +02:00
schweby
8a17da7761
sources: update nix packages 2021-03-27 11:53:49 +01:00
schweby
d1e88ef87a
hainich/nginx: disable /var/secrets/ingest.conf
If the file in not present, the preExec check for the config fails and
disrupts the deploy.
Before readding make sure the file will always be present!
2021-03-27 11:48:43 +01:00
schweby
1064836092
Revert "security: remove hexchen"
This reverts commit bab826b1c7.
Also fixes hexchen nix due new logic
2021-03-26 22:04:27 +01:00
schweby
5579a60b4e
Revert "security: remove hexchen mail"
This reverts commit 32b5958279.
2021-03-26 21:53:17 +01:00
schweby
49fa714861
sources: update nix packages 2021-03-25 21:53:21 +01:00
011196f875
mattermost: disable analytics & telemetry
note that this ALSO disables the security alert features of mattermost [1],
which would send us alerts in case of security updates for our current
mattermost version. I have disabled it since it would send information
about our instance (including e.g. the current number of active users) to
mattermost every 24 hours.

Since we now essentially maintain our own set of mattermost packages, I
recommend at least some of us subscribe to the mattermost release blog [2],
and manually update the mattermost sources in `/pkgs/mattermost` as required
(I have done so already). The release blog is also available as an rss feed [3].

[1] https://docs.mattermost.com/administration/telemetry.html#security-update-check-feature
[2] https://mattermost.com/blog/category/releases
[3] https://mattermost.com/blog/category/releases/rss
2021-03-25 15:51:01 +01:00
d3af36bd3c
mattermost: update to version 5.30.3
This should be compatible with the version we currently use, and also include all hot-fixes
etc. which we definitely want to have.
2021-03-25 15:32:47 +01:00
stuebinm
d5cf2abccc
hainich: init mattermost beta 2021-03-24 22:37:38 +01:00
schweby
29e15bc2bd
sources: update nix packages 2021-03-24 22:22:10 +01:00
schweby
e4a0367a51
sources: remove unecessary refs 2021-03-24 21:30:06 +01:00
schweby
b604cee52a
hainich/minecraft: Update to paper 1.16.6-167 2021-03-24 21:13:26 +01:00
schweby
077e8264f7
hainich/hasenloch: set config suitable for r2r 2021-03-24 19:28:22 +01:00
schweby
f54be467b8
hainich/hasenloch: update to r2r version
to update to this version removal of the cache at
*engelsystem/storage/cache is necessary for the site to work
2021-03-24 19:19:33 +01:00
schweby
99d534586a
hainich/minecraft: update to paper 1.16.5-562 2021-03-20 17:09:58 +01:00
schweby
8377d27b87 hainich: init minecraft server
this server replaces the vanilla minecraft server on libocedrus
2021-03-20 16:59:47 +01:00
schweby
071f135ef4
hainich: Blacklist ip_tables and ip6_tables
Prevent **something** (docker) from loading the iptables kernel modules
and breaking nftables
2021-03-20 16:56:56 +01:00
schweby
233ffdd769
hainich/nginx: redirect hacc.space to hacc.earth
redirect was previously managed on libocerus
hacc.space now points to hainich
2021-03-18 19:12:14 +01:00
schweby
77c06c5509
hainich/nginx: let all empty subdomains 404
* make hainich.hacc.space the default virtualHost for nginx
if no host is running on that subdomain, this will be shown
* disable SSL, so no pesky SSL error for empty subdomains anymore
* remove lots of unneeded brackes and semicolons
2021-03-18 19:04:00 +01:00
schweby
94eafe59d2
hainich/nginx: remove rc3 cluster site 2021-03-18 19:01:44 +01:00
dbbdde76c7
mumble.hacc.space: move site from gitlab into nix derivation
Since the delivery of mumble.hacc.space/murmur.hacc.space via gitlab pages
broke (for whatever reason), I've packaged the site into an ad-hoc nix
derivation, which is now delivered locally by nginx instead. This has a
couple benefits (mainly that we no longer depend on gitlab pages), but
also the downside that we can't just update the site via gitlab's CI/CD
pipelines anymore.
2021-03-17 22:35:51 +01:00
schweby
32b5958279 security: remove hexchen mail 2021-03-13 00:27:53 +01:00
schweby
bab826b1c7 security: remove hexchen 2021-03-12 23:53:51 +01:00
schweby
db51a3adde common: set schweby's shell to fish 2021-03-12 12:28:26 +01:00
faee8da700 nixda: bump version of obs to nixpkgs/unstable 2021-03-11 00:12:08 +01:00
schweby
2d4309fdf4 hainich: init workadventure 2021-03-11 00:11:51 +01:00
schweby
d11ca2bb3e sources: update nix packages 2021-03-10 20:59:23 +01:00
hexchen
b186473e68 sources: update nix-hexchen
lots of fancy new stuff, but most importantly: we no longer import all
of my user config, just the very base.

none of that fancy stuff is active right now, this should mostly be a
no-op unless we do the same restructure that i have just done in my
nixfiles here as well.
2021-03-10 20:58:31 +01:00
hexchen
6f2cc7bf7f hainich: remove obsolete nginx host 2021-03-09 10:10:03 +00:00
hexchen
bc58060390 mail: update rinderhacc password and alias 2021-03-09 10:03:18 +00:00
hexchen
6b055167e3 sources: update nix-hexchen 2021-03-01 13:08:34 +00:00
schweby
cd3efc616d updated nix packages 2021-02-24 21:42:02 +00:00
hexchen
16f05ceadf
ci: remove instantiate stage
instantiating takes a lot of time now (lots of dependencies), and the
gain of not starting a build if the instantiation fails is minimal.
2021-02-22 09:41:15 +00:00
d7b70742fe remove old engelsystem config (NOP)
this removes the old (unused) config for an angel system used during the
fridays for future camp 2020. Since it was configured "by hand" and not
in a declarative manner, and since there is now an actual module
`services.engelsystem` that we already use for the divoc it seems unlikely
that we will ever need the old config again.

From Nix's point of view, this commit is equivalent to doing nothing.
2021-02-21 14:58:25 +01:00
Matthias Stübinger
3b42b89bd7 Hasenloch (Engelsystem for divoc)
Seems to work fine, except for the domain — the engelsystem tries
to load its ressources from the IP of the container instead of its
url set in the config.
2021-02-20 23:32:00 +01:00
schweby
1a8842457d restic: added mumur to backup 2021-02-20 21:56:05 +01:00
hexchen
233a4c7cab hainich: init restic backups 2021-02-15 07:23:23 +00:00
hexchen
e42376687f hainich/syncthing: add hexchen's server 2021-02-13 19:56:15 +00:00
Schweby mit Hut
be90dca334 hainich/syncthing: added raphael-laptop 2021-02-11 22:31:35 +01:00
Schweby mit Hut
442e320be5 hainich/syncthing: Updated id for schweby 2021-02-11 22:17:36 +01:00
hexchen
c36eb51ff4 Revert 43d36bb3d7
This is a partial revert, reintroducing hexchen to the project.
As it turns out, I am still quite invested in the project and require
frequent access to the nix-based infrastructure.
2021-02-11 18:59:10 +00:00
schweby
aca670d778 sources: updated sources 2021-02-10 22:53:55 +00:00
schweby
9d516c83ae sources: removed immae-nix 2021-02-10 23:48:18 +01:00
hexchen
0ea8daad24 hainich/gitlab-runner: Move registration token
Move it to /etc instead so that it's persisted across reboots
2021-02-10 22:40:03 +00:00
hexchen
0d362a17fc hainich/monitoring: init prometheus 2021-02-06 16:41:02 +00:00
Schweby mit Hut
323b4edf1c hainich/murmur,mumble: let the websites be fixed. 2021-02-03 23:33:08 +01:00
Matthias Stübinger
1ccc8b2b9c Fix mumble sites 2021-02-03 11:12:23 +01:00
schweby
b384ff8b38 updated nixpkgs etc 2021-01-27 23:44:18 +01:00
Schweby mit Hut
4813284e82 syncthing 2021-01-27 23:27:59 +01:00
hexchen
4c9a200c83 sources: switch to upstream
this involves moving the blackmagic package and module from hexchen's
nixpkgs fork into this repo directly.
2021-01-27 22:06:56 +01:00
hexchen
dad94d6e0d sources: update nixpkgs 2021-01-26 20:18:54 +00:00
hexchen
43d36bb3d7 remove hexchen from the project
I am no longer comfortable with putting resources into this project and
therefore request to be removed from all infrastructure. I am still
happy to help out with software I set up, but I will no longer actively
maintain any services. As far as possible, I will remove myself from all
access groups or other privileged positions related to this project.

Essentially, I'm stepping down as a maintainer. I still reserve the
right to make changes via the established change processes (Merge
Requests as well as Issues in the meta-repositories), but I will no
longer make direct changes to infrastructure without going through those
review processes.
2021-01-25 11:37:34 +00:00
hexchen
3f280ae6ba default: unclutter by using a recursive attrset 2021-01-22 19:26:05 +00:00
hexchen
fe5a626891 readme: add golden commit rule
which i just broke but i guess this is an exception.
2021-01-20 18:47:57 +00:00
hexchen
1a383c5ca4 readme: remove old and add commit format 2021-01-20 18:45:21 +00:00
hexchen
ee2a3ae0b8 hainich/murmur: fix proxy_pass 2021-01-20 18:38:50 +00:00
schweby
351303f060 made loge appropriate size 2021-01-17 23:37:20 +00:00
Schweby mit Hut
c7894cd9d6 updated Logo 2021-01-17 23:31:01 +01:00
waldfunk danni
5006365684 Update lantifa.nix 2021-01-17 22:31:37 +01:00
hexchen
95da394e01 hainich/nat: add docker and container IPs
for some reason, masquerading by interface does not work atm, should fix
itself with a host reboot though.
2021-01-15 23:55:06 +00:00
hexchen
61db3bc33f modules/nftnat: init nftables nat module 2021-01-15 23:55:06 +00:00
hexchen
c0efd41e74 nftables: import module and init config 2021-01-15 22:45:34 +00:00
hexchen
d86418307f fixup!common: disable logs 2021-01-15 21:09:32 +00:00
hexchen
4e1430bfc7 common: disable nginx access log 2021-01-15 21:02:03 +00:00
octycs
57334cd690 lantifa: Attempt to configure short URLs (to fix VisualEditor)
Signed-off-by: hexchen <hexchen@lilwit.ch>
2021-01-15 10:56:13 +00:00
octycs
4964ac6817 Add DynamicPageList + PageForms extension
Signed-off-by: hexchen <hexchen@lilwit.ch>
2021-01-15 10:40:55 +00:00
hexchen
d0eedd4dcc Revert "hotfix!desktop: remove firefox"
This reverts commit 010b1b94fb.
2021-01-15 00:44:39 +00:00
hexchen
a863459bb1 sources: update nixpkgs 2021-01-15 00:44:37 +00:00
hexchen
e876bcc29f modules/peertube: fix reference to immaenix 2021-01-15 00:38:59 +00:00
schweby
c6b3a895fd added wiki added path to logo 2021-01-14 23:26:13 +00:00
hexchen
af89eb2e45 hainich/mail: allow mail for discourse 2021-01-14 00:02:32 +00:00
hexchen
3d4b6e4148 fixup!hainich/mail: discuss@infra4future.de pass 2021-01-13 23:40:14 +00:00
hexchen
dbe5cb55fb hainich/mail: update setup for discourse 2021-01-13 23:20:44 +00:00
hexchen
1ccc94b37f hainich/mail: add noreply@infra4future.de 2021-01-13 21:32:22 +00:00
hexchen
010b1b94fb hotfix!desktop: remove firefox 2021-01-13 19:29:12 +00:00
hexchen
2ccb2d3ded hainich/lantifa: fix visualeditor 2021-01-13 18:48:06 +00:00
octycs
410d9fa13d hainich/lantifa: update mediawiki config
Use correct TemplateData version & add plugins: visualeditor, inputbox

Signed-off-by: hexchen <hexchen@lilwit.ch>
2021-01-13 17:24:43 +00:00
hexchen
548188be4d hainich/lantifa: attempt visualeditor fix 2021-01-13 17:18:16 +00:00
hexchen
ea80c4fe41 hainich/lantifa: update mediawiki to use unstable 2021-01-12 23:21:19 +00:00
Schweby mit Hut
2d8eeb45ab added Wiki DB & Template Data plugins 2021-01-12 23:14:05 +01:00
hexchen
5006060d68 hainich/mail: add gitlab service account 2021-01-12 18:40:25 +00:00
hexchen
d1412f0d3b hainich/lantifa: init mediawiki 2021-01-12 18:20:49 +00:00
hexchen
3956861948 sources: update nix-hexchen 2021-01-11 01:57:28 +00:00
hexchen
b288102f76 common/users: import hex-nix to deduplicate config 2021-01-11 00:30:08 +00:00
hexchen
f5c9d5f0c7 docs: add readme.md 2021-01-11 00:22:37 +00:00
hexchen
1399f74e87 pkgs: pass nixpkgs config properly
see cee4094d91
for details of upstream changes
2021-01-11 00:11:40 +00:00
hexchen
78ba4399a9 nixpkgs: allowUnfree = true 2021-01-11 00:00:15 +00:00
hexchen
b68e324c4c restructure: remove redundant file 2021-01-10 23:56:49 +00:00
hexchen
851052014a complete restructure of haccfiles
here be winkekatzen
2021-01-10 23:53:41 +00:00
hexchen
9263583ad7 hainich: fix double journald config 2021-01-10 13:40:59 +00:00
hexchen
fc1359b1b4 hainich/mail: loosen sender restriction 2021-01-07 01:43:31 +00:00
hexchen
ee78f31519 nixda: remove makemkv 2021-01-07 00:36:07 +00:00
hexchen
56ad50f3f4 hainich/murmur: add mumble.infra4future.de website 2021-01-07 00:30:53 +00:00
hexchen
0539ebd097 hainich/mail: fix email config 2021-01-07 00:22:36 +00:00
hexchen
93862d8e08 hainich/mail: enable receiving for infra4future.de 2021-01-07 00:22:16 +00:00
hexchen
812169ed3a default: make log retention 48h (or 512MiB) 2021-01-07 00:18:08 +00:00
288 changed files with 43137 additions and 25886 deletions

View file

@ -1,31 +1,9 @@
stages:
- instantiate
- build
instantiate 20.09:
tags:
- nix
stage: instantiate
script:
- nix-instantiate -I nixpkgs=https://github.com/hexchen/nixpkgs/archive/hexchen-20.09.tar.gz -A deploy.all
instantiate main:
tags:
- nix
stage: instantiate
script:
- nix-instantiate -I nixpkgs=https://github.com/hexchen/nixpkgs/archive/hexchen-main.tar.gz -A deploy.all
build 20.09:
build-parsons:
tags:
- nix
stage: build
script:
- nix-build -A deploy.all -I nixpkgs=https://github.com/hexchen/nixpkgs/archive/hexchen-20.09.tar.gz
build main:
tags:
- nix
stage: build
script:
- nix-build -A deploy.all -I nixpkgs=https://github.com/hexchen/nixpkgs/archive/hexchen-main.tar.gz
- nix-build -A deploy.parsons

47
README.md Normal file
View file

@ -0,0 +1,47 @@
# hacc nixfiles
welcome to hacc nixfiles (haccfiles). this is the code describing our nix-based infrastructure.
## structure
- `default.nix`: Entrypoint to the config
- `common/`: configuration common to all hosts
- `desktop/`: desktop-relevant communication
- `modules/`: home-grown modules for hacc-specific services
- `nix/`: sources files, managed with niv
- `pkgs/`: packages we built and don't want to upstream
- `hosts/`: configuration.nix per host
- `services/`: all services we run; imported in appropriate host config
## working with the haccfiles
deploy:
``` shell
nix build -f . deploy.$hostname && ./result switch
```
`$hostname` can be replaced with any hostname or group
## 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:
```shell
nix copy --from ssh://parsons /nix/store/...
```
Note: don't just copy the .drv file (which Nix complains about if it can't
build something), that's just the description of how to build it! If you
don't know the actual outpath, look in the .drv file (should start with
`Derive([("out","[the path you want]"...`)
## committing to haccfiles
- Golden Rule: DO NOT COMMIT TO MAIN
- exceptions apply, if you are not sure where to commit, don't commit to main
- 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: "$prefix$place: $change"
- prefix: one of fixup, nothing
- place: one of "modules/$module", "$hostname/service", "common/($place)", "pkgs/$pkgs" or "sources"
- change: describe your change, don't go over the character limit where git starts hiding/wrapping
- Exception: autogenerated messages (merge commits, reverts, etc)

View file

@ -1,25 +1,24 @@
{ config, lib, pkgs, ... }:
{ config, lib, pkgs, modules, ... }:
{
let
sources = import ../nix/sources.nix;
in {
imports = [
../../modules
./external.nix
../modules
./users.nix
(sources.home-manager + "/nixos")
modules.network.nftables
];
nixpkgs.overlays = [
(self: super: import ../../pkgs { nixpkgs = super.path; })
];
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages;
boot.kernelParams = [ "quiet" ];
networking.domain = lib.mkDefault "hacc.space";
petabyte.nftables = {
enable = lib.mkDefault true;
};
services.journald.extraConfig = "SystemMaxUse=512M";
services.journald.extraConfig = ''
SystemMaxUse=512M
MaxRetentionSec=48h
'';
nix.gc.automatic = lib.mkDefault true;
nix.gc.options = lib.mkDefault "--delete-older-than 1w";
nix.trustedUsers = [ "root" "@wheel" ];
@ -37,7 +36,6 @@
security.sudo.wheelNeedsPassword = lib.mkDefault false;
i18n.defaultLocale = "en_IE.UTF-8";
time.timeZone = "UTC";
console = {
font = "Lat2-Terminus16";
keyMap = "de";
@ -46,8 +44,8 @@
environment.systemPackages = with pkgs; [
smartmontools lm_sensors htop tcpdump nload iftop
# bottom
ripgrep
bottom
ripgrep vgrep
git wget
kitty.terminfo
rsync pv progress
@ -63,7 +61,7 @@
socat
tmux
gnupg
vim
vim neovim
patchelf
binutils
dnsutils
@ -71,13 +69,17 @@
nmap
s-tui stress
ffmpeg-full
bat
niv
];
petabyte.vnstat = {
enable = true;
nginx.enable = true;
};
security.acme.email = "info+acme@hacc.space";
security.acme.acceptTerms = true;
services.nginx.appendHttpConfig = ''
access_log off;
add_header Permissions-Policy "interest-cohort=()";
'';
networking.nftables.enable = true;
}

9
common/hexchen.nix Normal file
View file

@ -0,0 +1,9 @@
{config, lib, pkgs, ...}:
let
sources = import ../nix/sources.nix;
in {
imports = [
(import sources.nix-hexchen {}).users.hexchen.base
];
}

View file

@ -1,4 +1,4 @@
{ config, pkgs, ... }:
{ config, pkgs, lib, ... }:
{
imports = [
@ -12,17 +12,11 @@
openssh.authorizedKeys.keys = with pkgs.lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
};
# all the actual config is imported from hexchen's nixfiles
hexchen = {
uid = 1000;
uid = lib.mkForce 1000;
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDNVUDKx9sukRkb6INny432+2HZBWx/qIEAOvngF1qcj hexchen@montasch"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvzA8w0/th/EJcqwogd5LIyTV4lcK6iSbkRYUtKli/V hexchen@mobile"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDI3T1eFS77URHZ/HVWkMOqx7W1U54zJtn9C7QWsHOtyH72i/4EVj8SxYqLllElh1kuKUXSUipPeEzVsipFVvfH0wEuTDgFffiSQ3a8lfUgdEBuoySwceEoPgc5deapkOmiDIDeeWlrRe3nqspLRrSWU1DirMxoFPbwqJXRvpl6qJPxRg+2IolDcXlZ6yxB4Vv48vzRfVzZNUz7Pjmy2ebU8PbDoFWL/S3m7yOzQpv3L7KYBz7+rkjuF3AU2vy6CAfIySkVpspZZLtkTGCIJF228ev0e8NvhuN6ZnjzXxVTQOy32HCdPdbBbicu0uHfZ5O7JX9DjGd8kk1r2dnZwwy/ hexchen@yubi5"
];
shell = pkgs.fish;
packages = with pkgs; [ python38 go ];
};
stuebinm = {
@ -54,12 +48,13 @@
packages = with pkgs; [ ffmpeg ];
};
schweby = {
moira = {
uid = 1004;
shell = pkgs.fish;
isNormalUser = true;
extraGroups = [ "wheel" "cdrom" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL6JWi0MBDz0Zy4zjauQv28xYmHyapb8D4zeesq91LLE schweby@txsbcct"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJrcJRF71+XM5YZj+SaSiGcdVZ0IDxGBXIWssDtHiTtr moira_2022_06"
];
hashedPassword = "$6$zkAsaVdmIduqZxez$GY9aBlYeP41F0it/VbbZzLLLRQhHAbDdFsa3e/1GS9McTuSimMHODg6HqNVEH1zSqD3afhK/0UHfqbtF5qpi90";
};

View file

@ -1,32 +0,0 @@
let
pbb-nixfiles = fetchGit {
url = "https://git.petabyte.dev/petabyteboy/nixfiles";
rev = "b15d29e0440716fc37414547d55839717c9ed2f9";
};
qyliss-nixlib = fetchTarball {
url = "https://git.qyliss.net/nixlib/snapshot/nixlib-e14330c5be9b005d4310cd4dc0d384cff882aedc.tar.zst";
sha256 = "0nan14ixhdzxxddnckqqhaxhr96yw08rgcmxssddhji6aq5a445j";
};
home-manager = fetchGit {
url = "https://github.com/nix-community/home-manager";
rev = "a98ec6ec158686387d66654ea96153ec06be33d7";
};
in {
imports = [
(pbb-nixfiles + "/modules")
(home-manager + "/nixos")
];
nixpkgs.overlays = [
(self: super: {
pleroma = self.callPackage (pbb-nixfiles + "/pkgs/pleroma") {
elixir_1_10 = super.elixir;
};
dino = self.callPackage (qyliss-nixlib + "/overlays/patches/dino") {
inherit (super) dino;
};
})
];
}

View file

@ -1,79 +0,0 @@
{config, lib, pkgs, ...}:
{
home-manager.users.hexchen = {
programs.direnv = {
enable = true;
enableFishIntegration = true;
enableNixDirenvIntegration = true;
};
programs.fish = {
enable = true;
shellAliases = {
icat = "${pkgs.kitty}/bin/kitty +kitten icat";
};
plugins = [
{
name = "bass";
src = pkgs.fetchFromGitHub {
owner = "edc";
repo = "bass";
rev = "d63054b24c2f63aaa3a08fb9ec9d0da4c70ab922";
sha256 = "0pwci5xxm8308nrb52s5nyxijk0svar8nqrdfvkk2y34z1cg319b";
};
}
];
};
programs.vim = {
enable = true;
extraConfig = ''
set viminfo='20,<1000
set mouse=a
''; /*
set tabstop=2
set shiftwidth=2
set expandtab
'';*/
};
programs.git = {
enable = true;
userName = "hexchen";
userEmail = "hexchen@lilwit.ch";
signing = {
key = "B1DF5EAD";
signByDefault = false;
};
extraConfig = {
pull.rebase = true;
};
};
programs.bat.enable = true;
programs.jq.enable = true;
programs.tmux.enable = true;
programs.ssh = {
enable = true;
controlMaster = "auto";
controlPersist = "10m";
hashKnownHosts = true;
matchBlocks = let
hexchen = {
forwardAgent = true;
extraOptions = {
RemoteForward = "/run/user/1000/gnupg/S.gpg-agent /run/user/1000/gnupg/S.gpg-agent.extra";
};
port = 62954;
};
in {
"*.chaoswit.ch" = hexchen;
"*.copyonwit.ch" = hexchen;
"*.lilwit.ch" = hexchen;
"*.hxchn.de" = hexchen;
"*.hacc.space" = hexchen;
"*.hacc.media" = hexchen;
};
};
};
}

View file

@ -1,51 +0,0 @@
{ config, lib, pkgs, ... }:
{
boot.plymouth.enable = true;
nixpkgs.config = {
mumble.speechdSupport = true;
allowUnfree = true;
};
# boot.plymouth.splashBeforeUnlock = true;
users.users.schweby.packages = config.users.users.hexchen.packages
++ (with pkgs; [ alacritty picom feh copyq polybar cinnamon.nemo rofi arandr notepadqq nomacs bat ]);
users.users.hexchen = {
packages = with pkgs; [
pulsemixer pavucontrol
firefox git kitty j4-dmenu-desktop bemenu
breeze-qt5 mako
mpv youtube-dl
wl-clipboard mumble
xdg_utils
slurp grim libnotify
_1password-gui
# gnome3.nautilus
];
extraGroups = [ "video" "audio" ];
};
home-manager.users.hexchen = {
gtk = {
enable = true;
iconTheme = {
name = "Adwaita";
package = pkgs.gnome3.adwaita-icon-theme;
};
theme = {
name = "Adwaita";
package = pkgs.gnome3.adwaita-icon-theme;
};
};
};
sound.enable = true;
hardware.pulseaudio = {
enable = true;
package = pkgs.pulseaudioFull;
};
networking.useDHCP = lib.mkDefault true;
hardware.opengl.enable = true;
services.xserver = {
windowManager.bspwm.enable = true;
layout = "de";
};
}

View file

@ -1,42 +0,0 @@
{ config, pkgs, lib, ... }:
{
fonts.fonts = with pkgs; [ font-awesome nerdfonts ];
users.users.hexchen.packages = with pkgs; [ ];
home-manager.users.hexchen = {
programs.waybar = {
enable = true;
settings = [{
modules-left = [ "sway/workspaces" "sway/mode" ];
modules-center = [ "sway/window" ];
modules-right = [ "pulseaudio" "network" "cpu" "memory" "temperature" "battery" "clock" "tray" ];
modules = {
battery = {
states = {
good = 95;
warning = 30;
critical = 15;
};
format = "{capacity}% {icon}";
format-charging = "{capacity}% ";
format-plugged = "{capacity}% ";
format-alt = "{time} {icon}";
format-icons = ["" "" "" "" ""];
};
network = {
format-wifi = "{essid} ({signalStrength}%) ";
format-ethernet = "{ifname}: {ipaddr}/{cidr} ";
format-linked = "{ifname} (No IP) ";
format-disconnected = "Disconnected ";
format-alt = "{ifname}: {ipaddr}/{cidr}";
};
};
}];
};
};
programs.sway.enable = true;
}

View file

@ -1,22 +0,0 @@
# deploy auf hainich
**NICHT** nix os-re build sw itch
Auf hainich mit ssh verbinden.
Im root Verzeichnis sollte das haccfiles repro (das hier) liegen
Falls ja, einfach pullen
``git pull origin main;``
sonst erneut clonen
``git clone https://gitlab.infra4future.de/infra/haccfiles.git``
dann in das repro wechseln
``cd /root/haccfiles``
Und das ganze bauen
``nix build -f . -I nixpkgs=https://github.com/hexchen/nixpkgs/archive/hexchen-20.09.tar.gz deploy.hainich``
und mit ``./result`` als neue boot option auswählen und darauf wechseln
oder
mit``./result test`` das ganze nur bis zum reboot zu behalten.

View file

@ -1,26 +0,0 @@
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-config.nix
../../../common
../../../server/cdn/cdn-lb.nix
];
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.devices = [ "/dev/sda" ];
networking.interfaces.ens3.useDHCP = true;
networking.hostName = "cdn-loadbalancer";
# 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. Its 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.03"; # Did you read the comment?
}

View file

@ -1,26 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, ... }:
{
imports =
[ <nixpkgs/nixos/modules/profiles/qemu-guest.nix>
];
boot.initrd.availableKernelModules = [ "ata_piix" "virtio_pci" "xhci_pci" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/e371ee1d-a03f-4964-b03d-4a5c59ff5911";
fsType = "ext4";
};
swapDevices = [ ];
nix.maxJobs = lib.mkDefault 1;
}

View file

@ -1,26 +0,0 @@
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-config.nix
../../../common
../../../server/cdn/cdn-master.nix
];
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.devices = [ "/dev/sda" ];
networking.interfaces.ens3.useDHCP = true;
networking.hostName = "cdn-master";
# 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. Its 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.03"; # Did you read the comment?
}

View file

@ -1,25 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, ... }:
{
imports =
[ <nixpkgs/nixos/modules/profiles/qemu-guest.nix>
];
boot.initrd.availableKernelModules = [ "ata_piix" "virtio_pci" "xhci_pci" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/14cc7936-f928-41e3-8f72-ee6bf18d6c19";
fsType = "ext4";
};
swapDevices = [ ];
nix.maxJobs = lib.mkDefault 1;
}

View file

@ -1,26 +0,0 @@
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-config.nix
../../../common
../../../server/cdn/cdn-node.nix
];
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.devices = [ "/dev/sda" ];
networking.interfaces.ens3.useDHCP = true;
networking.hostName = "cdn-node-1";
# 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. Its 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.03"; # Did you read the comment?
}

View file

@ -1,25 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, ... }:
{
imports =
[ <nixpkgs/nixos/modules/profiles/qemu-guest.nix>
];
boot.initrd.availableKernelModules = [ "ata_piix" "virtio_pci" "xhci_pci" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/52dddb3d-9294-4105-9157-bf003dc7bdf9";
fsType = "ext4";
};
swapDevices = [ ];
nix.maxJobs = lib.mkDefault 1;
}

View file

@ -1,26 +0,0 @@
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-config.nix
../../../common
../../../server/cdn/cdn-node.nix
];
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.devices = [ "/dev/sda" ];
networking.interfaces.ens3.useDHCP = true;
networking.hostName = "cdn-node-2";
# 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. Its 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.03"; # Did you read the comment?
}

View file

@ -1,25 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, ... }:
{
imports =
[ <nixpkgs/nixos/modules/profiles/qemu-guest.nix>
];
boot.initrd.availableKernelModules = [ "ata_piix" "virtio_pci" "xhci_pci" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/a92ff89e-e1c2-4fda-8711-1be7257f6470";
fsType = "ext4";
};
swapDevices = [ ];
nix.maxJobs = lib.mkDefault 1;
}

View file

@ -1,37 +0,0 @@
let
hosts = {
hainich = {
ssh.host = "hainich.hacc.space";
groups = [ "server" "hacc" ];
};
nixda = {
ssh.host = "nixda.hacc.space";
groups = [ "server" "desktop" "hacc" "live" ];
};
"cdn/node-2" = {
ssh.host = "cdn-node-2.live.hacc.media";
groups = [ "server" "hacc" "live" "livecdn" "livecdn-node" ];
};
"cdn/node-1" = {
ssh.host = "cdn-node-1.live.hacc.media";
groups = [ "server" "hacc" "live" "livecdn" "livecdn-node" ];
};
"cdn/master" = {
ssh.host = "cdn-master.live.hacc.media";
groups = [ "server" "hacc" "live" "livecdn" "livecdn-master" ];
};
"cdn/loadbalancer" = {
ssh.host = "cdn-loadbalancer.live.hacc.media";
groups = [ "server" "hacc" "live" "livecdn" "livecdn-lb" ];
};
};
pkgs = import <nixpkgs> {};
evalConfig = import <nixpkgs/nixos/lib/eval-config.nix>;
lib = pkgs.lib;
in lib.mapAttrs (name: host: host // {
config = if (host ? config) then host.config else (evalConfig {
modules = [
(import "${toString ./.}/${name}/configuration.nix")
];
}).config;
}) hosts

View file

@ -1,107 +0,0 @@
{ config, lib, pkgs, ... }:
{
imports = [
../../common
./encboot.nix
./hardware.nix
./services/murmur.nix
./services/mail.nix
# ./services/engelsystem.nix
./services/codimd.nix
../../common
# ./wireguard.nix
./services/nginx.nix
# ./k8s.nix
./services/docker.nix
./services/gitlab-runner.nix
./services/funkwhale.nix
];
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.device = "/dev/sda";
boot.supportedFilesystems = [ "zfs" ];
# networking
networking.hostName = "hainich";
networking.hostId = "8a58cb2f";
networking.useDHCP = true;
networking.interfaces.enp6s0.ipv4.addresses = [
{
address = "46.4.63.148";
prefixLength = 27;
}
{
address = "46.4.63.158";
prefixLength = 27;
}
];
networking.interfaces.enp6s0.ipv6.addresses = [ {
address = "2a01:4f8:140:84c9::1";
prefixLength = 64;
} ];
networking.defaultGateway = "46.4.63.129";
networking.nameservers = [
"1.1.1.1" "1.0.0.1"
"2606:4700:4700::1111" "2606:4700:4700::1001"
];
networking.defaultGateway6 = {
address = "fe80::1";
interface = "enp6s0";
};
networking.nat.enable = true;
networking.nat.internalInterfaces = ["ve-+"];
networking.nat.externalInterface = "enp6s0";
networking.firewall.allowedTCPPorts = [ 22 80 443 ];
# networking.firewall.allowedUDPPorts = [ ... ];
# networking.firewall.enable = false;
# misc
time.timeZone = "UTC";
environment.systemPackages = with pkgs; [
wget vim git
];
services.openssh.enable = true;
services.openssh.ports = [ 22 62954 ];
users.users.root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDNVUDKx9sukRkb6INny432+2HZBWx/qIEAOvngF1qcj hexchen@montasch"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL6JWi0MBDz0Zy4zjauQv28xYmHyapb8D4zeesq91LLE schweby@txsbcct"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCvmrk3i04tXfrSlZtHFbG3o6lQgh3ODMWmGDING4TJ4ctidexmMNY15IjVjzXZgQSET1uKLDLITiaPsii8vaWERZfjm3jjub845mpKkKv48nYdM0eCbv7n604CA3lwoB5ebRgULg4oGTi60rQ4trFf3iTkJfmiLsieFBZz7l+DfgeDEjDNSJcrkOggGBrjE5vBXoDimdkNh8kBNwgMDj1kPR/FHDqybSd5hohCJ5FzQg9vzl/x/H1rzJJKYPO4svSgHkYNkeoL84IZNeHom+UEHX0rw2qAIEN6AiHvNUJR38relvQYxbVdDSlaGN3g26H2ehsmolf+U0uQlRAXTHo0NbXNVYOfijFKL/jWxNfH0aRycf09Lu60oY54gkqS/J0GoQe/OGNq1Zy72DI+zAwEzyCGfSDbAgVF7Y3mU2HqcqGqNzu7Ade5oCbLmkT7yzDM3x6IsmT1tO8dYiT8Qv+zFAECkRpw3yDkJkPOxNKg10oM318whMTtM3yqntE90hk= schweby@taxusbaccata"
];
initialHashedPassword = "$6$F316njEF2$GMF4OmPSF6QgZ3P/DblQ/UFMgoo98bztbdw7X0ygvBGC1UMMIc13Vtxjd/ZGRYW/pEHACZZ7sbRZ48t6xhvO7/";
# shell = pkgs.fish;
};
# storage stuffs!
services.zfs = {
autoSnapshot = {
enable = true;
};
autoScrub = {
enable = true;
};
};
services.journald.extraConfig = ''
MaxFileSec=6h
MaxRetentionSec=72h
'';
boot.kernelPackages = pkgs.linuxPackages;
# 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. Its 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.03"; # Did you read the comment?
}

View file

@ -1,28 +0,0 @@
{ config, lib, pkgs, ... }:
{
boot.initrd.kernelModules = [ "r8169" ]; # add network card driver
boot.kernelParams = ["ip=:::::enp6s0:dhcp"]; # enable dhcp on primary network interface
boot.initrd.network = {
enable = true;
ssh = {
enable = true;
port = 2222;
# TODO: Modify system config so that this works
# authorizedKeys = with lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
authorizedKeys = config.users.users.root.openssh.authorizedKeys.keys;
hostKeys = [ /run/keys/ecdsa_host ];
};
# TODO: curl some webhook here to alert?
# possibly quite hard to do, we only have limited wget or netcat available
# how this all works:
# when someone logs in via ssh, they are prompted to unlock the zfs volume
# afterwards zfs is killed in order for the boot to progress
# timeout of 120s still applies afaik
postCommands = ''
zpool import zroot
zpool import dpool
echo "zfs load-key -a; killall zfs && exit" >> /root/.profile
'';
};
}

View file

@ -1,52 +0,0 @@
{ config, lib, pkgs, ... }:
{
boot.initrd.availableKernelModules = [ "uhci_hcd" "ahci" "sd_mod" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "zroot/root/nixos";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "zroot/root/nixos/nix";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "dpool/home";
fsType = "zfs";
};
fileSystems."/var/lib/containers" =
{ device = "dpool/containers";
fsType = "zfs";
};
fileSystems."/var/lib/docker" =
{ device = "dpool/docker";
fsType = "zfs";
};
fileSystems."/var/lib/gitlab-runner" =
{ device = "dpool/gitlab-runner";
fsType = "zfs";
};
fileSystems."/data" =
{ device = "dpool/data";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/40125f55-7fe8-4850-902e-b4d6e22f0335";
fsType = "ext2";
};
swapDevices = [ ];
nix.maxJobs = lib.mkDefault 12;
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
}

View file

@ -1,125 +0,0 @@
{ config, pkgs, ... }:
{
services.etcd = {
advertiseClientUrls = [
"https://[2a0d:eb04:8:10::1]:2379"
];
listenClientUrls = [
"https://[2a0d:eb04:8:10::1]:2379"
];
listenPeerUrls = [
"https://[::1]:2380"
];
};
services.kubernetes = {
roles = [ "master" "node" ];
flannel.enable = false;
addons.dns = {
enable = true;
clusterIp = "2a0d:eb04:8:11::53";
reconcileMode = "EnsureExists";
};
pki.cfsslAPIExtraSANs = [ "hainich.hacc.space" ];
apiserver = {
advertiseAddress = "2a0d:eb04:8:10::1";
extraSANs = [
"2a0d:eb04:8:10::1" "2a0d:eb04:8:11::1" "hainich.hacc.space"
];
bindAddress = "::";
insecureBindAddress = "::1";
etcd = {
servers = [ "https://[2a0d:eb04:8:10::1]:2379" ];
};
serviceClusterIpRange = "2a0d:eb04:8:11::/120";
extraOpts = "--allow-privileged=true";
};
controllerManager = {
bindAddress = "::";
clusterCidr = "2a0d:eb04:8:12::/64";
};
kubelet = {
address = "::";
clusterDns = "2a0d:eb04:8:11::53";
};
proxy = {
bindAddress = "::";
};
scheduler = {
address = "::1" ;
};
apiserverAddress = "https://[2a0d:eb04:8:10::1]:6443";
clusterCidr = "2a0d:eb04:8:12::/64";
easyCerts = true;
masterAddress = "hainich.hacc.space";
};
networking.firewall = {
allowedTCPPorts = [ 80 443 6443 ];
trustedInterfaces = [
"cbr0" "tunnat64"
];
extraCommands = ''
iptables -t nat -A POSTROUTING -o enp6s0 -j SNAT --to 46.4.63.158
iptables -A FORWARD -i tunnat64 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp -d 46.4.63.158 --dport 80 -j DNAT --to-destination 10.255.255.2:80
iptables -t nat -A PREROUTING -p tcp -d 46.4.63.158 --dport 443 -j DNAT --to-destination 10.255.255.2:443
iptables -t nat -A PREROUTING -p tcp -d 46.4.63.158 --dport 6443 -j DNAT --to-destination 10.255.255.1:443
ip6tables -A FORWARD -i tunnat64 -j ACCEPT
ip6tables -A INPUT -i tunnat64 -j ACCEPT
'';
extraStopCommands = ''
iptables -t nat -D POSTROUTING -o enp6s0 -j SNAT --to 46.4.63.158
iptables -D FORWARD -i tunnat64 -j ACCEPT
iptables -t nat -D PREROUTING -p tcp -d 46.4.63.158 --dport 80 -j DNAT --to-destination 10.255.255.2:80
iptables -t nat -D PREROUTING -p tcp -d 46.4.63.158 --dport 443 -j DNAT --to-destination 10.255.255.2:443
iptables -t nat -D PREROUTING -p tcp -d 46.4.63.158 --dport 6443 -j DNAT --to-destination 10.255.255.1:443
ip6tables -A FORWARD -i tunnat64 -j ACCEPT
ip6tables -A INPUT -i tunnat64 -j ACCEPT
'';
};
systemd.services.tayga = (let
config = pkgs.writeText "tayga.conf" ''
tun-device tunnat64
ipv4-addr 10.255.255.254
prefix 2a0d:eb04:8:10:64::/96
dynamic-pool 10.255.255.0/24
map 10.255.255.1 2a0d:eb04:8:10::1
map 10.255.255.2 2a0d:eb04:8:11::2
strict-frag-hdr 1
'';
startScript = pkgs.writeScriptBin "tayga-start" ''
#! ${pkgs.runtimeShell} -e
${pkgs.iproute}/bin/ip link set up tunnat64 || true
${pkgs.iproute}/bin/ip route add 10.255.255.0/24 dev tunnat64 || true
${pkgs.iproute}/bin/ip -6 route add 2a0d:eb04:8:10:64::/96 dev tunnat64 || true
${pkgs.tayga}/bin/tayga -d --config ${config}
'';
in {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = ''${startScript}/bin/tayga-start'';
};
});
networking.interfaces.cbr0.ipv6.routes = [{
address = "2a0d:eb04:8:10::";
prefixLength = 60;
}];
networking.interfaces.tunnat64 = {
virtual = true;
};
# openebs expects some stuff to be there.
system.activationScripts.openebs = ''
mkdir -p /usr/lib /usr/sbin
ln -sf ${pkgs.zfs.lib}/lib/* /usr/lib/
ln -sf ${pkgs.zfs}/bin/zfs /usr/sbin/
'';
}

View file

@ -1,80 +0,0 @@
{ config, lib, pkgs, ... }:
{
containers.codimd = {
privateNetwork = true;
hostAddress = "192.168.100.1";
localAddress = "192.168.100.3";
autoStart = true;
config = { config, lib, pkgs, ... }: {
networking.firewall.allowedTCPPorts = [ 3000 ];
services.coredns = {
enable = true;
config = ''
.:53 {
forward . 1.1.1.1
}
'';
};
services.hedgedoc = {
enable = true;
configuration = {
allowAnonymous = true;
allowFreeURL = true;
allowGravatar = false;
allowOrigin = [ "localhost" "pad.hacc.space" "fff-muc.de" ];
dbURL = "postgres://codimd:codimd@localhost:5432/codimd";
defaultPermission = "limited";
domain = "pad.hacc.space";
host = "0.0.0.0";
protocolUseSSL = true;
hsts.preload = false;
email = false;
oauth2 = {
authorizationURL = "https://auth.infra4future.de/auth/realms/forfuture/protocol/openid-connect/auth";
tokenURL = "https://auth.infra4future.de/auth/realms/forfuture/protocol/openid-connect/token";
clientID = "codimd";
clientSecret = "1a730af1-4d6e-4c1d-8f7e-72375c9b8d62";
};
};
};
systemd.services.hedgedoc.environment = {
"CMD_OAUTH2_USER_PROFILE_URL" = "https://auth.infra4future.de/auth/realms/forfuture/protocol/openid-connect/userinfo";
"CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR" = "name";
"CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR" = "display-name";
"CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR" = "email";
"CMD_OAUTH2_PROVIDERNAME" = "Infra4Future";
};
services.postgresql = {
enable = true;
ensureDatabases = [ "codimd" ];
ensureUsers = [{
name = "codimd";
ensurePermissions = {
"DATABASE codimd" = "ALL PRIVILEGES";
};
}];
};
};
};
services.nginx.virtualHosts."pad.hacc.space" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://192.168.100.3:3000";
extraConfig = ''
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
add_header Access-Control-Allow-Origin "*";
proxy_buffering off;
'';
};
};
}

View file

@ -1,34 +0,0 @@
{ config, lib, pkgs, ... }:
{
# disable nftables since it breaks shit
petabyte.nftables.enable = false;
virtualisation.oci-containers.containers."ghost-waszumfff" = {
autoStart = true;
environment = {
url = "https://waszumfff.4future.dev";
};
image = "ghost:alpine";
ports = [ "127.0.0.1:2368:2368" ];
volumes = [ "/run/florinori:/var/lib/ghost/content" ];
};
fileSystems."/run/florinori" =
{ device = "dpool/k8s/florinori";
fsType = "zfs";
};
services.nginx.virtualHosts."waszumfff.4future.dev" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:2368";
extraConfig = "
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
";
};
};
}

View file

@ -1,93 +0,0 @@
{ config, lib, pkgs, ... }:
# TODO: Make this confix nix-y, so it doesn't require a metric shitton of
# manual intervention to install
{
containers.engelsystem = {
config = { pkgs, lib, config, ... }:
let
app = "engelsystem";
domain = "himmel.hacc.earth";
dataDir = "/srv/http/${domain}/public";
engelport-py-pack = python-packages: with pkgs.python38Packages; [
mysqlclient
];
engelport-py = pkgs.python38.withPackages engelport-py-pack;
in {
networking.firewall.enable = false;
networking.nameservers = ["1.1.1.1" "1.0.0.1"];
networking.hosts."192.168.100.1" = [ "mail.hacc.space" ];
services.phpfpm.pools.${app} = {
user = app;
settings = {
"listen.owner" = config.services.nginx.user;
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 5;
"php_admin_value[error_log]" = "stderr";
"php_admin_flag[log_errors]" = true;
"catch_workers_output" = true;
};
phpEnv."PATH" = lib.makeBinPath [ pkgs.php ];
};
services.nginx = {
enable = true;
virtualHosts.${domain}.locations = {
"/" = {
extraConfig = "rewrite ^ /index.php;";
};
"/assets" = {
root = dataDir;
};
"/index.php" = {
root = dataDir;
extraConfig = ''
include ${pkgs.nginx}/conf/fastcgi.conf;
fastcgi_split_path_info ^(.+\.php)(\\/.*)$;
try_files $fastcgi_script_name =404;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:${config.services.phpfpm.pools.${app}.socket};
fastcgi_intercept_errors on;
'';
};
};
};
users.users.${app} = {
isSystemUser = true;
createHome = true;
home = dataDir;
group = app;
};
users.groups.${app} = {};
services.mysql = {
enable = true;
ensureDatabases = [ "engelsystem" ];
ensureUsers = [{
name = "engelsystem";
ensurePermissions."engelsystem.*" = "ALL PRIVILEGES";
}];
package = pkgs.mariadb;
};
environment.systemPackages = [
pkgs.php pkgs.php74Packages.composer pkgs.yarn engelport-py
];
};
privateNetwork = true;
hostAddress = "192.168.100.1";
localAddress = "192.168.100.2";
autoStart = true;
};
services.nginx.virtualHosts."himmel.hacc.earth" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://192.168.100.2";
extraConfig = "add_header Host himmel.hacc.earth;";
};
};
}

View file

@ -1,55 +0,0 @@
{ config, lib, pkgs, ... }:
{
containers.funkwhale = {
inherit pkgs;
privateNetwork = true;
hostAddress = "192.168.100.1";
localAddress = "192.168.100.4";
autoStart = true;
config = { config, lib, pkgs, ... }: {
imports = [
../../../../modules
];
services.coredns = {
enable = true;
config = ''
.:53 {
forward . 1.1.1.1
}
'';
};
networking.firewall.enable = false;
services.funkwhale = {
enable = true;
apiIp = "192.168.100.4";
hostname = "funkwhale.hacc.media";
protocol = "https";
defaultFromEmail = "funkwhale@hacc.media";
api.djangoSecretKey = "TwsgANNKid+HZ0HwhR/FgTcxFIW6sZ8s4n7HxV6zPdU=";
};
services.nginx.virtualHosts."funkwhale.hacc.media" = {
enableACME = lib.mkForce false;
forceSSL = lib.mkForce false;
};
};
};
services.nginx.virtualHosts."funkwhale.hacc.media" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://192.168.100.4";
extraConfig = ''
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_buffering off;
'';
};
};
}

View file

@ -1,62 +0,0 @@
{config, pkgs, lib, ...}:
{
services.gitlab-runner = {
enable = true;
concurrent = 4;
services = {
infra4future = {
buildsDir = "/var/lib/gitlab-runner/builds";
dockerImage = "nixos/nix";
executor = "docker";
registrationConfigFile = "/run/gitlab-runner.env";
};
nix = {
registrationConfigFile = "/run/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 = "/var/lib/gitlab-runner";
extraGroups = [ "docker" ];
isSystemUser = true;
};
virtualisation.docker.storageDriver = "zfs";
}

View file

@ -1,154 +0,0 @@
{ config, pkgs, lib, ... }:
{
imports = let commit = "02a45d9965133434c7b816cab2f47c8a7505e764"; in [
(builtins.fetchTarball {
url = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/${commit}/nixos-mailserver-${commit}.tar.gz";
sha256 = "04v66z0ijjm8bqpiqmq1aqrqj6r6jjz591lgijmk4frz7lksnz8k";
})
];
mailserver = {
mailDirectory = "/data/mail";
enable = true;
fqdn = "mail.hacc.space";
domains = [ "hacc.space" "hacc.earth" "4future.dev" "4futu.re" ];
loginAccounts = {
"hexchen@hacc.space" = {
hashedPassword = "$6$x9skYtRp4dgxC$1y8gPC2BuVqG3kJVSMGgzZv0Bg1T9qxcnBWLIDbANy1d//SQ23Y7s3IMYcEPd1/l/MYWD9Y/Qse6HbT5w5Xwq/";
aliases = [
"postmaster@hacc.space"
"abuse@hacc.space"
];
};
"octycs@hacc.space" = {
hashedPassword = "$6$KceTivtJ$58jxhYF6ULfivNsb3Z0J7PnGea0Hs2wTWh3c9FrKRIAmuOD96u2IDgZRCn6P5NrXA0BL.n6HC2RS3r.4JnOmg.";
aliases = [
"markus@hacc.space"
];
};
"raphael@hacc.space" = {
hashedPassword = "$6$QveHpwMcp9mkFVAU$EFuahOrJIxPg.c.WGFHtrP3.onwJYwvP7fiBHHGb9jhosewZ2tEUP.2D3uyDLhd9Cfny6Yp4jDk/Hkjk7/ME1/";
};
"engelsystem@hacc.space" = {
hashedPassword = "$6$5cIAEhJ7af7M$eJBPQc3ONd.N3HKPFpxfG7liZbUXPvWuSpWVgeG7rmsG7f7.Zdxtodvt5VaXoA3AEiv3GqcY.gKHISK/Gg0ib/";
};
"schweby@hacc.space" = {
hashedPassword = "$6$BpYhwcZNrkLhVqK$6FMqA/vUkdV4GBlHLSqS5DRCb/CaLDNeIsBcZ8G30heytS/tJj2Ag7b1ovSltTA4PUfhee3pJrz1BkwkA93vN1";
};
"zauberberg@hacc.space" = {
hashedPassword = "$6$ISAaU8X6D$oGKe9WXDWrRpGzHUTdxrxdtg9zuGOlBMuDc82IZhegpsv1bqd550FhZZrI40IjZTA5Hy2MZ8j/0efpnQ4fOQH0";
aliases = [
"lukas@hacc.space"
];
};
"talx@hacc.space" = {
hashedPassword = "$6$0hIKRoMJS./JSE$tXizRgphhNM3ZYx216VdRv1OiyZoYXsjGqSudTDu8vB8eZb03Axi31VKV87RXiEGGixdvTsHEKpx032aOzzt31";
};
"unms@hacc.space" = {
hashedPassword = "$6$pYlNP37913$sGE3L722ceP.1Qm5lsffYUN919hPP1xRTrzco3ic3Op21iiknBkOY04eY2l3Um/Bpk/yV89aJD0eaB/5RCbWR1";
};
"noreply@hacc.space" = {
hashedPassword = "$6$YsqMoItITZUzI5wo$5Lejf8XBHRx4LW4VuZ9wJCiBbT4kOV/EZaCdWQ07eVIrkRTZwXWZ5zfsh.olXEFwvpNWN.DBnU.dQc.cC0/ra/";
};
"stuebinm@hacc.space" = {
hashedPassword = "$6$mjrMQG5smqLRlm$WzmbiZnGlEXGT7hj/n2qz0nvVzGyZfMToCyLRi0wErfVEHI7y7jtWoHqIWnpcHAM29UocsIFFsUCb3XqQCwwB.";
};
"newsletter@hacc.space" = {
hashedPassword = "$6$f0xKnQxBInd$zbVIi1lTKWauqW.c8sMNLHNwzn81oQrVOiIfJwPa98n9xWz/NkjuWLYuFpK.MSZwNwP7Yv/a/qaOb9v8qv/.N1";
};
"lenny@hacc.space" = {
hashedPassword = "$6$dR.lhYiJDpsR4.dw$n7bCbyTm97v/O8Ue44n58YwOmmct..Gt5TeAmen8C5FWyPTwTh65XCjwc27gNFVGnZLwsRJwMJ.E9D0oJEzUh0";
};
};
extraVirtualAliases = {
# address = forward address;
"info@hacc.space" = [
"hexchen@hacc.space"
"octycs@hacc.space"
"raphael@hacc.space"
"schweby@hacc.space"
"zauberberg@hacc.space"
"stuebinm@hacc.space"
"lenny@hacc.space"
];
"himmel@hacc.space" = [
"hexchen@hacc.space"
"schweby@hacc.space"
"zauberberg@hacc.space"
];
"admin@hacc.space" = [
"hexchen@hacc.space"
"schweby@hacc.space"
];
"voc@hacc.space" = [
"hexchen@hacc.space"
"schweby@hacc.space"
"octycs@hacc.space"
"stuebinm@hacc.space"
"zauberberg@hacc.space"
"lenny@hacc.space"
];
"vorstand@hacc.space" = [
"raphael@hacc.space"
"schweby@hacc.space"
"zauberberg@hacc.space"
];
"mitglieder@hacc.space" = [
"raphael@hacc.space"
"schweby@hacc.space"
"zauberberg@hacc.space"
"lenny@hacc.space"
"octycs@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 = "reject_non_fqdn_sender,reject_unknown_sender_domain,permit";
services.postfix.virtual = ''
@4future.dev @hacc.space
@4futu.re @hacc.space
@hacc.earth @hacc.space
contact@hacc.space info@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";
};
services.nginx.virtualHosts."mail.hacc.space" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://[::1]:1323";
};
}

View file

@ -1,26 +0,0 @@
{ config, lib, pkgs, ... }:
{
services.murmur = {
enable = true;
logDays = -1;
welcometext = "Welcome to mumble4future! Brought to you by infra4future";
sslKey = "/var/lib/acme/mumble.hacc.space/key.pem";
sslCert = "/var/lib/acme/mumble.hacc.space/fullchain.pem";
bandwidth = 128000;
};
networking.firewall.allowedTCPPorts = [ config.services.murmur.port ];
networking.firewall.allowedUDPPorts = [ config.services.murmur.port ];
services.nginx.virtualHosts."mumble.hacc.space" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "https://stuebinm.4future.dev/mumble.infra4future.de/";
};
};
# set ACLs so that the murmur user can read the certificates
security.acme.certs."mumble.hacc.space".postRun = "setfacl -Rm u:murmur:rX /var/lib/acme/mumble.hacc.space";
}

View file

@ -1,61 +0,0 @@
{ config, lib, pkgs, ... }:
{
security.acme.acceptTerms = true;
security.acme.email = "info+acme@hacc.space";
services.nginx.enable = true;
services.nginx.package = pkgs.nginx.override {
modules = [ pkgs.nginxModules.rtmp ];
};
# services.nginx.recommendedProxySettings = true;
services.nginx.virtualHosts = let
rc3clustersite = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "https://stuebinm.4future.dev/about-future-website/";
};
in {
"hainich.chaoswit.ch" = {
enableACME = true;
forceSSL = true;
};
"hainich.hacc.space" = {
enableACME = true;
forceSSL = true;
locations = {
"/" = {
return = "404";
};
};
};
"freedom.rc3.io" = rc3clustersite;
"future.rc3.io" = rc3clustersite;
};
networking.firewall.allowedTCPPorts = [ 1935 ];
services.nginx.appendConfig = ''
rtmp {
server {
listen 1935;
application cutiestream {
live on;
allow publish all;
allow play all;
}
application ingest {
live on;
record all;
record_path /data/ingest;
record_unique on;
include /var/secrets/ingest.conf;
}
}
}
'';
systemd.services.nginx.serviceConfig.ReadWriteDirectories = "/data/ingest /var/secrets";
}

View file

@ -1,34 +0,0 @@
{ config, lib, pkgs, ... }:
{
systemd.services.wireguard-upstream = {
wants = [ "wg-upstream-key.service" ];
after = [ "wg-upstream-key.service" ];
};
networking.wireguard.interfaces.upstream = {
ips = [ "2a0d:eb04:8:ffff:2::2/128" ];
generatePrivateKeyFile = true;
privateKeyFile = "/etc/wireguard/upstream.key";
listenPort = 51820;
peers = [
{
allowedIPs = [ "::/0" ];
endpoint = "103.105.50.220:51823";
publicKey = "qL5xKnQ7xLbtTvu0VmLBwHExteJBhmCe5S/0ZoXBeXY=";
}
];
postSetup = ''
${pkgs.iproute}/bin/ip addr del dev upstream 2a0d:eb04:8:ffff:2::2/128
${pkgs.iproute}/bin/ip addr add dev upstream 2a0d:eb04:8:ffff:2::2/128 peer 2a0d:eb04:8:ffff:2::1/128
'';
};
networking.interfaces.lo.ipv6 = {
addresses = [{
address = "2a0d:eb04:8:10::1";
prefixLength = 128;
}];
};
networking.defaultGateway6 = {
address = "2a0d:eb04:8:ffff:2::1";
interface = "upstream";
};
}

View file

@ -1,26 +0,0 @@
{config, lib, pkgs, ...}:
{
imports = [
./common.nix
];
services.nginx = {
virtualHosts."${config.networking.hostName}.live.hacc.media" = {
locations = {
"/" = {
return = "301 \"https://$cdnhosts$request_uri\"";
extraConfig = ''
auth_basic off;
add_header 'Access-Control-Allow-Origin' '*';
'';
};
};
};
appendHttpConfig = ''
split_clients "$remote_addr" $cdnhosts {
50% "cdn-node-1.live.hacc.media";
50% "cdn-node-2.live.hacc.media";
}
'';
};
}

View file

@ -1,42 +0,0 @@
{config, lib, pkgs, ...}:
let
host-server = "https://rosenbaum.lukas.studio";
in {
imports = [
./common.nix
];
services.nginx = {
virtualHosts."${config.networking.hostName}.live.hacc.media" = {
locations = {
"~* \\.(m3u8)$" = {
proxyPass = "${host-server}$request_uri";
extraConfig = ''
#proxy_cache = off;
expires 2s;
auth_basic off;
'';
};
"/hls" = {
proxyPass = "${host-server}$request_uri";
extraConfig = ''
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
proxy_cache hls;
proxy_ignore_headers Cache-Control;
proxy_cache_valid any 30m;
auth_basic off;
'';
};
};
};
appendHttpConfig = ''
proxy_cache_path /tmp keys_zone=hls:10m max_size=10g inactive=60m use_temp_path=on;
resolver 1.1.1.1;
'';
};
}

View file

@ -1,43 +0,0 @@
{config, lib, pkgs, ...}:
{
imports = [
./common.nix
];
# Enable nginx service
services.nginx = {
virtualHosts."${config.networking.hostName}.live.hacc.media" = {
forceSSL = true;
enableACME = true;
# basicAuth = basicAuthLogin;
locations = {
"~* \\.(m3u8)$" = {
proxyPass = "https://cdn-master.live.hacc.media$request_uri";
extraConfig = ''
#proxy_cache = off;
expires 3s;
auth_basic off;
'';
};
"/hls" = {
proxyPass = "https://cdn-master.live.hacc.media$request_uri";
extraConfig = ''
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
proxy_cache hls;
proxy_ignore_headers Cache-Control;
proxy_cache_valid any 30m;
auth_basic off;
'';
};
};
};
appendHttpConfig = ''
proxy_cache_path /tmp keys_zone=hls:10m max_size=10g inactive=60m use_temp_path=on;
resolver 1.1.1.1;
'';
};
}

View file

@ -1,61 +0,0 @@
{config, lib, pkgs, ...}:
{
networking.firewall.allowedTCPPorts = [
80 # HTTP
443 # HTTPs
];
services.netdata = {
enable = true;
configText = ''
[global]
dbengine multihost disk space = 2307
'';
};
# Enable nginx service
services.nginx = {
enable = true;
# Use recommended settings
# Don't use recommended Proxy settings because it does funky things with the setup
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
virtualHosts."${config.networking.hostName}.live.hacc.media" = {
forceSSL = true;
enableACME = true;
# basicAuth = basicAuthLogin;
locations = {
"/stats" = {
return = "301 /stats/";
};
"~ /stats/(?<ndpath>.*)" = {
proxyPass = "http://127.0.0.1:19999/$ndpath$is_args$args";
extraConfig = ''
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_pass_request_headers on;
proxy_set_header Connection "keep-alive";
proxy_store off;
gzip on;
gzip_proxied any;
gzip_types *;
'';
};
"/nginx_status" = {
extraConfig = ''
stub_status;
auth_basic off;
'';
};
};
};
};
}

View file

@ -1,4 +1,11 @@
{
inherit (import ./lib/deploy.nix) deploy;
pkgs = import ./pkgs;
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; };
}

35
desktop/default.nix Normal file
View file

@ -0,0 +1,35 @@
{ 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";
};
}

View file

@ -7,13 +7,4 @@
};
environment.systemPackages = with pkgs; [ obs-studio ];
home-manager.users.hexchen = {
programs.obs-studio = {
enable = true;
plugins = with pkgs; [
obs-wlrobs obs-v4l2sink
];
};
};
}

View file

@ -1,4 +1,4 @@
{ config, pkgs, ... }:
{ config, pkgs, lib, ... }:
{
imports =
@ -7,7 +7,6 @@
../../common
../../desktop
../../desktop/streaming.nix
../../desktop/sway.nix
../../desktop/gnome.nix
];
@ -26,14 +25,15 @@
networking.hostName = "nixda"; # Define your hostname.
environment.systemPackages = with pkgs; [ blackmagicDesktopVideo makemkv blender ];
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 = "ip link set dev cornbox mtu 1400";
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";
@ -41,6 +41,34 @@
];
};
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. Its perfectly fine and recommended to leave

View file

@ -0,0 +1,96 @@
{ config, lib, pkgs, sources, modules, ... }:
{
imports = [
../../common
./hardware.nix
modules.encboot
modules.network.nftables modules.nftnat
((import sources.nix-hexchen) {}).profiles.nopersist
../../services/nextcloud
../../services/mattermost.nix
../../services/thelounge.nix
../../services/murmur.nix
../../services/hedgedoc-hacc.nix
../../services/hedgedoc-i4f.nix
../../services/mail.nix
../../services/syncthing.nix
../../services/gitea.nix
../../services/nginx-pages.nix
../../services/lantifa.nix
../../services/vaultwarden.nix
../../services/uffd.nix
# ../../services/workadventure.nix
./lxc.nix
];
hexchen.encboot = {
enable = true;
dataset = "-a";
networkDrivers = [ "igb" ];
};
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.devices = [ "/dev/nvme0n1" "/dev/nvme1n1" ];
boot.supportedFilesystems = [ "zfs" ];
networking.hostId = "b2867696";
networking.useDHCP = true;
networking.nftables.enable = true;
hexchen.nftables.nat.enable = true;
networking.nat.internalInterfaces = ["ve-+"];
networking.nat.externalInterface = "enp35s0";
networking.interfaces.enp35s0.ipv6.addresses = [{
address = "2a01:4f9:3a:2ddb::1";
prefixLength = 64;
}];
networking.defaultGateway6 = {
address = "fe80::1";
interface = "enp35s0";
};
boot = {
kernelModules = [ "nf_nat_ftp" ];
kernel.sysctl = {
"net.ipv4.conf.all.forwarding" = lib.mkOverride 90 true;
"net.ipv4.conf.default.forwarding" = lib.mkOverride 90 true;
};
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"parsons.hacc.space" = {
default = true;
locations."/".return = "404";
};
"hacc.space" = {
enableACME = true;
forceSSL = true;
locations."/".return = "302 https://hacc.earth";
};
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.restic.backups.tardis = {
passwordFile = "/persist/restic/system";
environmentFile = "/persist/restic/system.s3creds";
paths = [
"/home"
"/persist"
];
pruneOpts = [
"--keep-daily 7"
"--keep-weekly 5"
"--keep-monthly 3"
];
repository = "b2:tardis-parsons:system";
};
system.stateVersion = "21.05";
}

View file

@ -0,0 +1,65 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "zroot/local/root";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/daf2a731-952f-45c7-9c25-49e1a2f56062";
fsType = "ext4";
};
fileSystems."/nix" =
{ device = "zroot/local/nix";
fsType = "zfs";
};
fileSystems."/persist" =
{ device = "zroot/safe/persist";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "zroot/safe/home";
fsType = "zfs";
};
fileSystems."/root" =
{ device = "zroot/safe/root";
fsType = "zfs";
};
fileSystems."/var/cache/restic-backups-tardis" =
{ device = "zroot/safe/restic-cache";
fsType = "zfs";
};
fileSystems."/tmp" =
{ device = "zroot/local/tmp";
fsType = "zfs";
};
fileSystems."/persist/data" =
{ device = "dpool/safe/data";
fsType = "zfs";
};
fileSystems."/var/lib/docker" =
{ device = "zroot/local/docker";
fsType = "zfs";
};
swapDevices = [ ];
}

36
hosts/parsons/lxc.nix Normal file
View file

@ -0,0 +1,36 @@
{ config, lib, pkgs, ... }:
{
networking.bridges.lxcbr0.interfaces = [];
networking.interfaces.lxcbr0.ipv4.addresses = [
{
address = "10.1.2.1";
prefixLength = 24;
}
];
networking.nat.internalInterfaces = [ "lxcbr0" ];
virtualisation.lxc.enable = true;
virtualisation.lxc.systemConfig = ''
lxc.bdev.zfs.root = zroot/safe/containers/lxc
lxc.lxcpath = /persist/lxc
'';
users.users.root.subUidRanges = [{ count = 65536; startUid = 100000; }];
users.users.root.subGidRanges = [{ count = 65536; startGid = 100000; }];
environment.etc."lxc/share".source = "${pkgs.lxc}/share/lxc";
services.nginx.virtualHosts."onlyoffice.infra4future.de" = {
locations."/".proxyPass = "http://10.1.2.233:80";
enableACME = true;
forceSSL = true;
};
services.nginx.virtualHosts."auth.infra4future.de" = {
locations."/".proxyPass = "http://10.1.2.104:8080";
enableACME = true;
forceSSL = true;
};
}

View file

@ -1,76 +0,0 @@
let
pkgs = import <nixpkgs> {};
lib = pkgs.lib;
hosts = import ../configuration/hosts;
nixosHosts = lib.filterAttrs (name: host: host ? ssh) hosts;
allGroups = lib.unique (
lib.flatten (
lib.mapAttrsToList (
name: host: host.groups
) hosts
)
);
hostsInGroup = group:
lib.filterAttrs (
k: v: builtins.elem group v.groups
) hosts;
hostsInAllGroups = lib.listToAttrs (
map (
group: lib.nameValuePair group (
lib.attrNames (hostsInGroup group)
)
) allGroups );
mkDeploy = hostnames: pkgs.writeScript "deploy-${lib.concatStringsSep "-" hostnames}" ''
#!${pkgs.stdenv.shell}
set -e -o pipefail
export PATH=/run/wrappers/bin/:${with pkgs; lib.makeBinPath [
coreutils
openssh
nix
gnutar
findutils
nettools
gzip
git
]}
MODE=$1
shift || true
ARGS=$@
[ "$MODE" == "" ] && MODE="switch"
${lib.concatMapStrings (hostname: let
hostAttrs = nixosHosts.${hostname};
nixosSystem = (import <nixpkgs/nixos/lib/eval-config.nix> {
modules = [
"${toString ../configuration}/hosts/${hostname}/configuration.nix"
];
system = if hostAttrs ? system then hostAttrs.system else "x86_64-linux";
}).config.system.build.toplevel;
in ''
(
echo "deploying ${hostname}..."
nix copy --no-check-sigs -s --to ssh://${hostAttrs.ssh.host} ${nixosSystem}
ssh $NIX_SSHOPTS ${hostAttrs.ssh.host} "sudo nix-env -p /nix/var/nix/profiles/system -i ${nixosSystem}"
ssh $NIX_SSHOPTS ${hostAttrs.ssh.host} "sudo /nix/var/nix/profiles/system/bin/switch-to-configuration $MODE $ARGS"
) &
PID_LIST+=" $!"
'') hostnames}
echo "deploys started, waiting for them to finish..."
trap "kill $PID_LIST" SIGINT
wait $PID_LIST
'';
in {
deploy = (lib.mapAttrs (hostname: hostAttrs: mkDeploy [ hostname ]) nixosHosts)
// (lib.mapAttrs (group: hosts: mkDeploy hosts) hostsInAllGroups)
// { all = mkDeploy (lib.attrNames nixosHosts); };
}

21
modules/decklink.nix Normal file
View file

@ -0,0 +1,21 @@
{ 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";
};
};
}

View file

@ -1,13 +1,16 @@
{ ... }:
let
immaeNix = fetchGit {
url = "https://git.immae.eu/perso/Immae/Config/Nix.git";
rev = "7ad4966f41db0669a77c7a6ee7f87f0d4e586b0c";
};
sources = import ../nix/sources.nix;
in {
imports = [
"${immaeNix}/modules/webapps/peertube.nix"
./funkwhale
./nftnat
./decklink.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"
];
}

View file

@ -1,563 +0,0 @@
{config, lib, pkgs, ...}:
with lib;
let
django-cacheops = with final; with pkgs.python3.pkgs; ( buildPythonPackage rec {
pname = "django-cacheops";
version = "5.1";
src = fetchPypi {
inherit pname version;
sha256 = "sha256-1YUc178whzhKH87PqN3bj1UDDu39b98SciW3W8oPmd0=";
};
propagatedBuildInputs = [ django redis six funcy ];
doCheck = false;
});
pythonEnv = (pkgs.python3.override {
packageOverrides = self: super: rec {
django = self.django_2_2;
};
}).withPackages (ps: [
django-cacheops
ps.aioredis
ps.aiohttp
ps.arrow
ps.autobahn
ps.av
ps.bleach
ps.boto3
ps.celery
ps.channels
ps.channels-redis
ps.click
ps.django
ps.django-allauth
ps.django-auth-ldap
ps.django-oauth-toolkit
ps.django-cleanup
ps.django-cors-headers
ps.django-dynamic-preferences
ps.django_environ
ps.django-filter
ps.django_redis
ps.django-rest-auth
ps.djangorestframework
ps.djangorestframework-jwt
ps.django-storages
ps.django_taggit
ps.django-versatileimagefield
ps.feedparser
ps.gunicorn
ps.kombu
ps.ldap
ps.markdown
ps.mutagen
ps.musicbrainzngs
ps.pillow
ps.pendulum
ps.persisting-theory
ps.psycopg2
ps.pyacoustid
ps.pydub
ps.PyLD
ps.pymemoize
ps.pyopenssl
ps.python_magic
ps.pytz
ps.redis
ps.requests
ps.requests-http-signature
ps.service-identity
ps.unidecode
ps.unicode-slugify
ps.uvicorn
ps.watchdog
]);
cfg = config.services.funkwhale;
databasePassword = if (cfg.database.passwordFile != null)
then builtins.readFile cfg.database.passwordFile
else cfg.database.password;
databaseUrl = if (cfg.database.createLocally && cfg.database.socket != null)
then "postgresql:///${cfg.database.name}?host=${cfg.database.socket}"
else "postgresql://${cfg.database.user}:${databasePassword}@${cfg.database.host}:${toString cfg.database.port}/${cfg.database.name}";
funkwhaleEnvironment = [
"FUNKWHALE_URL=${cfg.hostname}"
"FUNKWHALE_HOSTNAME=${cfg.hostname}"
"FUNKWHALE_PROTOCOL=${cfg.protocol}"
"EMAIL_CONFIG=${cfg.emailConfig}"
"DEFAULT_FROM_EMAIL=${cfg.defaultFromEmail}"
"REVERSE_PROXY_TYPE=nginx"
"DATABASE_URL=${databaseUrl}"
"CACHE_URL=redis://localhost:${toString config.services.redis.port}/0"
"MEDIA_ROOT=${cfg.api.mediaRoot}"
"STATIC_ROOT=${cfg.api.staticRoot}"
"DJANGO_SECRET_KEY=${cfg.api.djangoSecretKey}"
"RAVEN_ENABLED=${boolToString cfg.enableRaven}"
"RAVEN_DSN=${cfg.ravenDsn}"
"MUSIC_DIRECTORY_PATH=${cfg.musicDirectoryPath}"
"MUSIC_DIRECTORY_SERVE_PATH=${cfg.musicDirectoryPath}"
"FUNKWHALE_FRONTEND_PATH=${cfg.dataDir}/front/dist"
];
funkwhaleEnvFileData = builtins.concatStringsSep "\n" funkwhaleEnvironment;
funkwhaleEnvScriptData = builtins.concatStringsSep " " funkwhaleEnvironment;
funkwhaleEnvFile = pkgs.writeText "funkwhale.env" funkwhaleEnvFileData;
funkwhaleEnv = {
ENV_FILE = "${funkwhaleEnvFile}";
};
in
{
options = {
services.funkwhale = {
enable = mkEnableOption "funkwhale";
user = mkOption {
type = types.str;
default = "funkwhale";
description = "User under which Funkwhale is ran.";
};
group = mkOption {
type = types.str;
default = "funkwhale";
description = "Group under which Funkwhale is ran.";
};
database = {
host = mkOption {
type = types.str;
default = "localhost";
description = "Database host address.";
};
port = mkOption {
type = types.int;
default = 5432;
defaultText = "5432";
description = "Database host port.";
};
name = mkOption {
type = types.str;
default = "funkwhale";
description = "Database name.";
};
user = mkOption {
type = types.str;
default = "funkwhale";
description = "Database user.";
};
password = mkOption {
type = types.str;
default = "";
description = ''
The password corresponding to <option>database.user</option>.
Warning: this is stored in cleartext in the Nix store!
Use <option>database.passwordFile</option> instead.
'';
};
passwordFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/keys/funkwhale-dbpassword";
description = ''
A file containing the password corresponding to
<option>database.user</option>.
'';
};
socket = mkOption {
type = types.nullOr types.path;
default = "/run/postgresql";
defaultText = "/run/postgresql";
example = "/run/postgresql";
description = "Path to the unix socket file to use for authentication for local connections.";
};
createLocally = mkOption {
type = types.bool;
default = true;
description = "Create the database and database user locally.";
};
};
dataDir = mkOption {
type = types.str;
default = "/srv/funkwhale";
description = ''
Where to keep the funkwhale data.
'';
};
apiIp = mkOption {
type = types.str;
default = "127.0.0.1";
description = ''
Funkwhale API IP.
'';
};
webWorkers = mkOption {
type = types.int;
default = 1;
description = ''
Funkwhale number of web workers.
'';
};
apiPort = mkOption {
type = types.port;
default = 5000;
description = ''
Funkwhale API Port.
'';
};
hostname = mkOption {
type = types.str;
description = ''
The definitive, public domain you will use for your instance.
'';
example = "funkwhale.yourdomain.net";
};
protocol = mkOption {
type = types.enum [ "http" "https" ];
default = "https";
description = ''
Web server protocol.
'';
};
emailConfig = mkOption {
type = types.str;
default = "consolemail://";
description = ''
Configure email sending. By default, it outputs emails to console instead of sending them. See https://docs.funkwhale.audio/configuration.html#email-config for details.
'';
example = "smtp+ssl://user@:password@youremail.host:465";
};
defaultFromEmail = mkOption {
type = types.str;
description = ''
The email address to use to send system emails.
'';
example = "funkwhale@yourdomain.net";
};
api = {
mediaRoot = mkOption {
type = types.str;
default = "/srv/funkwhale/media";
description = ''
Where media files (such as album covers or audio tracks) should be stored on your system ? Ensure this directory actually exists.
'';
};
staticRoot = mkOption {
type = types.str;
default = "/srv/funkwhale/static";
description = ''
Where static files (such as API css or icons) should be compiled on your system ? Ensure this directory actually exists.
'';
};
djangoSecretKey = mkOption {
type = types.str;
description = ''
Django secret key. Generate one using `openssl rand -base64 45` for example.
'';
example = "6VhAWVKlqu/dJSdz6TVgEJn/cbbAidwsFvg9ddOwuPRssEs0OtzAhJxLcLVC";
};
};
musicDirectoryPath = mkOption {
type = types.str;
default = "/srv/funkwhale/music";
description = ''
In-place import settings.
'';
};
enableRaven = mkOption {
type = types.bool;
default = false;
description = ''
Sentry/Raven error reporting (server side).
Enable Raven if you want to help improve funkwhale by
automatically sending error reports to the funkwhale developers Sentry instance.
This will help them detect and correct bugs.
'';
};
ravenDsn = mkOption {
type = types.str;
default = "https://44332e9fdd3d42879c7d35bf8562c6a4:0062dc16a22b41679cd5765e5342f716@sentry.eliotberriot.com/5";
description = ''
Sentry/Raven DSN.
The default is the Funkwhale developers instance DSN.
'';
};
};
};
config = mkIf cfg.enable {
assertions = [
{ assertion = cfg.database.passwordFile != null || cfg.database.password != "" || cfg.database.socket != null;
message = "one of services.funkwhale.database.socket, services.funkwhale.database.passwordFile, or services.funkwhale.database.password must be set";
}
{ assertion = cfg.database.createLocally -> cfg.database.user == cfg.user;
message = "services.funkwhale.database.user must be set to ${cfg.user} if services.funkwhale.database.createLocally is set true";
}
{ assertion = cfg.database.createLocally -> cfg.database.socket != null;
message = "services.funkwhale.database.socket must be set if services.funkwhale.database.createLocally is set to true";
}
{ assertion = cfg.database.createLocally -> cfg.database.host == "localhost";
message = "services.funkwhale.database.host must be set to localhost if services.funkwhale.database.createLocally is set to true";
}
];
users.users.funkwhale = mkIf (cfg.user == "funkwhale")
{ name = "funkwhale";
group = cfg.group;
};
users.groups.funkwhale = mkIf (cfg.group == "funkwhale") { name = "funkwhale"; };
services.postgresql = mkIf cfg.database.createLocally {
enable = true;
ensureDatabases = [ cfg.database.name ];
ensureUsers = [
{ name = cfg.database.user;
ensurePermissions = { "DATABASE ${cfg.database.name}" = "ALL PRIVILEGES"; };
}
];
};
services.redis.enable = true;
services.nginx = {
enable = true;
appendHttpConfig = ''
upstream funkwhale-api {
server ${cfg.apiIp}:${toString cfg.apiPort};
}
'';
virtualHosts =
let proxyConfig = ''
# global proxy conf
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Port $server_port;
proxy_redirect off;
# websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
'';
withSSL = cfg.protocol == "https";
in {
"${cfg.hostname}" = {
enableACME = withSSL;
forceSSL = withSSL;
root = "${pkgs.funkwhale}/front";
# gzip config is nixos nginx recommendedGzipSettings with gzip_types from funkwhale doc (https://docs.funkwhale.audio/changelog.html#id5)
extraConfig = ''
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:";
add_header Referrer-Policy "strict-origin-when-cross-origin";
gzip on;
gzip_disable "msie6";
gzip_proxied any;
gzip_comp_level 5;
gzip_types
application/javascript
application/vnd.geo+json
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
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;
gzip_vary on;
'';
locations = {
"/" = {
extraConfig = proxyConfig;
proxyPass = "http://funkwhale-api/";
};
"/front/" = {
alias = "${pkgs.funkwhale}/front/";
extraConfig = ''
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:";
add_header Referrer-Policy "strict-origin-when-cross-origin";
expires 30d;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
'';
};
"= /front/embed.html" = {
alias = "${pkgs.funkwhale}/front/embed.html";
extraConfig = ''
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header X-Frame-Options "ALLOW";
expires 30d;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
'';
};
"/federation/" = {
extraConfig = proxyConfig;
proxyPass = "http://funkwhale-api/federation/";
};
"/rest/" = {
extraConfig = proxyConfig;
proxyPass = "http://funkwhale-api/api/subsonic/rest/";
};
"/.well-known/" = {
extraConfig = proxyConfig;
proxyPass = "http://funkwhale-api/.well-known/";
};
"/media/".alias = "${cfg.api.mediaRoot}/";
"/_protected/media/" = {
extraConfig = ''
internal;
'';
alias = "${cfg.api.mediaRoot}/";
};
"/_protected/music/" = {
extraConfig = ''
internal;
'';
alias = "${cfg.musicDirectoryPath}/";
};
"/staticfiles/".alias = "${cfg.api.staticRoot}/";
};
};
};
};
systemd.tmpfiles.rules = [
"d ${cfg.dataDir} 0755 ${cfg.user} ${cfg.group} - -"
"d ${cfg.api.mediaRoot} 0755 ${cfg.user} ${cfg.group} - -"
"d ${cfg.api.staticRoot} 0755 ${cfg.user} ${cfg.group} - -"
"d ${cfg.musicDirectoryPath} 0755 ${cfg.user} ${cfg.group} - -"
];
systemd.targets.funkwhale = {
description = "Funkwhale";
wants = ["funkwhale-server.service" "funkwhale-worker.service" "funkwhale-beat.service"];
};
systemd.services =
let serviceConfig = {
User = "${cfg.user}";
WorkingDirectory = "${pkgs.funkwhale}";
EnvironmentFile = "${funkwhaleEnvFile}";
};
in {
funkwhale-psql-init = mkIf cfg.database.createLocally {
description = "Funkwhale database preparation";
after = [ "redis.service" "postgresql.service" ];
wantedBy = [ "funkwhale-init.service" ];
before = [ "funkwhale-init.service" ];
serviceConfig = {
User = "postgres";
ExecStart = '' ${config.services.postgresql.package}/bin/psql -d ${cfg.database.name} -c 'CREATE EXTENSION IF NOT EXISTS "unaccent";CREATE EXTENSION IF NOT EXISTS "citext";' '';
};
};
funkwhale-init = {
description = "Funkwhale initialization";
wantedBy = [ "funkwhale-server.service" "funkwhale-worker.service" "funkwhale-beat.service" ];
before = [ "funkwhale-server.service" "funkwhale-worker.service" "funkwhale-beat.service" ];
environment = funkwhaleEnv;
serviceConfig = {
User = "${cfg.user}";
Group = "${cfg.group}";
};
script = ''
${pythonEnv}/bin/python ${pkgs.funkwhale}/manage.py migrate
${pythonEnv}/bin/python ${pkgs.funkwhale}/manage.py collectstatic --no-input
if ! test -e ${cfg.dataDir}/createSuperUser.sh; then
echo "#!/bin/sh
${funkwhaleEnvScriptData} ${pythonEnv}/bin/python ${pkgs.funkwhale}/manage.py createsuperuser" > ${cfg.dataDir}/createSuperUser.sh
chmod u+x ${cfg.dataDir}/createSuperUser.sh
chown -R ${cfg.user}.${cfg.group} ${cfg.dataDir}
fi
if ! test -e ${cfg.dataDir}/config; then
mkdir -p ${cfg.dataDir}/config
ln -s ${funkwhaleEnvFile} ${cfg.dataDir}/config/.env
ln -s ${funkwhaleEnvFile} ${cfg.dataDir}/.env
fi
'';
};
funkwhale-server = {
description = "Funkwhale application server";
partOf = [ "funkwhale.target" ];
serviceConfig = serviceConfig // {
ExecStart = "${pythonEnv}/bin/gunicorn config.asgi:application -w ${toString cfg.webWorkers} -k uvicorn.workers.UvicornWorker -b ${cfg.apiIp}:${toString cfg.apiPort}";
};
environment = funkwhaleEnv;
wantedBy = [ "multi-user.target" ];
};
funkwhale-worker = {
description = "Funkwhale celery worker";
partOf = [ "funkwhale.target" ];
serviceConfig = serviceConfig // {
RuntimeDirectory = "funkwhaleworker";
ExecStart = "${pythonEnv}/bin/celery -A funkwhale_api.taskapp worker -l INFO";
};
environment = funkwhaleEnv;
wantedBy = [ "multi-user.target" ];
};
funkwhale-beat = {
description = "Funkwhale celery beat process";
partOf = [ "funkwhale.target" ];
serviceConfig = serviceConfig // {
RuntimeDirectory = "funkwhalebeat";
ExecStart = '' ${pythonEnv}/bin/celery -A funkwhale_api.taskapp beat -l INFO --schedule="/run/funkwhalebeat/celerybeat-schedule.db" --pidfile="/run/funkwhalebeat/celerybeat.pid" '';
};
environment = funkwhaleEnv;
wantedBy = [ "multi-user.target" ];
};
};
};
meta = {
maintainers = with lib.maintainers; [ mmai ];
};
}

251
modules/mattermost.nix Normal file
View file

@ -0,0 +1,251 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.mattermost-patched;
database = "postgres://${cfg.localDatabaseUser}:${cfg.localDatabasePassword}@localhost:5432/${cfg.localDatabaseName}?sslmode=disable&connect_timeout=10";
mattermostConf = foldl recursiveUpdate {}
[ { 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";
};
};
})
];
}

755
modules/nextcloud.nix Normal file
View file

@ -0,0 +1,755 @@
{ 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.&lt;name&gt;.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;
''}
'';
};
}
]);
}

View file

@ -0,0 +1,60 @@
{ 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}
}
}
'';
};
};
}

53
modules/websites.nix Normal file
View file

@ -0,0 +1,53 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.hacc.websites;
in
{
options.hacc.websites = {
enable = mkOption {
type = types.bool;
default = false;
};
directory = mkOption {
type = types.path;
description = "all subdirectories of the given path are expected to contain a (static) website";
};
ignore = mkOption {
type = types.listOf types.str;
default = [];
description = "subdirectories that shouldn't be published";
};
};
config = mkIf cfg.enable {
services.nginx = {
enable = true;
virtualHosts =
let
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);
};
};
}

102
nix/sources.json Normal file
View file

@ -0,0 +1,102 @@
{
"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": "2ea14ef395fad8919b2f4137642a7f50b370ffba",
"sha256": "1k5zqnc4yqnad2cw1wpqk22mjra08jz9gf4v692kbrgx3x4d13kh",
"type": "tarball",
"url": "https://github.com/mattermost/mattermost-server/archive/refs/tags/v6.7.2.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/refs/tags/v<version>.tar.gz",
"version": "6.7.2"
},
"mattermost-webapp": {
"sha256": "0pwjfklk0q28yza2iny0im5pq3x430jskvq6rvfq7ycx251s98hx",
"type": "tarball",
"url": "https://releases.mattermost.com/6.7.2/mattermost-6.7.2-linux-amd64.tar.gz",
"url_template": "https://releases.mattermost.com/<version>/mattermost-<version>-linux-amd64.tar.gz",
"version": "6.7.2"
},
"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": "eabc38219184cc3e04a974fe31857d8e0eac098d",
"sha256": "04ffwp2gzq0hhz7siskw6qh9ys8ragp7285vi1zh8xjksxn1msc5",
"type": "tarball",
"url": "https://github.com/nixos/nixpkgs/archive/eabc38219184cc3e04a974fe31857d8e0eac098d.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": "ae1dc133ea5f1538d035af41e5ddbc2ebcb67b90",
"sha256": "0dq22dagzk76x2ws4dz88w018i6byamd6rnzqizx68bzimg6g7xn",
"type": "tarball",
"url": "https://github.com/nixos/nixpkgs/archive/ae1dc133ea5f1538d035af41e5ddbc2ebcb67b90.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"
}
}

194
nix/sources.nix Normal file
View file

@ -0,0 +1,194 @@
# 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`!";
submodules = if spec ? submodules then spec.submodules else false;
submoduleArg =
let
nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0;
emptyArgWithWarning =
if submodules == true
then
builtins.trace
(
"The niv input \"${name}\" uses submodules "
+ "but your nix's (${builtins.nixVersion}) builtins.fetchGit "
+ "does not support them"
)
{}
else {};
in
if nixSupportsSubmodules
then { inherit submodules; }
else emptyArgWithWarning;
in
builtins.fetchGit
({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg);
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); }

View file

@ -0,0 +1,49 @@
{ 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;
};
}

View file

@ -0,0 +1,92 @@
{ 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"
'';
}

478
pkgs/companion/package.json Executable file
View file

@ -0,0 +1,478 @@
{
"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"
}
}

13213
pkgs/companion/yarn-webui.nix Normal file

File diff suppressed because it is too large Load diff

10067
pkgs/companion/yarn.nix Normal file

File diff suppressed because it is too large Load diff

48
pkgs/decklink/default.nix Normal file
View file

@ -0,0 +1,48 @@
{ 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;
};
}

View file

@ -1,25 +1,68 @@
{ nixpkgs ? <nixpkgs>, ... }:
{ config ? {}, system ? builtins.currentSystem, ... }@args:
let
pkgs = import nixpkgs {};
sources = import ../nix/sources.nix;
pkgs = import sources.nixpkgs args;
unstable = import sources.nixpkgs-unstable args;
callPackage = pkgs.lib.callPackageWith (pkgs // newpkgs);
wasiSrc = fetchGit {
url = "https://gitlab.infra4future.de/wasi/wasi-rust";
rev = "356dbc23a3683d134f13156af71baeaa06fb80d1";
};
immaeNix = fetchGit {
url = "https://git.immae.eu/perso/Immae/Config/Nix.git";
rev = "7ad4966f41db0669a77c7a6ee7f87f0d4e586b0c";
};
newpkgs = {
# package = callPackage ./package {};
wasi = import wasiSrc { inherit wasiSrc; pkgs = pkgs // newpkgs; };
peertube = callPackage ./peertube { mylibs = import "${immaeNix}/lib" { inherit pkgs; }; };
alps = callPackage ./alps {};
funkwhale = callPackage ./funkwhale {};
companion = callPackage ./companion {};
libvips = callPackage ./libvips {};
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 {};
inherit (unstable) bottom vaultwarden vaultwarden-vault;
};
in newpkgs
in pkgs.extend(_: _: newpkgs)

View file

@ -1,47 +0,0 @@
{ stdenv, fetchurl, unzip }:
# Look for the correct urls for build_front and build_api artifacts on the tags page of the project : https://dev.funkwhale.audio/funkwhale/funkwhale/pipelines?scope=tags
# Attention : do not use the url "https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/artifacts/${release}/download?job=" : it is not guaranteed to be stable
let
release = "1.0.1";
srcs = {
api = fetchurl {
url = https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/56793/artifacts/download;
name = "api.zip";
sha256 = "0p21r8kbn7sr33chp7404fi9pm4yz6qhfz4z7gxf3vamg9fbsbsc";
};
frontend = fetchurl {
url = https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/56790/artifacts/download;
name = "frontend.zip";
sha256 = "0hz4d59sva6zi5q53wj3f6yaw5didcl9z148s6rsy2m6gyr8566d";
};
};
in stdenv.mkDerivation {
name = "funkwhale";
version = "${release}";
src = srcs.api;
nativeBuildInputs = [ unzip ];
postPatch = ''
substituteInPlace requirements/base.txt \
--replace "django-cleanup==3.2.0" django-cleanup
'';
installPhase = ''
mkdir $out
cp -R ./* $out
unzip ${srcs.frontend} -d $out
mv $out/front/ $out/front_tmp
mv $out/front_tmp/dist $out/front
rmdir $out/front_tmp
'';
meta = with stdenv.lib; {
description = "A modern, convivial and free music server";
homepage = https://funkwhale.audio/;
license = licenses.agpl3;
platforms = platforms.linux;
maintainers = with maintainers; [ mmai ];
};
}

18
pkgs/libvips/default.nix Normal file
View file

@ -0,0 +1,18 @@
{
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 ];
}

View file

@ -0,0 +1,49 @@
{ 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;
};
}

File diff suppressed because it is too large Load diff

View file

@ -1,207 +0,0 @@
{ ldap ? false, sendmail ? false, light ? null, syden ? false, runCommand, libsass
, lib, stdenv, rsync, fetchzip, youtube-dl, fetchurl, mylibs, python, nodejs, nodePackages, yarn2nix-moretea }:
let
nodeHeaders = fetchurl {
url = "https://nodejs.org/download/release/v${nodejs.version}/node-v${nodejs.version}-headers.tar.gz";
sha256 = "17kf05a92r4y4n1lj78265wr6zhkpzbr1k8nbwrl8sq71npd6n5j";
};
source = mylibs.fetchedGithub ./peertube.json;
patchedSource = stdenv.mkDerivation (source // rec {
phases = [ "unpackPhase" "patchPhase" "installPhase" ];
patches = [ ./yarn_fix_http_node.patch ]
++ lib.optionals ldap [ ./ldap.patch ]
++ lib.optionals sendmail [ ./sendmail.patch ]
++ lib.optionals syden [ ./syden.patch ];
installPhase = ''
mkdir $out
cp -a . $out/
'';
});
serverPatchedPackage = runCommand "server-package" {} ''
mkdir -p $out
cp ${patchedSource}/package.json $out/
cp ${patchedSource}/yarn.lock $out/
'';
clientPatchedPackage = runCommand "client-package" {} ''
mkdir -p $out
cp ${patchedSource}/client/package.json $out/
cp ${patchedSource}/client/yarn.lock $out/
'';
yarnModulesConfig = {
bcrypt = {
buildInputs = [ nodePackages.node-pre-gyp ];
postInstall = let
node_module_version = "72";
bcrypt_lib = fetchurl {
url = "https://github.com/kelektiv/node.bcrypt.js/releases/download/v3.0.7/bcrypt_lib-v3.0.7-node-v${node_module_version}-linux-x64-glibc.tar.gz";
sha256 = "0kpm9j0yc4lqsafldfsql3m72rr1fapljlb6ddxvy3zi13rb7ppx";
};
in
''
if [ "$(node -e "console.log(process.versions.modules)")" != "${node_module_version}" ]; then
echo "mismatching version with nodejs please update bcrypt derivation"
false
fi
mkdir lib && tar -C lib -xf ${bcrypt_lib}
patchShebangs ../node-pre-gyp
npm run install
'';
};
dtrace-provider = {
buildInputs = [ python nodePackages.node-gyp ];
postInstall = ''
npx node-gyp rebuild --tarball=${nodeHeaders}
'';
};
node-sass = {
buildInputs = [ libsass python ];
postInstall =
''
node scripts/build.js --tarball=${nodeHeaders}
'';
};
sharp = {
buildInputs = [ python nodePackages.node-gyp ];
postInstall =
let
tarball = fetchurl {
url = "https://github.com/lovell/sharp-libvips/releases/download/v8.8.1/libvips-8.8.1-linux-x64.tar.gz";
sha256 = "0xqv61g6s6rkvc31zq9a3bf8rp56ijnpw0xhr91hc88asqprd5yh";
};
in
''
mkdir vendor
tar -C vendor -xf ${tarball}
patchShebangs ../prebuild-install
npx node install/libvips
npx node install/dll-copy
npx prebuild-install || npx node-gyp rebuild --tarball=${nodeHeaders}
'';
};
utf-8-validate = {
buildInputs = [ nodePackages.node-gyp-build ];
};
youtube-dl = {
postInstall = ''
mkdir bin
ln -s ${youtube-dl}/bin/youtube-dl bin/youtube-dl
cat > bin/details <<EOF
{"version":"${youtube-dl.version}","path":null,"exec":"youtube-dl"}
EOF
'';
};
};
serverYarnModulesArg = rec {
pname = "peertube-server-yarn-modules";
version = source.version;
name = "${pname}-${version}";
packageJSON = "${serverPatchedPackage}/package.json";
yarnLock = "${serverPatchedPackage}/yarn.lock";
yarnNix = ./server-yarn-packages.nix;
pkgConfig = yarnModulesConfig;
};
clientYarnModulesArg = rec {
pname = "peertube-client-yarn-modules";
version = source.version;
name = "${pname}-${version}";
packageJSON = "${clientPatchedPackage}/package.json";
yarnLock = "${clientPatchedPackage}/yarn.lock";
yarnNix = ./client-yarn-packages.nix;
pkgConfig = yarnModulesConfig;
};
yarnModulesNoWorkspace = args: (yarn2nix-moretea.mkYarnModules args).overrideAttrs(old: {
buildPhase = builtins.replaceStrings [" ./package.json"] [" /dev/null; cp deps/*/package.json ."] old.buildPhase;
});
patchedPackages = stdenv.mkDerivation (source // rec {
patches = if ldap then [ ./ldap.patch ] else [ ./yarn_fix_http_node.patch ];
installPhase = ''
mkdir $out
cp package.json yarn.lock $out/
'';
});
serverYarnModules = yarnModulesNoWorkspace serverYarnModulesArg;
serverYarnModulesProd = yarnModulesNoWorkspace (serverYarnModulesArg // { yarnFlags = yarn2nix-moretea.defaultYarnFlags ++ [ "--production" ]; });
clientYarnModules = yarnModulesNoWorkspace clientYarnModulesArg;
server = stdenv.mkDerivation ({
pname = "peertube-server";
version = source.version;
src = patchedSource;
buildPhase = ''
ln -s ${serverYarnModules}/node_modules .
npm run build:server
'';
installPhase = ''
mkdir $out
cp -a dist $out
'';
buildInputs = [ nodejs serverYarnModules ];
});
client = stdenv.mkDerivation ({
pname = "peertube-client";
version = source.version;
src = patchedSource;
buildPhase = let
lightArg = if light == null then "" else if light == true then "--light" else "--light-language";
in ''
ln -s ${serverYarnModules}/node_modules .
cp -a ${clientYarnModules}/node_modules client/
chmod +w client/node_modules
patchShebangs .
npm run build:client -- ${lightArg}
'';
installPhase = ''
mkdir $out
cp -a client/dist $out
'';
buildInputs = [ nodejs clientYarnModules ];
});
package = stdenv.mkDerivation rec {
version = source.version;
pname = "peertube";
src = patchedSource;
buildPhase = ''
ln -s ${serverYarnModulesProd}/node_modules .
ln -s ${clientYarnModules}/node_modules client/
rm -rf dist && cp -a ${server}/dist dist
rm -rf client/dist && cp -a ${client}/dist client/
'';
installPhase = ''
mkdir $out
cp -a * $out
ln -s /tmp $out/.cache
'';
meta = {
description = "A free software to take back control of your videos";
longDescription = ''
PeerTube aspires to be a decentralized and free/libre alternative to video
broadcasting services.
PeerTube is not meant to become a huge platform that would centralize
videos from all around the world. Rather, it is a network of
inter-connected small videos hosters.
Anyone with a modicum of technical skills can host a PeerTube server, aka
an instance. Each instance hosts its users and their videos. In this way,
every instance is created, moderated and maintained independently by
various administrators.
You can still watch from your account videos hosted by other instances
though if the administrator of your instance had previously connected it
with other instances.
'';
license = stdenv.lib.licenses.agpl3Plus;
homepage = "https://joinpeertube.org/";
platforms = stdenv.lib.platforms.linux; # not sure here
maintainers = with stdenv.lib.maintainers; [ matthiasbeyer immae ];
};
};
in
package

View file

@ -1,597 +0,0 @@
commit ffb4a59047a014d6bb050b67a2fc7bc116be4682
Author: Ismaël Bouya <ismael.bouya@normalesup.org>
Date: Tue Feb 12 18:47:53 2019 +0100
Add LDAP authentication
diff --git a/config/default.yaml b/config/default.yaml
index 3260c62fc..dcce721b9 100644
--- a/config/default.yaml
+++ b/config/default.yaml
@@ -51,6 +51,19 @@ redis:
auth: null
db: 0
+auth:
+ local:
+ enabled: true
+ ldap:
+ enabled: true
+ url: ldap://localhost:389/dc=example,dc=com
+ insecure_tls: false
+ bind_dn: cn=admin,dc=example,dc=com
+ bind_password: adminPass
+ base: dc=example,dc=com
+ mail_entry: "mail"
+ user_filter: "(|(email=%username%)(uid=%username%))"
+
smtp:
hostname: null
port: 465
diff --git a/config/production.yaml.example b/config/production.yaml.example
index 30cd2ffe0..c56691bf4 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -51,6 +51,19 @@ redis:
auth: null
db: 0
+auth:
+ local:
+ enabled: true
+ ldap:
+ enabled: true
+ url: ldap://localhost:389/dc=example,dc=com
+ insecure_tls: false
+ bind_dn: cn=admin,dc=example,dc=com
+ bind_password: adminPass
+ base: dc=example,dc=com
+ mail_entry: "mail"
+ user_filter: "(|(email=%username%)(uid=%username%))"
+
# SMTP server to send emails
smtp:
hostname: null
diff --git a/package.json b/package.json
index 49d9faf97..31eccf797 100644
--- a/package.json
+++ b/package.json
@@ -112,6 +112,7 @@
"iso-639-3": "^1.0.1",
"js-yaml": "^3.5.4",
"jsonld": "~2.0.1",
+ "ldapjs": "^1.0.2",
"lodash": "^4.17.10",
"lru-cache": "^5.1.1",
"magnet-uri": "^5.1.4",
diff --git a/server/initializers/config.ts b/server/initializers/config.ts
index 7fd77f3e8..45a667826 100644
--- a/server/initializers/config.ts
+++ b/server/initializers/config.ts
@@ -34,6 +34,21 @@ const CONFIG = {
AUTH: config.has('redis.auth') ? config.get<string>('redis.auth') : null,
DB: config.has('redis.db') ? config.get<number>('redis.db') : null
},
+ AUTH: {
+ LOCAL: {
+ ENABLED: config.has('auth.local.enabled') ? config.get<boolean>('auth.local.enabled') : true,
+ },
+ LDAP: {
+ ENABLED: config.has('auth.ldap.enabled') ? config.get<boolean>('auth.ldap.enabled') : false,
+ URL: config.has('auth.ldap.url') ? config.get<string>('auth.ldap.url') : null,
+ INSECURE_TLS: config.has('auth.ldap.insecure_tls') ? config.get<boolean>('auth.ldap.insecure_tls') : false,
+ BIND_DN: config.has('auth.ldap.bind_dn') ? config.get<string>('auth.ldap.bind_dn') : null,
+ BIND_PASSWORD: config.has('auth.ldap.bind_password') ? config.get<string>('auth.ldap.bind_password') : null,
+ BASE: config.has('auth.ldap.base') ? config.get<string>('auth.ldap.base') : null,
+ MAIL_ENTRY: config.has('auth.ldap.mail_entry') ? config.get<string>('auth.ldap.mail_entry') : 'mail',
+ USER_FILTER: config.has('auth.ldap.user_filter') ? config.get<string>('auth.ldap.user_filter') : null
+ },
+ },
SMTP: {
HOSTNAME: config.get<string>('smtp.hostname'),
PORT: config.get<number>('smtp.port'),
diff --git a/server/initializers/migrations/0375-user-ldap-dn.ts b/server/initializers/migrations/0375-user-ldap-dn.ts
new file mode 100644
index 000000000..a9d68124b
--- /dev/null
+++ b/server/initializers/migrations/0375-user-ldap-dn.ts
@@ -0,0 +1,26 @@
+import * as Sequelize from 'sequelize'
+
+async function up (utils: {
+ transaction: Sequelize.Transaction,
+ queryInterface: Sequelize.QueryInterface,
+ sequelize: Sequelize.Sequelize
+}): Promise<void> {
+
+ {
+ const data = {
+ type: Sequelize.STRING,
+ allowNull: true,
+ defaultValue: null
+ }
+ await utils.queryInterface.addColumn('user', 'ldapDn', data)
+ }
+}
+
+function down (options) {
+ throw new Error('Not implemented.')
+}
+
+export {
+ up,
+ down
+}
diff --git a/server/lib/ldap.ts b/server/lib/ldap.ts
new file mode 100644
index 000000000..e6601e5cb
--- /dev/null
+++ b/server/lib/ldap.ts
@@ -0,0 +1,89 @@
+import * as express from 'express'
+import { createClient, Client, parseFilter } from 'ldapjs'
+import { logger } from '../helpers/logger'
+import { CONFIG } from '../initializers/config'
+
+class Ldap {
+
+ private static instance: Ldap
+ private initialized = false
+ private client: Client
+ private prefix: string
+
+ private constructor () {}
+
+ init () {
+ // Already initialized
+ if (this.initialized === true) return
+ this.initialized = true
+
+ this.client = createClient(Ldap.getLdapClientOptions())
+ }
+
+ static getLdapClientOptions () {
+ return Object.assign({}, {
+ url: CONFIG.AUTH.LDAP.URL,
+ reconnect: true,
+ tlsOptions: { rejectUnauthorized: !CONFIG.AUTH.LDAP.INSECURE_TLS }
+ })
+ }
+
+ getClient () {
+ this.init()
+ return this.client
+ }
+
+ findUser (username: string) {
+ const filter = parseFilter(CONFIG.AUTH.LDAP.USER_FILTER)
+ filter.forEach(function (element) {
+ if (element.value === '%username%') element.value = username
+ })
+ const opts = {
+ filter,
+ scope: 'sub',
+ attributes: [ CONFIG.AUTH.LDAP.MAIL_ENTRY, 'dn' ]
+ }
+
+ const client = this.getClient()
+
+ return new Promise(function (resolve, reject) {
+ client.bind(CONFIG.AUTH.LDAP.BIND_DN, CONFIG.AUTH.LDAP.BIND_PASSWORD, function (err) {
+ if (err) reject(err)
+ let entries = []
+ client.search(CONFIG.AUTH.LDAP.BASE, opts, function (err, search) {
+ if (err) reject(err)
+ search.on('searchEntry', function (entry) {
+ entries.push(entry.object)
+ })
+ search.on('end', function (result) {
+ if (entries.length === 1) {
+ resolve(entries[0])
+ } else {
+ reject("No user found corresponding to this username")
+ }
+ })
+ })
+ })
+ })
+ }
+
+ checkUser (dn: string, password: string) {
+ const client = this.getClient()
+ return new Promise(function (resolve, reject) {
+ client.bind(dn, password, function (err) {
+ resolve(!err)
+ })
+ })
+ }
+
+
+ static get Instance () {
+ return this.instance || (this.instance = new this())
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ Ldap
+}
diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts
index 086856f41..ab10effd0 100644
--- a/server/lib/oauth-model.ts
+++ b/server/lib/oauth-model.ts
@@ -9,6 +9,7 @@ import { Transaction } from 'sequelize'
import { CONFIG } from '../initializers/config'
import * as LRUCache from 'lru-cache'
import { MOAuthTokenUser } from '@server/typings/models/oauth/oauth-token'
+import { MUserDefault } from '@server/typings/models'
type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date }
@@ -74,7 +75,13 @@ function getRefreshToken (refreshToken: string) {
async function getUser (usernameOrEmail: string, password: string) {
logger.debug('Getting User (username/email: ' + usernameOrEmail + ', password: ******).')
- const user = await UserModel.loadByUsernameOrEmail(usernameOrEmail)
+ let user : MUserDefault
+ if (CONFIG.AUTH.LDAP.ENABLED) {
+ user = await UserModel.findOrCreateLDAPUser(usernameOrEmail)
+ }
+ if (!user && CONFIG.AUTH.LOCAL.ENABLED) {
+ user = await UserModel.loadByUsernameOrEmail(usernameOrEmail)
+ }
if (!user) return null
const passwordMatch = await user.isPasswordMatch(password)
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index 4c2c5e278..0b38f7cb2 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -1,4 +1,5 @@
import { FindOptions, literal, Op, QueryTypes, where, fn, col } from 'sequelize'
+import { Ldap } from '../../lib/ldap'
import {
AfterDestroy,
AfterUpdate,
@@ -50,7 +51,9 @@ import { AccountModel } from './account'
import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type'
import { values } from 'lodash'
import { DEFAULT_THEME_NAME, DEFAULT_USER_THEME_NAME, NSFW_POLICY_TYPES } from '../../initializers/constants'
+import { CONFIG } from '../../initializers/config'
import { clearCacheByUserId } from '../../lib/oauth-model'
+import { createUserAccountAndChannelAndPlaylist } from '../../lib/user'
import { UserNotificationSettingModel } from './user-notification-setting'
import { VideoModel } from '../video/video'
import { ActorModel } from '../activitypub/actor'
@@ -149,6 +152,11 @@ export class UserModel extends Model<UserModel> {
@Column(DataType.STRING(400))
pendingEmail: string
+ @AllowNull(true)
+ @Default(null)
+ @Column
+ ldapDn: string
+
@AllowNull(true)
@Default(null)
@Is('UserEmailVerified', value => throwIfNotValid(value, isUserEmailVerifiedValid, 'email verified boolean', true))
@@ -440,6 +448,48 @@ export class UserModel extends Model<UserModel> {
return UserModel.findOne(query)
}
+ static loadByLdapDn (ldapDn: string) {
+ const query = {
+ where: {
+ ldapDn
+ }
+ }
+
+ return UserModel.findOne(query)
+ }
+
+ static async findOrCreateLDAPUser (username: string) {
+ try {
+ const userInfos = await Ldap.Instance.findUser(username)
+ const user = await UserModel.loadByLdapDn(userInfos['dn'])
+ if (user) {
+ return user
+ } else {
+ return await UserModel.createLDAPUser(username, userInfos)
+ }
+ } catch (e) {
+ return null
+ }
+ }
+
+ static async createLDAPUser (username: string, userInfos: {}) {
+ const userToCreate = new UserModel({
+ username,
+ password: 'SomeInvalidPassword',
+ email: userInfos[CONFIG.AUTH.LDAP.MAIL_ENTRY],
+ ldapDn: userInfos['dn'],
+ nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
+ autoPlayVideo: true,
+ role: UserRole.USER,
+ videoQuota: CONFIG.USER.VIDEO_QUOTA,
+ videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY,
+ emailVerified: true,
+ adminFlags: UserAdminFlag.NONE
+ })
+ const { user } = await createUserAccountAndChannelAndPlaylist({ userToCreate })
+ return user
+ }
+
static loadForMeAPI (username: string): Bluebird<MUserNotifSettingChannelDefault> {
const query = {
where: {
@@ -627,7 +677,11 @@ export class UserModel extends Model<UserModel> {
}
isPasswordMatch (password: string) {
- return comparePassword(password, this.password)
+ if (this.ldapDn === null) {
+ return comparePassword(password, this.password)
+ } else {
+ return Ldap.Instance.checkUser(this.ldapDn, password)
+ }
}
toFormattedJSON (this: MUserFormattable, parameters: { withAdminFlags?: boolean } = {}): User {
diff --git a/yarn.lock b/yarn.lock
index 76ce7ed27..f087746df 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -616,6 +616,11 @@ arraybuffer.slice@~0.0.7:
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
+asn1@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+ integrity sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=
+
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
@@ -623,6 +628,11 @@ asn1@~0.2.3:
dependencies:
safer-buffer "~2.1.0"
+assert-plus@0.1.5:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160"
+ integrity sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=
+
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
@@ -692,6 +702,13 @@ backo2@1.0.2:
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
integrity sha1-MasayLEpNjRj41s+u2n038+6eUc=
+backoff@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f"
+ integrity sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=
+ dependencies:
+ precond "0.2"
+
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@@ -1001,6 +1018,16 @@ bull@^3.4.2:
util.promisify "^1.0.0"
uuid "^3.3.3"
+bunyan@^1.8.3:
+ version "1.8.12"
+ resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797"
+ integrity sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=
+ optionalDependencies:
+ dtrace-provider "~0.8"
+ moment "^2.10.6"
+ mv "~2"
+ safe-json-stringify "~1"
+
busboy@^0.2.11:
version "0.2.14"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453"
@@ -1619,7 +1646,7 @@ d@1, d@^1.0.1:
es5-ext "^0.10.50"
type "^1.0.1"
-dashdash@^1.12.0:
+dashdash@^1.12.0, dashdash@^1.14.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
@@ -1845,6 +1872,13 @@ double-ended-queue@^2.1.0-0:
resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=
+dtrace-provider@~0.8:
+ version "0.8.8"
+ resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e"
+ integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==
+ dependencies:
+ nan "^2.14.0"
+
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
@@ -2228,6 +2262,11 @@ extend@^3.0.0, extend@~3.0.0, extend@~3.0.2:
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
+extsprintf@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.2.0.tgz#5ad946c22f5b32ba7f8cd7426711c6e8a3fc2529"
+ integrity sha1-WtlGwi9bMrp/jNdCZxHG6KP8JSk=
+
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
@@ -2567,6 +2606,17 @@ glob@7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^6.0.1:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
+ integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "2 || 3"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
glob@^7.0.3, glob@^7.1.1, glob@^7.1.3:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
@@ -3356,6 +3406,30 @@ latest-version@^3.0.0:
dependencies:
package-json "^4.0.0"
+ldap-filter@0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/ldap-filter/-/ldap-filter-0.2.2.tgz#f2b842be0b86da3352798505b31ebcae590d77d0"
+ integrity sha1-8rhCvguG2jNSeYUFsx68rlkNd9A=
+ dependencies:
+ assert-plus "0.1.5"
+
+ldapjs@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/ldapjs/-/ldapjs-1.0.2.tgz#544ff7032b7b83c68f0701328d9297aa694340f9"
+ integrity sha1-VE/3Ayt7g8aPBwEyjZKXqmlDQPk=
+ dependencies:
+ asn1 "0.2.3"
+ assert-plus "^1.0.0"
+ backoff "^2.5.0"
+ bunyan "^1.8.3"
+ dashdash "^1.14.0"
+ ldap-filter "0.2.2"
+ once "^1.4.0"
+ vasync "^1.6.4"
+ verror "^1.8.1"
+ optionalDependencies:
+ dtrace-provider "~0.8"
+
libxmljs@0.19.7:
version "0.19.7"
resolved "https://registry.yarnpkg.com/libxmljs/-/libxmljs-0.19.7.tgz#96c2151b0b73f33dd29917edec82902587004e5a"
@@ -3724,7 +3798,7 @@ mimic-response@^2.0.0:
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.0.0.tgz#996a51c60adf12cb8a87d7fb8ef24c2f3d5ebb46"
integrity sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==
-minimatch@3.0.4, minimatch@^3.0.4:
+"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@@ -3825,7 +3899,7 @@ moment-timezone@^0.5.21, moment-timezone@^0.5.25:
dependencies:
moment ">= 2.9.0"
-"moment@>= 2.9.0", moment@^2.24.0:
+"moment@>= 2.9.0", moment@^2.10.6, moment@^2.24.0:
version "2.24.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
@@ -3898,6 +3972,15 @@ mute-stream@~0.0.4:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
+mv@~2:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2"
+ integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=
+ dependencies:
+ mkdirp "~0.5.1"
+ ncp "~2.0.0"
+ rimraf "~2.4.0"
+
nan@2.14.0, nan@^2.14.0, nan@~2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
@@ -3913,6 +3996,11 @@ ncp@1.0.x:
resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246"
integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=
+ncp@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
+ integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=
+
needle@^2.2.1:
version "2.4.0"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c"
@@ -4597,6 +4685,11 @@ prebuild-install@^5.3.3:
tunnel-agent "^0.6.0"
which-pm-runs "^1.0.0"
+precond@0.2:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac"
+ integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=
+
prepend-http@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
@@ -5032,6 +5125,13 @@ rimraf@^3.0.0:
dependencies:
glob "^7.1.3"
+rimraf@~2.4.0:
+ version "2.4.5"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da"
+ integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=
+ dependencies:
+ glob "^6.0.1"
+
run-parallel-limit@^1.0.3:
version "1.0.5"
resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.0.5.tgz#c29a4fd17b4df358cb52a8a697811a63c984f1b7"
@@ -5069,6 +5169,11 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2,
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
+safe-json-stringify@~1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd"
+ integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==
+
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@@ -6337,7 +6442,14 @@ vary@^1, vary@~1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
-verror@1.10.0:
+vasync@^1.6.4:
+ version "1.6.4"
+ resolved "https://registry.yarnpkg.com/vasync/-/vasync-1.6.4.tgz#dfe93616ad0e7ae801b332a9d88bfc5cdc8e1d1f"
+ integrity sha1-3+k2Fq0OeugBszKp2Iv8XNyOHR8=
+ dependencies:
+ verror "1.6.0"
+
+verror@1.10.0, verror@^1.8.1:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
@@ -6346,6 +6458,13 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
+verror@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.6.0.tgz#7d13b27b1facc2e2da90405eb5ea6e5bdd252ea5"
+ integrity sha1-fROyex+swuLakEBetepuW90lLqU=
+ dependencies:
+ extsprintf "1.2.0"
+
videostream@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/videostream/-/videostream-3.2.1.tgz#643688ad4bfbf37570d421e3196b7e0ad38eeebc"

View file

@ -1,15 +0,0 @@
{
"tag": "v2.1.1",
"meta": {
"name": "peertube",
"url": "https://github.com/Chocobozzz/PeerTube",
"branch": "refs/tags/v2.1.1"
},
"github": {
"owner": "Chocobozzz",
"repo": "PeerTube",
"rev": "76f7b571c04c03ba422bd5790944fe80dbb24067",
"sha256": "147gm1j657fkpv2ix1bmkhl7ld5h224q7hgdj9ffj3z14mqgk8hj",
"fetchSubmodules": true
}
}

View file

@ -1,121 +0,0 @@
commit 486964fad93334a52fb05e7d0497ecac3eb684fe
Author: Ismaël Bouya <ismael.bouya@normalesup.org>
Date: Wed Feb 13 12:16:27 2019 +0100
Add sendmail
diff --git a/config/production.yaml.example b/config/production.yaml.example
index c56691bf4..8abdfb2a7 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -66,6 +66,8 @@ auth:
# SMTP server to send emails
smtp:
+ transport: smtp
+ sendmail: null
hostname: null
port: 465 # If you use StartTLS: 587
username: null
diff --git a/server/initializers/config.ts b/server/initializers/config.ts
index 45a667826..c1c15f05b 100644
--- a/server/initializers/config.ts
+++ b/server/initializers/config.ts
@@ -50,6 +50,8 @@ const CONFIG = {
},
},
SMTP: {
+ TRANSPORT: config.has('smtp.transport') ? config.get<string>('smtp.transport') : 'smtp',
+ SENDMAIL: config.has('smtp.sendmail') ? config.get<string>('smtp.sendmail') : null,
HOSTNAME: config.get<string>('smtp.hostname'),
PORT: config.get<number>('smtp.port'),
USERNAME: config.get<string>('smtp.username'),
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts
index 7484524a4..512c5c068 100644
--- a/server/lib/emailer.ts
+++ b/server/lib/emailer.ts
@@ -40,33 +40,41 @@ class Emailer {
this.initialized = true
if (Emailer.isEnabled()) {
- logger.info('Using %s:%s as SMTP server.', CONFIG.SMTP.HOSTNAME, CONFIG.SMTP.PORT)
-
- let tls
- if (CONFIG.SMTP.CA_FILE) {
- tls = {
- ca: [ readFileSync(CONFIG.SMTP.CA_FILE) ]
+ if (CONFIG.SMTP.TRANSPORT === 'smtp') {
+ logger.info('Using %s:%s as SMTP server.', CONFIG.SMTP.HOSTNAME, CONFIG.SMTP.PORT)
+
+ let tls
+ if (CONFIG.SMTP.CA_FILE) {
+ tls = {
+ ca: [ readFileSync(CONFIG.SMTP.CA_FILE) ]
+ }
}
- }
- let auth
- if (CONFIG.SMTP.USERNAME && CONFIG.SMTP.PASSWORD) {
- auth = {
- user: CONFIG.SMTP.USERNAME,
- pass: CONFIG.SMTP.PASSWORD
+ let auth
+ if (CONFIG.SMTP.USERNAME && CONFIG.SMTP.PASSWORD) {
+ auth = {
+ user: CONFIG.SMTP.USERNAME,
+ pass: CONFIG.SMTP.PASSWORD
+ }
}
- }
- this.transporter = createTransport({
- host: CONFIG.SMTP.HOSTNAME,
- port: CONFIG.SMTP.PORT,
- secure: CONFIG.SMTP.TLS,
- debug: CONFIG.LOG.LEVEL === 'debug',
- logger: bunyanLogger as any,
- ignoreTLS: CONFIG.SMTP.DISABLE_STARTTLS,
- tls,
- auth
- })
+ this.transporter = createTransport({
+ host: CONFIG.SMTP.HOSTNAME,
+ port: CONFIG.SMTP.PORT,
+ secure: CONFIG.SMTP.TLS,
+ debug: CONFIG.LOG.LEVEL === 'debug',
+ logger: bunyanLogger as any,
+ ignoreTLS: CONFIG.SMTP.DISABLE_STARTTLS,
+ tls,
+ auth
+ })
+ } else { // sendmail
+ this.transporter = createTransport({
+ sendmail: true,
+ newline: 'unix',
+ path: CONFIG.SMTP.SENDMAIL,
+ })
+ }
} else {
if (!isTestInstance()) {
logger.error('Cannot use SMTP server because of lack of configuration. PeerTube will not be able to send mails!')
@@ -75,11 +83,17 @@ class Emailer {
}
static isEnabled () {
- return !!CONFIG.SMTP.HOSTNAME && !!CONFIG.SMTP.PORT
+ if (CONFIG.SMTP.TRANSPORT === 'sendmail') {
+ return !!CONFIG.SMTP.SENDMAIL
+ } else if (CONFIG.SMTP.TRANSPORT === 'smtp') {
+ return !!CONFIG.SMTP.HOSTNAME && !!CONFIG.SMTP.PORT
+ } else {
+ return false
+ }
}
async checkConnectionOrDie () {
- if (!this.transporter) return
+ if (!this.transporter || CONFIG.SMTP.TRANSPORT !== 'smtp') return
logger.info('Testing SMTP server...')

File diff suppressed because it is too large Load diff

View file

@ -1,211 +0,0 @@
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
index b07b9c1a6..2e69c1de3 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
@@ -16,22 +16,10 @@
#videosSelection
>
<ng-template ptTemplate="globalButtons">
- <span class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()">
- <my-global-icon iconName="delete"></my-global-icon>
- <ng-container i18n>Delete</ng-container>
- </span>
</ng-template>
<ng-template ptTemplate="rowButtons" let-video>
- <my-delete-button (click)="deleteVideo(video)"></my-delete-button>
-
<my-edit-button [routerLink]="[ '/videos', 'update', video.uuid ]"></my-edit-button>
-
- <my-button i18n-label label="Change ownership"
- className="action-button-change-ownership grey-button"
- icon="im-with-her"
- (click)="changeOwnership($event, video)"
- ></my-button>
</ng-template>
</my-videos-selection>
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts
index 9ae008e39..58366de41 100644
--- a/client/src/app/core/auth/auth.service.ts
+++ b/client/src/app/core/auth/auth.service.ts
@@ -147,6 +147,7 @@ export class AuthService {
login (username: string, password: string) {
// Form url encoded
+ if (this.isLoggedIn()) this.logout()
const body = {
client_id: this.clientId,
client_secret: this.clientSecret,
diff --git a/client/src/app/login/login.component.ts b/client/src/app/login/login.component.ts
index 580f28822..1d2d1873c 100644
--- a/client/src/app/login/login.component.ts
+++ b/client/src/app/login/login.component.ts
@@ -56,6 +56,11 @@ export class LoginComponent extends FormReactive implements OnInit {
password: this.loginValidatorsService.LOGIN_PASSWORD
})
+ if (!this.authService.isLoggedIn()) {
+ this.form.controls.username.setValue("invite")
+ this.form.controls.password.setValue("invite")
+ this.login()
+ }
this.input.nativeElement.focus()
}
diff --git a/client/src/app/shared/video/video-actions-dropdown.component.ts b/client/src/app/shared/video/video-actions-dropdown.component.ts
index afdeab18d..ee8a5929b 100644
--- a/client/src/app/shared/video/video-actions-dropdown.component.ts
+++ b/client/src/app/shared/video/video-actions-dropdown.component.ts
@@ -141,7 +141,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
}
isVideoDownloadable () {
- return this.video && this.video instanceof VideoDetails && this.video.downloadEnabled
+ return this.video && this.video instanceof VideoDetails && this.video.isDownloadableBy(this.user)
}
/* Action handlers */
diff --git a/client/src/app/shared/video/video.model.ts b/client/src/app/shared/video/video.model.ts
index fb98d5382..3098fc831 100644
--- a/client/src/app/shared/video/video.model.ts
+++ b/client/src/app/shared/video/video.model.ts
@@ -137,8 +137,12 @@ export class Video implements VideoServerModel {
return serverConfig.instance.defaultNSFWPolicy !== 'display'
}
+ isDownloadableBy (user: AuthUser) {
+ return user && this.isLocal === true && user.hasRight(UserRight.SEE_ALL_VIDEOS)
+ }
+
isRemovableBy (user: AuthUser) {
- return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.REMOVE_ANY_VIDEO))
+ return user && this.isLocal === true && user.hasRight(UserRight.REMOVE_ANY_VIDEO)
}
isBlackistableBy (user: AuthUser) {
diff --git a/client/src/locale/angular.en-US.xlf b/client/src/locale/angular.en-US.xlf
index a87278e88..d4ad8522f 100644
--- a/client/src/locale/angular.en-US.xlf
+++ b/client/src/locale/angular.en-US.xlf
@@ -1071,7 +1071,7 @@
<source>
If you are looking for an account…
</source><target state="final">
- If you are looking for an account…
+ Open instance
</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/login/login.component.html</context>
@@ -1086,12 +1086,7 @@
Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="&lt;a>"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a>"/>.
</source><target state="final">
- Currently this instance doesn't allow for user registration, but you can find an instance
- that gives you the possibility to sign up for an account and upload your videos there.
-
- <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/>"/>
-
- Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="&lt;a>"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a>"/>.
+ This instance doesn't allow for user registration, but it is open. You may connect with login "invite" and any password.
</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/login/login.component.html</context>
diff --git a/client/src/locale/angular.fr-FR.xlf b/client/src/locale/angular.fr-FR.xlf
index 6b58a1e1e..77ccc44fc 100644
--- a/client/src/locale/angular.fr-FR.xlf
+++ b/client/src/locale/angular.fr-FR.xlf
@@ -1074,7 +1074,7 @@
<trans-unit id="d780b02074a6317126378e0365e1066c890a3570" datatype="html">
<source>If you are looking for an account…</source>
<target state="new">
- If you are looking for an account…
+ Instance ouverte
</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/login/login.component.html</context>
@@ -1084,12 +1084,7 @@
<trans-unit id="79dacac459775e2cf163bce6c3f05ed814f82ba2" datatype="html">
<source>Currently this instance doesn't allow for user registration, but you can find an instance that gives you the possibility to sign up for an account and upload your videos there. <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>. </source>
<target state="new">
- Currently this instance doesn't allow for user registration, but you can find an instance
- that gives you the possibility to sign up for an account and upload your videos there.
-
- <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>
-
- Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.
+ Cette instance ne permet pas de créer un compte, mais elle est ouverte. Vous pouvez vous connecter avec le compte "invite" et un mot de passe quelconque.
</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/login/login.component.html</context>
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 8d4ff07eb..4eb9354c3 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -26,6 +26,7 @@ import {
asyncMiddleware,
asyncRetryTransactionMiddleware,
authenticate,
+ ensureUserHasRight,
checkVideoFollowConstraints,
commonVideosFiltersValidator,
optionalAuthenticate,
@@ -39,6 +40,7 @@ import {
videosSortValidator,
videosUpdateValidator
} from '../../../middlewares'
+import { UserRight } from '../../../../shared'
import { TagModel } from '../../../models/video/tag'
import { VideoModel } from '../../../models/video/video'
import { VideoFileModel } from '../../../models/video/video-file'
@@ -141,6 +143,7 @@ videosRouter.post('/:id/views',
videosRouter.delete('/:id',
authenticate,
+ ensureUserHasRight(UserRight.REMOVE_ANY_VIDEO),
asyncMiddleware(videosRemoveValidator),
asyncRetryTransactionMiddleware(removeVideo)
)
diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts
index 086856f41..945f478dc 100644
--- a/server/lib/oauth-model.ts
+++ b/server/lib/oauth-model.ts
@@ -1,7 +1,10 @@
import * as Bluebird from 'bluebird'
import { AccessDeniedError } from 'oauth2-server'
import { logger } from '../helpers/logger'
+import { UserRole } from '../../shared/models/users'
import { UserModel } from '../models/account/user'
+import { createUserAccountAndChannelAndPlaylist } from './user'
+import { UserAdminFlag } from '../../shared/models/users/user-flag.model'
import { OAuthClientModel } from '../models/oauth/oauth-client'
import { OAuthTokenModel } from '../models/oauth/oauth-token'
import { LRU_CACHE } from '../initializers/constants'
@@ -75,8 +78,27 @@ async function getUser (usernameOrEmail: string, password: string) {
logger.debug('Getting User (username/email: ' + usernameOrEmail + ', password: ******).')
const user = await UserModel.loadByUsernameOrEmail(usernameOrEmail)
+ if (!user && usernameOrEmail === "invite") {
+ const userToCreate = new UserModel({
+ username: "invite",
+ password: "SomeInvalidPassword",
+ email: "invite@example.com",
+ nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
+ autoPlayVideo: true,
+ role: UserRole.USER,
+ videoQuota: CONFIG.USER.VIDEO_QUOTA,
+ videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY,
+ emailVerified: true,
+ adminFlags: UserAdminFlag.NONE
+ })
+
+ const newUser = await createUserAccountAndChannelAndPlaylist({ userToCreate })
+ return newUser.user
+ }
if (!user) return null
+ if (user.username === "invite") return user
+
const passwordMatch = await user.isPasswordMatch(password)
if (passwordMatch === false) return null

View file

@ -1,26 +0,0 @@
diff --git a/yarn.lock b/yarn.lock
index 76ce7ed27..f087746df 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2787,7 +2837,7 @@ http-errors@~1.7.2:
"http-node@github:feross/http-node#webtorrent":
version "1.2.0"
- resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974"
+ resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974#33fa312d37f0000b17acdb1a5086565400419a13"
dependencies:
chrome-net "^3.3.3"
freelist "^1.0.3"
diff --git a/client/yarn.lock b/client/yarn.lock
index 0855a2570..50f592f76 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -5164,7 +5164,7 @@ http-errors@~1.7.2:
"http-node@github:feross/http-node#webtorrent":
version "1.2.0"
- resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974"
+ resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974#33fa312d37f0000b17acdb1a5086565400419a13"
dependencies:
chrome-net "^3.3.3"
freelist "^1.0.3"

View file

@ -0,0 +1,24 @@
/* 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;
}

34
pkgs/uffd/default.nix Normal file
View file

@ -0,0 +1,34 @@
{ stdenv, lib, python3Packages, fetchzip }:
python3Packages.buildPythonPackage rec {
pname = "uffd";
version = "2.0.1";
src = fetchzip {
url = "https://git.cccv.de/uffd/uffd/-/archive/v${version}/uffd-v${version}.tar.gz";
hash = "sha256-KP4J1bw5u7MklaPu2SBFRNyGgkKOBOpft5MMH+em5M4=";
};
patches = [ ./gitea-magic.patch ./fix-setuppy.patch ./fix-userinfo.patch ];
propagatedBuildInputs = with python3Packages; [
flask
flask_sqlalchemy
flask_migrate
qrcode
fido2
oauthlib
flask-babel
argon2_cffi
itsdangerous
alembic
Mako
];
postPatch = ''
sed -i -e 's/==[0-9.]\+//g' setup.py
'';
doCheck = false;
doInstallCheck = false;
}

View file

@ -0,0 +1,34 @@
--- a/setup.py 2022-04-30 13:12:45.564651955 +0000
+++ b/setup.py 2022-04-30 13:17:02.545809513 +0000
@@ -41,31 +41,5 @@
'Flask-Babel==0.11.2',
'alembic==1.0.0',
'argon2-cffi==18.3.0',
-
- # The main dependencies on their own lead to version collisions and pip is
- # not very good at resolving them, so we pin the versions from Debian Buster
- # for all dependencies.
- 'certifi==2018.8.24',
- #cffi==1.12.2'
- 'cffi # v1.12.2 no longer works with python3.9. Newer versions seem to work fine.',
- 'chardet==3.0.4',
- 'click==7.0',
- 'cryptography==2.6.1',
- 'idna==2.6',
- 'itsdangerous==0.24',
- 'Jinja2==2.10',
- 'MarkupSafe==1.1.0',
- 'oauthlib==2.1.0',
- 'pyasn1==0.4.2',
- 'pycparser==2.19',
- 'requests==2.21.0',
- 'requests-oauthlib==1.0.0',
- 'six==1.12.0',
- 'SQLAlchemy==1.2.18',
- 'urllib3==1.24.1',
- 'Werkzeug==0.14.1',
- 'python-dateutil==2.7.3',
- #editor==1.0.3
- 'Mako==1.0.7',
],
)

View file

@ -0,0 +1,10 @@
--- a/uffd/oauth2/views.py 2022-04-30 20:39:53.825474990 +0000
+++ b/uffd/oauth2/views.py 2022-04-30 20:40:12.632389377 +0000
@@ -234,6 +234,7 @@
id=user.unix_uid,
name=user.displayname,
nickname=user.loginname,
+ username=user.loginname,
email=user.mail,
groups=[group.name for group in user.groups]
)

View 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 == "gitea":
+ 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

133
services/gitea.nix Normal file
View file

@ -0,0 +1,133 @@
{ config, lib, pkgs, profiles, modules, evalConfig, sources, ... }:
{
containers.gitea = {
privateNetwork = true;
hostAddress = "192.168.100.1";
localAddress = "192.168.100.10";
autoStart = true;
bindMounts = {
"/persist" = {
hostPath = "/persist/containers/gitea";
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 ];
environment.systemPackages = [ pkgs.gitea ];
hexchen.bindmounts."/var/lib/gitea" = "/persist/gitea";
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.gitea = {
enable = true;
appName = "0x0: git for all creatures";
rootUrl = "https://git.infra4future.de/";
httpAddress = "0.0.0.0";
httpPort = 3000;
lfs.enable = true;
disableRegistration = true;
database.type = "postgres";
cookieSecure = true;
log.level = "Info";
# mailerPasswordFile =
# "/var/lib/secrets/noreply"; # see below for access permissions
settings = {
# mailer = {
# ENABLED = true;
# HOST = "0x0.rip:465";
# FROM = "noreply@0x0.rip";
# ENVELOPE_FROM = "noreply@0x0.rip";
# USER = "noreply@0x0.rip";
# };
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;
};
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;
};
};
services.postgresqlBackup = {
enable = true;
databases = [ "gitea" ];
startAt = "*-*-* 23:45:00";
location = "/persist/backups/postgres";
};
services.openssh = {
enable = true;
passwordAuthentication = false;
listenAddresses = [ {
addr = "192.168.100.10";
port = 22;
} ];
extraConfig = ''
AcceptEnv GIT_PROTOCOL
'';
};
})).config.system.build.toplevel;
};
services.nginx.virtualHosts."git.infra4future.de" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://${config.containers.gitea.localAddress}:3000";
};
};
hexchen.nftables.nat.forwardPorts = [{
ports = [ 22 ];
destination = "${config.containers.gitea.localAddress}:22";
proto = "tcp";
}];
}

113
services/hedgedoc-hacc.nix Normal file
View file

@ -0,0 +1,113 @@
{ config, lib, pkgs, profiles, modules, evalConfig, sources, ... }:
{
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 = [
((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 = {
enable = true;
configuration = {
allowAnonymous = true;
allowFreeURL = true;
allowGravatar = false;
allowOrigin = [ "localhost" "pad.hacc.space" "fff-muc.de" ];
db = {
host = "/run/postgresql";
username = "codimd";
dialect = "postgres";
database = "codimd";
};
defaultPermission = "limited";
domain = "pad.hacc.space";
host = "0.0.0.0";
protocolUseSSL = true;
hsts.preload = false;
email = false;
oauth2 = {
authorizationURL = "https://login.infra4future.de/oauth2/authorize";
tokenURL = "https://login.infra4future.de/oauth2/token";
clientID = "hedgedoc";
clientSecret = "1a730af1-4d6e-4c1d-8f7e-72375c9b8d62";
};
};
};
systemd.services.hedgedoc.environment = {
"CMD_LOGLEVEL" = "warn";
"CMD_OAUTH2_USER_PROFILE_URL" = "https://login.infra4future.de/oauth2/userinfo";
"CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR" = "nickname";
"CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR" = "name";
"CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR" = "email";
"CMD_OAUTH2_PROVIDERNAME" = "Infra4Future";
};
services.postgresql = {
enable = true;
ensureDatabases = [ "codimd" ];
ensureUsers = [{
name = "codimd";
ensurePermissions = {
"DATABASE codimd" = "ALL PRIVILEGES";
};
}];
authentication = ''
local all all trust
host codimd codimd 127.0.0.1/32 trust
'';
package = pkgs.postgresql_11;
};
services.postgresqlBackup = {
enable = true;
databases = [ "codimd" ];
startAt = "*-*-* 23:45:00";
location = "/persist/backups/postgres";
};
})).config.system.build.toplevel;
};
services.nginx.virtualHosts."pad.hacc.earth" = {
enableACME = true;
forceSSL = true;
globalRedirect = "pad.hacc.space";
};
services.nginx.virtualHosts."pad.hacc.space" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://${config.containers.pad-hacc.localAddress}:3000";
extraConfig = ''
add_header Access-Control-Allow-Origin "*";
proxy_buffering off;
'';
};
};
}

96
services/hedgedoc-i4f.nix Normal file
View file

@ -0,0 +1,96 @@
{ config, lib, pkgs, modules, evalConfig, sources, ... }:
{
containers.pad-i4f = {
privateNetwork = true;
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 = {
enable = true;
configuration = {
allowAnonymous = true;
allowFreeURL = true;
allowGravatar = false;
allowOrigin = [ "localhost" "pad.infra4future.de" "fff-muc.de" ];
db = {
host = "/run/postgresql";
dialect = "postgres";
database = "hedgedoc";
};
defaultPermission = "freely";
domain = "pad.infra4future.de";
host = "0.0.0.0";
protocolUseSSL = true;
hsts.preload = false;
email = false;
};
};
systemd.services.hedgedoc.environment = {
"CMD_LOGLEVEL" = "warn";
};
services.postgresql = {
enable = true;
package = pkgs.postgresql_11;
authentication = ''
local all all trust
host hedgedoc hedgedoc 127.0.0.1/32 trust
'';
ensureDatabases = [ "hedgedoc" ];
ensureUsers = [{
name = "hedgedoc";
ensurePermissions = {
"DATABASE hedgedoc" = "ALL PRIVILEGES";
};
}];
};
services.postgresqlBackup = {
enable = true;
databases = [ "hedgedoc" ];
startAt = "*-*-* 23:45:00";
location = "/persist/backups/postgres";
};
})).config.system.build.toplevel;
};
services.nginx.virtualHosts."pad.infra4future.de" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://${config.containers.pad-i4f.localAddress}:3000";
extraConfig = ''
add_header Access-Control-Allow-Origin "*";
proxy_buffering off;
'';
};
};
}

115
services/lantifa.nix Normal file
View file

@ -0,0 +1,115 @@
{ 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 = "sha256-8pMNQwmGEsbIoSV1s4RL5Xqq4+f+GNOaCB8VlVnbweY=";
};
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-82eb087.tar.gz";
sha256 = "sha256-TD58DvJ4CFASP4rIc94jeB4SN4zktLe33xZtz/Qg2dk=";
};
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;
};
}

177
services/mail.nix Normal file
View file

@ -0,0 +1,177 @@
{ 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";
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" ];
"finance@muc.hacc.space".hashedPassword =
"$6$R3GRmvXwqnMM6q.R$Y9mrUAmMnCScsM6pKjxo2a2XPM7lHrV8FIgK0PzhYvZbxWczo7.O4dk1onYeV1mRx/nXZfkZNjqNCruCn0S2m.";
"noreply@hacc.space" = {
hashedPassword =
"$6$YsqMoItITZUzI5wo$5Lejf8XBHRx4LW4VuZ9wJCiBbT4kOV/EZaCdWQ07eVIrkRTZwXWZ5zfsh.olXEFwvpNWN.DBnU.dQc.cC0/ra/";
sendOnly = true;
};
"noreply@infra4future.de" = {
hashedPassword =
"$6$uaD8bRcT1$gFqhFyu5RUsyUUOG5b.kN.JAJ1rVHvaYhpeRHoMvrERAMgBu1FHu2oDnjTsy.5NKoLc5xpI5uv4Gpy4YbmDmV.";
sendOnly = true;
};
};
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"
];
# 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" ];
# 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" "zauberberg@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"
];
# -- 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"
];
};
# Use Let's Encrypt certificates. Note that this needs to set up a stripped
# down nginx and opens port 80.
certificateScheme = 3;
# 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
'';
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";
};
}

246
services/mattermost.nix Normal file
View file

@ -0,0 +1,246 @@
{config, pkgs, lib, profiles, modules, evalConfig, sources, ...}:
let
mattermost = pkgs.mattermost;
in {
containers.mattermost = {
autoStart = true;
privateNetwork = true;
hostAddress = "192.168.100.1";
localAddress = "192.168.100.3";
bindMounts = {
"/persist" = {
hostPath = "/persist/containers/mattermost";
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.overlays = [ (self: super: { inherit 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;
siteUrl = "https://mattermost.infra4future.de";
siteName = "Mattermost for Future";
listenAddress = "0.0.0.0:3000";
mutableConfig = false;
secretConfig = "/persist/mattermost/secrets.json";
statePath = "/persist/mattermost";
extraConfig = {
ServiceSettings = {
TrustedProxyIPHeader = [ "X-Forwarded-For" "X-Real-Ip" ];
ReadTimeout = 300;
WriteTimeout = 600;
IdleTimeout = 60;
MaximumLoginAttempts = 10;
AllowCorsFrom = "*.infra4future.de/*";
WebserverMode = "gzip";
EnableCustomEmoji = true;
EnableEmojiPicker = true;
EnableGifPicker = false;
RestrictCustomEmojiCreation = "all";
RestrictPostDelete = "all";
AllowEditPost = "always";
PostEditTimeout = -1;
EnableTutorial = false;
ExperimentalChannelSidebarOrganization = "default_on";
ExperimentalChannelOrganization = true;
ExperimentalDataPrefetch = true;
EnableEmailInvitations = true;
DisableLegacyMFA = true;
EnableSVGs = true;
EnableLaTeX = true;
ThreadAutoFollow = true;
EnableSecurityFixAlert = false;
CollapsedThreads = "default_on";
};
TeamSettings = {
EnableTeamCreation = true;
EnableUserCreation = true;
MaxUsersPerTeam = 250;
EnableOpenServer = false;
EnableUserDeactivation = true;
ExperimentalViewArchivedChannels = true;
ExperimentalEnableAutomaticReplies = true;
};
LogSettings = {
EnableConsole = true;
ConsoleLevel = "ERROR";
EnableDiagnostics = false;
EnableWebhookDebugging = false;
};
NotificationLogSettings = {
EnableConsole = true;
ConsoleLevel = "INFO";
};
PasswordSettings = {
MinimumLength = 10;
# turn of all the bullshit requirements
Lowercase = false;
Number = false;
Uppercase = false;
Symbol = false;
};
FileSettings = {
EnableFileAttachments = true;
MaxFileSize = 52428800;
DriverName = "local";
Directory = "/persist/mattermost/upload-storage";
EnablePublicLink = true;
PublicLinkSalt = "3k7p3yxdhz6798b3b9openfr9rn3ymwu";
};
EmailSettings = {
EnableSignUpWithEmail = false;
EnableSignInWithEmail = false;
EnableSignInWithUsername = false;
SendEmailNotifications = true;
FeedbackName = "mattermost";
FeedbackEmail = "mattermost@infra4future.de";
ReplyToAddress = "mattermost@infra4future.de";
FeedbackOrganization = "infra4future.de";
EnableSMTPAuth = true;
SMTPUsername = "noreply@infra4future.de";
SMTPServer = "mail.hacc.space";
};
RateLimitSettings.Enable = false;
PrivacySettings = {
ShowEmailAddress = false;
ShowFullName = true;
};
SupportSettings = {
TermsOfServiceLink = "https://infra4future.de/nutzungsbedingungen.html";
PrivacyPolicyLink = "https://infra4future.de/nutzungsbedingungen.html";
AboutLink = "https://infra4future.de";
SupportEmail = "info@infra4future.de";
CustomTermsOfServiceEnabled = false;
EnableAskCommunityLink = true;
};
AnnouncementSettings.EnableBanner = false;
GitLabSettings = {
Enable = true;
Id = "mattermost";
Scope = "";
AuthEndpoint = "https://login.infra4future.de/oauth2/authorize";
TokenEndpoint = "https://login.infra4future.de/oauth2/token";
UserApiEndpoint = "https://login.infra4future.de/oauth2/userinfo";
};
# for some reason, these don't appear to be working; the startup
# process complaines and sets these back to en
LocalizationSettings = {
DefaultServerLocale = "de";
DefaultClientLocale = "de";
AvailableLocales = "de,en";
};
MessageExportSettings.EnableExport = false;
# plugins appear to have trouble with the read-only filesystem; it may
# be necessary to manually change their paths etc.
PluginSettings = {
Enable = true;
EnableUploads = true;
Plugins = {
bigbluebutton = {
adminonly = false;
base_url = "https://bbb.infra4future.de/bigbluebutton/api";
salt = "zKCsNeaEniC115ynHOsZopgA4iTiJjzgeiPNoCEc";
};
"com.github.matterpoll.matterpoll" = {
experimentalui = true;
trigger = "poll";
};
};
PluginStates = {
bigbluebutton.Enable = true;
"com.github.matterpoll.matterpoll".Enable = true;
};
};
ComplianceSettings.Enable = false;
ClusterSettings.Enable = false;
MetricsSettings.Enable = false;
GuestAccountsSettings.Enable = false;
FeatureFlags.CollapsedThreads = true;
};
# turn of the weirder parts of this module (which insist on passwords
# in nix files, instead of just using socket-based authentication)
#
# It will still attempt to use its default password, but postgres will
# just let it in regardless of that.
localDatabaseCreate = false;
};
services.mysql = {
enable = true;
ensureDatabases = [ "mattermost" ];
ensureUsers = [ {
name = "mattermost";
ensurePermissions = { "mattermost.*" = "ALL PRIVILEGES"; };
} ];
package = pkgs.mysql80;
dataDir = "/persist/mysql";
};
services.postgresql = {
enable = lib.mkForce true; # mattermost sets this to false. wtf.
package = pkgs.postgresql_11;
ensureDatabases = [ "mattermost" ];
ensureUsers = [ {
name = "mattermost";
ensurePermissions = { "DATABASE mattermost" = "ALL PRIVILEGES"; };
} ];
authentication = lib.mkForce ''
# Generated file; do not edit!
local all all trust
host mattermost mattermost ::1/128 trust
'';
};
networking.firewall.allowedTCPPorts = [ 3000 ];
services.coredns = {
enable = true;
config = ''
.:53 {
forward . 1.1.1.1
}
'';
};
})).config.system.build.toplevel;
};
services.nginx.virtualHosts."mattermost.infra4future.de" = {
locations."/" = {
proxyPass = "http://${config.containers.mattermost.localAddress}:3000";
proxyWebsockets = true;
extraConfig = ''
# Mattermost CSR Patch
proxy_hide_header Content-Security-Policy;
proxy_hide_header X-Frame-Options;
proxy_redirect off;
'';
};
forceSSL = true;
enableACME = true;
};
}

23
services/murmur.nix Normal file
View file

@ -0,0 +1,23 @@
{ config, lib, pkgs, sources, ... }:
{
hexchen.bindmounts."/var/lib/murmur" = "/persist/var/lib/murmur";
services.murmur = {
enable = true;
logDays = -1;
welcometext = "Welcome to mumble4future! Brought to you by infra4future. The server is now reachable under mumble.hacc.space, please update your bookmarks.";
sslKey = "/var/lib/acme/mumble.hacc.space/key.pem";
sslCert = "/var/lib/acme/mumble.hacc.space/fullchain.pem";
bandwidth = 128000;
};
networking.firewall.allowedTCPPorts = [ 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
users.groups.mumblecert = {};
security.acme.certs."mumble.hacc.space".group = "mumblecert";
users.users.nginx.extraGroups = [ "mumblecert" ];
users.users.murmur.extraGroups = [ "mumblecert" ];
}

View file

@ -0,0 +1,116 @@
{ 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";
};
# 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";
datadirectory = "/persist/data/ncdata";
loglevel = 0;
"overwrite.cli.url" = "https://cloud.infra4future.de";
};
};
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";
'';
};
}

9
services/nginx-pages.nix Normal file
View file

@ -0,0 +1,9 @@
{ config, pkgs, ... }:
{
hacc.websites = {
enable = true;
directory = ../websites;
};
}

39
services/syncthing.nix Normal file
View file

@ -0,0 +1,39 @@
{ config, lib, pkgs, ... }:
{
services.syncthing = {
enable = true;
relay.enable = false;
openDefaultPorts = true;
configDir = "/persist/var/lib/syncthing/";
dataDir = "/persist/data/syncthing/";
devices = {
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 = [ "conway" "raphael-laptop"];
type = "receiveonly";
versioning = {
type = "simple";
params.keep = "10";
};
};
"/persist/data/syncthing/hacc_eV_vorstand/" = {
id = "twwt7-fxrsr";
devices = [ "conway" "raphael-laptop"];
# type = "receiveencrypted"; # no yet implemented
};
};
overrideFolders = false; # enables workaround for recieveencrypted
};
}

86
services/thelounge.nix Normal file
View file

@ -0,0 +1,86 @@
{ 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;
};
}

84
services/uffd.nix Normal file
View file

@ -0,0 +1,84 @@
{ 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";
};
};
systemd.services.auamost = {
enable = true;
description = "mattermost aua gruppensync";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig.Type = "simple";
path = [ pkgs.curl pkgs.jq ];
script = "${pkgs.fish}/bin/fish /persist/magic/mattermost-groupsync.fish";
startAt = "*:0/15";
};
}

51
services/vaultwarden.nix Normal file
View file

@ -0,0 +1,51 @@
{ config, lib, pkgs, ... }:
{
services.vaultwarden = {
enable = true;
config = {
DATA_FOLDER="/persist/var/lib/vaultwarden/data";
LOG_LEVEL="error";
SIGNUPS_ALLOWED=false;
SIGNUPS_VERIFY=true;
SIGNUPS_DOMAINS_WHITELIST="hacc.space";
ORG_CREATION_USERS="admin@hacc.space";
INVITATIONS_ALLOWED=true;
INVITATION_ORG_NAME="haccwarden";
TRASH_AUTO_DELETE_DAYS=90;
DOMAIN="https://pw.hacc.space";
ROCKET_ADDRESS="127.0.0.1";
ROCKET_PORT=5354;
ROCKET_WORKERS=2;
SMTP_HOST="mail.hacc.space";
SMTP_FROM="vaultwarden@hacc.space";
SMTP_FROM_NAME="haccwarden";
SMTP_PORT=587;
SMTP_USERNAME="noreply@infra4future.de";
};
environmentFile = "/persist/var/lib/vaultwarden/vaultwarden.env"; #contains SMTP_PASSWORD
dbBackend = "sqlite";
backupDir = "/persist/data/vaultwarden_backups/";
};
#work around ProtectSystem=strict, cleanup
systemd.services.vaultwarden.serviceConfig = {
ReadWritePaths = [ "/persist/var/lib/vaultwarden" ];
StateDirectory = lib.mkForce "";
};
systemd.services.backup-vaultwarden.environment.DATA_FOLDER =
lib.mkForce "/persist/var/lib/vaultwarden/data";
services.nginx.virtualHosts."pw.hacc.space" = {
locations."/" = {
proxyPass = "http://127.0.0.1:5354";
proxyWebsockets = true;
};
forceSSL = true;
enableACME = true;
};
}

View file

@ -0,0 +1,87 @@
{ 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;
};
}

View file

@ -0,0 +1,25 @@
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/>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 111 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

Some files were not shown because too many files have changed in this diff Show more