/sys/machines -> /hosts
This commit is contained in:
parent
2c475dd099
commit
9c9a3d543c
38 changed files with 2 additions and 2 deletions
71
hosts/hopper/default.nix
Normal file
71
hosts/hopper/default.nix
Normal file
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
inputs,
|
||||
systemProfiles,
|
||||
specialArgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports =
|
||||
[
|
||||
inputs.hardware.nixosModules.common-cpu-intel
|
||||
inputs.vpn-confinement.nixosModules.default
|
||||
inputs.nix-minecraft.nixosModules.minecraft-servers
|
||||
inputs.impermanence.nixosModules.impermanence
|
||||
|
||||
./hardware.nix
|
||||
./lab
|
||||
./roblox-playtime.nix
|
||||
./desktop.nix
|
||||
./persistent.nix
|
||||
|
||||
{
|
||||
home-manager = {
|
||||
backupFileExtension = "hm-backup";
|
||||
users.desktop.imports = [
|
||||
./home.nix
|
||||
{home.stateVersion = "24.11";}
|
||||
];
|
||||
extraSpecialArgs = specialArgs;
|
||||
};
|
||||
}
|
||||
]
|
||||
++ (map (x: systemProfiles + x) [
|
||||
/programs/home-manager.nix
|
||||
|
||||
/core/security.nix
|
||||
/core/locale.nix
|
||||
/core/tools.nix
|
||||
/core/ssh.nix
|
||||
/core/deploy.nix
|
||||
|
||||
/hardware/graphics.nix
|
||||
/hardware/steam-hardware.nix
|
||||
/hardware/bluetooth.nix
|
||||
|
||||
/nix/default.nix # TODO slim this down
|
||||
/nix/gc.nix
|
||||
|
||||
/network/tailscale.nix
|
||||
/network/avahi.nix
|
||||
/network/networkd.nix
|
||||
]);
|
||||
|
||||
nixpkgs.config = {
|
||||
allowUnfreePredicate = pkg:
|
||||
builtins.elem (lib.getName pkg) [
|
||||
"nvidia-x11"
|
||||
"nvidia-settings"
|
||||
|
||||
"stremio-shell"
|
||||
"stremio-server"
|
||||
];
|
||||
};
|
||||
|
||||
networking.hostName = "hopper";
|
||||
|
||||
swapDevices = [];
|
||||
|
||||
networking.interfaces.eno1.wakeOnLan.enable = true;
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
}
|
39
hosts/hopper/desktop.nix
Normal file
39
hosts/hopper/desktop.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
users.users.desktop = {
|
||||
isNormalUser = true;
|
||||
useDefaultShell = true;
|
||||
createHome = true;
|
||||
extraGroups = [
|
||||
"input"
|
||||
"video"
|
||||
"render"
|
||||
"audio"
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
firefox
|
||||
];
|
||||
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
settings = {
|
||||
default_session = {
|
||||
command = lib.getExe config.programs.sway.package;
|
||||
user = "desktop";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.sway = {
|
||||
enable = true;
|
||||
wrapperFeatures.gtk = true;
|
||||
extraOptions = ["--unsupported-gpu"];
|
||||
};
|
||||
}
|
92
hosts/hopper/hardware.nix
Normal file
92
hosts/hopper/hardware.nix
Normal file
|
@ -0,0 +1,92 @@
|
|||
{lib, ...}: {
|
||||
nixpkgs.hostPlatform.system = "x86_64-linux";
|
||||
|
||||
## nvidia gpu
|
||||
services.xserver.videoDrivers = ["nvidia"];
|
||||
hardware.nvidia = {
|
||||
open = false;
|
||||
};
|
||||
|
||||
#hardware.nvidia = {
|
||||
# modesetting.enable = true;
|
||||
# package = config.boot.kernelPackages.nvidiaPackages.stable;
|
||||
#};
|
||||
|
||||
boot = {
|
||||
blacklistedKernelModules = [
|
||||
"xhci_pci" # was causing issues (100% udevd cpu usage)
|
||||
];
|
||||
initrd = {
|
||||
availableKernelModules = [
|
||||
"ehci_pci"
|
||||
"ahci"
|
||||
"usb_storage"
|
||||
"usbhid"
|
||||
"sd_mod"
|
||||
];
|
||||
kernelModules = [];
|
||||
};
|
||||
kernelModules = ["kvm-intel" "wireguard"];
|
||||
extraModulePackages = [];
|
||||
loader = {
|
||||
systemd-boot = {
|
||||
enable = true;
|
||||
configurationLimit = 10;
|
||||
};
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
};
|
||||
|
||||
boot.initrd.postResumeCommands = lib.mkAfter ''
|
||||
mkdir /btrfs_tmp
|
||||
mount /dev/disk/by-uuid/1297e638-f2ff-49a2-a362-314ac7eeaabc /btrfs_tmp
|
||||
if [[ -e /btrfs_tmp/root ]]; then
|
||||
mkdir -p /btrfs_tmp/old_roots
|
||||
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
|
||||
mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
|
||||
fi
|
||||
|
||||
delete_subvolume_recursively() {
|
||||
IFS=$'\n'
|
||||
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
|
||||
delete_subvolume_recursively "/btrfs_tmp/$i"
|
||||
done
|
||||
btrfs subvolume delete "$1"
|
||||
}
|
||||
|
||||
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do
|
||||
delete_subvolume_recursively "$i"
|
||||
done
|
||||
|
||||
btrfs subvolume create /btrfs_tmp/root
|
||||
umount /btrfs_tmp
|
||||
'';
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/1297e638-f2ff-49a2-a362-314ac7eeaabc";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=root" "compress=zstd" "autodefrag" "noatime"];
|
||||
};
|
||||
"/home" = {
|
||||
device = "/dev/disk/by-uuid/1297e638-f2ff-49a2-a362-314ac7eeaabc";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=home" "compress=zstd"];
|
||||
};
|
||||
"/nix" = {
|
||||
device = "/dev/disk/by-uuid/1297e638-f2ff-49a2-a362-314ac7eeaabc";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=nix" "compress=zstd" "noatime"];
|
||||
};
|
||||
"/persist" = {
|
||||
device = "/dev/disk/by-uuid/1297e638-f2ff-49a2-a362-314ac7eeaabc";
|
||||
neededForBoot = true;
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=persist" "compress=zstd"];
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/8D4C-2F05";
|
||||
fsType = "vfat";
|
||||
};
|
||||
};
|
||||
}
|
41
hosts/hopper/home.nix
Normal file
41
hosts/hopper/home.nix
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
homeProfiles,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
imports = map (x: homeProfiles + x) [
|
||||
/terminal/programs/xdg.nix
|
||||
/terminal/programs/comma.nix
|
||||
|
||||
/editors/nvim.nix
|
||||
/terminal/emulator/foot.nix
|
||||
|
||||
/programs/desktop/default.nix
|
||||
/programs/desktop/sway/default.nix
|
||||
|
||||
/programs/media/mpv.nix
|
||||
|
||||
/services/playerctl.nix
|
||||
/services/polkit-agent.nix
|
||||
];
|
||||
|
||||
wayland.windowManager.sway.config.output."HDMI-A-1".scale = "2.0";
|
||||
|
||||
services = {
|
||||
udiskie.enable = true;
|
||||
};
|
||||
home.packages = with pkgs; [
|
||||
pwvucontrol
|
||||
qpwgraph
|
||||
|
||||
stremio
|
||||
moonlight-qt
|
||||
];
|
||||
|
||||
home = {
|
||||
username = "desktop";
|
||||
homeDirectory = lib.mkForce "/home/desktop";
|
||||
};
|
||||
programs.home-manager.enable = true;
|
||||
}
|
25
hosts/hopper/lab/acme.nix
Normal file
25
hosts/hopper/lab/acme.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
config,
|
||||
vars,
|
||||
...
|
||||
}: let
|
||||
inherit (vars) domain;
|
||||
in {
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "xunuwu@gmail.com";
|
||||
certs = {
|
||||
"${domain}" = {
|
||||
domain = "${domain}";
|
||||
extraDomainNames = ["*.${domain}" "*.hopper.priv.${domain}"];
|
||||
dnsProvider = "cloudflare";
|
||||
reloadServices = ["caddy.service"];
|
||||
credentialFiles = {
|
||||
CF_DNS_API_TOKEN_FILE = config.sops.secrets.cloudflare.path;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/var/lib/acme"];
|
||||
}
|
11
hosts/hopper/lab/audiobookshelf.nix
Normal file
11
hosts/hopper/lab/audiobookshelf.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{config, ...}: {
|
||||
services.audiobookshelf = {
|
||||
enable = true;
|
||||
host = "0.0.0.0";
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/var/lib/${config.services.audiobookshelf.dataDir}"];
|
||||
services.restic.backups.hopper.paths = [
|
||||
"/var/lib/${config.services.audiobookshelf.dataDir}"
|
||||
];
|
||||
}
|
73
hosts/hopper/lab/caddy.nix
Normal file
73
hosts/hopper/lab/caddy.nix
Normal file
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
config,
|
||||
vars,
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (vars) domain;
|
||||
bridge = config.vpnNamespaces."wg".bridgeAddress;
|
||||
in {
|
||||
systemd.services.caddy.vpnConfinement = {
|
||||
enable = true;
|
||||
vpnNamespace = "wg";
|
||||
};
|
||||
|
||||
systemd.services.caddy = {
|
||||
environment.CADDY_ADMIN = "0.0.0.0:2019";
|
||||
serviceConfig.RuntimeDirectory = "caddy";
|
||||
};
|
||||
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
globalConfig = "metrics";
|
||||
virtualHosts = let
|
||||
mkPublicEntry = name: destination: {
|
||||
hostName = "${name}.${domain}:80";
|
||||
extraConfig = ''
|
||||
reverse_proxy {
|
||||
to ${destination}
|
||||
}
|
||||
'';
|
||||
};
|
||||
mkPrivateEntry = name: destination: {
|
||||
hostName = "${name}.hopper.priv.${domain}";
|
||||
useACMEHost = domain;
|
||||
extraConfig = ''
|
||||
@blocked not remote_ip ${bridge}
|
||||
respond @blocked "limited to intranet" 403
|
||||
reverse_proxy ${destination}
|
||||
'';
|
||||
};
|
||||
in {
|
||||
navidrome = mkPublicEntry "navidrome" "${bridge}:${toString config.services.navidrome.settings.Port}";
|
||||
vaultwarden = mkPublicEntry "vw" "${bridge}:${toString config.services.vaultwarden.config.ROCKET_PORT}";
|
||||
abs = mkPublicEntry "abs" "${bridge}:${toString config.services.audiobookshelf.port}";
|
||||
|
||||
navidrome2 = mkPrivateEntry "navidrome" "${bridge}:${toString config.services.navidrome.settings.Port}";
|
||||
slskd = mkPrivateEntry "slskd" "localhost:${toString config.services.slskd.settings.web.port}";
|
||||
prometheus = mkPrivateEntry "prometheus" "${bridge}:${toString config.services.prometheus.port}";
|
||||
transmission = mkPrivateEntry "transmission" "localhost:${toString config.services.transmission.settings.rpc-port}";
|
||||
dash = mkPrivateEntry "dash" "${bridge}:${toString config.services.homepage-dashboard.listenPort}";
|
||||
absPriv = mkPrivateEntry "abs" "${bridge}:${toString config.services.audiobookshelf.port}";
|
||||
glances = mkPrivateEntry "glances" "${bridge}:${toString config.services.glances.port}";
|
||||
|
||||
base = {
|
||||
hostName = "${domain}:80";
|
||||
extraConfig = ''
|
||||
root * ${inputs.own-website.packages.${pkgs.system}.default}
|
||||
file_server
|
||||
'';
|
||||
};
|
||||
|
||||
other = {
|
||||
hostName = "*.${domain}:80";
|
||||
extraConfig = ''
|
||||
respond 404 {
|
||||
body "uhh that doesnt exist, i hope this isnt my fault.."
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
33
hosts/hopper/lab/default.nix
Normal file
33
hosts/hopper/lab/default.nix
Normal file
|
@ -0,0 +1,33 @@
|
|||
## TODO look into sops-nix placeholders
|
||||
## reference: https://github.com/javigomezo/nixos/blob/b3ebe8d570ea9b37aea8bb3a343f6e16e054e322/services/network/authelia/user_database.nix
|
||||
{
|
||||
imports = [
|
||||
./acme.nix
|
||||
./audiobookshelf.nix
|
||||
./caddy.nix
|
||||
./dnsmasq.nix
|
||||
./glances.nix
|
||||
./homepage.nix
|
||||
./minecraft.nix
|
||||
./navidrome
|
||||
./prometheus.nix
|
||||
./restic.nix
|
||||
./samba.nix
|
||||
./slskd.nix
|
||||
./transmission.nix
|
||||
./vaultwarden.nix
|
||||
./vpn-namespace.nix
|
||||
];
|
||||
|
||||
users.groups.media = {};
|
||||
users.users.media = {
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
allowedUDPPorts = [1900 7359]; # Jellyfin auto-discovery
|
||||
};
|
||||
|
||||
boot.kernel.sysctl."fs.inotify.max_user_watches" = 99999999;
|
||||
}
|
16
hosts/hopper/lab/dnsmasq.nix
Normal file
16
hosts/hopper/lab/dnsmasq.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
vars,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
services.dnsmasq = {
|
||||
enable = true;
|
||||
resolveLocalQueries = false;
|
||||
settings = {
|
||||
server = ["1.1.1.1" "8.8.8.8"];
|
||||
interface = ["tailscale0"];
|
||||
bind-interfaces = true;
|
||||
address = lib.mapAttrsToList (n: v: "/.${n}.priv.${vars.domain}/${v}") vars.tailnet;
|
||||
};
|
||||
};
|
||||
}
|
5
hosts/hopper/lab/glances.nix
Normal file
5
hosts/hopper/lab/glances.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
services.glances = {
|
||||
enable = true;
|
||||
};
|
||||
}
|
86
hosts/hopper/lab/homepage.nix
Normal file
86
hosts/hopper/lab/homepage.nix
Normal file
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
config,
|
||||
vars,
|
||||
...
|
||||
}: let
|
||||
inherit (vars) domain;
|
||||
bridge = config.vpnNamespaces."wg".bridgeAddress;
|
||||
in {
|
||||
services.homepage-dashboard = {
|
||||
enable = true;
|
||||
allowedHosts = "dash.hopper.priv.${domain}";
|
||||
widgets = [
|
||||
{
|
||||
resources = {
|
||||
cpu = true;
|
||||
disk = "/";
|
||||
uptime = "";
|
||||
units = "metric";
|
||||
cputemp = true;
|
||||
memory = true;
|
||||
network = true;
|
||||
};
|
||||
}
|
||||
];
|
||||
services = [
|
||||
{
|
||||
"Downloading" = [
|
||||
{
|
||||
"transmission" = {
|
||||
href = "https://transmission.hopper.priv.${domain}";
|
||||
icon = "transmission";
|
||||
widget = {
|
||||
type = "transmission";
|
||||
url = "http://${config.vpnNamespaces."wg".namespaceAddress}:${toString config.services.transmission.settings.rpc-port}";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"slskd" = {
|
||||
href = "https://slskd.hopper.priv.${domain}";
|
||||
icon = "slskd";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"Services" = [
|
||||
{
|
||||
"navidrome" = {
|
||||
href = "https://navidrome.${domain}";
|
||||
icon = "navidrome";
|
||||
};
|
||||
}
|
||||
{
|
||||
"audiobookshelf" = {
|
||||
href = "https://abs.${domain}";
|
||||
icon = "audiobookshelf";
|
||||
};
|
||||
}
|
||||
{
|
||||
"prometheus" = {
|
||||
href = "https://prometheus.hopper.priv.${domain}";
|
||||
icon = "prometheus";
|
||||
widget = {
|
||||
type = "prometheus";
|
||||
url = "http://localhost:${toString config.services.prometheus.port}";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"glances" = {
|
||||
href = "https://glances.hopper.priv.${domain}";
|
||||
icon = "glances";
|
||||
};
|
||||
}
|
||||
{
|
||||
"vaultwarden" = {
|
||||
href = "https://vw.${domain}";
|
||||
icon = "vaultwarden";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
50
hosts/hopper/lab/minecraft.nix
Normal file
50
hosts/hopper/lab/minecraft.nix
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
services.minecraft-servers = {
|
||||
enable = false;
|
||||
eula = true;
|
||||
openFirewall = true;
|
||||
servers.owo = {
|
||||
enable = true;
|
||||
package = inputs.nix-minecraft.legacyPackages.${pkgs.system}.fabricServers.fabric-1_21_5;
|
||||
serverProperties = {
|
||||
max-players = 5;
|
||||
motd = "owo";
|
||||
difficulty = "normal";
|
||||
allow-flight = true;
|
||||
view-distance = 16;
|
||||
};
|
||||
jvmOpts = "-Xms1024M -Xmx4096M";
|
||||
symlinks.mods = pkgs.linkFarmFromDrvs "mods" (
|
||||
builtins.attrValues {
|
||||
Fabric-API = pkgs.fetchurl {
|
||||
url = "https://cdn.modrinth.com/data/P7dR8mSH/versions/hBmLTbVB/fabric-api-0.121.0%2B1.21.5.jar";
|
||||
hash = "sha256-GbKETZqAN5vfXJF0yNgwTiogDAI434S3Rj9rZw6B53E=";
|
||||
};
|
||||
Lithium = pkgs.fetchurl {
|
||||
url = "https://cdn.modrinth.com/data/gvQqBUqZ/versions/VWYoZjBF/lithium-fabric-0.16.2%2Bmc1.21.5.jar";
|
||||
hash = "sha256-XqvnQxASa4M0l3JJxi5Ej6TMHUWgodOmMhwbzWuMYGg=";
|
||||
};
|
||||
FerriteCore = pkgs.fetchurl {
|
||||
url = "https://cdn.modrinth.com/data/uXXizFIs/versions/CtMpt7Jr/ferritecore-8.0.0-fabric.jar";
|
||||
hash = "sha256-K5C/AMKlgIw8U5cSpVaRGR+HFtW/pu76ujXpxMWijuo=";
|
||||
};
|
||||
C2ME = pkgs.fetchurl {
|
||||
url = "https://cdn.modrinth.com/data/VSNURh3q/versions/VEjpHAOG/c2me-fabric-mc1.21.5-0.3.2%2Brc.1.0.jar";
|
||||
hash = "sha256-D7Ho8N4vZwHeacmfNe8YMcxsQCSlyNWFsxOp2b+vujE=";
|
||||
};
|
||||
Krypton = pkgs.fetchurl {
|
||||
url = "https://cdn.modrinth.com/data/fQEb0iXm/versions/neW85eWt/krypton-0.2.9.jar";
|
||||
hash = "sha256-uGYia+H2DPawZQxBuxk77PMKfsN8GEUZo3F1zZ3MY6o=";
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/srv/minecraft"];
|
||||
services.restic.backups.hopper.paths = ["/srv/minecraft"];
|
||||
}
|
28
hosts/hopper/lab/navidrome/default.nix
Normal file
28
hosts/hopper/lab/navidrome/default.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
users.users.navidrome.extraGroups = ["media"];
|
||||
|
||||
services.navidrome = {
|
||||
enable = true;
|
||||
package = pkgs.navidrome.overrideAttrs {
|
||||
patches = [./scrobbleAlbumArtist.patch];
|
||||
doCheck = false;
|
||||
};
|
||||
settings = {
|
||||
MusicFolder = "/media/library/music";
|
||||
Address = config.vpnNamespaces."wg".bridgeAddress;
|
||||
EnableSharing = true;
|
||||
};
|
||||
};
|
||||
systemd.services.navidrome.serviceConfig.EnvironmentFile = config.sops.secrets.navidrome.path;
|
||||
|
||||
environment.persistence."/persist".directories = ["/var/lib/navidrome"];
|
||||
|
||||
services.restic.backups.hopper = {
|
||||
paths = ["/var/lib/navidrome"];
|
||||
exclude = ["/var/lib/navidrome/cache"];
|
||||
};
|
||||
}
|
23
hosts/hopper/lab/navidrome/scrobbleAlbumArtist.patch
Normal file
23
hosts/hopper/lab/navidrome/scrobbleAlbumArtist.patch
Normal file
|
@ -0,0 +1,23 @@
|
|||
diff --git a/core/agents/lastfm/client.go b/core/agents/lastfm/client.go
|
||||
index 6a24ac80..bbc0aebb 100644
|
||||
--- a/core/agents/lastfm/client.go
|
||||
+++ b/core/agents/lastfm/client.go
|
||||
@@ -131,7 +131,7 @@ type ScrobbleInfo struct {
|
||||
func (c *client) updateNowPlaying(ctx context.Context, sessionKey string, info ScrobbleInfo) error {
|
||||
params := url.Values{}
|
||||
params.Add("method", "track.updateNowPlaying")
|
||||
- params.Add("artist", info.artist)
|
||||
+ params.Add("artist", info.albumArtist)
|
||||
params.Add("track", info.track)
|
||||
params.Add("album", info.album)
|
||||
params.Add("trackNumber", strconv.Itoa(info.trackNumber))
|
||||
@@ -154,7 +154,7 @@ func (c *client) scrobble(ctx context.Context, sessionKey string, info ScrobbleI
|
||||
params := url.Values{}
|
||||
params.Add("method", "track.scrobble")
|
||||
params.Add("timestamp", strconv.FormatInt(info.timestamp.Unix(), 10))
|
||||
- params.Add("artist", info.artist)
|
||||
+ params.Add("artist", info.albumArtist)
|
||||
params.Add("track", info.track)
|
||||
params.Add("album", info.album)
|
||||
params.Add("trackNumber", strconv.Itoa(info.trackNumber))
|
||||
|
53
hosts/hopper/lab/prometheus.nix
Normal file
53
hosts/hopper/lab/prometheus.nix
Normal file
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
services.prometheus = {
|
||||
enable = true;
|
||||
port = 9001;
|
||||
extraFlags = ["--storage.tsdb.retention.time=30d"];
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "node";
|
||||
static_configs = lib.singleton {
|
||||
targets = ["127.0.0.1:${toString config.services.prometheus.exporters.node.port}"];
|
||||
};
|
||||
}
|
||||
{
|
||||
job_name = "tailscale_client";
|
||||
static_configs = lib.singleton {
|
||||
targets = ["100.100.100.100"];
|
||||
};
|
||||
}
|
||||
{
|
||||
job_name = "caddy";
|
||||
static_configs = lib.singleton {
|
||||
targets = ["${config.vpnNamespaces."wg".namespaceAddress}:2019"];
|
||||
};
|
||||
}
|
||||
{
|
||||
job_name = "slskd";
|
||||
static_configs = lib.singleton {
|
||||
targets = ["${config.vpnNamespaces."wg".namespaceAddress}:${toString config.services.slskd.settings.web.port}"];
|
||||
};
|
||||
metric_relabel_configs = lib.singleton {
|
||||
source_labels = ["__name__"];
|
||||
regex = "node_.*";
|
||||
action = "drop";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.prometheus.exporters = {
|
||||
node = {
|
||||
enable = true;
|
||||
enabledCollectors = ["systemd"];
|
||||
};
|
||||
systemd.enable = true;
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/var/lib/prometheus2"];
|
||||
services.restic.backups.hopper.paths = ["/var/lib/prometheus2"];
|
||||
}
|
21
hosts/hopper/lab/restic.nix
Normal file
21
hosts/hopper/lab/restic.nix
Normal file
|
@ -0,0 +1,21 @@
|
|||
{config, ...}: {
|
||||
services.restic.backups.hopper = {
|
||||
initialize = true;
|
||||
inhibitsSleep = true;
|
||||
repository = "rest:http://nixdesk:8000/hopper";
|
||||
passwordFile = config.sops.secrets.restic-password.path;
|
||||
timerConfig = {
|
||||
OnCalendar = "18:00";
|
||||
Persistent = true;
|
||||
RandomizedDelaySec = "1h";
|
||||
};
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 5"
|
||||
"--keep-monthly 6"
|
||||
];
|
||||
paths = [
|
||||
"/media/library/music"
|
||||
];
|
||||
};
|
||||
}
|
80
hosts/hopper/lab/samba.nix
Normal file
80
hosts/hopper/lab/samba.nix
Normal file
|
@ -0,0 +1,80 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
# only used for samba
|
||||
users.groups.xun = {};
|
||||
users.users.xun = {
|
||||
isSystemUser = true;
|
||||
group = "xun";
|
||||
extraGroups = ["transmission" "vault" "media"];
|
||||
};
|
||||
|
||||
users.users.media = {
|
||||
isSystemUser = true;
|
||||
group = "media";
|
||||
};
|
||||
|
||||
users.groups.vault = {};
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /srv/vault 0770 root vault -"
|
||||
"d /media/library 0770 media media -"
|
||||
];
|
||||
services.samba = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
settings = {
|
||||
global = {
|
||||
"log level" = "3 passdb:5 auth:5";
|
||||
"log file" = "/var/log/samba/samba.log";
|
||||
"server string" = config.networking.hostName;
|
||||
"hosts allow" = "192.168.50.0/24";
|
||||
"map to guest" = "bad user";
|
||||
"passdb backend" = "smbpasswd:${config.sops.secrets.samba-pass.path}";
|
||||
};
|
||||
transmission = {
|
||||
path = "/var/lib/transmission";
|
||||
browseable = "yes";
|
||||
"read only" = "yes";
|
||||
"guest ok" = "no";
|
||||
"create mask" = "0660";
|
||||
"directory mask" = "0770";
|
||||
};
|
||||
vault = {
|
||||
path = "/srv/vault";
|
||||
browseable = "yes";
|
||||
"read only" = "no";
|
||||
"guest ok" = "no";
|
||||
"create mask" = "0660";
|
||||
"directory mask" = "0770";
|
||||
"force user" = "xun";
|
||||
"force group" = "xun";
|
||||
};
|
||||
slskd = {
|
||||
path = "/var/lib/slskd";
|
||||
browseable = "yes";
|
||||
"read only" = "no";
|
||||
"guest ok" = "no";
|
||||
"create mask" = "0660";
|
||||
"directory mask" = "0770";
|
||||
"force user" = "slskd";
|
||||
"force group" = "slskd";
|
||||
};
|
||||
library = {
|
||||
path = "media/library";
|
||||
browseable = "yes";
|
||||
"read only" = "no";
|
||||
"guest ok" = "no";
|
||||
"create mask" = "0660";
|
||||
"directory mask" = "0770";
|
||||
"force user" = "media";
|
||||
"force group" = "media";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/srv/vault"];
|
||||
services.restic.backups.hopper.paths = ["/srv/vault"];
|
||||
}
|
43
hosts/hopper/lab/slskd.nix
Normal file
43
hosts/hopper/lab/slskd.nix
Normal file
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
systemd.services.slskd.vpnConfinement = {
|
||||
enable = true;
|
||||
vpnNamespace = "wg";
|
||||
};
|
||||
|
||||
users.users.slskd.extraGroups = ["media"];
|
||||
|
||||
services.slskd = {
|
||||
enable = true;
|
||||
environmentFile = config.sops.secrets.slskd.path;
|
||||
domain = null; # why isnt this the default?
|
||||
settings = {
|
||||
metrics = {
|
||||
enabled = true;
|
||||
authentication.disabled = true;
|
||||
};
|
||||
remote_file_management = true;
|
||||
shares.directories = ["/media/library/music"];
|
||||
soulseek = {
|
||||
listen_port = 24001;
|
||||
picture = pkgs.fetchurl {
|
||||
url = "https://cdn.donmai.us/original/57/65/__kasane_teto_utau_drawn_by_nonounno__576558c9a54c63a268f9b584f1e84c9f.png";
|
||||
hash = "sha256-7WOClBi4QgOfmcMaMorK/t8FGGO7dNUwxg3AVEjRemw=";
|
||||
};
|
||||
};
|
||||
web.authentication.disabled = true;
|
||||
global = {
|
||||
upload = {
|
||||
slots = 50;
|
||||
speed_limit = 10000;
|
||||
};
|
||||
download.speed_limit = 10000;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/var/lib/slskd"];
|
||||
}
|
34
hosts/hopper/lab/transmission.nix
Normal file
34
hosts/hopper/lab/transmission.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
vars,
|
||||
...
|
||||
}: {
|
||||
systemd.services.transmission.vpnConfinement = {
|
||||
enable = true;
|
||||
vpnNamespace = "wg";
|
||||
};
|
||||
|
||||
services.transmission = {
|
||||
enable = true;
|
||||
package = pkgs.transmission_4;
|
||||
performanceNetParameters = true;
|
||||
settings = let
|
||||
mbit = 125;
|
||||
in {
|
||||
speed-limit-up-enabled = true;
|
||||
speed-limit-up = 50 * mbit;
|
||||
speed-limit-down-enabled = true;
|
||||
speed-limit-down = 150 * mbit;
|
||||
peer-port = 24003;
|
||||
rpc-authentication-required = false;
|
||||
rpc-bind-address = "0.0.0.0";
|
||||
rpc-host-whitelist = "transmission.hopper.priv.${vars.domain}";
|
||||
rpc-whitelist-enabled = true;
|
||||
rpc-whitelist = "127.0.0.1,192.168.\*.\*,100.\*.\*.\*";
|
||||
};
|
||||
# credentialsFile = config.sops.secrets.transmission.path;
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/var/lib/transmission"];
|
||||
}
|
20
hosts/hopper/lab/vaultwarden.nix
Normal file
20
hosts/hopper/lab/vaultwarden.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
{config, ...}: {
|
||||
systemd.services.vaultwarden = {
|
||||
serviceConfig.EnvironmentFile = config.sops.secrets.vaultwarden-env.path;
|
||||
};
|
||||
# NOTE send doesnt work, probably due to my cloudflare port rewriting rules
|
||||
services.vaultwarden = {
|
||||
enable = true;
|
||||
config = {
|
||||
DOMAIN = "https://${config.services.caddy.virtualHosts.vaultwarden.hostName}";
|
||||
ROCKET_ADDRESS = "0.0.0.0";
|
||||
ROCKET_PORT = 35381;
|
||||
ROCKET_LOG = "critical";
|
||||
SIGNUPS_ALLOWED = false;
|
||||
IP_HEADER = "X-Forwarded-For";
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/var/lib/bitwarden_rs"];
|
||||
services.restic.backups.hopper.paths = ["/var/lib/bitwarden_rs"];
|
||||
}
|
75
hosts/hopper/lab/vpn-namespace.nix
Normal file
75
hosts/hopper/lab/vpn-namespace.nix
Normal file
|
@ -0,0 +1,75 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
networking.firewall = let
|
||||
allowTcpFromVPNToDefaultPorts = [
|
||||
config.services.prometheus.port
|
||||
config.services.vaultwarden.config.ROCKET_PORT
|
||||
config.services.homepage-dashboard.listenPort
|
||||
config.services.audiobookshelf.port
|
||||
config.services.navidrome.settings.Port
|
||||
config.services.glances.port
|
||||
];
|
||||
in {
|
||||
extraCommands = builtins.concatStringsSep "\n" (map
|
||||
(port: "iptables -A nixos-fw -p tcp -s ${config.vpnNamespaces."wg".namespaceAddress} --dport ${toString port} -j nixos-fw-accept")
|
||||
allowTcpFromVPNToDefaultPorts);
|
||||
extraStopCommands = builtins.concatStringsSep "\n" (
|
||||
map
|
||||
(port: "iptables -D nixos-fw -p tcp -s ${config.vpnNamespaces."wg".namespaceAddress} --dport ${toString port} -j nixos-fw-accept || true")
|
||||
allowTcpFromVPNToDefaultPorts
|
||||
);
|
||||
};
|
||||
|
||||
vpnNamespaces."wg" = {
|
||||
enable = true;
|
||||
wireguardConfigFile = config.sops.secrets.wireguard.path;
|
||||
accessibleFrom = [
|
||||
"192.168.0.0/24"
|
||||
# "127.0.0.1"
|
||||
];
|
||||
|
||||
# Forwarded to my vpn, for making things accessible from outside
|
||||
openVPNPorts = [
|
||||
{
|
||||
port = 443; # caddy
|
||||
protocol = "tcp";
|
||||
}
|
||||
{
|
||||
port = 80; # caddy
|
||||
protocol = "tcp";
|
||||
}
|
||||
|
||||
{
|
||||
port = 24001; # slskd
|
||||
protocol = "both";
|
||||
}
|
||||
{
|
||||
port = 24002; # slskd
|
||||
protocol = "both";
|
||||
}
|
||||
{
|
||||
port = 24003; # transmission
|
||||
protocol = "both";
|
||||
}
|
||||
];
|
||||
|
||||
# From inside of the vpn namespace to outside of it, for making things inside accessible to LAN
|
||||
portMappings = let
|
||||
passthrough = [
|
||||
8336 # caddy
|
||||
80 # caddy
|
||||
443 # caddy
|
||||
2019 # caddy admin, for prometheus metrics
|
||||
config.services.transmission.settings.rpc-port
|
||||
config.services.slskd.settings.web.port
|
||||
];
|
||||
in (lib.map (x: {
|
||||
from = x;
|
||||
to = x;
|
||||
})
|
||||
passthrough);
|
||||
};
|
||||
}
|
18
hosts/hopper/persistent.nix
Normal file
18
hosts/hopper/persistent.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
environment.persistence."/persist" = {
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
"/home/desktop"
|
||||
"/home/deploy"
|
||||
"/media"
|
||||
"/var/log"
|
||||
"/var/lib/nixos"
|
||||
"/var/lib/bluetooth"
|
||||
];
|
||||
files = [
|
||||
"/etc/machine-id"
|
||||
"/etc/ssh/ssh_host_ed25519_key"
|
||||
"/etc/ssh/ssh_host_ed25519_key.pub"
|
||||
];
|
||||
};
|
||||
}
|
15
hosts/hopper/roblox-playtime.nix
Normal file
15
hosts/hopper/roblox-playtime.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
inputs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
imports = [inputs.roblox-playtime.nixosModules.roblox-playtime];
|
||||
|
||||
services.roblox-playtime = {
|
||||
enable = true;
|
||||
configFile = config.sops.secrets.roblox-playtime.path;
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/var/lib/roblox-playtime"];
|
||||
services.restic.backups.hopper.paths = ["/var/lib/roblox-playtime"];
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue