forked from hacc/haccfiles
Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
05c4fe4823 |
288 changed files with 25888 additions and 43139 deletions
|
@ -1,9 +1,31 @@
|
||||||
stages:
|
stages:
|
||||||
|
- instantiate
|
||||||
- build
|
- build
|
||||||
|
|
||||||
build-parsons:
|
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:
|
||||||
tags:
|
tags:
|
||||||
- nix
|
- nix
|
||||||
stage: build
|
stage: build
|
||||||
script:
|
script:
|
||||||
- nix-build -A deploy.parsons
|
- 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
|
||||||
|
|
47
README.md
47
README.md
|
@ -1,47 +0,0 @@
|
||||||
# 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)
|
|
|
@ -1,9 +0,0 @@
|
||||||
{config, lib, pkgs, ...}:
|
|
||||||
|
|
||||||
let
|
|
||||||
sources = import ../nix/sources.nix;
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
(import sources.nix-hexchen {}).users.hexchen.base
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,24 +1,25 @@
|
||||||
{ config, lib, pkgs, modules, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
{
|
||||||
sources = import ../nix/sources.nix;
|
|
||||||
in {
|
|
||||||
imports = [
|
imports = [
|
||||||
../modules
|
../../modules
|
||||||
|
./external.nix
|
||||||
./users.nix
|
./users.nix
|
||||||
(sources.home-manager + "/nixos")
|
|
||||||
modules.network.nftables
|
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages;
|
nixpkgs.overlays = [
|
||||||
|
(self: super: import ../../pkgs { nixpkgs = super.path; })
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
|
||||||
boot.kernelParams = [ "quiet" ];
|
boot.kernelParams = [ "quiet" ];
|
||||||
|
|
||||||
networking.domain = lib.mkDefault "hacc.space";
|
networking.domain = lib.mkDefault "hacc.space";
|
||||||
|
petabyte.nftables = {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
};
|
||||||
|
|
||||||
services.journald.extraConfig = ''
|
services.journald.extraConfig = "SystemMaxUse=512M";
|
||||||
SystemMaxUse=512M
|
|
||||||
MaxRetentionSec=48h
|
|
||||||
'';
|
|
||||||
nix.gc.automatic = lib.mkDefault true;
|
nix.gc.automatic = lib.mkDefault true;
|
||||||
nix.gc.options = lib.mkDefault "--delete-older-than 1w";
|
nix.gc.options = lib.mkDefault "--delete-older-than 1w";
|
||||||
nix.trustedUsers = [ "root" "@wheel" ];
|
nix.trustedUsers = [ "root" "@wheel" ];
|
||||||
|
@ -36,6 +37,7 @@ in {
|
||||||
security.sudo.wheelNeedsPassword = lib.mkDefault false;
|
security.sudo.wheelNeedsPassword = lib.mkDefault false;
|
||||||
|
|
||||||
i18n.defaultLocale = "en_IE.UTF-8";
|
i18n.defaultLocale = "en_IE.UTF-8";
|
||||||
|
time.timeZone = "UTC";
|
||||||
console = {
|
console = {
|
||||||
font = "Lat2-Terminus16";
|
font = "Lat2-Terminus16";
|
||||||
keyMap = "de";
|
keyMap = "de";
|
||||||
|
@ -44,8 +46,8 @@ in {
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
smartmontools lm_sensors htop tcpdump nload iftop
|
smartmontools lm_sensors htop tcpdump nload iftop
|
||||||
bottom
|
# bottom
|
||||||
ripgrep vgrep
|
ripgrep
|
||||||
git wget
|
git wget
|
||||||
kitty.terminfo
|
kitty.terminfo
|
||||||
rsync pv progress
|
rsync pv progress
|
||||||
|
@ -61,7 +63,7 @@ in {
|
||||||
socat
|
socat
|
||||||
tmux
|
tmux
|
||||||
gnupg
|
gnupg
|
||||||
vim neovim
|
vim
|
||||||
patchelf
|
patchelf
|
||||||
binutils
|
binutils
|
||||||
dnsutils
|
dnsutils
|
||||||
|
@ -69,17 +71,13 @@ in {
|
||||||
nmap
|
nmap
|
||||||
s-tui stress
|
s-tui stress
|
||||||
ffmpeg-full
|
ffmpeg-full
|
||||||
bat
|
|
||||||
niv
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
petabyte.vnstat = {
|
||||||
|
enable = true;
|
||||||
|
nginx.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
security.acme.email = "info+acme@hacc.space";
|
security.acme.email = "info+acme@hacc.space";
|
||||||
security.acme.acceptTerms = true;
|
security.acme.acceptTerms = true;
|
||||||
|
|
||||||
services.nginx.appendHttpConfig = ''
|
|
||||||
access_log off;
|
|
||||||
add_header Permissions-Policy "interest-cohort=()";
|
|
||||||
'';
|
|
||||||
|
|
||||||
networking.nftables.enable = true;
|
|
||||||
}
|
}
|
32
configuration/common/external.nix
Normal file
32
configuration/common/external.nix
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
79
configuration/common/hexchen.nix
Normal file
79
configuration/common/hexchen.nix
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
{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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -12,11 +12,17 @@
|
||||||
openssh.authorizedKeys.keys = with pkgs.lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
|
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 = {
|
hexchen = {
|
||||||
uid = lib.mkForce 1000;
|
uid = 1000;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" ];
|
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 = {
|
stuebinm = {
|
||||||
|
@ -48,13 +54,12 @@
|
||||||
packages = with pkgs; [ ffmpeg ];
|
packages = with pkgs; [ ffmpeg ];
|
||||||
};
|
};
|
||||||
|
|
||||||
moira = {
|
schweby = {
|
||||||
uid = 1004;
|
uid = 1004;
|
||||||
shell = pkgs.fish;
|
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" "cdrom" ];
|
extraGroups = [ "wheel" "cdrom" ];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJrcJRF71+XM5YZj+SaSiGcdVZ0IDxGBXIWssDtHiTtr moira_2022_06"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL6JWi0MBDz0Zy4zjauQv28xYmHyapb8D4zeesq91LLE schweby@txsbcct"
|
||||||
];
|
];
|
||||||
hashedPassword = "$6$zkAsaVdmIduqZxez$GY9aBlYeP41F0it/VbbZzLLLRQhHAbDdFsa3e/1GS9McTuSimMHODg6HqNVEH1zSqD3afhK/0UHfqbtF5qpi90";
|
hashedPassword = "$6$zkAsaVdmIduqZxez$GY9aBlYeP41F0it/VbbZzLLLRQhHAbDdFsa3e/1GS9McTuSimMHODg6HqNVEH1zSqD3afhK/0UHfqbtF5qpi90";
|
||||||
};
|
};
|
51
configuration/desktop/default.nix
Normal file
51
configuration/desktop/default.nix
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{ 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";
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,4 +7,13 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ obs-studio ];
|
environment.systemPackages = with pkgs; [ obs-studio ];
|
||||||
|
|
||||||
|
home-manager.users.hexchen = {
|
||||||
|
programs.obs-studio = {
|
||||||
|
enable = true;
|
||||||
|
plugins = with pkgs; [
|
||||||
|
obs-wlrobs obs-v4l2sink
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
42
configuration/desktop/sway.nix
Normal file
42
configuration/desktop/sway.nix
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{ 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;
|
||||||
|
|
||||||
|
}
|
22
configuration/hosts/README.md
Normal file
22
configuration/hosts/README.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# 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.
|
26
configuration/hosts/cdn/loadbalancer/configuration.nix
Normal file
26
configuration/hosts/cdn/loadbalancer/configuration.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ 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. It‘s perfectly fine and recommended to leave
|
||||||
|
# this value at the release version of the first install of this system.
|
||||||
|
# Before changing this value read the documentation for this option
|
||||||
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
|
system.stateVersion = "20.03"; # Did you read the comment?
|
||||||
|
}
|
26
configuration/hosts/cdn/loadbalancer/hardware-config.nix
Normal file
26
configuration/hosts/cdn/loadbalancer/hardware-config.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
26
configuration/hosts/cdn/master/configuration.nix
Normal file
26
configuration/hosts/cdn/master/configuration.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ 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. It‘s perfectly fine and recommended to leave
|
||||||
|
# this value at the release version of the first install of this system.
|
||||||
|
# Before changing this value read the documentation for this option
|
||||||
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
|
system.stateVersion = "20.03"; # Did you read the comment?
|
||||||
|
}
|
25
configuration/hosts/cdn/master/hardware-config.nix
Normal file
25
configuration/hosts/cdn/master/hardware-config.nix
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
|
|
26
configuration/hosts/cdn/node-1/configuration.nix
Normal file
26
configuration/hosts/cdn/node-1/configuration.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ 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. It‘s perfectly fine and recommended to leave
|
||||||
|
# this value at the release version of the first install of this system.
|
||||||
|
# Before changing this value read the documentation for this option
|
||||||
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
|
system.stateVersion = "20.03"; # Did you read the comment?
|
||||||
|
}
|
25
configuration/hosts/cdn/node-1/hardware-config.nix
Normal file
25
configuration/hosts/cdn/node-1/hardware-config.nix
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
|
|
26
configuration/hosts/cdn/node-2/configuration.nix
Normal file
26
configuration/hosts/cdn/node-2/configuration.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ 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. It‘s perfectly fine and recommended to leave
|
||||||
|
# this value at the release version of the first install of this system.
|
||||||
|
# Before changing this value read the documentation for this option
|
||||||
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
|
system.stateVersion = "20.03"; # Did you read the comment?
|
||||||
|
}
|
25
configuration/hosts/cdn/node-2/hardware-config.nix
Normal file
25
configuration/hosts/cdn/node-2/hardware-config.nix
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
|
|
37
configuration/hosts/default.nix
Normal file
37
configuration/hosts/default.nix
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
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
|
107
configuration/hosts/hainich/configuration.nix
Normal file
107
configuration/hosts/hainich/configuration.nix
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
{ 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. It‘s perfectly fine and recommended to leave
|
||||||
|
# this value at the release version of the first install of this system.
|
||||||
|
# Before changing this value read the documentation for this option
|
||||||
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
|
system.stateVersion = "20.03"; # Did you read the comment?
|
||||||
|
}
|
28
configuration/hosts/hainich/encboot.nix
Normal file
28
configuration/hosts/hainich/encboot.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
52
configuration/hosts/hainich/hardware.nix
Normal file
52
configuration/hosts/hainich/hardware.nix
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
{ 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";
|
||||||
|
}
|
125
configuration/hosts/hainich/k8s.nix
Normal file
125
configuration/hosts/hainich/k8s.nix
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
{ 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/
|
||||||
|
'';
|
||||||
|
}
|
80
configuration/hosts/hainich/services/codimd.nix
Normal file
80
configuration/hosts/hainich/services/codimd.nix
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
{ 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;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
34
configuration/hosts/hainich/services/docker.nix
Normal file
34
configuration/hosts/hainich/services/docker.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{ 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;
|
||||||
|
";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
93
configuration/hosts/hainich/services/engelsystem.nix
Normal file
93
configuration/hosts/hainich/services/engelsystem.nix
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
{ 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;";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
55
configuration/hosts/hainich/services/funkwhale.nix
Normal file
55
configuration/hosts/hainich/services/funkwhale.nix
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
{ 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;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
62
configuration/hosts/hainich/services/gitlab-runner.nix
Normal file
62
configuration/hosts/hainich/services/gitlab-runner.nix
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
{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";
|
||||||
|
}
|
154
configuration/hosts/hainich/services/mail.nix
Normal file
154
configuration/hosts/hainich/services/mail.nix
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
{ 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";
|
||||||
|
};
|
||||||
|
}
|
26
configuration/hosts/hainich/services/murmur.nix
Normal file
26
configuration/hosts/hainich/services/murmur.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ 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";
|
||||||
|
}
|
61
configuration/hosts/hainich/services/nginx.nix
Normal file
61
configuration/hosts/hainich/services/nginx.nix
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
{ 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";
|
||||||
|
}
|
34
configuration/hosts/hainich/wireguard.nix
Normal file
34
configuration/hosts/hainich/wireguard.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{ 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";
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
imports =
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
../../common
|
../../common
|
||||||
../../desktop
|
../../desktop
|
||||||
../../desktop/streaming.nix
|
../../desktop/streaming.nix
|
||||||
|
../../desktop/sway.nix
|
||||||
../../desktop/gnome.nix
|
../../desktop/gnome.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -25,15 +26,14 @@
|
||||||
|
|
||||||
networking.hostName = "nixda"; # Define your hostname.
|
networking.hostName = "nixda"; # Define your hostname.
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ blackmagicDesktopVideo blender companion ];
|
environment.systemPackages = with pkgs; [ blackmagicDesktopVideo makemkv blender ];
|
||||||
|
|
||||||
networking.wg-quick.interfaces.cornbox = {
|
networking.wg-quick.interfaces.cornbox = {
|
||||||
privateKeyFile = "/etc/wireguard/cornbox.key";
|
privateKeyFile = "/etc/wireguard/cornbox.key";
|
||||||
address = [ "195.39.247.67/28" "2a0f:4ac0:1337::12/64" ];
|
address = [ "195.39.247.67/28" "2a0f:4ac0:1337::12/64" ];
|
||||||
postUp = "/run/wrappers/bin/ping -c5 195.39.247.65";
|
postUp = "ip link set dev cornbox mtu 1400";
|
||||||
peers = [
|
peers = [
|
||||||
{
|
{
|
||||||
persistentKeepalive = 25;
|
|
||||||
allowedIPs = [ "2a0f:4ac0:1337::/48" "195.39.247.64/27" ];
|
allowedIPs = [ "2a0f:4ac0:1337::/48" "195.39.247.64/27" ];
|
||||||
publicKey = "8IWyiQL3wKP9CD/4UdS9b8mcbL67mkUyeSPORgEPvV0=";
|
publicKey = "8IWyiQL3wKP9CD/4UdS9b8mcbL67mkUyeSPORgEPvV0=";
|
||||||
endpoint = "cornbox.hetzner.chaoswit.ch:51821";
|
endpoint = "cornbox.hetzner.chaoswit.ch:51821";
|
||||||
|
@ -41,34 +41,6 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
# This value determines the NixOS release from which the default
|
||||||
# settings for stateful data, like file locations and database versions
|
# settings for stateful data, like file locations and database versions
|
||||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
# on your system were taken. It‘s perfectly fine and recommended to leave
|
26
configuration/server/cdn/cdn-lb.nix
Normal file
26
configuration/server/cdn/cdn-lb.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{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";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
42
configuration/server/cdn/cdn-master.nix
Normal file
42
configuration/server/cdn/cdn-master.nix
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{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;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
43
configuration/server/cdn/cdn-node.nix
Normal file
43
configuration/server/cdn/cdn-node.nix
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
{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;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
61
configuration/server/cdn/common.nix
Normal file
61
configuration/server/cdn/common.nix
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
{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;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
13
default.nix
13
default.nix
|
@ -1,11 +1,4 @@
|
||||||
rec {
|
{
|
||||||
sources = import ./nix/sources.nix;
|
inherit (import ./lib/deploy.nix) deploy;
|
||||||
pkgs = import ./pkgs {};
|
pkgs = import ./pkgs;
|
||||||
inherit (pkgs) lib;
|
|
||||||
inherit (import (sources.nix-hexchen + "/lib/hosts.nix") {
|
|
||||||
inherit pkgs sources;
|
|
||||||
inherit ((import sources.nix-hexchen) {}) modules;
|
|
||||||
hostsDir = ./hosts; commonImports = [./common]; pkgsPath = ./pkgs;
|
|
||||||
}) hosts groups;
|
|
||||||
deploy = import (sources.nix-hexchen + "/lib/deploy.nix") { inherit pkgs hosts groups; };
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
boot.plymouth.enable = true;
|
|
||||||
nixpkgs.config = {
|
|
||||||
mumble.speechdSupport = true;
|
|
||||||
allowUnfree = true;
|
|
||||||
};
|
|
||||||
# boot.plymouth.splashBeforeUnlock = true;
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
pulsemixer pavucontrol
|
|
||||||
firefox kitty j4-dmenu-desktop bemenu
|
|
||||||
breeze-qt5 mako
|
|
||||||
mpv youtube-dl
|
|
||||||
wl-clipboard mumble
|
|
||||||
xdg_utils
|
|
||||||
slurp grim libnotify
|
|
||||||
_1password-gui
|
|
||||||
gimp
|
|
||||||
# gnome3.nautilus
|
|
||||||
] ++ (with pkgs; [ alacritty picom feh copyq polybar cinnamon.nemo rofi arandr notepadqq nomacs imv gthumb ]);
|
|
||||||
|
|
||||||
sound.enable = true;
|
|
||||||
time.timeZone = "Europe/Berlin";
|
|
||||||
hardware.pulseaudio = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.pulseaudioFull;
|
|
||||||
};
|
|
||||||
networking.useDHCP = lib.mkDefault true;
|
|
||||||
hardware.opengl.enable = true;
|
|
||||||
services.xserver = {
|
|
||||||
windowManager.bspwm.enable = true;
|
|
||||||
layout = "de";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
{ 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";
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
{ 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 = [ ];
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
{ 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;
|
|
||||||
};
|
|
||||||
}
|
|
76
lib/deploy.nix
Normal file
76
lib/deploy.nix
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
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); };
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.hardware.decklink;
|
|
||||||
kernelPackages = config.boot.kernelPackages;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.hardware.decklink.enable = mkEnableOption "Enable hardware support for the Blackmagic Design Decklink audio/video interfaces.";
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
boot.kernelModules = [ "blackmagic" "blackmagic-io" "snd_blackmagic-io" ];
|
|
||||||
boot.extraModulePackages = [ kernelPackages.decklink ];
|
|
||||||
systemd.services."DecklinkVideoHelper" = {
|
|
||||||
after = [ "syslog.target" "local-fs.target" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig.ExecStart = "${pkgs.blackmagicDesktopVideo}/bin/DesktopVideoHelper -n";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,16 +1,13 @@
|
||||||
{ ... }:
|
{ ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
sources = import ../nix/sources.nix;
|
immaeNix = fetchGit {
|
||||||
|
url = "https://git.immae.eu/perso/Immae/Config/Nix.git";
|
||||||
|
rev = "7ad4966f41db0669a77c7a6ee7f87f0d4e586b0c";
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./nftnat
|
"${immaeNix}/modules/webapps/peertube.nix"
|
||||||
./decklink.nix
|
./funkwhale
|
||||||
./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"
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
563
modules/funkwhale/default.nix
Normal file
563
modules/funkwhale/default.nix
Normal file
|
@ -0,0 +1,563 @@
|
||||||
|
{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 ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,251 +0,0 @@
|
||||||
{ 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";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,755 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.nextcloud-patched;
|
|
||||||
fpm = config.services.phpfpm.pools.nextcloud;
|
|
||||||
|
|
||||||
phpPackage =
|
|
||||||
let
|
|
||||||
base = pkgs.php74;
|
|
||||||
in
|
|
||||||
base.buildEnv {
|
|
||||||
extensions = { enabled, all }: with all;
|
|
||||||
enabled ++ [
|
|
||||||
apcu redis memcached imagick
|
|
||||||
];
|
|
||||||
extraConfig = phpOptionsStr;
|
|
||||||
};
|
|
||||||
|
|
||||||
toKeyValue = generators.toKeyValue {
|
|
||||||
mkKeyValue = generators.mkKeyValueDefault {} " = ";
|
|
||||||
};
|
|
||||||
|
|
||||||
phpOptions = {
|
|
||||||
upload_max_filesize = cfg.maxUploadSize;
|
|
||||||
post_max_size = cfg.maxUploadSize;
|
|
||||||
memory_limit = cfg.maxUploadSize;
|
|
||||||
} // cfg.phpOptions
|
|
||||||
// optionalAttrs cfg.caching.apcu {
|
|
||||||
"apc.enable_cli" = "1";
|
|
||||||
};
|
|
||||||
phpOptionsStr = toKeyValue phpOptions;
|
|
||||||
|
|
||||||
occ = pkgs.writeScriptBin "nextcloud-occ" ''
|
|
||||||
#! ${pkgs.runtimeShell}
|
|
||||||
cd ${cfg.package}
|
|
||||||
sudo=exec
|
|
||||||
if [[ "$USER" != nextcloud ]]; then
|
|
||||||
sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR --preserve-env=OC_PASS'
|
|
||||||
fi
|
|
||||||
export NEXTCLOUD_CONFIG_DIR="${cfg.home}/config"
|
|
||||||
$sudo \
|
|
||||||
${phpPackage}/bin/php \
|
|
||||||
occ $*
|
|
||||||
'';
|
|
||||||
|
|
||||||
inherit (config.system) stateVersion;
|
|
||||||
|
|
||||||
in {
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
(mkRemovedOptionModule [ "services" "nextcloud-patched" "nginx" "enable" ] ''
|
|
||||||
The nextcloud module supports `nginx` as reverse-proxy by default and doesn't
|
|
||||||
support other reverse-proxies officially.
|
|
||||||
|
|
||||||
However it's possible to use an alternative reverse-proxy by
|
|
||||||
|
|
||||||
* disabling nginx
|
|
||||||
* setting `listen.owner` & `listen.group` in the phpfpm-pool to a different value
|
|
||||||
|
|
||||||
Further details about this can be found in the `Nextcloud`-section of the NixOS-manual
|
|
||||||
(which can be openend e.g. by running `nixos-help`).
|
|
||||||
'')
|
|
||||||
];
|
|
||||||
|
|
||||||
options.services.nextcloud-patched = {
|
|
||||||
enable = mkEnableOption "nextcloud";
|
|
||||||
hostName = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "FQDN for the nextcloud instance.";
|
|
||||||
};
|
|
||||||
home = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/var/lib/nextcloud";
|
|
||||||
description = "Storage path of nextcloud.";
|
|
||||||
};
|
|
||||||
logLevel = mkOption {
|
|
||||||
type = types.ints.between 0 4;
|
|
||||||
default = 2;
|
|
||||||
description = "Log level value between 0 (DEBUG) and 4 (FATAL).";
|
|
||||||
};
|
|
||||||
https = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Use https for generated links.";
|
|
||||||
};
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
description = "Which package to use for the Nextcloud instance.";
|
|
||||||
relatedPackages = [ "nextcloud18" "nextcloud19" "nextcloud20" "nextcloud21" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
maxUploadSize = mkOption {
|
|
||||||
default = "512M";
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Defines the upload limit for files. This changes the relevant options
|
|
||||||
in php.ini and nginx if enabled.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
skeletonDirectory = mkOption {
|
|
||||||
default = "";
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
The directory where the skeleton files are located. These files will be
|
|
||||||
copied to the data directory of new users. Leave empty to not copy any
|
|
||||||
skeleton files.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
webfinger = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Enable this option if you plan on using the webfinger plugin.
|
|
||||||
The appropriate nginx rewrite rules will be added to your configuration.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
phpOptions = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
default = {
|
|
||||||
short_open_tag = "Off";
|
|
||||||
expose_php = "Off";
|
|
||||||
error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT";
|
|
||||||
display_errors = "stderr";
|
|
||||||
"opcache.enable_cli" = "1";
|
|
||||||
"opcache.interned_strings_buffer" = "8";
|
|
||||||
"opcache.max_accelerated_files" = "10000";
|
|
||||||
"opcache.memory_consumption" = "128";
|
|
||||||
"opcache.revalidate_freq" = "1";
|
|
||||||
"opcache.fast_shutdown" = "1";
|
|
||||||
"openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt";
|
|
||||||
catch_workers_output = "yes";
|
|
||||||
};
|
|
||||||
description = ''
|
|
||||||
Options for PHP's php.ini file for nextcloud.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
poolSettings = mkOption {
|
|
||||||
type = with types; attrsOf (oneOf [ str int bool ]);
|
|
||||||
default = {
|
|
||||||
"pm" = "dynamic";
|
|
||||||
"pm.max_children" = "32";
|
|
||||||
"pm.start_servers" = "2";
|
|
||||||
"pm.min_spare_servers" = "2";
|
|
||||||
"pm.max_spare_servers" = "4";
|
|
||||||
"pm.max_requests" = "500";
|
|
||||||
};
|
|
||||||
description = ''
|
|
||||||
Options for nextcloud's PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
poolConfig = mkOption {
|
|
||||||
type = types.nullOr types.lines;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Options for nextcloud's PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
dbtype = mkOption {
|
|
||||||
type = types.enum [ "sqlite" "pgsql" "mysql" ];
|
|
||||||
default = "sqlite";
|
|
||||||
description = "Database type.";
|
|
||||||
};
|
|
||||||
dbname = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = "nextcloud";
|
|
||||||
description = "Database name.";
|
|
||||||
};
|
|
||||||
dbuser = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = "nextcloud";
|
|
||||||
description = "Database user.";
|
|
||||||
};
|
|
||||||
dbpass = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Database password. Use <literal>dbpassFile</literal> to avoid this
|
|
||||||
being world-readable in the <literal>/nix/store</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
dbpassFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
The full path to a file that contains the database password.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
dbhost = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = "localhost";
|
|
||||||
description = ''
|
|
||||||
Database host.
|
|
||||||
|
|
||||||
Note: for using Unix authentication with PostgreSQL, this should be
|
|
||||||
set to <literal>/run/postgresql</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
dbport = mkOption {
|
|
||||||
type = with types; nullOr (either int str);
|
|
||||||
default = null;
|
|
||||||
description = "Database port.";
|
|
||||||
};
|
|
||||||
dbtableprefix = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Table prefix in Nextcloud database.";
|
|
||||||
};
|
|
||||||
adminuser = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "root";
|
|
||||||
description = "Admin username.";
|
|
||||||
};
|
|
||||||
adminpass = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Admin password. Use <literal>adminpassFile</literal> to avoid this
|
|
||||||
being world-readable in the <literal>/nix/store</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
adminpassFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
The full path to a file that contains the admin's password. Must be
|
|
||||||
readable by user <literal>nextcloud</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraTrustedDomains = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Trusted domains, from which the nextcloud installation will be
|
|
||||||
acessible. You don't need to add
|
|
||||||
<literal>services.nextcloud.hostname</literal> here.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
trustedProxies = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Trusted proxies, to provide if the nextcloud installation is being
|
|
||||||
proxied to secure against e.g. spoofing.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
overwriteProtocol = mkOption {
|
|
||||||
type = types.nullOr (types.enum [ "http" "https" ]);
|
|
||||||
default = null;
|
|
||||||
example = "https";
|
|
||||||
|
|
||||||
description = ''
|
|
||||||
Force Nextcloud to always use HTTPS i.e. for link generation. Nextcloud
|
|
||||||
uses the currently used protocol by default, but when behind a reverse-proxy,
|
|
||||||
it may use <literal>http</literal> for everything although Nextcloud
|
|
||||||
may be served via HTTPS.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultPhoneRegion = mkOption {
|
|
||||||
default = null;
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
example = "DE";
|
|
||||||
description = ''
|
|
||||||
<warning>
|
|
||||||
<para>This option exists since Nextcloud 21! If older versions are used,
|
|
||||||
this will throw an eval-error!</para>
|
|
||||||
</warning>
|
|
||||||
|
|
||||||
<link xlink:href="https://www.iso.org/iso-3166-country-codes.html">ISO 3611-1</link>
|
|
||||||
country codes for automatic phone-number detection without a country code.
|
|
||||||
|
|
||||||
With e.g. <literal>DE</literal> set, the <literal>+49</literal> can be omitted for
|
|
||||||
phone-numbers.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
defaultapp = mkOption {
|
|
||||||
default = null;
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
example = "files";
|
|
||||||
description = ''
|
|
||||||
This options sets the app that opens as default.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
caching = {
|
|
||||||
apcu = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Whether to load the APCu module into PHP.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
redis = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Whether to load the Redis module into PHP.
|
|
||||||
You still need to enable Redis in your config.php.
|
|
||||||
See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
memcached = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Whether to load the Memcached module into PHP.
|
|
||||||
You still need to enable Memcached in your config.php.
|
|
||||||
See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
autoUpdateApps = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Run regular auto update of all apps installed from the nextcloud app store.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
startAt = mkOption {
|
|
||||||
type = with types; either str (listOf str);
|
|
||||||
default = "05:00:00";
|
|
||||||
example = "Sun 14:00:00";
|
|
||||||
description = ''
|
|
||||||
When to run the update. See `systemd.services.<name>.startAt`.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
occ = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = occ;
|
|
||||||
internal = true;
|
|
||||||
description = ''
|
|
||||||
The nextcloud-occ program preconfigured to target this Nextcloud instance.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraOptions = mkOption {
|
|
||||||
type = types.attrs;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
Extra options which should be appended to nextcloud's config.php file
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
secretFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Secret options which will be appended to nextcloud's config.php file (written in JSON, in the same
|
|
||||||
form as the `extraOptions` option).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable (mkMerge [
|
|
||||||
{ assertions = let acfg = cfg.config; in [
|
|
||||||
{ assertion = !(acfg.dbpass != null && acfg.dbpassFile != null);
|
|
||||||
message = "Please specify no more than one of dbpass or dbpassFile";
|
|
||||||
}
|
|
||||||
{ assertion = ((acfg.adminpass != null || acfg.adminpassFile != null)
|
|
||||||
&& !(acfg.adminpass != null && acfg.adminpassFile != null));
|
|
||||||
message = "Please specify exactly one of adminpass or adminpassFile";
|
|
||||||
}
|
|
||||||
{ assertion = versionOlder cfg.package.version "21" -> cfg.config.defaultPhoneRegion == null;
|
|
||||||
message = "The `defaultPhoneRegion'-setting is only supported for Nextcloud >=21!";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
warnings = []
|
|
||||||
++ (optional (cfg.poolConfig != null) ''
|
|
||||||
Using config.services.nextcloud.poolConfig is deprecated and will become unsupported in a future release.
|
|
||||||
Please migrate your configuration to config.services.nextcloud.poolSettings.
|
|
||||||
'')
|
|
||||||
++ (optional (versionOlder cfg.package.version "18") ''
|
|
||||||
A legacy Nextcloud install (from before NixOS 20.03) may be installed.
|
|
||||||
|
|
||||||
You're currently deploying an older version of Nextcloud. This may be needed
|
|
||||||
since Nextcloud doesn't allow major version upgrades that skip multiple
|
|
||||||
versions (i.e. an upgrade from 16 is possible to 17, but not 16 to 18).
|
|
||||||
|
|
||||||
It is assumed that Nextcloud will be upgraded from version 16 to 17.
|
|
||||||
|
|
||||||
* If this is a fresh install, there will be no upgrade to do now.
|
|
||||||
|
|
||||||
* If this server already had Nextcloud installed, first deploy this to your
|
|
||||||
server, and wait until the upgrade to 17 is finished.
|
|
||||||
|
|
||||||
Then, set `services.nextcloud.package` to `pkgs.nextcloud18` to upgrade to
|
|
||||||
Nextcloud version 18. Please note that Nextcloud 19 is already out and it's
|
|
||||||
recommended to upgrade to nextcloud19 after that.
|
|
||||||
'')
|
|
||||||
++ (optional (versionOlder cfg.package.version "19") ''
|
|
||||||
A legacy Nextcloud install (from before NixOS 20.09) may be installed.
|
|
||||||
|
|
||||||
If/After nextcloud18 is installed successfully, you can safely upgrade to
|
|
||||||
nextcloud19. If not, please upgrade to nextcloud18 first since Nextcloud doesn't
|
|
||||||
support upgrades that skip multiple versions (i.e. an upgrade from 17 to 19 isn't
|
|
||||||
possible, but an upgrade from 18 to 19).
|
|
||||||
'')
|
|
||||||
++ (optional (versionOlder cfg.package.version "21") ''
|
|
||||||
The latest Nextcloud release is v21 which can be installed by setting
|
|
||||||
`services.nextcloud.package` to `pkgs.nextcloud21`. Please note that if you're
|
|
||||||
on `pkgs.nextcloud19`, you'll have to install `pkgs.nextcloud20` first.
|
|
||||||
'');
|
|
||||||
|
|
||||||
services.nextcloud-patched.package = with pkgs;
|
|
||||||
mkDefault (
|
|
||||||
if pkgs ? nextcloud
|
|
||||||
then throw ''
|
|
||||||
The `pkgs.nextcloud`-attribute has been removed. If it's supposed to be the default
|
|
||||||
nextcloud defined in an overlay, please set `services.nextcloud.package` to
|
|
||||||
`pkgs.nextcloud`.
|
|
||||||
''
|
|
||||||
else if versionOlder stateVersion "20.03" then nextcloud17
|
|
||||||
else if versionOlder stateVersion "20.09" then nextcloud18
|
|
||||||
else nextcloud19
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
{ systemd.timers.nextcloud-cron = {
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig.OnBootSec = "5m";
|
|
||||||
timerConfig.OnUnitActiveSec = "15m";
|
|
||||||
timerConfig.Unit = "nextcloud-cron.service";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services = {
|
|
||||||
# When upgrading the Nextcloud package, Nextcloud can report errors such as
|
|
||||||
# "The files of the app [all apps in /var/lib/nextcloud/apps] were not replaced correctly"
|
|
||||||
# Restarting phpfpm on Nextcloud package update fixes these issues (but this is a workaround).
|
|
||||||
phpfpm-nextcloud.restartTriggers = [ cfg.package ];
|
|
||||||
|
|
||||||
nextcloud-setup = let
|
|
||||||
c = cfg.config;
|
|
||||||
writePhpArrary = a: "[${concatMapStringsSep "," (val: ''"${toString val}"'') a}]";
|
|
||||||
overrideConfig = pkgs.writeText "nextcloud-config.php" ''
|
|
||||||
<?php
|
|
||||||
${optionalString (c.dbpassFile != null) ''
|
|
||||||
function nix_read_pwd() {
|
|
||||||
$file = "${c.dbpassFile}";
|
|
||||||
if (!file_exists($file)) {
|
|
||||||
throw new \RuntimeException(sprintf(
|
|
||||||
"Cannot start Nextcloud, dbpass file %s set by NixOS doesn't exist!",
|
|
||||||
$file
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return trim(file_get_contents($file));
|
|
||||||
}
|
|
||||||
''}
|
|
||||||
${optionalString (cfg.secretFile != null) ''
|
|
||||||
function nix_read_secrets() {
|
|
||||||
$file = "${cfg.secretFile}";
|
|
||||||
if (!file_exists($file)) {
|
|
||||||
throw new \RuntimeException(sprintf(
|
|
||||||
"Cannot start Nextcloud, secrets file %s set by NixOS doesn't exist!",
|
|
||||||
$file
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return json_decode(file_get_contents($file));
|
|
||||||
}
|
|
||||||
''}
|
|
||||||
$CONFIG = [
|
|
||||||
'apps_paths' => [
|
|
||||||
[ 'path' => '${cfg.home}/apps', 'url' => '/apps', 'writable' => false ],
|
|
||||||
[ 'path' => '${cfg.home}/store-apps', 'url' => '/store-apps', 'writable' => true ],
|
|
||||||
],
|
|
||||||
'datadirectory' => '${cfg.home}/data',
|
|
||||||
'skeletondirectory' => '${cfg.skeletonDirectory}',
|
|
||||||
${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"}
|
|
||||||
'log_type' => 'syslog',
|
|
||||||
'log_level' => '${builtins.toString cfg.logLevel}',
|
|
||||||
${optionalString (c.defaultapp != null) "'defaultapp' => '${c.defaultapp}',"}
|
|
||||||
${optionalString (c.overwriteProtocol != null) "'overwriteprotocol' => '${c.overwriteProtocol}',"}
|
|
||||||
${optionalString (c.dbname != null) "'dbname' => '${c.dbname}',"}
|
|
||||||
${optionalString (c.dbhost != null) "'dbhost' => '${c.dbhost}',"}
|
|
||||||
${optionalString (c.dbport != null) "'dbport' => '${toString c.dbport}',"}
|
|
||||||
${optionalString (c.dbuser != null) "'dbuser' => '${c.dbuser}',"}
|
|
||||||
${optionalString (c.dbtableprefix != null) "'dbtableprefix' => '${toString c.dbtableprefix}',"}
|
|
||||||
${optionalString (c.dbpass != null) "'dbpassword' => '${c.dbpass}',"}
|
|
||||||
${optionalString (c.dbpassFile != null) "'dbpassword' => nix_read_pwd(),"}
|
|
||||||
'dbtype' => '${c.dbtype}',
|
|
||||||
'trusted_domains' => ${writePhpArrary ([ cfg.hostName ] ++ c.extraTrustedDomains)},
|
|
||||||
'trusted_proxies' => ${writePhpArrary (c.trustedProxies)},
|
|
||||||
${optionalString (c.defaultPhoneRegion != null) "'default_phone_region' => '${c.defaultPhoneRegion}',"}
|
|
||||||
];
|
|
||||||
|
|
||||||
$EXTRACONFIG = json_decode('${builtins.toJSON cfg.extraOptions}', true);
|
|
||||||
|
|
||||||
array_push($CONFIG, $EXTRACONFIG);
|
|
||||||
${optionalString (cfg.secretFile != null) "array_push($CONFIG, nix_read_secrets());"}
|
|
||||||
'';
|
|
||||||
occInstallCmd = let
|
|
||||||
dbpass = if c.dbpassFile != null
|
|
||||||
then ''"$(<"${toString c.dbpassFile}")"''
|
|
||||||
else if c.dbpass != null
|
|
||||||
then ''"${toString c.dbpass}"''
|
|
||||||
else ''""'';
|
|
||||||
adminpass = if c.adminpassFile != null
|
|
||||||
then ''"$(<"${toString c.adminpassFile}")"''
|
|
||||||
else ''"${toString c.adminpass}"'';
|
|
||||||
installFlags = concatStringsSep " \\\n "
|
|
||||||
(mapAttrsToList (k: v: "${k} ${toString v}") {
|
|
||||||
"--database" = ''"${c.dbtype}"'';
|
|
||||||
# The following attributes are optional depending on the type of
|
|
||||||
# database. Those that evaluate to null on the left hand side
|
|
||||||
# will be omitted.
|
|
||||||
${if c.dbname != null then "--database-name" else null} = ''"${c.dbname}"'';
|
|
||||||
${if c.dbhost != null then "--database-host" else null} = ''"${c.dbhost}"'';
|
|
||||||
${if c.dbport != null then "--database-port" else null} = ''"${toString c.dbport}"'';
|
|
||||||
${if c.dbuser != null then "--database-user" else null} = ''"${c.dbuser}"'';
|
|
||||||
"--database-pass" = dbpass;
|
|
||||||
${if c.dbtableprefix != null
|
|
||||||
then "--database-table-prefix" else null} = ''"${toString c.dbtableprefix}"'';
|
|
||||||
"--admin-user" = ''"${c.adminuser}"'';
|
|
||||||
"--admin-pass" = adminpass;
|
|
||||||
"--data-dir" = ''"${cfg.home}/data"'';
|
|
||||||
});
|
|
||||||
in ''
|
|
||||||
${occ}/bin/nextcloud-occ maintenance:install \
|
|
||||||
${installFlags}
|
|
||||||
'';
|
|
||||||
occSetTrustedDomainsCmd = concatStringsSep "\n" (imap0
|
|
||||||
(i: v: ''
|
|
||||||
${occ}/bin/nextcloud-occ config:system:set trusted_domains \
|
|
||||||
${toString i} --value="${toString v}"
|
|
||||||
'') ([ cfg.hostName ] ++ cfg.config.extraTrustedDomains));
|
|
||||||
|
|
||||||
in {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
before = [ "phpfpm-nextcloud.service" ];
|
|
||||||
path = [ occ ];
|
|
||||||
script = ''
|
|
||||||
chmod og+x ${cfg.home}
|
|
||||||
|
|
||||||
${optionalString (c.dbpassFile != null) ''
|
|
||||||
if [ ! -r "${c.dbpassFile}" ]; then
|
|
||||||
echo "dbpassFile ${c.dbpassFile} is not readable by nextcloud:nextcloud! Aborting..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ -z "$(<${c.dbpassFile})" ]; then
|
|
||||||
echo "dbpassFile ${c.dbpassFile} is empty!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
''}
|
|
||||||
${optionalString (c.adminpassFile != null) ''
|
|
||||||
if [ ! -r "${c.adminpassFile}" ]; then
|
|
||||||
echo "adminpassFile ${c.adminpassFile} is not readable by nextcloud:nextcloud! Aborting..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ -z "$(<${c.adminpassFile})" ]; then
|
|
||||||
echo "adminpassFile ${c.adminpassFile} is empty!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
''}
|
|
||||||
|
|
||||||
ln -sf ${cfg.package}/apps ${cfg.home}/
|
|
||||||
|
|
||||||
# create nextcloud directories.
|
|
||||||
# if the directories exist already with wrong permissions, we fix that
|
|
||||||
for dir in ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps; do
|
|
||||||
if [ ! -e $dir ]; then
|
|
||||||
install -o nextcloud -g nextcloud -d $dir
|
|
||||||
elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then
|
|
||||||
chgrp -R nextcloud $dir
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php
|
|
||||||
|
|
||||||
# Do not install if already installed
|
|
||||||
if [[ ! -e ${cfg.home}/config/config.php ]]; then
|
|
||||||
${occInstallCmd}
|
|
||||||
fi
|
|
||||||
|
|
||||||
${occ}/bin/nextcloud-occ upgrade
|
|
||||||
|
|
||||||
${occ}/bin/nextcloud-occ config:system:delete trusted_domains
|
|
||||||
${occSetTrustedDomainsCmd}
|
|
||||||
'';
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
serviceConfig.User = "nextcloud";
|
|
||||||
};
|
|
||||||
nextcloud-cron = {
|
|
||||||
environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
serviceConfig.User = "nextcloud";
|
|
||||||
serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php";
|
|
||||||
};
|
|
||||||
nextcloud-update-plugins = mkIf cfg.autoUpdateApps.enable {
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
serviceConfig.ExecStart = "${occ}/bin/nextcloud-occ app:update --all";
|
|
||||||
serviceConfig.User = "nextcloud";
|
|
||||||
startAt = cfg.autoUpdateApps.startAt;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.phpfpm = {
|
|
||||||
pools.nextcloud = {
|
|
||||||
user = "nextcloud";
|
|
||||||
group = "nextcloud";
|
|
||||||
phpOptions = phpOptionsStr;
|
|
||||||
phpPackage = phpPackage;
|
|
||||||
phpEnv = {
|
|
||||||
NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
|
|
||||||
PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin";
|
|
||||||
};
|
|
||||||
settings = mapAttrs (name: mkDefault) {
|
|
||||||
"listen.owner" = config.services.nginx.user;
|
|
||||||
"listen.group" = config.services.nginx.group;
|
|
||||||
} // cfg.poolSettings;
|
|
||||||
extraConfig = cfg.poolConfig;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.nextcloud = {
|
|
||||||
home = "${cfg.home}";
|
|
||||||
group = "nextcloud";
|
|
||||||
createHome = true;
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ];
|
|
||||||
|
|
||||||
environment.systemPackages = [ occ ];
|
|
||||||
|
|
||||||
services.nginx.enable = mkDefault true;
|
|
||||||
|
|
||||||
services.nginx.virtualHosts.${cfg.hostName} = let
|
|
||||||
major = toInt (versions.major cfg.package.version);
|
|
||||||
in {
|
|
||||||
root = cfg.package;
|
|
||||||
locations = {
|
|
||||||
"= /robots.txt" = {
|
|
||||||
priority = 100;
|
|
||||||
extraConfig = ''
|
|
||||||
allow all;
|
|
||||||
log_not_found off;
|
|
||||||
access_log off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"= /" = {
|
|
||||||
priority = 100;
|
|
||||||
extraConfig = ''
|
|
||||||
if ( $http_user_agent ~ ^DavClnt ) {
|
|
||||||
return 302 /remote.php/webdav/$is_args$args;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"/" = {
|
|
||||||
priority = 900;
|
|
||||||
extraConfig = "rewrite ^ /index.php;";
|
|
||||||
};
|
|
||||||
"~ ^/store-apps" = {
|
|
||||||
priority = 201;
|
|
||||||
extraConfig = "root ${cfg.home};";
|
|
||||||
};
|
|
||||||
"^~ /.well-known" = {
|
|
||||||
priority = 210;
|
|
||||||
extraConfig = ''
|
|
||||||
absolute_redirect off;
|
|
||||||
location = /.well-known/carddav {
|
|
||||||
return 301 /remote.php/dav;
|
|
||||||
}
|
|
||||||
location = /.well-known/caldav {
|
|
||||||
return 301 /remote.php/dav;
|
|
||||||
}
|
|
||||||
location ~ ^/\.well-known/(?!acme-challenge|pki-validation) {
|
|
||||||
return 301 /index.php$request_uri;
|
|
||||||
}
|
|
||||||
try_files $uri $uri/ =404;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)".extraConfig = ''
|
|
||||||
return 404;
|
|
||||||
'';
|
|
||||||
"~ ^/(?:\\.(?!well-known)|autotest|occ|issue|indie|db_|console)".extraConfig = ''
|
|
||||||
return 404;
|
|
||||||
'';
|
|
||||||
"~ ^\\/(?:index|remote|public|cron|core\\/ajax\\/update|status|ocs\\/v[12]|updater\\/.+|oc[ms]-provider\\/.+|.+\\/richdocumentscode\\/proxy)\\.php(?:$|\\/)" = {
|
|
||||||
priority = 500;
|
|
||||||
extraConfig = ''
|
|
||||||
include ${config.services.nginx.package}/conf/fastcgi.conf;
|
|
||||||
fastcgi_split_path_info ^(.+?\.php)(\\/.*)$;
|
|
||||||
set $path_info $fastcgi_path_info;
|
|
||||||
try_files $fastcgi_script_name =404;
|
|
||||||
fastcgi_param PATH_INFO $path_info;
|
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
||||||
fastcgi_param HTTPS ${if cfg.https then "on" else "off"};
|
|
||||||
fastcgi_param modHeadersAvailable true;
|
|
||||||
fastcgi_param front_controller_active true;
|
|
||||||
fastcgi_pass unix:${fpm.socket};
|
|
||||||
fastcgi_intercept_errors on;
|
|
||||||
fastcgi_request_buffering off;
|
|
||||||
fastcgi_read_timeout 120s;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"~ \\.(?:css|js|woff2?|svg|gif|map)$".extraConfig = ''
|
|
||||||
try_files $uri /index.php$request_uri;
|
|
||||||
expires 6M;
|
|
||||||
access_log off;
|
|
||||||
'';
|
|
||||||
"~ ^\\/(?:updater|ocs-provider|ocm-provider)(?:$|\\/)".extraConfig = ''
|
|
||||||
try_files $uri/ =404;
|
|
||||||
index index.php;
|
|
||||||
'';
|
|
||||||
"~ \\.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$".extraConfig = ''
|
|
||||||
try_files $uri /index.php$request_uri;
|
|
||||||
access_log off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
extraConfig = ''
|
|
||||||
index index.php index.html /index.php$request_uri;
|
|
||||||
expires 1m;
|
|
||||||
add_header X-Content-Type-Options nosniff;
|
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
|
||||||
add_header X-Robots-Tag none;
|
|
||||||
add_header X-Download-Options noopen;
|
|
||||||
add_header X-Permitted-Cross-Domain-Policies none;
|
|
||||||
add_header X-Frame-Options sameorigin;
|
|
||||||
add_header Referrer-Policy no-referrer;
|
|
||||||
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
|
|
||||||
client_max_body_size ${cfg.maxUploadSize};
|
|
||||||
fastcgi_buffers 64 4K;
|
|
||||||
fastcgi_hide_header X-Powered-By;
|
|
||||||
gzip on;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_comp_level 4;
|
|
||||||
gzip_min_length 256;
|
|
||||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
|
||||||
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
|
||||||
|
|
||||||
${optionalString cfg.webfinger ''
|
|
||||||
rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
|
|
||||||
rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.hacc.nftables.nat;
|
|
||||||
nats = config.networking.nat;
|
|
||||||
in {
|
|
||||||
options.hacc.nftables.nat = {
|
|
||||||
enable = mkEnableOption "Wrap NAT into nftables.";
|
|
||||||
forwardPorts = mkOption {
|
|
||||||
type = with types; listOf (submodule {
|
|
||||||
options = {
|
|
||||||
ports = mkOption {
|
|
||||||
type = types.listOf (types.either types.int (types.strMatching "[[:digit:]]+-[[:digit:]]+"));
|
|
||||||
};
|
|
||||||
destination = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "10.0.0.1";
|
|
||||||
};
|
|
||||||
proto = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "tcp";
|
|
||||||
example = "udp";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
default = [];
|
|
||||||
example = [{ ports = [ 8080 "9100-9200" ]; destination = "192.168.100.2"; proto = "udp"; }];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.nat.enable = mkOverride 99 false;
|
|
||||||
|
|
||||||
boot = {
|
|
||||||
kernelModules = [ "nf_nat_ftp" ];
|
|
||||||
kernel.sysctl = {
|
|
||||||
"net.ipv4.conf.all.forwarding" = mkOverride 90 true;
|
|
||||||
"net.ipv4.conf.default.forwarding" = mkOverride 90 true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.nftables = {
|
|
||||||
extraConfig = ''
|
|
||||||
table ip nat {
|
|
||||||
chain prerouting {
|
|
||||||
type nat hook prerouting priority -100
|
|
||||||
${concatMapStringsSep "\n" (rule: "iif ${nats.externalInterface} ${rule.proto} dport { ${concatStringsSep ", " (map (x: toString x) rule.ports)} } dnat ${rule.destination}") cfg.forwardPorts}
|
|
||||||
}
|
|
||||||
chain postrouting {
|
|
||||||
type nat hook postrouting priority 100
|
|
||||||
${concatMapStringsSep "\n" (iface: "iifname ${replaceStrings ["+"] ["*"] iface} oifname ${nats.externalInterface} masquerade") nats.internalInterfaces}
|
|
||||||
${concatMapStringsSep "\n" (addr: "ip saddr ${addr} oifname ${nats.externalInterface} masquerade") nats.internalIPs}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
{ 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
102
nix/sources.json
|
@ -1,102 +0,0 @@
|
||||||
{
|
|
||||||
"haccmap": {
|
|
||||||
"branch": "master",
|
|
||||||
"repo": "https://gitlab.infra4future.de/hacc/haccspace-rc3-map",
|
|
||||||
"rev": "9490ebf656ef379e51cb518ec0038e15d6aeaac6",
|
|
||||||
"type": "git"
|
|
||||||
},
|
|
||||||
"home-manager": {
|
|
||||||
"branch": "release-21.11",
|
|
||||||
"description": "Manage a user environment using Nix [maintainer=@rycee] ",
|
|
||||||
"homepage": "https://nix-community.github.io/home-manager/",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "home-manager",
|
|
||||||
"rev": "d93d56ab8c1c6aa575854a79b9d2f69d491db7d0",
|
|
||||||
"sha256": "1fi27zabvqlyc2ggg7wr01j813gs46rswg1i897h9hqkbgqsjkny",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://github.com/nix-community/home-manager/archive/d93d56ab8c1c6aa575854a79b9d2f69d491db7d0.tar.gz",
|
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
|
||||||
},
|
|
||||||
"mattermost-server": {
|
|
||||||
"branch": "master",
|
|
||||||
"description": "Open source Slack-alternative in Golang and React - Mattermost",
|
|
||||||
"homepage": "https://mattermost.com",
|
|
||||||
"owner": "mattermost",
|
|
||||||
"repo": "mattermost-server",
|
|
||||||
"rev": "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
194
nix/sources.nix
|
@ -1,194 +0,0 @@
|
||||||
# This file has been generated by Niv.
|
|
||||||
|
|
||||||
let
|
|
||||||
|
|
||||||
#
|
|
||||||
# The fetchers. fetch_<type> fetches specs of type <type>.
|
|
||||||
#
|
|
||||||
|
|
||||||
fetch_file = pkgs: name: spec:
|
|
||||||
let
|
|
||||||
name' = sanitizeName name + "-src";
|
|
||||||
in
|
|
||||||
if spec.builtin or true then
|
|
||||||
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
|
|
||||||
else
|
|
||||||
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
|
|
||||||
|
|
||||||
fetch_tarball = pkgs: name: spec:
|
|
||||||
let
|
|
||||||
name' = sanitizeName name + "-src";
|
|
||||||
in
|
|
||||||
if spec.builtin or true then
|
|
||||||
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
|
|
||||||
else
|
|
||||||
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
|
|
||||||
|
|
||||||
fetch_git = name: spec:
|
|
||||||
let
|
|
||||||
ref =
|
|
||||||
if spec ? ref then spec.ref else
|
|
||||||
if spec ? branch then "refs/heads/${spec.branch}" else
|
|
||||||
if spec ? tag then "refs/tags/${spec.tag}" else
|
|
||||||
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
|
|
||||||
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); }
|
|
|
@ -1,49 +0,0 @@
|
||||||
{ stdenv, requireFile, lib,
|
|
||||||
libcxx, libcxxabi
|
|
||||||
}:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "blackmagic-desktop-video";
|
|
||||||
version = "12.2.2";
|
|
||||||
|
|
||||||
buildInputs = [
|
|
||||||
libcxx libcxxabi
|
|
||||||
];
|
|
||||||
|
|
||||||
src = requireFile {
|
|
||||||
name = "Blackmagic_Desktop_Video_Linux_12.2.2.tar.gz";
|
|
||||||
url = "https://www.blackmagicdesign.com/support/";
|
|
||||||
sha256 = "8bca946bd3f002d2d404a74210c881935351e1a0d03f750559b180fdb439ef35";
|
|
||||||
};
|
|
||||||
|
|
||||||
setSourceRoot = ''
|
|
||||||
tar xf Blackmagic_Desktop_Video_Linux_12.2.2/other/x86_64/desktopvideo-12.2.2a6-x86_64.tar.gz
|
|
||||||
sourceRoot=$NIX_BUILD_TOP/desktopvideo-12.2.2a6-x86_64
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
mkdir -p $out/{bin,share/doc,lib}
|
|
||||||
cp -r $sourceRoot/usr/share/doc/desktopvideo $out/share/doc
|
|
||||||
cp $sourceRoot/usr/lib/*.so $out/lib
|
|
||||||
ln -s ${libcxx}/lib/* ${libcxxabi}/lib/* $out/lib
|
|
||||||
cp $sourceRoot/usr/lib/blackmagic/DesktopVideo/libgcc_s.so.1 $out/lib/
|
|
||||||
cp $sourceRoot/usr/lib/blackmagic/DesktopVideo/DesktopVideoHelper $out/bin/
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
postFixup = ''
|
|
||||||
patchelf --set-interpreter ${stdenv.cc.bintools.dynamicLinker} \
|
|
||||||
--set-rpath "$out/lib:${lib.makeLibraryPath [ libcxx libcxxabi ]}" \
|
|
||||||
$out/bin/DesktopVideoHelper
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
homepage = "https://www.blackmagicdesign.com/support/family/capture-and-playback";
|
|
||||||
maintainers = [ maintainers.hexchen ];
|
|
||||||
license = licenses.unfree;
|
|
||||||
description = "Supporting applications for Blackmagic Decklink. Doesn't include the desktop applications, only the helper required to make the driver work.";
|
|
||||||
platforms = platforms.linux;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
{ stdenv, mkYarnPackage, mkYarnModules, fetchFromGitHub, libsass, python, python3, pkg-config, libusb, fetchurl, nodejs, electron, writeText, makeWrapper, udev, nodePackages, libvips }:
|
|
||||||
|
|
||||||
let
|
|
||||||
version = "2.1.3";
|
|
||||||
source = fetchFromGitHub {
|
|
||||||
owner = "bitfocus";
|
|
||||||
repo = "companion";
|
|
||||||
# rev = "v${version}";
|
|
||||||
rev = "1cc51029a19d7263a09058f73922277ca53a1583";
|
|
||||||
sha256 = "0305wwdic3n20whzhh9zqcd3dwj7hc4fpycs645ncc3sk48azmj0";
|
|
||||||
};
|
|
||||||
nodeHeaders = fetchurl {
|
|
||||||
url = "https://nodejs.org/download/release/v${nodejs.version}/node-v${nodejs.version}-headers.tar.gz";
|
|
||||||
sha256 = "19b0dg8292cjx758wlrvpb3jf520bpyvjal2n7r4fyvk38x9flik";
|
|
||||||
};
|
|
||||||
webui = mkYarnPackage rec {
|
|
||||||
inherit version;
|
|
||||||
pname = "bitfocus-companion-webui";
|
|
||||||
|
|
||||||
src = "${source}/webui";
|
|
||||||
|
|
||||||
configurePhase = "
|
|
||||||
cp -r $node_modules node_modules
|
|
||||||
chmod -R u+w node_modules
|
|
||||||
";
|
|
||||||
buildPhase = "PUBLIC_URL=. yarn build";
|
|
||||||
installPhase = "mv build $out";
|
|
||||||
distPhase = "true";
|
|
||||||
|
|
||||||
yarnNix = ./yarn-webui.nix;
|
|
||||||
|
|
||||||
pkgConfig = {
|
|
||||||
node-sass = {
|
|
||||||
buildInputs = [ libsass python ];
|
|
||||||
postInstall = "node scripts/build.js --tarball=${nodeHeaders}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
yarnModulesNoWorkspace = args: (mkYarnModules args).overrideAttrs(old: {
|
|
||||||
buildPhase = builtins.replaceStrings [" ./package.json"] [" /dev/null; cp deps/*/package.json ."] old.buildPhase;
|
|
||||||
});
|
|
||||||
|
|
||||||
modules = yarnModulesNoWorkspace rec {
|
|
||||||
inherit version;
|
|
||||||
pname = "companion-modules";
|
|
||||||
name = "${pname}-${version}";
|
|
||||||
yarnNix = ./yarn.nix;
|
|
||||||
packageJSON = "${source}/package.json";
|
|
||||||
yarnLock = "${source}/yarn.lock";
|
|
||||||
|
|
||||||
pkgConfig = {
|
|
||||||
node-hid = {
|
|
||||||
buildInputs = [ udev libusb python3 pkg-config ];
|
|
||||||
postInstall = "${nodePackages.node-gyp}/bin/node-gyp rebuild --tarball=${nodeHeaders}";
|
|
||||||
};
|
|
||||||
sharp = {
|
|
||||||
buildInputs = [ libvips pkg-config ];
|
|
||||||
postInstall = ''
|
|
||||||
sed -i "s|<!(node -p \"require(\\\\'./lib/libvips\\\\').minimumLibvipsVersion\")|${libvips.version}|" binding.gyp
|
|
||||||
sed -i "s|<!(node -p \"require(\\\\'./lib/libvips\\\\').pkgConfigPath()\")||" binding.gyp
|
|
||||||
sed -i "s|<!(node -p \"Boolean(require(\\\\'./lib/libvips\\\\').useGlobalLibvips()).toString()\")|true|" binding.gyp
|
|
||||||
sed -i "s|PKG_CONFIG_PATH=\"<(pkg_config_path)\" ||" binding.gyp
|
|
||||||
${nodePackages.node-gyp}/bin/node-gyp rebuild --tarball=${nodeHeaders}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in stdenv.mkDerivation rec {
|
|
||||||
inherit version webui modules;
|
|
||||||
pname = "bitfocus-companion";
|
|
||||||
|
|
||||||
src = source;
|
|
||||||
|
|
||||||
nativeBuildInputs = [ makeWrapper ];
|
|
||||||
|
|
||||||
configurePhase = "";
|
|
||||||
buildPhase = "";
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/share
|
|
||||||
cp --no-preserve=mode -r $src "$out/share/companion"
|
|
||||||
echo "nixos-f00baa-0" > $out/share/companion/BUILD
|
|
||||||
ln -s '${webui}' "$out/share/companion/static"
|
|
||||||
cp -r '${modules}/node_modules' "$out/share/companion/node_modules"
|
|
||||||
|
|
||||||
sed -i "s|process.resourcesPath|\"$out/share/companion\"|" $out/share/companion/lib/server_http.js
|
|
||||||
sed -i "s|require('app-root-path')|\"$out/share/companion\"|" $out/share/companion/{app,lib/{schedule,help,instance}}.js
|
|
||||||
|
|
||||||
makeWrapper '${electron}/bin/electron' "$out/bin/companion" \
|
|
||||||
--add-flags "$out/share/companion"
|
|
||||||
'';
|
|
||||||
}
|
|
|
@ -1,478 +0,0 @@
|
||||||
{
|
|
||||||
"name": "companion",
|
|
||||||
"version": "2.2.0",
|
|
||||||
"description": "Companion",
|
|
||||||
"main": "electron.js",
|
|
||||||
"build": {
|
|
||||||
"productName": "Companion",
|
|
||||||
"appId": "companion.bitfocus.no",
|
|
||||||
"remoteBuild": false,
|
|
||||||
"dmg": {
|
|
||||||
"artifactName": "companion-mac-${arch}.dmg",
|
|
||||||
"sign": true
|
|
||||||
},
|
|
||||||
"mac": {
|
|
||||||
"target": "dmg",
|
|
||||||
"category": "no.bitfocus.companion",
|
|
||||||
"extendInfo": {
|
|
||||||
"LSBackgroundOnly": 1,
|
|
||||||
"LSUIElement": 1
|
|
||||||
},
|
|
||||||
"extraFiles": [
|
|
||||||
{
|
|
||||||
"from": "./node_modules/sharp/vendor/8.10.6/lib",
|
|
||||||
"to": "Frameworks",
|
|
||||||
"filter": [
|
|
||||||
"!glib-2.0/**/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"win": {
|
|
||||||
"target": "nsis",
|
|
||||||
"extraFiles": [
|
|
||||||
{
|
|
||||||
"from": "./node_modules/sharp/build/Release",
|
|
||||||
"to": ".",
|
|
||||||
"filter": [
|
|
||||||
"lib*.dll"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"nsis": {
|
|
||||||
"artifactName": "companion-win64.exe",
|
|
||||||
"createStartMenuShortcut": true,
|
|
||||||
"perMachine": true,
|
|
||||||
"oneClick": false,
|
|
||||||
"allowElevation": true,
|
|
||||||
"allowToChangeInstallationDirectory": true,
|
|
||||||
"installerIcon": "icon.ico",
|
|
||||||
"installerSidebar": "compinst.bmp",
|
|
||||||
"uninstallerSidebar": "compinst.bmp"
|
|
||||||
},
|
|
||||||
"directories": {
|
|
||||||
"buildResources": "assets/",
|
|
||||||
"output": "electron-output/"
|
|
||||||
},
|
|
||||||
"linux": {
|
|
||||||
"target": "dir",
|
|
||||||
"extraFiles": [
|
|
||||||
{
|
|
||||||
"from": "./node_modules/sharp/vendor/8.10.6/lib",
|
|
||||||
"to": ".",
|
|
||||||
"filter": [
|
|
||||||
"libvips*.so.*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"**/*",
|
|
||||||
"assets/icon.png",
|
|
||||||
"assets/bitfocus-logo.png",
|
|
||||||
"assets/trayTemplate.png",
|
|
||||||
"assets/trayTemplate@2x.png",
|
|
||||||
"!webui/**/*",
|
|
||||||
"!font/*",
|
|
||||||
"!tools/*",
|
|
||||||
"!*.md",
|
|
||||||
"!node_modules/sharp/vendor/lib"
|
|
||||||
],
|
|
||||||
"extraResources": [
|
|
||||||
{
|
|
||||||
"from": "webui/build",
|
|
||||||
"to": "static"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"prod": "./tools/build_writefile.sh && electron .",
|
|
||||||
"dev": "./tools/build_writefile.sh && cross-env DEVELOPER=1 electron .",
|
|
||||||
"update": "./tools/update.sh",
|
|
||||||
"pack": "electron-builder --dir",
|
|
||||||
"dist:webui": "yarn --cwd webui build",
|
|
||||||
"dist:prepare": "./tools/build_writefile.sh ; rm -rf electron-output && yarn dist:webui",
|
|
||||||
"dist": "yarn dist:prepare && yarn electron-rebuild && electron-builder",
|
|
||||||
"electron-rebuild": "yarn dist:prepare:sharp && electron-builder install-app-deps",
|
|
||||||
"testprod": "./node_modules/electron/cli.js .",
|
|
||||||
"macdist": "yarn dist:prepare && yarn dist:prepare:mac-x64 && electron-builder --publish=never --x64 --mac",
|
|
||||||
"macarmdist": "yarn dist:prepare && yarn dist:prepare:mac-arm64 && electron-builder --publish=never --arm64 --mac",
|
|
||||||
"windist": "yarn dist:prepare && yarn dist:prepare:win && electron-builder --publish=never --x64 --win",
|
|
||||||
"lindist": "yarn dist:prepare && yarn dist:prepare:linux && electron-builder --publish=never --x64 --linux",
|
|
||||||
"rpidist": "yarn dist:prepare && yarn dist:prepare:rpi && electron-builder --publish=never --armv7l --linux",
|
|
||||||
"dist:prepare:sharp": "cd node_modules/sharp && rimraf vendor && node install/libvips && node install/dll-copy",
|
|
||||||
"dist:prepare:win": "cross-env npm_config_platform=win32 npm_config_arch=x64 yarn dist:prepare:sharp",
|
|
||||||
"dist:prepare:mac-x64": "cross-env npm_config_platform=darwin npm_config_arch=x64 yarn dist:prepare:sharp",
|
|
||||||
"dist:prepare:mac-arm64": "cross-env npm_config_platform=darwin npm_config_arch=arm64 yarn dist:prepare:sharp",
|
|
||||||
"dist:prepare:linux": "cross-env npm_config_platform=linux npm_config_arch=x64 yarn dist:prepare:sharp",
|
|
||||||
"dist:prepare:rpi": "cross-env npm_config_platform=linux npm_config_arch=arm yarn dist:prepare:sharp",
|
|
||||||
"test": "mocha",
|
|
||||||
"postinstall": "./tools/build_writefile.sh",
|
|
||||||
"headless": "nodemon --ignore './webui/' headless.js",
|
|
||||||
"dev-headless": "./tools/build_writefile.sh && cross-env DEVELOPER=1 nodemon --ignore './webui/' headless.js",
|
|
||||||
"dev-webui": "yarn --cwd webui dev",
|
|
||||||
"format": "prettier --write ."
|
|
||||||
},
|
|
||||||
"repository": "https://github.com/bitfocus/companion",
|
|
||||||
"keywords": [
|
|
||||||
"bitfocus",
|
|
||||||
"companion"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"npm": "please-use-yarn",
|
|
||||||
"yarn": "^1.22",
|
|
||||||
"node": "^14.16"
|
|
||||||
},
|
|
||||||
"managed_node_version": "14",
|
|
||||||
"author": "Bitfocus AS",
|
|
||||||
"license": "MIT",
|
|
||||||
"devDependencies": {
|
|
||||||
"asar": "^3.0.3",
|
|
||||||
"aws-sdk": "^2.931.0",
|
|
||||||
"chai": "^4.3.4",
|
|
||||||
"chai-fs": "^2.0.0",
|
|
||||||
"cross-env": "^7.0.3",
|
|
||||||
"electron": "^13.1.2",
|
|
||||||
"electron-builder": "22.11.7",
|
|
||||||
"mocha": "^6.2.3",
|
|
||||||
"nodemon": "^2.0.7",
|
|
||||||
"p-all": "^3.0.0",
|
|
||||||
"prettier": "^2.3.1",
|
|
||||||
"rimraf": "^3.0.2",
|
|
||||||
"s3-upload-stream": "^1.0.7"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@sentry/electron": "^2.5.0",
|
|
||||||
"app-root-path": "^3.0.0",
|
|
||||||
"binopsy": "^0.0.0",
|
|
||||||
"check-ip": "^1.1.1",
|
|
||||||
"companion-module-7thsensedesign-delta": "github:bitfocus/companion-module-7thsensedesign-delta#v1.0.1",
|
|
||||||
"companion-module-agf-characterworks": "github:bitfocus/companion-module-agf-characterworks#v1.0.3",
|
|
||||||
"companion-module-aja-helo": "github:bitfocus/companion-module-aja-helo#v1.0.2",
|
|
||||||
"companion-module-aja-kipro": "github:bitfocus/companion-module-aja-kipro#v2.0.11",
|
|
||||||
"companion-module-aja-kumo": "github:bitfocus/companion-module-aja-kumo#v1.0.5",
|
|
||||||
"companion-module-allenheath-dlive-ilive": "github:bitfocus/companion-module-allenheath-dlive-ilive#v1.3.7",
|
|
||||||
"companion-module-allenheath-qu": "github:bitfocus/companion-module-allenheath-qu#v1.0.7",
|
|
||||||
"companion-module-allenheath-sq": "github:bitfocus/companion-module-allenheath-sq#v1.3.8",
|
|
||||||
"companion-module-analogway-eks500": "github:bitfocus/companion-module-analogway-eks500#v1.0.1",
|
|
||||||
"companion-module-analogway-livecore": "github:bitfocus/companion-module-analogway-livecore#v1.1.1",
|
|
||||||
"companion-module-analogway-livepremier": "github:bitfocus/companion-module-analogway-livepremier#v1.0.2",
|
|
||||||
"companion-module-analogway-midra": "github:bitfocus/companion-module-analogway-midra#v1.0.2",
|
|
||||||
"companion-module-analogway-picturall": "github:bitfocus/companion-module-analogway-picturall#v1.2.1",
|
|
||||||
"companion-module-analogway-pls300": "github:bitfocus/companion-module-analogway-pls300#v1.0.3",
|
|
||||||
"companion-module-analogway-vertige": "github:bitfocus/companion-module-analogway-vertige#v1.0.0",
|
|
||||||
"companion-module-analogway-vio": "github:bitfocus/companion-module-analogway-vio#v1.0.1",
|
|
||||||
"companion-module-anomes-millumin": "github:bitfocus/companion-module-anomes-millumin#v1.0.6",
|
|
||||||
"companion-module-arkaos-mediamaster": "github:bitfocus/companion-module-arkaos-mediamaster#v1.0.1",
|
|
||||||
"companion-module-aten-matrix": "github:bitfocus/companion-module-aten-matrix#v1.0.0",
|
|
||||||
"companion-module-audiostrom-liveprofessor": "github:bitfocus/companion-module-audiostrom-liveprofessor#v1.0.0",
|
|
||||||
"companion-module-audivero-unityintercom-client": "github:bitfocus/companion-module-audivero-unityintercom-client#v1.0.2",
|
|
||||||
"companion-module-avishop-hdbaset-matrix": "github:bitfocus/companion-module-avishop-hdbaset-matrix#v1.0.1",
|
|
||||||
"companion-module-avolites-ai": "github:bitfocus/companion-module-avolites-ai#v1.0.1",
|
|
||||||
"companion-module-avolites-titan": "github:bitfocus/companion-module-avolites-titan#v1.1.0",
|
|
||||||
"companion-module-avproconnect-acmx1616-auhd": "github:bitfocus/companion-module-avproconnect-acmx1616-auhd#v1.0.0",
|
|
||||||
"companion-module-avstumpfl-pixera": "github:bitfocus/companion-module-avstumpfl-pixera#v1.0.2",
|
|
||||||
"companion-module-axis-ptz": "github:bitfocus/companion-module-axis-ptz#v1.0.1",
|
|
||||||
"companion-module-barco-dcs": "github:bitfocus/companion-module-barco-dcs#v1.0.4",
|
|
||||||
"companion-module-barco-dp": "github:bitfocus/companion-module-barco-dp#v1.1.2",
|
|
||||||
"companion-module-barco-encore": "github:bitfocus/companion-module-barco-encore#v1.0.1",
|
|
||||||
"companion-module-barco-eventmaster": "github:bitfocus/companion-module-barco-eventmaster#v1.3.6",
|
|
||||||
"companion-module-barco-eventmaster-xml": "github:bitfocus/companion-module-barco-eventmaster-xml#v1.2.4",
|
|
||||||
"companion-module-barco-hdx": "github:bitfocus/companion-module-barco-hdx#v1.1.5",
|
|
||||||
"companion-module-barco-imagepro": "github:bitfocus/companion-module-barco-imagepro#v1.0.1",
|
|
||||||
"companion-module-barco-matrixpro": "github:bitfocus/companion-module-barco-matrixpro#v1.1.0",
|
|
||||||
"companion-module-barco-pds": "github:bitfocus/companion-module-barco-pds#v1.1.5",
|
|
||||||
"companion-module-barco-pulse": "github:bitfocus/companion-module-barco-pulse#v1.1.2",
|
|
||||||
"companion-module-bbc-raven": "github:bitfocus/companion-module-bbc-raven#v1.0.1",
|
|
||||||
"companion-module-behringer-wing": "github:bitfocus/companion-module-behringer-wing#v1.0.5",
|
|
||||||
"companion-module-behringer-x32": "github:bitfocus/companion-module-behringer-x32#v2.7.0",
|
|
||||||
"companion-module-behringer-xair": "github:bitfocus/companion-module-behringer-xair#v1.6.7",
|
|
||||||
"companion-module-biamp-audia": "github:bitfocus/companion-module-biamp-audia#v1.0.1",
|
|
||||||
"companion-module-birddog-studio": "github:bitfocus/companion-module-birddog-studio#v1.0.0",
|
|
||||||
"companion-module-birddog-visca": "github:bitfocus/companion-module-birddog-visca#v1.0.4",
|
|
||||||
"companion-module-bitfocus-companion": "github:bitfocus/companion-module-bitfocus-companion#v1.5.3",
|
|
||||||
"companion-module-bitfocus-snapshot": "github:bitfocus/companion-module-bitfocus-snapshot#v0.0.4",
|
|
||||||
"companion-module-blackbox-boxilla": "github:bitfocus/companion-module-blackbox-boxilla#v1.0.2",
|
|
||||||
"companion-module-blackdiamondvideo-phantom800": "github:bitfocus/companion-module-blackdiamondvideo-phantom800#v1.0.0",
|
|
||||||
"companion-module-bmd-atem": "github:bitfocus/companion-module-bmd-atem#v2.13.0",
|
|
||||||
"companion-module-bmd-audiomonitor": "github:bitfocus/companion-module-bmd-audiomonitor#v1.0.0",
|
|
||||||
"companion-module-bmd-hyperdeck": "github:bitfocus/companion-module-bmd-hyperdeck#v1.2.2",
|
|
||||||
"companion-module-bmd-multiview16": "github:bitfocus/companion-module-bmd-multiview16#v1.0.1",
|
|
||||||
"companion-module-bmd-multiview4": "github:bitfocus/companion-module-bmd-multiview4#v1.3.2",
|
|
||||||
"companion-module-bmd-smartview": "github:bitfocus/companion-module-bmd-smartview#v1.1.3",
|
|
||||||
"companion-module-bmd-teranex": "github:bitfocus/companion-module-bmd-teranex#v1.0.4",
|
|
||||||
"companion-module-bmd-videohub": "github:bitfocus/companion-module-bmd-videohub#v1.3.0",
|
|
||||||
"companion-module-bmd-webpresenterhd": "github:bitfocus/companion-module-bmd-webpresenterhd#v1.0.1",
|
|
||||||
"companion-module-boinx-mimolive": "github:bitfocus/companion-module-boinx-mimolive#v1.0.1",
|
|
||||||
"companion-module-borealsystems-director": "github:bitfocus/companion-module-borealsystems-director#v1.0.0",
|
|
||||||
"companion-module-brightsign-player": "github:bitfocus/companion-module-brightsign-player#v1.1.1",
|
|
||||||
"companion-module-brompton-tessera": "github:bitfocus/companion-module-brompton-tessera#v1.0.0",
|
|
||||||
"companion-module-canon-xf": "github:bitfocus/companion-module-canon-xf#v1.0.0",
|
|
||||||
"companion-module-casparcg-server": "github:bitfocus/companion-module-casparcg-server#v1.0.2",
|
|
||||||
"companion-module-chamsys-magicq-osc": "github:bitfocus/companion-module-chamsys-magicq-osc#v1.0.1",
|
|
||||||
"companion-module-chamsys-magicq-udp": "github:bitfocus/companion-module-chamsys-magicq-udp#v1.0.2",
|
|
||||||
"companion-module-christie-pandorasbox": "github:bitfocus/companion-module-christie-pandorasbox#v2.0.2",
|
|
||||||
"companion-module-christie-projector": "github:bitfocus/companion-module-christie-projector#v2.0.3",
|
|
||||||
"companion-module-christie-spyder": "github:bitfocus/companion-module-christie-spyder#v1.0.0",
|
|
||||||
"companion-module-christie-wd": "github:bitfocus/companion-module-christie-wd#v1.0.6",
|
|
||||||
"companion-module-cisco-cms": "github:bitfocus/companion-module-cisco-cms#v1.0.1",
|
|
||||||
"companion-module-cisco-webex-websocket": "github:bitfocus/companion-module-cisco-webex-websocket#v1.1.0",
|
|
||||||
"companion-module-cockos-reaper": "github:bitfocus/companion-module-cockos-reaper#v1.1.0",
|
|
||||||
"companion-module-connect-webcaster": "github:bitfocus/companion-module-connect-webcaster#v1.0.0",
|
|
||||||
"companion-module-crystal-scte": "github:bitfocus/companion-module-crystal-scte#v1.0.0",
|
|
||||||
"companion-module-dahuasecurity-ptz": "github:bitfocus/companion-module-dahuasecurity-ptz#v1.0.1",
|
|
||||||
"companion-module-dalite-scb": "github:bitfocus/companion-module-dalite-scb#v1.0.0",
|
|
||||||
"companion-module-dashare-multiplay": "github:bitfocus/companion-module-dashare-multiplay#v1.0.1",
|
|
||||||
"companion-module-datapath-fx4": "github:bitfocus/companion-module-datapath-fx4#v1.0.0",
|
|
||||||
"companion-module-dataton-watchout": "github:bitfocus/companion-module-dataton-watchout#v1.2.0",
|
|
||||||
"companion-module-datavideo-dvip": "github:bitfocus/companion-module-datavideo-dvip#v1.0.0",
|
|
||||||
"companion-module-datavideo-visca": "github:bitfocus/companion-module-datavideo-visca#v1.0.3",
|
|
||||||
"companion-module-dcc-ex-commandstation": "github:bitfocus/companion-module-dcc-ex-commandstation#v1.0.0",
|
|
||||||
"companion-module-denon-dn-500bd-mkii": "github:bitfocus/companion-module-denon-dn-500bd-mkii#v1.0.2",
|
|
||||||
"companion-module-denon-receiver": "github:bitfocus/companion-module-denon-receiver#v1.0.1",
|
|
||||||
"companion-module-denon-recorder": "github:bitfocus/companion-module-denon-recorder#v1.0.1",
|
|
||||||
"companion-module-depili-clock-8001": "github:bitfocus/companion-module-depili-clock-8001#v5.1.1",
|
|
||||||
"companion-module-dexon-dimax": "github:bitfocus/companion-module-dexon-dimax#v1.0.3",
|
|
||||||
"companion-module-dexon-divip": "github:bitfocus/companion-module-dexon-divip#v1.0.2",
|
|
||||||
"companion-module-dexon-matrix": "github:bitfocus/companion-module-dexon-matrix#v1.0.1",
|
|
||||||
"companion-module-digico-osc": "github:bitfocus/companion-module-digico-osc#v1.0.2",
|
|
||||||
"companion-module-digitalprojection-highlight": "github:bitfocus/companion-module-digitalprojection-highlight#v1.0.2",
|
|
||||||
"companion-module-disguise": "github:bitfocus/companion-module-disguise#v1.1.0",
|
|
||||||
"companion-module-disguise-mtc": "github:bitfocus/companion-module-disguise-mtc#v1.0.2",
|
|
||||||
"companion-module-dolby-cinemaprocessor": "github:bitfocus/companion-module-dolby-cinemaprocessor#v1.1.0",
|
|
||||||
"companion-module-draco-tera": "github:bitfocus/companion-module-draco-tera#v1.0.4",
|
|
||||||
"companion-module-dsan-limitimer": "github:bitfocus/companion-module-dsan-limitimer#v1.1.1",
|
|
||||||
"companion-module-dsan-perfectcue": "github:bitfocus/companion-module-dsan-perfectcue#v1.0.0",
|
|
||||||
"companion-module-dtvideolabs-playbackproplus": "github:bitfocus/companion-module-dtvideolabs-playbackproplus#v1.0.2",
|
|
||||||
"companion-module-elgato-keylight": "github:bitfocus/companion-module-elgato-keylight#v1.2.2",
|
|
||||||
"companion-module-epiphan-pearl": "github:bitfocus/companion-module-epiphan-pearl#v1.0.7",
|
|
||||||
"companion-module-etc-eos": "github:bitfocus/companion-module-etc-eos#v1.2.1",
|
|
||||||
"companion-module-extron-dxp": "github:bitfocus/companion-module-extron-dxp#v1.0.8",
|
|
||||||
"companion-module-extron-in1604": "github:bitfocus/companion-module-extron-in1604#v1.0.3",
|
|
||||||
"companion-module-extron-ipl-t-pcs4": "github:bitfocus/companion-module-extron-ipl-t-pcs4#v1.0.2",
|
|
||||||
"companion-module-extron-smp111": "github:bitfocus/companion-module-extron-smp111#v1.0.4",
|
|
||||||
"companion-module-extron-smp351": "github:bitfocus/companion-module-extron-smp351#v1.2.0",
|
|
||||||
"companion-module-extron-smx": "github:bitfocus/companion-module-extron-smx#v1.0.4",
|
|
||||||
"companion-module-faithchapel-videoplayoutserver": "github:bitfocus/companion-module-faithchapel-videoplayoutserver#v1.0.1",
|
|
||||||
"companion-module-figure53-go-button": "github:bitfocus/companion-module-figure53-go-button#v1.2.4",
|
|
||||||
"companion-module-figure53-qlab": "github:bitfocus/companion-module-figure53-qlab#v1.2.5",
|
|
||||||
"companion-module-figure53-qlab-advance": "github:bitfocus/companion-module-figure53-qlab-advance#v1.3.8",
|
|
||||||
"companion-module-figure53-qview": "github:bitfocus/companion-module-figure53-qview#v1.0.0",
|
|
||||||
"companion-module-folivora-btt": "github:bitfocus/companion-module-folivora-btt#v1.0.2",
|
|
||||||
"companion-module-fora-hvs": "github:bitfocus/companion-module-fora-hvs#v1.2.4",
|
|
||||||
"companion-module-foscam-ptz": "github:bitfocus/companion-module-foscam-ptz#v1.0.1",
|
|
||||||
"companion-module-gallery-virtualvtrpro": "github:bitfocus/companion-module-gallery-virtualvtrpro#v1.0.1",
|
|
||||||
"companion-module-gammacontrol-gmaestro": "github:bitfocus/companion-module-gammacontrol-gmaestro#v1.0.2",
|
|
||||||
"companion-module-gefen-dvimatrix": "github:bitfocus/companion-module-gefen-dvimatrix#v1.0.1",
|
|
||||||
"companion-module-generic-artnet": "github:bitfocus/companion-module-generic-artnet#v1.0.2",
|
|
||||||
"companion-module-generic-emberplus": "github:bitfocus/companion-module-generic-emberplus#v1.1.1",
|
|
||||||
"companion-module-generic-http": "github:bitfocus/companion-module-generic-http#v1.0.8",
|
|
||||||
"companion-module-generic-mqtt": "github:bitfocus/companion-module-generic-mqtt#v1.2.0",
|
|
||||||
"companion-module-generic-osc": "github:bitfocus/companion-module-generic-osc#v1.0.4",
|
|
||||||
"companion-module-generic-pjlink": "github:bitfocus/companion-module-generic-pjlink#v1.0.5",
|
|
||||||
"companion-module-generic-sacn": "github:bitfocus/companion-module-generic-sacn#v1.0.0",
|
|
||||||
"companion-module-generic-swp08": "github:bitfocus/companion-module-generic-swp08#v1.0.3",
|
|
||||||
"companion-module-generic-tcp-serial": "github:bitfocus/companion-module-generic-tcp-serial#v1.0.2",
|
|
||||||
"companion-module-generic-tcp-udp": "github:bitfocus/companion-module-generic-tcp-udp#v1.0.6",
|
|
||||||
"companion-module-generic-wakeonlan": "github:bitfocus/companion-module-generic-wakeonlan#v1.0.4",
|
|
||||||
"companion-module-generic-websocket": "github:bitfocus/companion-module-generic-websocket#v1.0.0",
|
|
||||||
"companion-module-globalcache-itac-cc": "github:bitfocus/companion-module-globalcache-itac-cc#v1.0.1",
|
|
||||||
"companion-module-globalcache-itac-ir": "github:bitfocus/companion-module-globalcache-itac-ir#v1.0.5",
|
|
||||||
"companion-module-globalcache-itac-sl": "github:bitfocus/companion-module-globalcache-itac-sl#v1.0.3",
|
|
||||||
"companion-module-grassvalley-amp": "github:bitfocus/companion-module-grassvalley-amp#v1.1.3",
|
|
||||||
"companion-module-greenhippo-hippotizer": "github:bitfocus/companion-module-greenhippo-hippotizer#v1.0.2",
|
|
||||||
"companion-module-h2r-graphics": "github:bitfocus/companion-module-h2r-graphics#v1.1.2",
|
|
||||||
"companion-module-haivision-connectdvr": "github:bitfocus/companion-module-haivision-connectdvr#v1.0.9",
|
|
||||||
"companion-module-haivision-kbencoder": "github:bitfocus/companion-module-haivision-kbencoder#v1.0.0",
|
|
||||||
"companion-module-highend-hog4": "github:bitfocus/companion-module-highend-hog4#v1.1.0",
|
|
||||||
"companion-module-hologfx-holographics": "github:bitfocus/companion-module-hologfx-holographics#v1.0.0",
|
|
||||||
"companion-module-homeassistant-server": "github:bitfocus/companion-module-homeassistant-server#v0.6.1",
|
|
||||||
"companion-module-ifelseware-avkey": "github:bitfocus/companion-module-ifelseware-avkey#v1.0.0",
|
|
||||||
"companion-module-ifelseware-avplayback": "github:bitfocus/companion-module-ifelseware-avplayback#v1.0.2",
|
|
||||||
"companion-module-imimot-mitti": "github:bitfocus/companion-module-imimot-mitti#v1.0.8",
|
|
||||||
"companion-module-interactivetechnologies-cueserver": "github:bitfocus/companion-module-interactivetechnologies-cueserver#v1.0.1",
|
|
||||||
"companion-module-irisdown-countdowntimer": "github:bitfocus/companion-module-irisdown-countdowntimer#v1.1.3",
|
|
||||||
"companion-module-irisdown-remoteshowcontrol": "github:bitfocus/companion-module-irisdown-remoteshowcontrol#v1.0.2",
|
|
||||||
"companion-module-jamesholt-x32tc": "github:bitfocus/companion-module-jamesholt-x32tc#v1.0.6",
|
|
||||||
"companion-module-joy-playdeck": "github:bitfocus/companion-module-joy-playdeck#v1.0.1",
|
|
||||||
"companion-module-justmacros-lua": "github:bitfocus/companion-module-justmacros-lua#v1.0.1",
|
|
||||||
"companion-module-jvc-ptz": "github:bitfocus/companion-module-jvc-ptz#v1.0.9",
|
|
||||||
"companion-module-kiloview-ndi": "github:bitfocus/companion-module-kiloview-ndi#v1.0.0",
|
|
||||||
"companion-module-kramer-matrix": "github:bitfocus/companion-module-kramer-matrix#v1.2.1",
|
|
||||||
"companion-module-kramer-vp727": "github:bitfocus/companion-module-kramer-vp727#v1.0.1",
|
|
||||||
"companion-module-kramer-vp734": "github:bitfocus/companion-module-kramer-vp734#v1.0.0",
|
|
||||||
"companion-module-kramer-vp773a": "github:bitfocus/companion-module-kramer-vp773a#v1.0.0",
|
|
||||||
"companion-module-kramer-vs41h": "github:bitfocus/companion-module-kramer-vs41h#v1.0.0",
|
|
||||||
"companion-module-leafcoders-titler": "github:bitfocus/companion-module-leafcoders-titler#v1.0.0",
|
|
||||||
"companion-module-lectrosonics-aspen": "github:bitfocus/companion-module-lectrosonics-aspen#v1.0.0",
|
|
||||||
"companion-module-lightware-lw2": "github:bitfocus/companion-module-lightware-lw2#v1.0.2",
|
|
||||||
"companion-module-lightware-lw3": "github:bitfocus/companion-module-lightware-lw3#v1.0.1",
|
|
||||||
"companion-module-liminalet-zoomosc": "github:bitfocus/companion-module-liminalet-zoomosc#v1.0.8",
|
|
||||||
"companion-module-linkbox-remote": "github:bitfocus/companion-module-linkbox-remote#v1.2.1",
|
|
||||||
"companion-module-livingasone-decoders": "github:bitfocus/companion-module-livingasone-decoders#v1.1.2",
|
|
||||||
"companion-module-ltn-schedule": "github:bitfocus/companion-module-ltn-schedule#v1.0.0",
|
|
||||||
"companion-module-lumens-mediaprocessor": "github:bitfocus/companion-module-lumens-mediaprocessor#v1.0.0",
|
|
||||||
"companion-module-lumens-visca": "github:bitfocus/companion-module-lumens-visca#v1.0.2",
|
|
||||||
"companion-module-lyntec-rpc-breaker": "github:bitfocus/companion-module-lyntec-rpc-breaker#v1.0.3",
|
|
||||||
"companion-module-magewell-proconvert-decoder": "github:bitfocus/companion-module-magewell-proconvert-decoder#v1.0.0",
|
|
||||||
"companion-module-magewell-ultrastream": "github:bitfocus/companion-module-magewell-ultrastream#v0.0.3",
|
|
||||||
"companion-module-magicsoft-recorder": "github:bitfocus/companion-module-magicsoft-recorder#v1.0.0",
|
|
||||||
"companion-module-malighting-grandma2": "github:bitfocus/companion-module-malighting-grandma2#v1.0.10",
|
|
||||||
"companion-module-malighting-msc": "github:bitfocus/companion-module-malighting-msc#v0.2.1",
|
|
||||||
"companion-module-matrox-monarch": "github:bitfocus/companion-module-matrox-monarch#v1.0.0",
|
|
||||||
"companion-module-media-player-classic": "github:bitfocus/companion-module-media-player-classic#v1.0.0",
|
|
||||||
"companion-module-metus-ingest": "github:bitfocus/companion-module-metus-ingest#v1.2.1",
|
|
||||||
"companion-module-middleatlantic-racklink": "github:bitfocus/companion-module-middleatlantic-racklink#v1.0.0",
|
|
||||||
"companion-module-middlethings-middlecontrol": "github:bitfocus/companion-module-middlethings-middlecontrol#v1.0.1",
|
|
||||||
"companion-module-modelighting-edin": "github:bitfocus/companion-module-modelighting-edin#v1.0.0",
|
|
||||||
"companion-module-modulo": "github:bitfocus/companion-module-modulo#v1.0.1",
|
|
||||||
"companion-module-motu-avb": "github:bitfocus/companion-module-motu-avb#v1.0.2",
|
|
||||||
"companion-module-msc-router": "github:bitfocus/companion-module-msc-router#v1.0.2",
|
|
||||||
"companion-module-multicamsystems-multicamsuite": "github:bitfocus/companion-module-multicamsystems-multicamsuite#v1.0.1",
|
|
||||||
"companion-module-muxlab-kvm": "github:bitfocus/companion-module-muxlab-kvm#v1.0.0",
|
|
||||||
"companion-module-neodarque-stagetimer2": "github:bitfocus/companion-module-neodarque-stagetimer2#v1.2.6",
|
|
||||||
"companion-module-netio-powerbox": "github:bitfocus/companion-module-netio-powerbox#v1.0.0",
|
|
||||||
"companion-module-nevion-mrp": "github:bitfocus/companion-module-nevion-mrp#v2.0.2",
|
|
||||||
"companion-module-newbluefx-titler": "github:bitfocus/companion-module-newbluefx-titler#v1.0.1",
|
|
||||||
"companion-module-newtek-ndistudiomonitor": "github:bitfocus/companion-module-newtek-ndistudiomonitor#v1.0.1",
|
|
||||||
"companion-module-newtek-tricaster": "github:bitfocus/companion-module-newtek-tricaster#v1.1.4",
|
|
||||||
"companion-module-nexo-nxamp": "github:bitfocus/companion-module-nexo-nxamp#v1.0.0",
|
|
||||||
"companion-module-nobe-omniscope": "github:bitfocus/companion-module-nobe-omniscope#v1.0.0",
|
|
||||||
"companion-module-noismada-octopuslistener": "github:bitfocus/companion-module-noismada-octopuslistener#v1.0.2",
|
|
||||||
"companion-module-noismada-octopusshowcontrol": "github:bitfocus/companion-module-noismada-octopusshowcontrol#v1.2.0",
|
|
||||||
"companion-module-novastar-controller": "github:bitfocus/companion-module-novastar-controller#v1.0.6",
|
|
||||||
"companion-module-obs-studio": "github:bitfocus/companion-module-obs-studio#v1.0.24",
|
|
||||||
"companion-module-obsidiancontrol-onyx": "github:bitfocus/companion-module-obsidiancontrol-onyx#v1.0.3",
|
|
||||||
"companion-module-octava-pro-dsx": "github:bitfocus/companion-module-octava-pro-dsx#v0.0.1",
|
|
||||||
"companion-module-openlp-http": "github:bitfocus/companion-module-openlp-http#v0.1.1",
|
|
||||||
"companion-module-opensong-api": "github:bitfocus/companion-module-opensong-api#v1.0.1",
|
|
||||||
"companion-module-openweather-rest": "github:bitfocus/companion-module-openweather-rest#v1.0.2",
|
|
||||||
"companion-module-opticis-omm-1000": "github:bitfocus/companion-module-opticis-omm-1000#v1.0.2",
|
|
||||||
"companion-module-optoma-z28s": "github:bitfocus/companion-module-optoma-z28s#v1.0.2",
|
|
||||||
"companion-module-orfast-ndi": "github:bitfocus/companion-module-orfast-ndi#v1.0.0",
|
|
||||||
"companion-module-panasonic-avhs": "github:bitfocus/companion-module-panasonic-avhs#v1.0.4",
|
|
||||||
"companion-module-panasonic-camera-controller": "github:bitfocus/companion-module-panasonic-camera-controller#v1.0.6",
|
|
||||||
"companion-module-panasonic-projector": "github:bitfocus/companion-module-panasonic-projector#v1.0.1",
|
|
||||||
"companion-module-panasonic-ptz": "github:bitfocus/companion-module-panasonic-ptz#v1.0.19",
|
|
||||||
"companion-module-panasonic-tv-th": "github:bitfocus/companion-module-panasonic-tv-th#v0.0.1",
|
|
||||||
"companion-module-pangolin-beyond": "github:bitfocus/companion-module-pangolin-beyond#v1.0.2",
|
|
||||||
"companion-module-phillips-hue": "github:bitfocus/companion-module-phillips-hue#v0.0.4",
|
|
||||||
"companion-module-pixap-pixtimerpro": "github:bitfocus/companion-module-pixap-pixtimerpro#v1.0.6",
|
|
||||||
"companion-module-planningcenter-serviceslive": "github:bitfocus/companion-module-planningcenter-serviceslive#v1.0.5",
|
|
||||||
"companion-module-presentationtools-aps": "github:bitfocus/companion-module-presentationtools-aps#v1.1.0",
|
|
||||||
"companion-module-presentationtools-cuetimer": "github:bitfocus/companion-module-presentationtools-cuetimer#v1.0.0",
|
|
||||||
"companion-module-protopie-bridge": "github:bitfocus/companion-module-protopie-bridge#v1.0.2",
|
|
||||||
"companion-module-prsi-ipower": "github:bitfocus/companion-module-prsi-ipower#v1.0.2",
|
|
||||||
"companion-module-ptzoptics-visca": "github:bitfocus/companion-module-ptzoptics-visca#v1.1.6",
|
|
||||||
"companion-module-qsys-remote-control": "github:bitfocus/companion-module-qsys-remote-control#v1.0.3",
|
|
||||||
"companion-module-radiodj-rest": "github:bitfocus/companion-module-radiodj-rest#v1.0.0",
|
|
||||||
"companion-module-rationalacoustics-smaart3": "github:bitfocus/companion-module-rationalacoustics-smaart3#v1.0.3",
|
|
||||||
"companion-module-renewedvision-propresenter": "github:bitfocus/companion-module-renewedvision-propresenter#v2.4.0",
|
|
||||||
"companion-module-renewedvision-pvp": "github:bitfocus/companion-module-renewedvision-pvp#v1.0.7",
|
|
||||||
"companion-module-resolume-arena": "github:bitfocus/companion-module-resolume-arena#v1.0.5",
|
|
||||||
"companion-module-rocosoft-ptzjoy": "github:bitfocus/companion-module-rocosoft-ptzjoy#v1.0.1",
|
|
||||||
"companion-module-roku-tv": "github:bitfocus/companion-module-roku-tv#v1.0.1",
|
|
||||||
"companion-module-roland-m5000": "github:bitfocus/companion-module-roland-m5000#v1.0.2",
|
|
||||||
"companion-module-roland-v1200hd": "github:bitfocus/companion-module-roland-v1200hd#v1.0.0",
|
|
||||||
"companion-module-roland-v600uhd": "github:bitfocus/companion-module-roland-v600uhd#v1.0.1",
|
|
||||||
"companion-module-roland-v60hd": "github:bitfocus/companion-module-roland-v60hd#v1.0.10",
|
|
||||||
"companion-module-roland-vp42h": "github:bitfocus/companion-module-roland-vp42h#v1.0.0",
|
|
||||||
"companion-module-roland-vr50hd-mk2": "github:bitfocus/companion-module-roland-vr50hd-mk2#v1.0.0",
|
|
||||||
"companion-module-roland-xs42h": "github:bitfocus/companion-module-roland-xs42h#v1.0.0",
|
|
||||||
"companion-module-roland-xs62s": "github:bitfocus/companion-module-roland-xs62s#v1.0.1",
|
|
||||||
"companion-module-roland-xs84h": "github:bitfocus/companion-module-roland-xs84h#v1.0.0",
|
|
||||||
"companion-module-rossvideo-caprica": "github:bitfocus/companion-module-rossvideo-caprica#v1.0.0",
|
|
||||||
"companion-module-rossvideo-nkrouter": "github:bitfocus/companion-module-rossvideo-nkrouter#v1.0.2",
|
|
||||||
"companion-module-rossvideo-rosstalk": "github:bitfocus/companion-module-rossvideo-rosstalk#v1.2.8",
|
|
||||||
"companion-module-rossvideo-xpression": "github:bitfocus/companion-module-rossvideo-xpression#v1.0.2",
|
|
||||||
"companion-module-sain-smart-relay": "github:bitfocus/companion-module-sain-smart-relay#v1.0.0",
|
|
||||||
"companion-module-seervision-suite": "github:bitfocus/companion-module-seervision-suite#v1.1.0",
|
|
||||||
"companion-module-sharp-tv": "github:bitfocus/companion-module-sharp-tv#v1.0.0",
|
|
||||||
"companion-module-showcuesystems-scs": "github:bitfocus/companion-module-showcuesystems-scs#v1.0.1",
|
|
||||||
"companion-module-shure-dis-ccu": "github:bitfocus/companion-module-shure-dis-ccu#v1.0.1",
|
|
||||||
"companion-module-shure-psm1000": "github:bitfocus/companion-module-shure-psm1000#v1.0.0",
|
|
||||||
"companion-module-shure-scm820": "github:bitfocus/companion-module-shure-scm820#v1.0.0",
|
|
||||||
"companion-module-shure-wireless": "github:bitfocus/companion-module-shure-wireless#v1.2.0",
|
|
||||||
"companion-module-sienna-ndimonitor": "github:bitfocus/companion-module-sienna-ndimonitor#v1.0.0",
|
|
||||||
"companion-module-singularlive-studio": "github:bitfocus/companion-module-singularlive-studio#v1.0.7",
|
|
||||||
"companion-module-slack-webhooks": "github:bitfocus/companion-module-slack-webhooks#v1.0.1",
|
|
||||||
"companion-module-softron-movierecorder": "github:bitfocus/companion-module-softron-movierecorder#v1.0.1",
|
|
||||||
"companion-module-softron-ontheairvideo": "github:bitfocus/companion-module-softron-ontheairvideo#v1.0.0",
|
|
||||||
"companion-module-sononum-horae": "github:bitfocus/companion-module-sononum-horae#v1.0.1",
|
|
||||||
"companion-module-sonoran-coyote": "github:bitfocus/companion-module-sonoran-coyote#v1.0.0",
|
|
||||||
"companion-module-sonos-speakers": "github:bitfocus/companion-module-sonos-speakers#v0.2.0",
|
|
||||||
"companion-module-sony-bravia": "github:bitfocus/companion-module-sony-bravia#v1.0.0",
|
|
||||||
"companion-module-sony-visca": "github:bitfocus/companion-module-sony-visca#v1.2.8",
|
|
||||||
"companion-module-soundcraft-ui": "github:bitfocus/companion-module-soundcraft-ui#v2.0.3",
|
|
||||||
"companion-module-sounddevices-pixnet": "github:bitfocus/companion-module-sounddevices-pixnet#v1.0.0",
|
|
||||||
"companion-module-spotify-remote": "github:bitfocus/companion-module-spotify-remote#v1.0.7",
|
|
||||||
"companion-module-spx-gc": "github:bitfocus/companion-module-spx-gc#v1.0.2",
|
|
||||||
"companion-module-studiocoast-vmix": "github:bitfocus/companion-module-studiocoast-vmix#v1.2.22",
|
|
||||||
"companion-module-symetrix-dsp": "github:bitfocus/companion-module-symetrix-dsp#v1.3.0",
|
|
||||||
"companion-module-tallyma-wirelesstally": "github:bitfocus/companion-module-tallyma-wirelesstally#v1.0.1",
|
|
||||||
"companion-module-tascam-bdmp1": "github:bitfocus/companion-module-tascam-bdmp1#v0.1.5",
|
|
||||||
"companion-module-tascam-cd": "github:bitfocus/companion-module-tascam-cd#v1.0.2",
|
|
||||||
"companion-module-techministry-midirelay": "github:bitfocus/companion-module-techministry-midirelay#v2.0.4",
|
|
||||||
"companion-module-techministry-protally": "github:bitfocus/companion-module-techministry-protally#v1.0.0",
|
|
||||||
"companion-module-techministry-tallyarbiter": "github:bitfocus/companion-module-techministry-tallyarbiter#v1.0.2",
|
|
||||||
"companion-module-teracom-tcw181b": "github:bitfocus/companion-module-teracom-tcw181b#v1.0.2",
|
|
||||||
"companion-module-teradek-vidiu": "github:bitfocus/companion-module-teradek-vidiu#v1.0.2",
|
|
||||||
"companion-module-tesla-smart": "github:bitfocus/companion-module-tesla-smart#v1.0.3",
|
|
||||||
"companion-module-thelightingcontroller": "github:bitfocus/companion-module-thelightingcontroller#v1.1.2",
|
|
||||||
"companion-module-thingm-blink1": "github:bitfocus/companion-module-thingm-blink1#v1.2.3",
|
|
||||||
"companion-module-tplink-kasasmartplug": "github:bitfocus/companion-module-tplink-kasasmartplug#v1.0.1",
|
|
||||||
"companion-module-tslproducts-umd": "github:bitfocus/companion-module-tslproducts-umd#v1.2.1",
|
|
||||||
"companion-module-tvone-corio": "github:bitfocus/companion-module-tvone-corio#v1.0.0",
|
|
||||||
"companion-module-twitch-api": "github:bitfocus/companion-module-twitch-api#v1.0.0",
|
|
||||||
"companion-module-ubiquiti-unifi": "github:bitfocus/companion-module-ubiquiti-unifi#v1.0.1",
|
|
||||||
"companion-module-vaddio-ptz": "github:bitfocus/companion-module-vaddio-ptz#v1.0.1",
|
|
||||||
"companion-module-vicreo-hotkey": "github:bitfocus/companion-module-vicreo-hotkey#v2.0.5",
|
|
||||||
"companion-module-vicreo-variablelistener": "github:bitfocus/companion-module-vicreo-variablelistener#v1.0.7",
|
|
||||||
"companion-module-videolan-vlc": "github:bitfocus/companion-module-videolan-vlc#v1.1.12",
|
|
||||||
"companion-module-visualproductions-bstation2": "github:bitfocus/companion-module-visualproductions-bstation2#v1.0.6",
|
|
||||||
"companion-module-vivitek-projector": "github:bitfocus/companion-module-vivitek-projector#v1.0.3",
|
|
||||||
"companion-module-vizio-smartcast": "github:bitfocus/companion-module-vizio-smartcast#v1.1.4",
|
|
||||||
"companion-module-vyv-photon": "github:bitfocus/companion-module-vyv-photon#v1.0.4",
|
|
||||||
"companion-module-wyrestorm-sw0402mv": "github:bitfocus/companion-module-wyrestorm-sw0402mv#v1.0.1",
|
|
||||||
"companion-module-xiamen-sprolink-vd-series": "github:bitfocus/companion-module-xiamen-sprolink-vd-series#v1.0.1",
|
|
||||||
"companion-module-yamaha-rcp": "github:bitfocus/companion-module-yamaha-rcp#v1.6.0",
|
|
||||||
"companion-module-youtube-live": "github:bitfocus/companion-module-youtube-live#v1.1.2",
|
|
||||||
"companion-module-zenvideo-ndirouter": "github:bitfocus/companion-module-zenvideo-ndirouter#v1.0.1",
|
|
||||||
"debug": "^4.2.0",
|
|
||||||
"elgato-stream-deck": "^4.1.0",
|
|
||||||
"emberplus-connection": "^0.0.4",
|
|
||||||
"express": "^4.16.3",
|
|
||||||
"find-process": "1.4.4",
|
|
||||||
"fs-extra": "^10.0.0",
|
|
||||||
"infinitton-idisplay": "^1.0.5",
|
|
||||||
"lodash": "^4.17.20",
|
|
||||||
"mkdirp": "^1.0.4",
|
|
||||||
"moment": "^2.29.1",
|
|
||||||
"network": "^0.4.1",
|
|
||||||
"node-fetch": "^2.6.1",
|
|
||||||
"node-rest-client": "^3.1.0",
|
|
||||||
"osc": "^2.4.1",
|
|
||||||
"pngjs": "^3.3.3",
|
|
||||||
"sharp": "^0.28.3",
|
|
||||||
"shortid": "^2.2.16",
|
|
||||||
"socket.io": "^4.1.2",
|
|
||||||
"strip-ansi": "^5.2.0",
|
|
||||||
"websocket": "^1.0.34",
|
|
||||||
"node-hid": "^2.1.1",
|
|
||||||
"serialport": "^9.2.0",
|
|
||||||
"ws": "^7.4.6"
|
|
||||||
},
|
|
||||||
"collective": {
|
|
||||||
"type": "donorbox",
|
|
||||||
"url": "https://donorbox.org/bitfocus-opensource"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"@julusian/jpeg-turbo": "^1.1.1"
|
|
||||||
},
|
|
||||||
"resolutions": {
|
|
||||||
"infinitton-idisplay/node-hid": "^2.1.1",
|
|
||||||
"**/osc/serialport": "^9.2.0",
|
|
||||||
"**/osc/ws": "^7.4.6"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
10067
pkgs/companion/yarn.nix
10067
pkgs/companion/yarn.nix
File diff suppressed because it is too large
Load diff
|
@ -1,48 +0,0 @@
|
||||||
{ stdenv, requireFile, fetchpatch, kernel, lib }:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "decklink";
|
|
||||||
version = "12.2.2";
|
|
||||||
|
|
||||||
src = requireFile {
|
|
||||||
name = "Blackmagic_Desktop_Video_Linux_12.2.2.tar.gz";
|
|
||||||
url = "https://www.blackmagicdesign.com/support/";
|
|
||||||
sha256 = "8bca946bd3f002d2d404a74210c881935351e1a0d03f750559b180fdb439ef35";
|
|
||||||
};
|
|
||||||
|
|
||||||
KERNELDIR = "${kernel.dev}/lib/modules/${kernel.modDirVersion}/build";
|
|
||||||
INSTALL_MOD_PATH = placeholder "out";
|
|
||||||
|
|
||||||
nativeBuildInputs = kernel.moduleBuildDependencies;
|
|
||||||
|
|
||||||
setSourceRoot = ''
|
|
||||||
tar xf Blackmagic_Desktop_Video_Linux_12.2.2/other/x86_64/desktopvideo-12.2.2a6-x86_64.tar.gz
|
|
||||||
sourceRoot=$NIX_BUILD_TOP/desktopvideo-12.2.2a6-x86_64/usr/src
|
|
||||||
'';
|
|
||||||
|
|
||||||
buildPhase = ''
|
|
||||||
runHook preBuild
|
|
||||||
|
|
||||||
make -C $sourceRoot/blackmagic-12.2.2a6 -j$NIX_BUILD_CORES
|
|
||||||
make -C $sourceRoot/blackmagic-io-12.2.2a6 -j$NIX_BUILD_CORES
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
make -C $KERNELDIR M=$sourceRoot/blackmagic-12.2.2a6 modules_install
|
|
||||||
make -C $KERNELDIR M=$sourceRoot/blackmagic-io-12.2.2a6 modules_install
|
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
homepage = "https://www.blackmagicdesign.com/support/family/capture-and-playback";
|
|
||||||
maintainers = [ maintainers.hexchen ];
|
|
||||||
license = licenses.unfree;
|
|
||||||
description = "Kernel module for the Blackmagic Design Decklink cards";
|
|
||||||
platforms = platforms.linux;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,68 +1,25 @@
|
||||||
{ config ? {}, system ? builtins.currentSystem, ... }@args:
|
{ nixpkgs ? <nixpkgs>, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
sources = import ../nix/sources.nix;
|
pkgs = import nixpkgs {};
|
||||||
pkgs = import sources.nixpkgs args;
|
|
||||||
unstable = import sources.nixpkgs-unstable args;
|
|
||||||
|
|
||||||
callPackage = pkgs.lib.callPackageWith (pkgs // newpkgs);
|
callPackage = pkgs.lib.callPackageWith (pkgs // newpkgs);
|
||||||
|
|
||||||
newpkgs = {
|
wasiSrc = fetchGit {
|
||||||
alps = callPackage ./alps {};
|
url = "https://gitlab.infra4future.de/wasi/wasi-rust";
|
||||||
|
rev = "356dbc23a3683d134f13156af71baeaa06fb80d1";
|
||||||
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 pkgs.extend(_: _: newpkgs)
|
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 {};
|
||||||
|
};
|
||||||
|
|
||||||
|
in newpkgs
|
||||||
|
|
47
pkgs/funkwhale/default.nix
Normal file
47
pkgs/funkwhale/default.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
{ 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 ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
stdenv, fetchurl, pkg-config, glib, expat,
|
|
||||||
libjpeg_turbo, libexif, librsvg, libtiff, libpng
|
|
||||||
}:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "libvips";
|
|
||||||
version = "8.11.3";
|
|
||||||
|
|
||||||
src = fetchurl {
|
|
||||||
url = "https://github.com/libvips/libvips/releases/download/v${version}/vips-${version}.tar.gz";
|
|
||||||
sha256 = "00fz7h7vb0qqsc9i2smp3aljwjyb5cin2fiqillv8vvx8wpis2lv";
|
|
||||||
};
|
|
||||||
|
|
||||||
propagatedBuildInputs = [ glib ];
|
|
||||||
buildInputs = [ expat libjpeg_turbo libexif librsvg libtiff libpng ];
|
|
||||||
nativeBuildInputs = [ pkg-config ];
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
{ stdenv, fetchurl, fetchFromGitHub, buildGoPackage, buildEnv, lib }:
|
|
||||||
|
|
||||||
let
|
|
||||||
sources = import ../../nix/sources.nix;
|
|
||||||
version = sources.mattermost-webapp.version;
|
|
||||||
|
|
||||||
mattermost-server = buildGoPackage rec {
|
|
||||||
pname = "mattermost-server";
|
|
||||||
inherit version;
|
|
||||||
|
|
||||||
src = sources.mattermost-server.outPath;
|
|
||||||
|
|
||||||
goPackagePath = "github.com/mattermost/mattermost-server";
|
|
||||||
|
|
||||||
ldflags = [
|
|
||||||
"-X ${goPackagePath}/model.BuildNumber=nixpkgs-${version}"
|
|
||||||
];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
mattermost-webapp = stdenv.mkDerivation {
|
|
||||||
pname = "mattermost-webapp";
|
|
||||||
inherit version;
|
|
||||||
|
|
||||||
src = sources.mattermost-webapp;
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out
|
|
||||||
cp -r client $out
|
|
||||||
cp -r i18n $out
|
|
||||||
cp -r fonts $out
|
|
||||||
cp -r templates $out
|
|
||||||
cp -r config $out
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
buildEnv {
|
|
||||||
name = "mattermost-${version}";
|
|
||||||
paths = [ mattermost-server mattermost-webapp ];
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description = "Open-source, self-hosted Slack-alternative";
|
|
||||||
homepage = "https://www.mattermost.org";
|
|
||||||
license = with licenses; [ agpl3 asl20 ];
|
|
||||||
maintainers = with maintainers; [ fpletz ryantm ];
|
|
||||||
platforms = platforms.unix;
|
|
||||||
};
|
|
||||||
}
|
|
13640
pkgs/peertube/client-yarn-packages.nix
Normal file
13640
pkgs/peertube/client-yarn-packages.nix
Normal file
File diff suppressed because it is too large
Load diff
207
pkgs/peertube/default.nix
Normal file
207
pkgs/peertube/default.nix
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
{ 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
|
597
pkgs/peertube/ldap.patch
Normal file
597
pkgs/peertube/ldap.patch
Normal file
|
@ -0,0 +1,597 @@
|
||||||
|
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"
|
15
pkgs/peertube/peertube.json
Normal file
15
pkgs/peertube/peertube.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
121
pkgs/peertube/sendmail.patch
Normal file
121
pkgs/peertube/sendmail.patch
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
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...')
|
||||||
|
|
8735
pkgs/peertube/server-yarn-packages.nix
Normal file
8735
pkgs/peertube/server-yarn-packages.nix
Normal file
File diff suppressed because it is too large
Load diff
211
pkgs/peertube/syden.patch
Normal file
211
pkgs/peertube/syden.patch
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
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="<a>"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="</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="<br/>"/>
|
||||||
|
-
|
||||||
|
- Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="<a>"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="</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="<br/>"/> Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="<a>"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/>. </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="<br/>"/>
|
||||||
|
-
|
||||||
|
- Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="<a>"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/>.
|
||||||
|
+ 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
|
||||||
|
|
26
pkgs/peertube/yarn_fix_http_node.patch
Normal file
26
pkgs/peertube/yarn_fix_http_node.patch
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
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"
|
|
@ -1,24 +0,0 @@
|
||||||
|
|
||||||
/* Hides extra fields on connect screen */
|
|
||||||
.connect-row:nth-of-type(4) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.connect-row:nth-of-type(2) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.connect-row:nth-of-type(5) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Hides side panel button */
|
|
||||||
.header > button:first-child {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hides channel options button (includes leave option) */
|
|
||||||
.header > button:nth-last-child(2) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
{ 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;
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
--- 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',
|
|
||||||
],
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
--- 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]
|
|
||||||
)
|
|
|
@ -1,32 +0,0 @@
|
||||||
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
|
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
{ 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";
|
|
||||||
}];
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
{ 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;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
{ 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;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
{ config, lib, pkgs, profiles, modules, evalConfig, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
containers.lantifa = {
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.8";
|
|
||||||
bindMounts = {
|
|
||||||
"/persist" = {
|
|
||||||
hostPath = "/persist/containers/lantifa";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
hexchen.bindmounts."/var/lib/mediawiki" = "/persist/var/lib/mediawiki";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.hosts."127.0.0.1" = [ "wiki.lantifa.org" ];
|
|
||||||
users.users.mediawiki.extraGroups = [ "keys" ];
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.mediawiki = {
|
|
||||||
enable = true;
|
|
||||||
name = "LANtifa";
|
|
||||||
database.createLocally = true;
|
|
||||||
passwordFile = "/var/lib/mediawiki/mediawiki-password";
|
|
||||||
extraConfig = let
|
|
||||||
wikidb = pkgs.fetchzip {
|
|
||||||
url = "https://www.kennel17.co.uk/uploads/testwiki/e/e9/WikiDB.zip";
|
|
||||||
sha256 = "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;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,177 +0,0 @@
|
||||||
{ config, pkgs, lib, sources, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ sources.nixos-mailserver.outPath ];
|
|
||||||
|
|
||||||
# reduce log spam
|
|
||||||
systemd.services.rspamd.serviceConfig.LogLevelMax =
|
|
||||||
3; # this is set to error because rspamd regularly complains about not enough learns
|
|
||||||
systemd.services.postfix.serviceConfig.LogLevelMax = 5; # = notice
|
|
||||||
systemd.services.dovecot2.serviceConfig.LogLevelMax = 5; # = notice
|
|
||||||
|
|
||||||
# stop postfix from dying if rspamd hiccups
|
|
||||||
systemd.services.postfix.unitConfig = {
|
|
||||||
Requires = lib.mkForce "dovecot2.service opendkim.service";
|
|
||||||
};
|
|
||||||
|
|
||||||
mailserver = {
|
|
||||||
mailDirectory = "/persist/mail";
|
|
||||||
enable = true;
|
|
||||||
fqdn = "mail.hacc.space";
|
|
||||||
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";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,246 +0,0 @@
|
||||||
{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;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
{ 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" ];
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
{ config, lib, pkgs, profiles, modules, evalConfig, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
containers.nextcloud = {
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.2";
|
|
||||||
bindMounts = {
|
|
||||||
"/persist" = {
|
|
||||||
hostPath = "/persist/containers/nextcloud";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
../../modules/nextcloud.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.htop ];
|
|
||||||
|
|
||||||
services.nextcloud-patched = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
# must be set manually; may not be incremented by more than one at
|
|
||||||
# a time, otherwise nextcloud WILL break
|
|
||||||
package = pkgs.nextcloud24;
|
|
||||||
|
|
||||||
home = "/persist/nextcloud";
|
|
||||||
https = true;
|
|
||||||
|
|
||||||
hostName = "cloud.infra4future.de";
|
|
||||||
config = {
|
|
||||||
dbtype = "pgsql";
|
|
||||||
dbuser = "nextcloud";
|
|
||||||
dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
|
|
||||||
dbname = "nextcloud";
|
|
||||||
adminpassFile = "/persist/nextcloud/config/admin_pw";
|
|
||||||
adminuser = "root";
|
|
||||||
defaultapp = "apporder";
|
|
||||||
};
|
|
||||||
|
|
||||||
# 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";
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{ config, pkgs, ... }:
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
hacc.websites = {
|
|
||||||
enable = true;
|
|
||||||
directory = ../websites;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
{ 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
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
{ config, lib, pkgs, evalConfig, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
# necessary since overlays won't propagate into the
|
|
||||||
# container's config
|
|
||||||
thelounge = pkgs.thelounge-hacked;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
containers.thelounge = {
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.4";
|
|
||||||
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.thelounge = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
extraConfig = {
|
|
||||||
public = true;
|
|
||||||
# respect X-Forwarded-For
|
|
||||||
reverseProxy = true;
|
|
||||||
defaults = {
|
|
||||||
name = "libera chat";
|
|
||||||
host = "irc.eu.libera.chat";
|
|
||||||
port = 6697;
|
|
||||||
# encrypt things!
|
|
||||||
tls = true;
|
|
||||||
# yes, please do actually check the cert …
|
|
||||||
rejectUnauthorized = true;
|
|
||||||
nick = "haccGuest%%%%";
|
|
||||||
join = "#hacc-webchat";
|
|
||||||
};
|
|
||||||
lockNetwork = true;
|
|
||||||
|
|
||||||
# don't log messages (default is text / sqlite)
|
|
||||||
messageStorage = [];
|
|
||||||
|
|
||||||
# darker theme
|
|
||||||
#theme = "morning";
|
|
||||||
|
|
||||||
# these three should result in having link previews
|
|
||||||
# which are fetched only by the server, then proxied
|
|
||||||
# (i.e. clients won't directly connect to arbitrary
|
|
||||||
# domains to get previews)
|
|
||||||
prefetch = true;
|
|
||||||
prefetchStorage = true;
|
|
||||||
disableMediaPreview = true;
|
|
||||||
|
|
||||||
leaveMessage = "happy haccing";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# override the package we use
|
|
||||||
systemd.services.thelounge.serviceConfig.ExecStart =
|
|
||||||
pkgs.lib.mkForce "${thelounge}/bin/thelounge start";
|
|
||||||
|
|
||||||
services.coredns = {
|
|
||||||
enable = true;
|
|
||||||
config = ''
|
|
||||||
.:53 {
|
|
||||||
forward . 1.1.1.1
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
})).config.system.build.toplevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."webchat.voc.hacc.space" = {
|
|
||||||
locations."/".proxyPass =
|
|
||||||
"http://${config.containers.thelounge.localAddress}:9000";
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
{ config, lib, pkgs, profiles, modules, evalConfig, sources, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
uffd = pkgs.uffd;
|
|
||||||
in {
|
|
||||||
containers.uffd = {
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.100.1";
|
|
||||||
localAddress = "192.168.100.9";
|
|
||||||
autoStart = true;
|
|
||||||
bindMounts = {
|
|
||||||
"/persist" = {
|
|
||||||
hostPath = "/persist/containers/uffd";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
networking.defaultGateway = {
|
|
||||||
address = "192.168.100.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
services.coredns = {
|
|
||||||
enable = true;
|
|
||||||
config = ''
|
|
||||||
.:53 {
|
|
||||||
forward . 1.1.1.1
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
services.uwsgi = {
|
|
||||||
enable = true;
|
|
||||||
plugins = [ "python3" ];
|
|
||||||
instance = {
|
|
||||||
type = "normal";
|
|
||||||
pythonPackages = self: with self; [ uffd ];
|
|
||||||
module = "uffd:create_app()";
|
|
||||||
# socket = "${config.services.uwsgi.runDir}/uwsgi.sock";
|
|
||||||
http = ":8080";
|
|
||||||
env = [
|
|
||||||
"CONFIG_PATH=/persist/uffd/uffd.conf"
|
|
||||||
];
|
|
||||||
hook-pre-app = "exec:FLASK_APP=${uffd}/lib/python3.9/site-packages/uffd flask db upgrade";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})).config.system.build.toplevel;
|
|
||||||
};
|
|
||||||
services.nginx.virtualHosts."login.infra4future.de" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
locations = {
|
|
||||||
"/".proxyPass = "http://${config.containers.uffd.localAddress}:8080";
|
|
||||||
"/static".root = "${uffd}/lib/python3.9/site-packages/uffd";
|
|
||||||
"/static/hacc.png".return = "302 https://infra4future.de/assets/img/logo_vernetzung.png";
|
|
||||||
"/static/infra4future.svg".return = "302 https://infra4future.de/assets/img/infra4future.svg";
|
|
||||||
"/static/hedgedoc.svg".return = "302 https://infra4future.de/assets/img/icons/hedgedoc.svg";
|
|
||||||
"/static/mattermost.svg".return = "302 https://infra4future.de/assets/img/icons/mattermost.svg";
|
|
||||||
"/static/nextcloud.svg".return = "302 https://infra4future.de/assets/img/icons/nextcloud.svg";
|
|
||||||
"/static/hot_shit.svg".return = "302 https://infra4future.de/assets/img/icons/hot_shit.svg";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
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";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
{ 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;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,87 +0,0 @@
|
||||||
{ config, lib, pkgs, modules, profiles, evalConfig, sources, ... }:
|
|
||||||
let
|
|
||||||
wapkgs = "${sources.workadventure}/wapkgs.nix";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.coturn = {
|
|
||||||
enable = true;
|
|
||||||
realm = "void.hacc.space";
|
|
||||||
no-cli = true;
|
|
||||||
lt-cred-mech = true;
|
|
||||||
|
|
||||||
extraConfig = ''
|
|
||||||
user=turn:a4c9ad080dc51146611eabd15a27b07fc92850a9ae90c53e7745fce6c5a2c457
|
|
||||||
fingerprint
|
|
||||||
external-ip=135.181.215.233
|
|
||||||
server-name=void.hacc.space
|
|
||||||
prometheus
|
|
||||||
'';
|
|
||||||
|
|
||||||
cert = config.security.acme.certs."void.hacc.space".directory + "full.pem";
|
|
||||||
pkey = config.security.acme.certs."void.hacc.space".directory + "key.pem";
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall = with config.services.coturn;
|
|
||||||
let
|
|
||||||
ports = [ listening-port tls-listening-port ];
|
|
||||||
in {
|
|
||||||
allowedTCPPorts = ports ++ [ 9641 ]; # 9641 is the port for the prometheus endpoint
|
|
||||||
allowedUDPPorts = ports;
|
|
||||||
allowedUDPPortRanges = [
|
|
||||||
{ from = min-port; to = max-port; }
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."void.hacc.space" = {
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://192.168.150.3";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
containers.wa-void = {
|
|
||||||
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = "192.168.150.1";
|
|
||||||
localAddress = "192.168.150.3";
|
|
||||||
|
|
||||||
|
|
||||||
path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
|
|
||||||
boot.isContainer = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
users.users.root.hashedPassword = "";
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
"${sources.workadventure.outPath}/default.nix"
|
|
||||||
((import sources.nix-hexchen) {}).profiles.nopersist
|
|
||||||
];
|
|
||||||
|
|
||||||
services.workadventure."void" = {
|
|
||||||
|
|
||||||
packageset = (import wapkgs {inherit pkgs;}).workadventure-xce;
|
|
||||||
|
|
||||||
nginx = {
|
|
||||||
default = true;
|
|
||||||
domain = "https://void.hacc.space";
|
|
||||||
maps.path = "${sources.haccmap.outPath}/";
|
|
||||||
maps.serve = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
frontend.startRoomUrl = "/_/global/void.hacc.space/maps/main.json";
|
|
||||||
commonConfig = {
|
|
||||||
webrtc.stun.url = "stun:void.hacc.space:3478";
|
|
||||||
webrtc.turn = {
|
|
||||||
url = "turn:135.181.215.233";
|
|
||||||
user = "turn";
|
|
||||||
password = "a4c9ad080dc51146611eabd15a27b07fc92850a9ae90c53e7745fce6c5a2c457";
|
|
||||||
};
|
|
||||||
jitsi.url = "meet.ffmuc.net";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})).config.system.build.toplevel;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
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.
Before Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 396 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 17 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 111 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 24 KiB |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue