add server config
This commit is contained in:
parent
8655459e46
commit
33b4fe95c2
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
private.nix
|
private.nix
|
||||||
|
private/
|
||||||
|
|
|
@ -1,5 +1,37 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"blobs": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1604995301,
|
||||||
|
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
|
||||||
|
"owner": "simple-nixos-mailserver",
|
||||||
|
"repo": "blobs",
|
||||||
|
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
|
||||||
|
"type": "gitlab"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "simple-nixos-mailserver",
|
||||||
|
"repo": "blobs",
|
||||||
|
"type": "gitlab"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1668681692,
|
||||||
|
"narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "009399224d5e398d03b22badca40a37ac85412a1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
|
@ -83,6 +115,32 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixos-mailserver": {
|
||||||
|
"inputs": {
|
||||||
|
"blobs": "blobs",
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"nixpkgs-22_11": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"utils": "utils"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1671738303,
|
||||||
|
"narHash": "sha256-PRgqtaWf2kMSYqVmcnmhTh+UsC0RmvXRTr+EOw5VZUA=",
|
||||||
|
"owner": "simple-nixos-mailserver",
|
||||||
|
"repo": "nixos-mailserver",
|
||||||
|
"rev": "6d0d9fb966cc565a3df74d3b686f924c7615118c",
|
||||||
|
"type": "gitlab"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "simple-nixos-mailserver",
|
||||||
|
"repo": "nixos-mailserver",
|
||||||
|
"type": "gitlab"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1683408522,
|
"lastModified": 1683408522,
|
||||||
|
@ -104,9 +162,10 @@
|
||||||
"impermanence": "impermanence",
|
"impermanence": "impermanence",
|
||||||
"nix-gaming": "nix-gaming",
|
"nix-gaming": "nix-gaming",
|
||||||
"nixos-hardware": "nixos-hardware",
|
"nixos-hardware": "nixos-hardware",
|
||||||
|
"nixos-mailserver": "nixos-mailserver",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"rust-overlay": "rust-overlay",
|
"rust-overlay": "rust-overlay",
|
||||||
"utils": "utils"
|
"utils": "utils_2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rust-overlay": {
|
"rust-overlay": {
|
||||||
|
@ -117,11 +176,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1683685144,
|
"lastModified": 1683708507,
|
||||||
"narHash": "sha256-HZBieMZj9Rp+WtbGiK5JaUciZwJ/2YX6LRe5z8jkfow=",
|
"narHash": "sha256-i5zgWcuyZcNBnlrzVjhpAFQdJWr4OyhvQ1owAEHFFKw=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "74e44edb87aeed50798f5b81795ebad250d4a0c0",
|
"rev": "ed55dc022aa23ed3c42f383cf1782290b3b939d5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -146,6 +205,21 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"utils": {
|
"utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1605370193,
|
||||||
|
"narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "5021eac20303a61fafe17224c087f5519baed54d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"utils_2": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils_2"
|
"flake-utils": "flake-utils_2"
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,14 +15,25 @@
|
||||||
url = "github:fufexan/nix-gaming";
|
url = "github:fufexan/nix-gaming";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
nixos-mailserver = {
|
||||||
|
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.nixpkgs-22_11.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs@{ self, nixpkgs, utils, nixos-hardware, impermanence, nix-gaming, ... }:
|
outputs = inputs@{ self, nixpkgs, utils, nixos-hardware, impermanence, nix-gaming, nixos-mailserver, ... }:
|
||||||
let
|
let
|
||||||
hw = nixos-hardware.nixosModules;
|
hw = nixos-hardware.nixosModules;
|
||||||
# IRL-related stuff I'd rather not put into git
|
# IRL-related stuff I'd rather not put into git
|
||||||
priv = if builtins.pathExists ./private.nix then (import ./private.nix) else { };
|
priv = if builtins.pathExists ./private/default.nix then (import ./private)
|
||||||
getPriv = (hostname: with builtins; if hasAttr hostname priv then getAttr hostname priv else { });
|
else if builtins.pathExists ./private.nix then (import ./private.nix)
|
||||||
|
else { };
|
||||||
|
getPriv = hostname: with builtins; if hasAttr hostname priv then getAttr hostname priv else { };
|
||||||
|
common = hostname: [ (getPriv hostname) impermanence.nixosModule ];
|
||||||
|
extraArgs = {
|
||||||
|
inherit nixpkgs;
|
||||||
|
};
|
||||||
in utils.lib.mkFlake {
|
in utils.lib.mkFlake {
|
||||||
inherit self inputs;
|
inherit self inputs;
|
||||||
hostDefaults.modules = [
|
hostDefaults.modules = [
|
||||||
|
@ -44,18 +55,24 @@
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = [
|
modules = [
|
||||||
./hosts/nixmsi.nix
|
./hosts/nixmsi.nix
|
||||||
impermanence.nixosModule
|
|
||||||
nix-gaming.nixosModules.pipewireLowLatency
|
nix-gaming.nixosModules.pipewireLowLatency
|
||||||
hw.common-pc-ssd # enables fstrim
|
hw.common-pc-ssd # enables fstrim
|
||||||
hw.common-cpu-amd # microcode
|
hw.common-cpu-amd # microcode
|
||||||
hw.common-cpu-amd-pstate # amd-pstate
|
hw.common-cpu-amd-pstate # amd-pstate
|
||||||
hw.common-gpu-amd # configures drivers
|
hw.common-gpu-amd # configures drivers
|
||||||
hw.common-pc-laptop # enables tlp
|
hw.common-pc-laptop # enables tlp
|
||||||
(getPriv "nixmsi")
|
] ++ common "nixmsi";
|
||||||
];
|
inherit extraArgs;
|
||||||
extraArgs = {
|
|
||||||
inherit nixpkgs;
|
|
||||||
};
|
};
|
||||||
|
nixserver = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
modules = [
|
||||||
|
./hosts/nixserver
|
||||||
|
nixos-mailserver.nixosModules.default
|
||||||
|
hw.common-pc-hdd
|
||||||
|
hw.common-cpu-intel
|
||||||
|
] ++ common "nixserver";
|
||||||
|
inherit extraArgs;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -108,6 +108,11 @@ in {
|
||||||
opengl.extraPackages = with pkgs; [ vulkan-validation-layers ];
|
opengl.extraPackages = with pkgs; [ vulkan-validation-layers ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings.PasswordAuthentication = false;
|
||||||
|
};
|
||||||
|
|
||||||
services.tlp.enable = true;
|
services.tlp.enable = true;
|
||||||
services.tlp.settings = {
|
services.tlp.settings = {
|
||||||
USB_EXCLUDE_PHONE = 1;
|
USB_EXCLUDE_PHONE = 1;
|
||||||
|
@ -207,7 +212,6 @@ in {
|
||||||
++ (lib.range 1714 1764);
|
++ (lib.range 1714 1764);
|
||||||
networking.firewall.allowedUDPPorts = lib.range 1714 1764;
|
networking.firewall.allowedUDPPorts = lib.range 1714 1764;
|
||||||
|
|
||||||
# networking.hostName = "nixmsi";
|
|
||||||
networking.wireless.iwd.enable = true;
|
networking.wireless.iwd.enable = true;
|
||||||
#networking.networkmanager.enable = true;
|
#networking.networkmanager.enable = true;
|
||||||
|
|
||||||
|
@ -327,17 +331,6 @@ in {
|
||||||
|
|
||||||
documentation.dev.enable = true;
|
documentation.dev.enable = true;
|
||||||
|
|
||||||
### RANDOM PATCHES ###
|
|
||||||
|
|
||||||
# I've had some weird issues with the entire system breaking after
|
|
||||||
# suspend because of /dev/shm getting nuked, maybe this'll help
|
|
||||||
services.logind.extraConfig = ''
|
|
||||||
RemoveIPC=no
|
|
||||||
'';
|
|
||||||
|
|
||||||
# why is this not part of base NixOS?
|
|
||||||
systemd.tmpfiles.rules = [ "d /var/lib/systemd/pstore 0755 root root 14d" ];
|
|
||||||
|
|
||||||
# autologin once after boot
|
# autologin once after boot
|
||||||
# --skip-login means directly call login instead of first asking for username
|
# --skip-login means directly call login instead of first asking for username
|
||||||
# (normally login asks for username too, but getty prefers to do it by itself for whatever reason)
|
# (normally login asks for username too, but getty prefers to do it by itself for whatever reason)
|
||||||
|
|
464
system/hosts/nixserver/default.nix
Normal file
464
system/hosts/nixserver/default.nix
Normal file
|
@ -0,0 +1,464 @@
|
||||||
|
{ lib
|
||||||
|
, pkgs
|
||||||
|
, config
|
||||||
|
, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.server;
|
||||||
|
# TODO: move to lib
|
||||||
|
quotePotentialIpV6 = addr:
|
||||||
|
if lib.hasInfix ":" addr then "[${addr}]" else addr;
|
||||||
|
|
||||||
|
efiPart = "/dev/disk/by-uuid/3E2A-A5CB";
|
||||||
|
rootUuid = "6aace237-9b48-4294-8e96-196759a5305b";
|
||||||
|
rootPart = "/dev/disk/by-uuid/${rootUuid}";
|
||||||
|
|
||||||
|
hosted-domains =
|
||||||
|
map
|
||||||
|
(prefix: if prefix == null then cfg.domainName else "${prefix}.${cfg.domainName}")
|
||||||
|
[
|
||||||
|
null
|
||||||
|
"dns"
|
||||||
|
"mumble"
|
||||||
|
"mail"
|
||||||
|
"music"
|
||||||
|
"www"
|
||||||
|
"matrix"
|
||||||
|
"search"
|
||||||
|
"git"
|
||||||
|
"cloud"
|
||||||
|
"ns1"
|
||||||
|
"ns2"
|
||||||
|
];
|
||||||
|
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./options.nix
|
||||||
|
./matrix.nix
|
||||||
|
./fdroid.nix
|
||||||
|
./mumble.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
system.stateVersion = "22.11";
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
initrd = {
|
||||||
|
availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "sd_mod" "sr_mod" "rtsx_pci_sdmmc" ];
|
||||||
|
};
|
||||||
|
kernelModules = [ "kvm-intel" ];
|
||||||
|
kernelParams = [
|
||||||
|
"consoleblank=60"
|
||||||
|
];
|
||||||
|
loader = {
|
||||||
|
grub = {
|
||||||
|
enable = true;
|
||||||
|
device = "nodev";
|
||||||
|
version = 2;
|
||||||
|
efiSupport = true;
|
||||||
|
efiInstallAsRemovable = true;
|
||||||
|
gfxmodeEfi = "1920x1080";
|
||||||
|
gfxmodeBios = "1920x1080";
|
||||||
|
};
|
||||||
|
efi.efiSysMountPoint = "/boot/efi";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
fileSystems = {
|
||||||
|
"/" = { device = "none"; fsType = "tmpfs"; neededForBoot = true;
|
||||||
|
options = [ "defaults" "size=2G" "mode=755" ]; };
|
||||||
|
"/persist" =
|
||||||
|
{ device = rootPart; fsType = "btrfs"; neededForBoot = true;
|
||||||
|
options = [ "compress=zstd:15" ]; };
|
||||||
|
"/boot" =
|
||||||
|
{ device = rootPart; fsType = "btrfs"; neededForBoot = true;
|
||||||
|
options = [ "compress=zstd:15" "subvol=boot" ]; };
|
||||||
|
"/boot/efi" =
|
||||||
|
{ device = efiPart; fsType = "vfat"; };
|
||||||
|
};
|
||||||
|
zramSwap.enable = true;
|
||||||
|
swapDevices = [ ];
|
||||||
|
impermanence = {
|
||||||
|
enable = true;
|
||||||
|
path = /persist;
|
||||||
|
directories = [
|
||||||
|
{ directory = /var/www/${cfg.domainName}; }
|
||||||
|
{ directory = /var/lib/maubot; }
|
||||||
|
{ directory = /var/lib/fdroid; }
|
||||||
|
{ directory = config.mailserver.dkimKeyDirectory; }
|
||||||
|
{ directory = config.mailserver.mailDirectory; }
|
||||||
|
{ directory = /home/user; }
|
||||||
|
{ directory = /root; }
|
||||||
|
{ directory = /nix; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
services.beesd = {
|
||||||
|
filesystems.root = {
|
||||||
|
spec = "UUID=${rootUuid}";
|
||||||
|
hashTableSizeMB = 128;
|
||||||
|
extraOptions = [ "--loadavg-target" "8.0" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
i18n.defaultLocale = lib.mkDefault "en_US.UTF-8";
|
||||||
|
i18n.supportedLocales = lib.mkDefault [
|
||||||
|
"C.UTF-8/UTF-8"
|
||||||
|
"en_US.UTF-8/UTF-8"
|
||||||
|
"en_DK.UTF-8/UTF-8"
|
||||||
|
];
|
||||||
|
# ISO-8601
|
||||||
|
i18n.extraLocaleSettings.LC_TIME = "en_DK.UTF-8";
|
||||||
|
console.font = "${pkgs.terminus_font}/share/consolefonts/ter-v24n.psf.gz";
|
||||||
|
networking.useDHCP = true;
|
||||||
|
networking.resolvconf.extraConfig = ''
|
||||||
|
name_servers="127.0.0.1 ::1"
|
||||||
|
'';
|
||||||
|
networking.firewall = {
|
||||||
|
enable = true;
|
||||||
|
allowedTCPPorts = [
|
||||||
|
# ssh
|
||||||
|
22
|
||||||
|
# dns
|
||||||
|
53 853
|
||||||
|
# http/s
|
||||||
|
80 443
|
||||||
|
];
|
||||||
|
allowedUDPPorts = [
|
||||||
|
# dns
|
||||||
|
53 853
|
||||||
|
# wireguard
|
||||||
|
# 5553
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# UNBOUND
|
||||||
|
services.unbound = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.unbound-with-systemd.override {
|
||||||
|
withPythonModule = true;
|
||||||
|
python = pkgs.python3.withPackages (pkgs: with pkgs; [ pydbus dnspython ]);
|
||||||
|
};
|
||||||
|
localControlSocketPath = "/run/unbound/unbound.ctl";
|
||||||
|
resolveLocalQueries = false;
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
interface = [ "0.0.0.0" "::" ];
|
||||||
|
access-control = [ "${cfg.lanCidrV4} allow" "${cfg.lanCidrV6} allow" ];
|
||||||
|
aggressive-nsec = true;
|
||||||
|
do-ip6 = true;
|
||||||
|
module-config = ''"validator iterator"'';
|
||||||
|
local-zone = [
|
||||||
|
''"local." static''
|
||||||
|
] ++ (lib.optionals (cfg.localIpV4 != null || cfg.localIpV6 != null) [
|
||||||
|
''"${cfg.domainName}." typetransparent''
|
||||||
|
]);
|
||||||
|
local-data = builtins.concatLists (map (domain:
|
||||||
|
lib.optionals (cfg.localIpV4 != null) [
|
||||||
|
''"${domain}. A ${cfg.localIpV4}"''
|
||||||
|
] ++ (lib.optionals (cfg.localIpV6 != null) [
|
||||||
|
''"${domain}. A ${cfg.localIpV6}"''
|
||||||
|
])) hosted-domains);
|
||||||
|
};
|
||||||
|
python.python-script = toString (pkgs.fetchurl {
|
||||||
|
url = "https://raw.githubusercontent.com/NLnetLabs/unbound/a912786ca9e72dc1ccde98d5af7d23595640043b/pythonmod/examples/avahi-resolver.py";
|
||||||
|
sha256 = "0r1iqjf08wrkpzvj6pql1jqa884hbbfy9ix5gxdrkrva09msiqgi";
|
||||||
|
});
|
||||||
|
remote-control.control-enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.unbound.environment.MDNS_ACCEPT_NAMES = "^.*\\.local\\.$";
|
||||||
|
# just in case
|
||||||
|
networking.hosts."127.0.0.1" = [ "localhost" ] ++ hosted-domains;
|
||||||
|
|
||||||
|
# CUPS
|
||||||
|
services.printing = {
|
||||||
|
enable = true;
|
||||||
|
allowFrom = [ cfg.lanCidrV4 cfg.lanCidrV6 ];
|
||||||
|
browsing = true;
|
||||||
|
clientConf = ''
|
||||||
|
ServerName ${cfg.domainName}
|
||||||
|
'';
|
||||||
|
defaultShared = true;
|
||||||
|
drivers = [ pkgs.hplip ];
|
||||||
|
startWhenNeeded = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fish.enable = true;
|
||||||
|
users.defaultUserShell = pkgs.fish;
|
||||||
|
users.users.user = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" config.services.unbound.group ];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
comma
|
||||||
|
git
|
||||||
|
vim
|
||||||
|
wget
|
||||||
|
# rxvt-unicode-unwrapped.terminfo
|
||||||
|
kitty.terminfo
|
||||||
|
tmux
|
||||||
|
];
|
||||||
|
|
||||||
|
services.postgresql.enable = true;
|
||||||
|
services.postgresql.package = pkgs.postgresql_13;
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
settings = {
|
||||||
|
allowed-users = [ "user" ];
|
||||||
|
auto-optimise-store = true;
|
||||||
|
};
|
||||||
|
gc = {
|
||||||
|
automatic = true;
|
||||||
|
dates = "weekly";
|
||||||
|
options = "--delete-older-than 30d";
|
||||||
|
};
|
||||||
|
package = pkgs.nixFlakes;
|
||||||
|
extraOptions = ''
|
||||||
|
experimental-features = nix-command flakes
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
systemd.services.nix-daemon.serviceConfig.LimitSTACKSoft = "infinity";
|
||||||
|
|
||||||
|
# SSH
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings.PermitRootLogin = "no";
|
||||||
|
settings.PasswordAuthentication = false;
|
||||||
|
listenAddresses = [{
|
||||||
|
addr = "0.0.0.0";
|
||||||
|
} {
|
||||||
|
addr = "::";
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
services.fail2ban.enable = true;
|
||||||
|
|
||||||
|
# SEARXNG
|
||||||
|
services.searx.enable = true;
|
||||||
|
services.searx.package = pkgs.searxng.overrideAttrs (_: {
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "searxng";
|
||||||
|
repo = "searxng";
|
||||||
|
rev = "cb1c3741d7de1354b524589114617f183009f6a8";
|
||||||
|
sha256 = "sha256-7erY5Bd1ZoTpAIDbhIupu64Xd1PQspaW6vBqu7knzNI=";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
services.searx.runInUwsgi = true;
|
||||||
|
services.searx.uwsgiConfig = let inherit (config.services.searx) settings; in {
|
||||||
|
socket = "${quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}";
|
||||||
|
};
|
||||||
|
users.groups.searx.members = [ "nginx" ];
|
||||||
|
services.searx.environmentFile = "/etc/nixos/private/searx.env";
|
||||||
|
services.searx.settings = {
|
||||||
|
use_default_settings = true;
|
||||||
|
search = {
|
||||||
|
safe_search = 0; # Filter results. 0: None, 1: Moderate, 2: Strict
|
||||||
|
autocomplete = "duckduckgo"; # Existing autocomplete backends: "dbpedia", "duckduckgo", "google", "startpage", "swisscows", "qwant", "wikipedia" - leave blank to turn it off by default
|
||||||
|
default_lang = ""; # Default search language - leave blank to detect from browser information or use codes from 'languages.py'
|
||||||
|
};
|
||||||
|
|
||||||
|
server = {
|
||||||
|
port = 8888;
|
||||||
|
bind_address = "::1";
|
||||||
|
secret_key = "@SEARX_SECRET_KEY@";
|
||||||
|
base_url = "https://search.${cfg.domainName}/";
|
||||||
|
image_proxy = true;
|
||||||
|
default_http_headers = {
|
||||||
|
X-Content-Type-Options = "nosniff";
|
||||||
|
X-XSS-Protection = "1; mode=block";
|
||||||
|
X-Download-Options = "noopen";
|
||||||
|
X-Robots-Tag = "noindex, nofollow";
|
||||||
|
Referrer-Policy = "no-referrer";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
outgoing = {
|
||||||
|
request_timeout = 5.0; # default timeout in seconds, can be override by engine
|
||||||
|
max_request_timeout = 15.0; # the maximum timeout in seconds
|
||||||
|
pool_connections = 100; # Maximum number of allowable connections, or null
|
||||||
|
pool_maxsize = 10; # Number of allowable keep-alive connections, or null
|
||||||
|
enable_http2 = true; # See https://www.python-httpx.org/http2/
|
||||||
|
};
|
||||||
|
/* = {
|
||||||
|
name = "soundcloud";
|
||||||
|
disabled = true;
|
||||||
|
};*/
|
||||||
|
};
|
||||||
|
services.nginx.virtualHosts."search.${cfg.domainName}" = let inherit (config.services.searx) settings; in {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
# locations."/".proxyPass = "http://${quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}";
|
||||||
|
locations."/".extraConfig = ''
|
||||||
|
uwsgi_pass "${quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}";
|
||||||
|
include ${config.services.nginx.package}/conf/uwsgi_params;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# NGINX
|
||||||
|
services.nginx.enable = true;
|
||||||
|
services.nginx.streamConfig =
|
||||||
|
let
|
||||||
|
cert = config.security.acme.certs."${cfg.domainName}".directory + "/fullchain.pem";
|
||||||
|
certKey = config.security.acme.certs."${cfg.domainName}".directory + "/key.pem";
|
||||||
|
trustedCert = config.security.acme.certs."${cfg.domainName}".directory + "/chain.pem";
|
||||||
|
in ''
|
||||||
|
upstream dns {
|
||||||
|
zone dns 64k;
|
||||||
|
server 127.0.0.1:53;
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
listen 853 ssl;
|
||||||
|
ssl_certificate ${cert};
|
||||||
|
ssl_certificate_key ${certKey};
|
||||||
|
ssl_trusted_certificate ${trustedCert};
|
||||||
|
proxy_pass dns;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
services.nginx.commonHttpConfig = "log_format postdata '{\"ip\":\"$remote_addr\",\"time\":\"$time_iso8601\",\"referer\":\"$http_referer\",\"body\":\"$request_body\",\"ua\":\"$http_user_agent\"}';";
|
||||||
|
services.nginx.recommendedTlsSettings = true;
|
||||||
|
services.nginx.recommendedOptimisation = true;
|
||||||
|
services.nginx.recommendedGzipSettings = true;
|
||||||
|
services.nginx.recommendedProxySettings = true;
|
||||||
|
|
||||||
|
# BLOG
|
||||||
|
services.nginx.virtualHosts."${cfg.domainName}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
extraConfig = "autoindex on;";
|
||||||
|
locations."/".root = "/var/www/${cfg.domainName}/";
|
||||||
|
locations."/src".root = "/var/www/${cfg.domainName}/";
|
||||||
|
locations."/src".extraConfig = "index force_dirlisting;";
|
||||||
|
locations."/submit_comment".extraConfig = ''
|
||||||
|
access_log /var/log/nginx/comments.log postdata;
|
||||||
|
proxy_pass https://${cfg.domainName}/submit.htm;
|
||||||
|
break;
|
||||||
|
'';
|
||||||
|
locations."/submit.htm" = {
|
||||||
|
extraConfig = ''
|
||||||
|
return 200 '<!doctype html><html><head><base href="/"/><link rel="preload" href="style.css" as="style"><title>Success!</title><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><link rel="icon" type="image/jpeg" href="pfp.jpg"><link rel="alternate" type="application/rss+xml" title="RSS" href="https://${cfg.domainName}/blog/index.xml"><link href="style.css" rel="stylesheet" /><script src="main.js"></script><meta http-equiv="refresh" content="10; url=$http_referer" /></head><body onload="documentLoaded()"><hr/><div class="main-body"><p>Success! It may take a while for your comment to get moderated.</p><p>Please wait for 10 seconds until you get redirected back...</p><p>Or just go there <a href="$http_referer">manually</a>.</p></div><hr/></body></html>';
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."www.${cfg.domainName}" = {
|
||||||
|
enableACME = true;
|
||||||
|
globalRedirect = cfg.domainName;
|
||||||
|
};
|
||||||
|
|
||||||
|
# MAILSERVER
|
||||||
|
# roundcube
|
||||||
|
services.nginx.virtualHosts."mail.${cfg.domainName}" = {
|
||||||
|
enableACME = true;
|
||||||
|
};
|
||||||
|
services.roundcube = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.roundcube.withPlugins (plugins: [ plugins.persistent_login ]);
|
||||||
|
dicts = with pkgs.aspellDicts; [ en ru ];
|
||||||
|
hostName = "mail.${cfg.domainName}";
|
||||||
|
maxAttachmentSize = 100;
|
||||||
|
plugins = [ "persistent_login" ];
|
||||||
|
};
|
||||||
|
mailserver = {
|
||||||
|
enable = true;
|
||||||
|
fqdn = "mail.${cfg.domainName}";
|
||||||
|
domains = [ cfg.domainName ];
|
||||||
|
certificateScheme = 1;
|
||||||
|
certificateFile = config.security.acme.certs."mail.${cfg.domainName}".directory + "/fullchain.pem";
|
||||||
|
keyFile = config.security.acme.certs."mail.${cfg.domainName}".directory + "/key.pem";
|
||||||
|
localDnsResolver = false;
|
||||||
|
recipientDelimiter = "-";
|
||||||
|
lmtpSaveToDetailMailbox = "no";
|
||||||
|
hierarchySeparator = "/";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Only allow local connections to noreply account
|
||||||
|
mailserver.loginAccounts."noreply@${cfg.domainName}" = {
|
||||||
|
# password is set in private.nix
|
||||||
|
hashedPassword = cfg.hashedNoreplyPassword;
|
||||||
|
sendOnly = true;
|
||||||
|
};
|
||||||
|
services.dovecot2.extraConfig =
|
||||||
|
let passwd = builtins.toFile "dovecot2-local-passwd" ''
|
||||||
|
noreply@${cfg.domainName}:{plain}${cfg.unhashedNoreplyPassword}::::::allow_nets=local,127.0.0.0/8,::1
|
||||||
|
'';
|
||||||
|
in ''
|
||||||
|
passdb {
|
||||||
|
driver = passwd-file
|
||||||
|
args = ${passwd}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# GITEA
|
||||||
|
services.nginx.virtualHosts."git.${cfg.domainName}" = let inherit (config.services.gitea) settings; in {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/".proxyPass = "http://${quotePotentialIpV6 settings.server.HTTP_ADDR}:${toString settings.server.HTTP_PORT}";
|
||||||
|
};
|
||||||
|
services.gitea = {
|
||||||
|
enable = true;
|
||||||
|
database = {
|
||||||
|
createDatabase = false;
|
||||||
|
passwordFile = "/var/lib/gitea/db_password";
|
||||||
|
type = "postgres";
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
mailer = {
|
||||||
|
ENABLED = true;
|
||||||
|
FROM = "Gitea <noreply@${cfg.domainName}>";
|
||||||
|
MAILER_TYPE = "smtp";
|
||||||
|
HOST = "mail.${cfg.domainName}:587";
|
||||||
|
USER = "noreply@${cfg.domainName}";
|
||||||
|
PASSWD = cfg.unhashedNoreplyPassword;
|
||||||
|
SKIP_VERIFY = true;
|
||||||
|
};
|
||||||
|
session = {
|
||||||
|
COOKIE_SECURE = true;
|
||||||
|
};
|
||||||
|
server = {
|
||||||
|
ROOT_URL = "https://git.${cfg.domainName}";
|
||||||
|
HTTP_ADDR = "::1";
|
||||||
|
HTTP_PORT = 3310;
|
||||||
|
DOMAIN = "git.${cfg.domainName}";
|
||||||
|
# START_SSH_SERVER = true;
|
||||||
|
# SSH_PORT = 2222;
|
||||||
|
};
|
||||||
|
service = {
|
||||||
|
DISABLE_REGISTRATION = true;
|
||||||
|
REGISTER_EMAIL_CONFIRM = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# NEXTCLOUD
|
||||||
|
services.nginx.virtualHosts."cloud.${cfg.domainName}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
};
|
||||||
|
services.nextcloud = {
|
||||||
|
enable = true;
|
||||||
|
enableBrokenCiphersForSSE = false;
|
||||||
|
package = pkgs.nextcloud26;
|
||||||
|
autoUpdateApps.enable = true;
|
||||||
|
# TODO: use socket auth and remove the next line
|
||||||
|
database.createLocally = false;
|
||||||
|
config = {
|
||||||
|
adminpassFile = "/var/lib/nextcloud/admin_password";
|
||||||
|
dbpassFile = "/var/lib/nextcloud/db_password";
|
||||||
|
dbtype = "pgsql";
|
||||||
|
dbhost = "/run/postgresql";
|
||||||
|
overwriteProtocol = "https";
|
||||||
|
};
|
||||||
|
hostName = "cloud.${cfg.domainName}";
|
||||||
|
https = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.pleroma.path = [ pkgs.exiftool pkgs.gawk ];
|
||||||
|
services.nginx.virtualHosts."pleroma.${cfg.domainName}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/".proxyPass = "http://127.0.0.1:9970";
|
||||||
|
};
|
||||||
|
|
||||||
|
/*locations."/dns-query".extraConfig = ''
|
||||||
|
grpc_pass grpc://127.0.0.1:53453;
|
||||||
|
'';*/
|
||||||
|
|
||||||
|
# TODO: firefox sync?
|
||||||
|
}
|
51
system/hosts/nixserver/fdroid.nix
Normal file
51
system/hosts/nixserver/fdroid.nix
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{ config
|
||||||
|
, pkgs
|
||||||
|
, lib
|
||||||
|
, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.server;
|
||||||
|
quotePotentialIpV6 = addr:
|
||||||
|
if lib.hasInfix ":" addr then "[${addr}]" else addr;
|
||||||
|
in {
|
||||||
|
services.nginx.virtualHosts."${cfg.domainName}" = {
|
||||||
|
locations."/fdroid/".alias = "/var/lib/fdroid/repo/";
|
||||||
|
};
|
||||||
|
users.users.fdroid = {
|
||||||
|
home = "/var/lib/fdroid";
|
||||||
|
group = "fdroid";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
users.groups.fdroid = { };
|
||||||
|
systemd.timers.update-fdroid = {
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
partOf = [ "update-fdroid.service" ];
|
||||||
|
# slightly unusual time to reduce server load
|
||||||
|
timerConfig.OnCalendar = [ "*-*-* 00:40:00" ]; # every day
|
||||||
|
};
|
||||||
|
systemd.services.update-fdroid = {
|
||||||
|
serviceConfig = let
|
||||||
|
inherit (pkgs) fdroidserver;
|
||||||
|
fdroidScript = pkgs.writeText "update-froid.py" ''
|
||||||
|
import requests, subprocess, os, sys
|
||||||
|
|
||||||
|
x = requests.get('https://api.github.com/repos/ppy/osu/releases').json()
|
||||||
|
|
||||||
|
for q in x:
|
||||||
|
for w in q.get('assets', []):
|
||||||
|
if w.get('name', "").endswith('.apk'):
|
||||||
|
os.chdir('/var/lib/fdroid')
|
||||||
|
subprocess.run(['${pkgs.wget}/bin/wget', w['browser_download_url'], '-O', '/var/tmp/lazer.apk'], check=True)
|
||||||
|
os.rename('/var/tmp/lazer.apk', '/var/lib/fdroid/repo/sh.ppy.osulazer.apk')
|
||||||
|
subprocess.run(['${fdroidserver}/bin/fdroid', 'update', '--allow-disabled-algorithms'])
|
||||||
|
sys.exit()
|
||||||
|
'';
|
||||||
|
fdroidPython = pkgs.python3.withPackages (p: with p; [ requests ]);
|
||||||
|
in {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${fdroidPython} ${fdroidScript}";
|
||||||
|
};
|
||||||
|
environment.JAVA_HOME = "${pkgs.jdk11_headless}";
|
||||||
|
path = [ pkgs.jdk11_headless ];
|
||||||
|
};
|
||||||
|
}
|
122
system/hosts/nixserver/matrix.nix
Normal file
122
system/hosts/nixserver/matrix.nix
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
{ config
|
||||||
|
, pkgs
|
||||||
|
, lib
|
||||||
|
, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.server;
|
||||||
|
quotePotentialIpV6 = addr:
|
||||||
|
if lib.hasInfix ":" addr then "[${addr}]" else addr;
|
||||||
|
matrixServerJson = {
|
||||||
|
"m.server" = "matrix.${cfg.domainName}:443";
|
||||||
|
};
|
||||||
|
matrixClientJson = {
|
||||||
|
"m.homeserver" = { base_url = "https://matrix.${cfg.domainName}"; };
|
||||||
|
"m.identity_server" = { base_url = "https://vector.im"; };
|
||||||
|
};
|
||||||
|
matrixServerConfigResponse = ''
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
return 200 '${builtins.toJSON matrixServerJson}';
|
||||||
|
'';
|
||||||
|
matrixClientConfigResponse = ''
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
return 200 '${builtins.toJSON matrixClientJson}';
|
||||||
|
'';
|
||||||
|
matrixAddr = "::1";
|
||||||
|
matrixPort = 8008;
|
||||||
|
in {
|
||||||
|
imports = [ ./maubot.nix ];
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 8008 8448 ];
|
||||||
|
systemd.services.matrix-synapse.serviceConfig.TimeoutStartSec = 180;
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."${cfg.domainName}" = {
|
||||||
|
locations."= /.well-known/matrix/server".extraConfig = matrixServerConfigResponse;
|
||||||
|
locations."= /.well-known/matrix/client".extraConfig = matrixClientConfigResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."matrix.${cfg.domainName}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations = {
|
||||||
|
"= /.well-known/matrix/server".extraConfig = matrixServerConfigResponse;
|
||||||
|
"= /.well-known/matrix/client".extraConfig = matrixClientConfigResponse;
|
||||||
|
"/".proxyPass = "http://${quotePotentialIpV6 matrixAddr}:${toString matrixPort}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.heisenbridge.wants = [ "matrix-synapse.service" ];
|
||||||
|
systemd.services.heisenbridge.after = [ "matrix-synapse.service" ];
|
||||||
|
services.heisenbridge = {
|
||||||
|
enable = true;
|
||||||
|
homeserver = "http://${quotePotentialIpV6 matrixAddr}:${toString matrixPort}/";
|
||||||
|
};
|
||||||
|
# so synapse can read the registration
|
||||||
|
users.groups.heisenbridge.members = [ "matrix-synapse" ];
|
||||||
|
|
||||||
|
services.matrix-synapse = {
|
||||||
|
enable = true;
|
||||||
|
extraConfigFiles = [ "/var/lib/matrix-synapse/config.yaml" ];
|
||||||
|
settings = {
|
||||||
|
app_service_config_files = [
|
||||||
|
"/var/lib/heisenbridge/registration.yml"
|
||||||
|
];
|
||||||
|
allow_guest_access = true;
|
||||||
|
url_preview_enabled = true;
|
||||||
|
tls_certificate_path = config.security.acme.certs."matrix.${cfg.domainName}".directory + "/fullchain.pem";
|
||||||
|
tls_private_key_path = config.security.acme.certs."matrix.${cfg.domainName}".directory + "/key.pem";
|
||||||
|
public_baseurl = "https://matrix.${cfg.domainName}/";
|
||||||
|
server_name = "matrix.${cfg.domainName}";
|
||||||
|
max_upload_size = "100M";
|
||||||
|
email = {
|
||||||
|
smtp_host = "mail.pavluk.org";
|
||||||
|
smtp_port = 587;
|
||||||
|
smtp_user = "noreply";
|
||||||
|
smtp_password = cfg.unhashedNoreplyPassword;
|
||||||
|
notif_from = "${cfg.domainName} matrix homeserver <noreply@${cfg.domainName}>";
|
||||||
|
app_name = cfg.domainName;
|
||||||
|
notif_for_new_users = false;
|
||||||
|
enable_notifs = true;
|
||||||
|
};
|
||||||
|
listeners = [{
|
||||||
|
port = matrixPort;
|
||||||
|
bind_addresses = [ matrixAddr ];
|
||||||
|
type = "http";
|
||||||
|
tls = false;
|
||||||
|
x_forwarded = true;
|
||||||
|
resources = [{
|
||||||
|
names = [ "client" "federation" ];
|
||||||
|
compress = false;
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# maubot
|
||||||
|
users.users.maubot = {
|
||||||
|
home = "/var/lib/maubot";
|
||||||
|
group = "maubot";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
users.groups.maubot = { };
|
||||||
|
systemd.services.maubot = {
|
||||||
|
description = "Maubot";
|
||||||
|
wants = [ "matrix-synapse.service" "nginx.service" ];
|
||||||
|
after = [ "matrix-synapse.service" "nginx.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
environment = {
|
||||||
|
LD_LIBRARY_PATH = "${pkgs.stdenv.cc.cc.lib}/lib";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
User = "maubot";
|
||||||
|
Group = "maubot";
|
||||||
|
WorkingDirectory = "/var/lib/maubot/data";
|
||||||
|
};
|
||||||
|
script = "${pkgs.python3.withPackages (pks: with pks; [
|
||||||
|
pkgs.maubot (pkgs.pineapplebot.override {
|
||||||
|
magic = cfg.pizzabotMagic;
|
||||||
|
}) feedparser levenshtein python-dateutil pytz
|
||||||
|
])}/bin/python3 -m maubot";
|
||||||
|
};
|
||||||
|
}
|
45
system/hosts/nixserver/maubot.nix
Normal file
45
system/hosts/nixserver/maubot.nix
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{ config
|
||||||
|
, pkgs
|
||||||
|
, lib
|
||||||
|
, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.server;
|
||||||
|
quotePotentialIpV6 = addr:
|
||||||
|
if lib.hasInfix ":" addr then "[${addr}]" else addr;
|
||||||
|
# i've yet to create a maubot module so this is hardcoded
|
||||||
|
maubotAddr = "127.0.0.1";
|
||||||
|
maubotPort = 29316;
|
||||||
|
in {
|
||||||
|
services.nginx.virtualHosts."matrix.${cfg.domainName}".locations = {
|
||||||
|
"/_matrix/maubot/" = {
|
||||||
|
proxyPass = "http://${quotePotentialIpV6 maubotAddr}:${toString maubotPort}";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
users.users.maubot = {
|
||||||
|
home = "/var/lib/maubot";
|
||||||
|
group = "maubot";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
users.groups.maubot = { };
|
||||||
|
systemd.services.maubot = {
|
||||||
|
description = "Maubot";
|
||||||
|
wants = [ "matrix-synapse.service" "nginx.service" ];
|
||||||
|
after = [ "matrix-synapse.service" "nginx.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
environment = {
|
||||||
|
LD_LIBRARY_PATH = "${pkgs.stdenv.cc.cc.lib}/lib";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
User = "maubot";
|
||||||
|
Group = "maubot";
|
||||||
|
WorkingDirectory = "/var/lib/maubot/data";
|
||||||
|
};
|
||||||
|
script = "${pkgs.python3.withPackages (pks: with pks; [
|
||||||
|
pkgs.maubot (pkgs.pineapplebot.override {
|
||||||
|
magic = cfg.pizzabotMagic;
|
||||||
|
}) feedparser levenshtein python-dateutil pytz
|
||||||
|
])}/bin/python3 -m maubot";
|
||||||
|
};
|
||||||
|
}
|
81
system/hosts/nixserver/mumble.nix
Normal file
81
system/hosts/nixserver/mumble.nix
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.server;
|
||||||
|
quotePotentialIpV6 = addr:
|
||||||
|
if lib.hasInfix ":" addr then "[${addr}]" else addr;
|
||||||
|
in {
|
||||||
|
services.murmur = {
|
||||||
|
enable = true;
|
||||||
|
imgMsgLength = 0;
|
||||||
|
textMsgLength = 0;
|
||||||
|
registerName = "mumble.${cfg.domainName}";
|
||||||
|
registerHostname = "mumble.${cfg.domainName}";
|
||||||
|
sslCa = config.security.acme.certs."mumble.${cfg.domainName}".directory + "/chain.pem";
|
||||||
|
sslCert = config.security.acme.certs."mumble.${cfg.domainName}".directory + "/fullchain.pem";
|
||||||
|
sslKey = config.security.acme.certs."mumble.${cfg.domainName}".directory + "/key.pem";
|
||||||
|
# clientCertRequired = true;
|
||||||
|
extraConfig = ''
|
||||||
|
bandwidth=320000
|
||||||
|
opusthreshold=0
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
# Allow murmur to read the certificate
|
||||||
|
security.acme.certs."mumble.${cfg.domainName}" = {
|
||||||
|
group = "nginxandmurmur";
|
||||||
|
postRun = "systemctl try-reload-or-restart murmur";
|
||||||
|
};
|
||||||
|
users.groups.nginxandmurmur.members = [ "murmur" "nginx" ];
|
||||||
|
|
||||||
|
# Mumble music bot
|
||||||
|
services.nginx.virtualHosts."mumble.${cfg.domainName}" = let inherit (config.services.botamusique) settings; in {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
globalRedirect = cfg.domainName;
|
||||||
|
locations."/music".extraConfig = "return 301 https://mumble.${cfg.domainName}/music/;";
|
||||||
|
locations."/music/".proxyPass = "http://${quotePotentialIpV6 settings.webinterface.listening_addr}:${toString settings.webinterface.listening_port}/";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.botamusique = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
youtube_dl = {
|
||||||
|
cookiefile = "/var/lib/botamusique/cookie_ydl";
|
||||||
|
};
|
||||||
|
webinterface = {
|
||||||
|
enabled = true;
|
||||||
|
listening_addr = "::1";
|
||||||
|
listening_port = 8181;
|
||||||
|
is_web_proxified = true;
|
||||||
|
access_address = "https://mumble.${cfg.domainName}/music";
|
||||||
|
auth_method = "token";
|
||||||
|
upload_enabled = true;
|
||||||
|
max_upload_file_size = "100MB";
|
||||||
|
delete_allowed = true;
|
||||||
|
};
|
||||||
|
bot = {
|
||||||
|
bandwidth = 200000;
|
||||||
|
volume = 1.0;
|
||||||
|
ducking = true;
|
||||||
|
ducking_volume = 0.75;
|
||||||
|
};
|
||||||
|
server.certificate = "/var/lib/botamusique/cert.pem";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.botamusique.wants = [ "murmur.service" ];
|
||||||
|
systemd.services.botamusique.after = [ "murmur.service" ];
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
allowedTCPPorts = [
|
||||||
|
64738
|
||||||
|
# Used for mumble-web signaling (not sure if it needs TCP or UDP)
|
||||||
|
# 20000 20001 20002 20003 20004 20005 20006 20007 20008 20009 20010
|
||||||
|
];
|
||||||
|
allowedUDPPorts = [
|
||||||
|
64738
|
||||||
|
# 20000 20001 20002 20003 20004 20005 20006 20007 20008 20009 20010
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
58
system/hosts/nixserver/options.nix
Normal file
58
system/hosts/nixserver/options.nix
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{ lib
|
||||||
|
, ... }:
|
||||||
|
{
|
||||||
|
options.server = with lib; mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
options = {
|
||||||
|
domainName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "pavluk.org";
|
||||||
|
description = "domain name";
|
||||||
|
};
|
||||||
|
lanCidrV4 = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "LAN mask (IPv4)";
|
||||||
|
example = "192.168.1.0/96";
|
||||||
|
default = "0.0.0.0/0";
|
||||||
|
};
|
||||||
|
lanCidrV6 = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "LAN mask (IPv6)";
|
||||||
|
example = "fd01:abcd::/64";
|
||||||
|
default = "::/0";
|
||||||
|
};
|
||||||
|
localIpV4 = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
description = "server's local IPv4 address";
|
||||||
|
example = "192.168.1.2";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
localIpV6 = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
description = "server's local IPv6 address";
|
||||||
|
example = "fd01:abcd::2";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
noreplyPassword = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "noreply (only available via localhost) account password";
|
||||||
|
default = "totallysafe";
|
||||||
|
};
|
||||||
|
hashedNoreplyPassword = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "hashed noreply password via mkpasswd -sm bcrypt";
|
||||||
|
};
|
||||||
|
unhashedNoreplyPassword = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "unhashed noreply password. \
|
||||||
|
This should preferably be different from the password that is hashed for better security (yes, really)";
|
||||||
|
};
|
||||||
|
pizzabotMagic = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "<PIZZABOT_MAGIC_SEP>";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
description = "server settings";
|
||||||
|
};
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
config.programs.ccache.cacheDir
|
config.programs.ccache.cacheDir
|
||||||
"/var/cache/sccache"
|
"/var/cache/sccache"
|
||||||
];
|
];
|
||||||
environment.persistence."/persist".directories = lib.mkIf config.programs.ccache.enable [
|
impermanence.directories = lib.mkIf config.programs.ccache.enable [
|
||||||
config.programs.ccache.cacheDir
|
config.programs.ccache.cacheDir
|
||||||
"/var/cache/sccache"
|
"/var/cache/sccache"
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.impermanence;
|
cfg = config.impermanence;
|
||||||
|
@ -16,7 +16,7 @@ in {
|
||||||
description = "Default path for persistence";
|
description = "Default path for persistence";
|
||||||
};
|
};
|
||||||
directories = mkOption {
|
directories = mkOption {
|
||||||
type = with types; listOf path;
|
type = with types; listOf (either path attrs);
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = "Extra directories to persist";
|
description = "Extra directories to persist";
|
||||||
};
|
};
|
||||||
|
@ -36,41 +36,90 @@ in {
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
# why is this not part of base NixOS?
|
||||||
|
systemd.tmpfiles.rules = [ "d /var/lib/systemd/pstore 0755 root root 14d" ];
|
||||||
# as weird as it sounds, I won't use tmpfs for /tmp in case I'll have to put files over 2GB there
|
# as weird as it sounds, I won't use tmpfs for /tmp in case I'll have to put files over 2GB there
|
||||||
boot.tmp.cleanOnBoot = lib.mkIf cfg.persistTmp true;
|
boot.tmp.cleanOnBoot = lib.mkIf cfg.persistTmp true;
|
||||||
environment.persistence.${toString cfg.path} = {
|
environment.persistence.${toString cfg.path} = {
|
||||||
hideMounts = true;
|
hideMounts = true;
|
||||||
directories = map toString ([
|
directories = map (x:
|
||||||
|
if builtins.isPath x then toString x
|
||||||
|
else if builtins.isAttrs x && x?directory && builtins.isPath x.directory then x // { directory = toString x.directory; }
|
||||||
|
else x)
|
||||||
|
([
|
||||||
# nixos files
|
# nixos files
|
||||||
/etc/nixos
|
{ directory = /etc/nixos; user = "root"; group = "root"; mode = "0755"; }
|
||||||
/var/lib/nixos
|
{ directory = /var/lib/nixos; user = "root"; group = "root"; mode = "0755"; }
|
||||||
|
|
||||||
/var/log
|
{ directory = /var/log; user = "root"; group = "root"; mode = "0755"; }
|
||||||
|
|
||||||
# persist this since everything here is cleaned up by systemd-tmpfiles over time anyway
|
# persist this since everything here is cleaned up by systemd-tmpfiles over time anyway
|
||||||
# ...or so I'd like to believe
|
# ...or so I'd like to believe
|
||||||
/var/lib/systemd
|
{ directory = /var/lib/systemd; user = "root"; group = "root"; mode = "0755"; }
|
||||||
/var/tmp
|
{ directory = /var/tmp; user = "root"; group = "root"; mode = "1777"; }
|
||||||
|
{ directory = /var/spool; user = "root"; group = "root"; mode = "0777"; }
|
||||||
] ++ (lib.optionals cfg.persistTmp [
|
] ++ (lib.optionals cfg.persistTmp [
|
||||||
/tmp
|
{ directory = /tmp; user = "root"; group = "root"; mode = "1777"; }
|
||||||
]) ++ (lib.optionals config.services.mullvad-vpn.enable [
|
]) ++ (lib.optionals config.services.mullvad-vpn.enable [
|
||||||
/etc/mullvad-vpn
|
{ directory = /etc/mullvad-vpn; user = "root"; group = "root"; mode = "0700"; }
|
||||||
/var/cache/mullvad-vpn
|
{ directory = /var/cache/mullvad-vpn; user = "root"; group = "root"; mode = "0755"; }
|
||||||
]) ++ (lib.optionals config.virtualisation.libvirtd.enable ([
|
]) ++ (lib.optionals config.virtualisation.libvirtd.enable ([
|
||||||
/var/cache/libvirt
|
# { directory = /var/cache/libvirt; user = "root"; group = "root"; mode = "0755"; }
|
||||||
/var/lib/libvirt
|
{ directory = /var/lib/libvirt; user = "root"; group = "root"; mode = "0755"; }
|
||||||
] ++ (lib.optionals config.virtualisation.libvirtd.qemu.swtpm.enable [
|
] ++ (lib.optionals config.virtualisation.libvirtd.qemu.swtpm.enable [
|
||||||
/var/lib/swtpm-localca
|
{ directory = /var/lib/swtpm-localca; user = "root"; group = "root"; mode = "0750"; }
|
||||||
]))) ++ (lib.optionals config.networking.wireless.iwd.enable [
|
]))) ++ (lib.optionals config.networking.wireless.iwd.enable [
|
||||||
/var/lib/iwd
|
{ directory = /var/lib/iwd; user = "root"; group = "root"; mode = "0700"; }
|
||||||
]) ++ (lib.optionals (builtins.any (x: x.useDHCP) (builtins.attrValues config.networking.interfaces) || config.networking.useDHCP) [
|
]) ++ (lib.optionals (builtins.any (x: x.useDHCP) (builtins.attrValues config.networking.interfaces) || config.networking.useDHCP) [
|
||||||
/var/db/dhcpcd
|
{ directory = /var/db/dhcpcd; user = "root"; group = "root"; mode = "0755"; }
|
||||||
|
]) ++ (lib.optionals config.services.gitea.enable [
|
||||||
|
{ directory = /var/lib/gitea; user = "gitea"; group = "gitea"; mode = "0755"; }
|
||||||
|
]) ++ (lib.optionals config.services.matrix-synapse.enable [
|
||||||
|
{ directory = /var/lib/matrix-synapse; user = "matrix-synapse"; group = "matrix-synapse"; mode = "0700"; }
|
||||||
|
]) ++ (lib.optionals config.services.heisenbridge.enable [
|
||||||
|
{ directory = /var/lib/heisenbridge; user = "heisenbridge"; group = "heisenbridge"; mode = "0755"; }
|
||||||
|
]) ++ (lib.optionals config.services.murmur.enable [
|
||||||
|
{ directory = /var/lib/murmur; user = "murmur"; group = "murmur"; mode = "0700"; }
|
||||||
|
]) ++ (lib.optionals config.services.nextcloud.enable [
|
||||||
|
{ directory = /var/lib/nextcloud; user = "nextcloud"; group = "nextcloud"; mode = "0750"; }
|
||||||
|
]) ++ (lib.optionals config.services.botamusique.enable [
|
||||||
|
{ directory = /var/lib/private/botamusique; user = "root"; group = "root"; mode = "0750"; }
|
||||||
|
]) ++ (lib.optionals config.security.acme.acceptTerms [
|
||||||
|
{ directory = /var/lib/acme; user = "acme"; group = "acme"; mode = "0755"; }
|
||||||
|
]) ++ (lib.optionals config.services.printing.enable [
|
||||||
|
{ directory = /var/lib/cups; user = "root"; group = "root"; mode = "0755"; }
|
||||||
|
]) ++ (lib.optionals config.services.fail2ban.enable [
|
||||||
|
{ directory = /var/lib/fail2ban; user = "fail2ban"; group = "fail2ban"; mode = "0750"; }
|
||||||
|
]) ++ (lib.optionals config.services.opendkim.enable [
|
||||||
|
{ directory = /var/lib/opendkim; user = "opendkim"; group = "opendkim"; mode = "0700"; }
|
||||||
|
]) ++ (lib.optionals config.services.pleroma.enable [
|
||||||
|
{ directory = /var/lib/pleroma; user = "pleroma"; group = "pleroma"; mode = "0700"; }
|
||||||
|
]) ++ (lib.optionals config.services.postfix.enable [
|
||||||
|
{ directory = /var/lib/postfix; user = "root"; group = "root"; mode = "0755"; }
|
||||||
|
]) ++ (lib.optionals config.services.postgresql.enable [
|
||||||
|
{ directory = /var/lib/postgresql; user = "postgres"; group = "postgres"; mode = "0755"; }
|
||||||
|
]) ++ (lib.optionals config.services.unbound.enable [
|
||||||
|
{ directory = /var/lib/unbound; user = "unbound"; group = "unbound"; mode = "0755"; }
|
||||||
|
]) ++ (lib.optionals config.services.roundcube.enable [
|
||||||
|
{ directory = /var/lib/roundcube; user = "roundcube"; group = "roundcube"; mode = "0700"; }
|
||||||
|
]) ++ (lib.optionals config.services.rspamd.enable [
|
||||||
|
{ directory = /var/lib/rspamd; user = "rspamd"; group = "rspamd"; mode = "0700"; }
|
||||||
|
]) ++ (lib.optionals (
|
||||||
|
(builtins.hasAttr "rspamd" config.services.redis.servers)
|
||||||
|
&& (builtins.hasAttr "enable" config.services.redis.servers.rspamd)
|
||||||
|
&& config.services.redis.servers.rspamd.enable
|
||||||
|
) [
|
||||||
|
{ directory = /var/lib/redis-rspamd; user = "redis-rspamd"; group = "redis-rspamd"; mode = "0700"; }
|
||||||
|
]) ++ (lib.optionals config.services.dovecot2.enable [
|
||||||
|
{ directory = /var/lib/dhparams; user = "root"; group = "root"; mode = "0755"; }
|
||||||
|
{ directory = /var/lib/dovecot; user = "root"; group = "root"; mode = "0755"; }
|
||||||
]) ++ (lib.optionals config.security.sudo.enable [
|
]) ++ (lib.optionals config.security.sudo.enable [
|
||||||
/var/db/sudo/lectured
|
{ directory = /var/db/sudo/lectured; user = "root"; group = "root"; mode = "0700"; }
|
||||||
]) ++ cfg.directories);
|
]) ++ cfg.directories);
|
||||||
files = map toString ([
|
files = map toString ([
|
||||||
# hardware-related
|
# hardware-related
|
||||||
/etc/adjtime
|
/etc/adjtime
|
||||||
|
# needed at least for /var/log
|
||||||
/etc/machine-id
|
/etc/machine-id
|
||||||
] ++ cfg.files);
|
] ++ cfg.files);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ options, config, lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.vfio;
|
cfg = config.vfio;
|
||||||
in {
|
in {
|
||||||
|
@ -73,9 +73,10 @@ in {
|
||||||
description = "VFIO settings";
|
description = "VFIO settings";
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
|
# compatibility so this module loads on non-amd hardware
|
||||||
config = let
|
config = let
|
||||||
enableIvshmem = config.vfio.lookingGlass.enable && (builtins.length config.vfio.lookingGlass.ivshmem) > 0;
|
enableIvshmem = cfg.lookingGlass.enable && (builtins.length cfg.lookingGlass.ivshmem) > 0;
|
||||||
in lib.mkIf config.vfio.enable {
|
in lib.mkIf cfg.enable {
|
||||||
# add a custom kernel param for early loading vfio drivers
|
# add a custom kernel param for early loading vfio drivers
|
||||||
# because if we change boot.initrd options in a specialization, two initrds will be built
|
# because if we change boot.initrd options in a specialization, two initrds will be built
|
||||||
# and we don't want to build two initrds
|
# and we don't want to build two initrds
|
||||||
|
@ -151,9 +152,13 @@ in {
|
||||||
SUBSYSTEM=="kvmfr", KERNEL=="kvmfr${toString i}", OWNER="${ivshmem.owner}", GROUP="kvm", MODE="0660"
|
SUBSYSTEM=="kvmfr", KERNEL=="kvmfr${toString i}", OWNER="${ivshmem.owner}", GROUP="kvm", MODE="0660"
|
||||||
'')
|
'')
|
||||||
cfg.lookingGlass.ivshmem));
|
cfg.lookingGlass.ivshmem));
|
||||||
|
hardware = {
|
||||||
|
opengl.enable = true;
|
||||||
|
} // (lib.optionalAttrs (cfg.enable && !(cfg.nvidiaGpu)) {
|
||||||
# disable early KMS so GPU can be properly unbound
|
# disable early KMS so GPU can be properly unbound
|
||||||
hardware.amdgpu.loadInInitrd = lib.mkIf (!cfg.nvidiaGpu) false;
|
# can't use mkif because the option may not even exist
|
||||||
hardware.opengl.enable = true;
|
amdgpu.loadInInitrd = false;
|
||||||
|
});
|
||||||
# needed for virt-manager
|
# needed for virt-manager
|
||||||
programs.dconf.enable = true;
|
programs.dconf.enable = true;
|
||||||
virtualisation.libvirtd = {
|
virtualisation.libvirtd = {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
{ pkgs, ... }: let inherit (pkgs) callPackage; in {
|
{ pkgs, ... }: let inherit (pkgs) callPackage; in {
|
||||||
system76-scheduler = callPackage ../pkgs/system76-scheduler.nix { };
|
system76-scheduler = callPackage ./system76-scheduler.nix { };
|
||||||
|
maubot = callPackage ./maubot.nix { };
|
||||||
|
pineapplebot = callPackage ./pineapplebot.nix { };
|
||||||
}
|
}
|
||||||
|
|
95
system/pkgs/maubot.nix
Normal file
95
system/pkgs/maubot.nix
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
{ lib
|
||||||
|
, fetchpatch
|
||||||
|
, python3
|
||||||
|
, runCommand
|
||||||
|
, encryptionSupport ? true
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
python = python3.override {
|
||||||
|
packageOverrides = self: super: {
|
||||||
|
sqlalchemy = super.buildPythonPackage rec {
|
||||||
|
pname = "SQLAlchemy";
|
||||||
|
version = "1.3.24";
|
||||||
|
|
||||||
|
src = super.fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "sha256-67t3fL+TEjWbiXv4G6ANrg9ctp+6KhgmXcwYpvXvdRk=";
|
||||||
|
};
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
sed -e 's:--max-worker-restart=5::g' -i setup.cfg
|
||||||
|
'';
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
self = with python.pkgs; buildPythonPackage rec {
|
||||||
|
pname = "maubot";
|
||||||
|
version = "0.4.1";
|
||||||
|
disabled = pythonOlder "3.8";
|
||||||
|
|
||||||
|
src = fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "sha256-Ro2PPgF8818F8JewPZ3AlbfWFNNHKTZkQq+1zpm3kk4=";
|
||||||
|
};
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
# add entry point
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://patch-diff.githubusercontent.com/raw/maubot/maubot/pull/146.patch";
|
||||||
|
sha256 = "0yn5357z346qzy5v5g124mgiah1xsi9yyfq42zg028c8paiw8s8x";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
propagatedBuildInputs = [
|
||||||
|
# requirements.txt
|
||||||
|
mautrix
|
||||||
|
aiohttp
|
||||||
|
yarl
|
||||||
|
sqlalchemy
|
||||||
|
asyncpg
|
||||||
|
aiosqlite
|
||||||
|
CommonMark
|
||||||
|
ruamel-yaml
|
||||||
|
attrs
|
||||||
|
bcrypt
|
||||||
|
packaging
|
||||||
|
click
|
||||||
|
colorama
|
||||||
|
questionary
|
||||||
|
jinja2
|
||||||
|
]
|
||||||
|
# optional-requirements.txt
|
||||||
|
++ lib.optionals encryptionSupport [
|
||||||
|
python-olm
|
||||||
|
pycryptodome
|
||||||
|
unpaddedbase64
|
||||||
|
];
|
||||||
|
|
||||||
|
passthru.tests = {
|
||||||
|
simple = runCommand "${pname}-tests" { } ''
|
||||||
|
${self}/bin/mbc --help > $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Setuptools is trying to do python -m maubot test
|
||||||
|
dontUseSetuptoolsCheck = true;
|
||||||
|
|
||||||
|
pythonImportsCheck = [
|
||||||
|
"maubot"
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "A plugin-based Matrix bot system written in Python";
|
||||||
|
homepage = "https://github.com/maubot/maubot";
|
||||||
|
changelog = "https://github.com/maubot/maubot/blob/v${version}/CHANGELOG.md";
|
||||||
|
license = licenses.agpl3Plus;
|
||||||
|
maintainers = with maintainers; [ chayleaf ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
self
|
34
system/pkgs/pineapplebot.nix
Normal file
34
system/pkgs/pineapplebot.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{ python3
|
||||||
|
, fetchFromGitHub
|
||||||
|
, rustPlatform
|
||||||
|
, magic ? "<PIZZABOT_MAGIC_SEP>"
|
||||||
|
, ... }:
|
||||||
|
|
||||||
|
python3.pkgs.buildPythonPackage rec {
|
||||||
|
pname = "pineapplebot";
|
||||||
|
version = "0.1.0";
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "chayleaf";
|
||||||
|
repo = "pizzabot_v3";
|
||||||
|
rev = "master";
|
||||||
|
sha256 = "sha256-ZLskMlllZfmqIlbSr0pNHHJehDycohiwqgYbuEYP7Qc=";
|
||||||
|
};
|
||||||
|
preBuild = ''
|
||||||
|
head -n13 Cargo.toml > Cargo.toml.new
|
||||||
|
mv Cargo.toml.new Cargo.toml
|
||||||
|
'';
|
||||||
|
sourceRoot = "source/pineapplebot";
|
||||||
|
cargoDeps = rustPlatform.fetchCargoTarball {
|
||||||
|
inherit src sourceRoot;
|
||||||
|
name = "${pname}-${version}";
|
||||||
|
sha256 = "14jxgykwg1apy97gy1j8mz7ny2cqg4q9s03a2bk9kx2y6ibm4668";
|
||||||
|
};
|
||||||
|
nativeBuildInputs = with rustPlatform; [
|
||||||
|
cargoSetupHook
|
||||||
|
maturinBuildHook
|
||||||
|
];
|
||||||
|
doCheck = false;
|
||||||
|
doInstallCheck = true;
|
||||||
|
pythonImportsCheck = [ "pineapplebot" ];
|
||||||
|
PIZZABOT_MAGIC = magic;
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
nixmsi = { ... }: {
|
|
||||||
# insert private config here
|
|
||||||
};
|
|
||||||
}
|
|
9
system/private.sample.nix
Normal file
9
system/private.sample.nix
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
nixmsi = { pkgs, lib, ... }: {
|
||||||
|
# insert private config here
|
||||||
|
# time.timeZone = ...;
|
||||||
|
# users.users.root.initialHashedPassword = ...;
|
||||||
|
# users.users.user.initialHashedPassword = ...;
|
||||||
|
};
|
||||||
|
nixserver = { ... }: { };
|
||||||
|
}
|
Loading…
Reference in a new issue