From dcf7b84d94f253623d8a6873a8467467d45e8de2 Mon Sep 17 00:00:00 2001 From: Swarsel Date: Mon, 23 Sep 2024 21:18:36 +0200 Subject: [PATCH] feat: init nixos-server, work screenshare & qol --- SwarselSystems.org | 854 +++++++++++++++++- flake.nix | 8 + modules/home/input.nix | 5 +- modules/home/monitors.nix | 4 + modules/nixos/default.nix | 1 + modules/nixos/input.nix | 10 + modules/nixos/setup.nix | 7 + overlays/default.nix | 13 +- pkgs/default.nix | 1 + pkgs/screenshare/default.nix | 7 + profiles/common/home/custom-packages.nix | 1 + profiles/common/home/sway.nix | 2 + profiles/common/home/zsh.nix | 42 +- profiles/common/nixos/zsh.nix | 2 +- profiles/nbl-imba-2/default.nix | 15 +- .../nbl-imba-2/hardware-configuration.nix | 2 +- profiles/optional/home/work.nix | 1 + profiles/server/common/calibre.nix | 32 + profiles/server/common/default.nix | 53 ++ profiles/server/common/jellyfin.nix | 44 + profiles/server/common/kavita.nix | 35 + profiles/server/common/matrix.nix | 273 ++++++ profiles/server/common/mpd.nix | 51 ++ profiles/server/common/navidrome.nix | 76 ++ profiles/server/common/nginx.nix | 30 + profiles/server/common/packages.nix | 9 + profiles/server/common/sops.nix | 9 + profiles/server/common/spotifyd.nix | 29 + profiles/server/common/ssh.nix | 11 + profiles/server/winters/default.nix | 54 ++ profiles/winters/home.nix | 108 --- profiles/winters/nixos.nix | 142 --- programs/swayidle/config | 6 +- scripts/screenshare.sh | 5 + 34 files changed, 1644 insertions(+), 298 deletions(-) create mode 100644 modules/nixos/input.nix create mode 100644 pkgs/screenshare/default.nix create mode 100644 profiles/server/common/calibre.nix create mode 100644 profiles/server/common/default.nix create mode 100644 profiles/server/common/jellyfin.nix create mode 100644 profiles/server/common/kavita.nix create mode 100644 profiles/server/common/matrix.nix create mode 100644 profiles/server/common/mpd.nix create mode 100644 profiles/server/common/navidrome.nix create mode 100644 profiles/server/common/nginx.nix create mode 100644 profiles/server/common/packages.nix create mode 100644 profiles/server/common/sops.nix create mode 100644 profiles/server/common/spotifyd.nix create mode 100644 profiles/server/common/ssh.nix create mode 100644 profiles/server/winters/default.nix delete mode 100644 profiles/winters/home.nix delete mode 100644 profiles/winters/nixos.nix create mode 100644 scripts/screenshare.sh diff --git a/SwarselSystems.org b/SwarselSystems.org index fa8313e..aba7a72 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -591,6 +591,13 @@ This section used to be much longer, since I performed all of my imports right h ]; }; + winters = lib.nixosSystem { + specialArgs = { inherit inputs outputs; }; + modules = [ + ./profiles/server/winters + ]; + }; + nginx = nixpkgs.lib.nixosSystem { specialArgs = { inherit inputs; }; modules = [ @@ -1883,6 +1890,7 @@ My work machine. Built for more security, this is the gold standard of my config { command = "teams-for-linux"; } { command = "1password"; } ]; + sharescreen = "eDP-2"; monitors = { main = { name = "BOE 0x0BC9 Unknown"; @@ -1930,7 +1938,7 @@ My work machine. Built for more security, this is the gold standard of my config scale = "1"; position = "-1280,0"; workspace = "1:一"; - output = "DP-8"; + output = "DP-9"; }; work_middle_middle_side = { name = "Hewlett Packard HP Z24i CN44250RDT"; @@ -1939,13 +1947,13 @@ My work machine. Built for more security, this is the gold standard of my config scale = "1"; position = "-2480,0"; workspace = "12:S"; - output = "DP-9"; + output = "DP-8"; }; work_seminary = { name = "Applied Creative Technology Transmitter QUATTRO201811"; mode = "1280x720"; scale = "1"; - position = "10000,10000"; + position = "10000,10000"; # i.e. this screen is inaccessible by moving the mouse workspace = "12:S"; output = "DP-4"; }; @@ -1975,12 +1983,80 @@ My work machine. Built for more security, this is the gold standard of my config }; }; keybindings = { - "Mod4+Ctrl+p" = "exec wl-mirror eDP-2"; + "Mod4+Ctrl+Shift+p" = "exec screenshare"; + }; + shellAliases = { + ans2-15_3-9 = ". ~/.venvs/ansible39_2_15_0/bin/activate"; + ans3-9 = ". ~/.venvs/ansible39/bin/activate"; + ans = ". ~/.venvs/ansible/bin/activate"; + ans2-15 = ". ~/.venvs/ansible2.15.0/bin/activate"; }; }; } +#+end_src + +**** Winters (Server) + + +#+begin_src nix :tangle profiles/server/winters/default.nix + { inputs, outputs, config, pkgs, lib, ... }: + { + + imports = [ + inputs.sops-nix.nixosModules.sops + + ./hardware-configuration.nix + + ../../optional/nixos/autologin.nix + ../../server/common + + ] ++ (builtins.attrValues outputs.nixosModules); + + + nixpkgs = { + inherit (outputs) overlays; + config = { + allowUnfree = true; + }; + }; + + + boot = { + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + kernelPackages = pkgs.linuxPackages_latest; + }; + + networking = { + hostName = "winters"; + firewall.enable = true; + }; + + + swarselsystems = { + hasBluetooth = false; + hasFingerprint = false; + impermanence = false; + isBtrfs = false; + server = { + enable = true; + kavita = true; + navidrome = true; + jellyfin = true; + spotifyd = true; + mpd = true; + matrix = true; + }; + shellAliases = { + nswitch = "cd /.dotfiles; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;"; + }; + }; + + } + + #+end_src *** Virtual hosts @@ -3893,6 +3969,7 @@ This is the central station for self-defined packages. These are all referenced fs-diff = callPackage ./fs-diff { }; update-checker = callPackage ./update-checker { }; github-notifications = callPackage ./github-notifications { }; + screenshare = callPackage ./screenshare { }; } #+end_src @@ -4419,6 +4496,30 @@ This utility checks if there are updated packages in nixpkgs-unstable. It does s } #+end_src +**** screenshare + + +#+begin_src shell :tangle scripts/screenshare.sh + + SHARESCREEN="$(nix eval --raw ~/.dotfiles#nixosConfigurations."$(hostname)".config.home-manager.users."$(whoami)".swarselsystems.sharescreen)" + + wl-mirror "$SHARESCREEN" & sleep 0.1 + swaymsg '[app_id=at.yrlf.wl_mirror] move to workspace 12:S' + swaymsg '[app_id=at.yrlf.wl_mirror] fullscreen' + +#+end_src + + +#+begin_src nix :tangle pkgs/screenshare/default.nix + { writeShellApplication, sway }: + + writeShellApplication { + name = "screenshare"; + runtimeInputs = [ sway ]; + text = builtins.readFile ../../scripts/screenshare.sh; + } +#+end_src + *** Overlays (additions, overrides, nixpkgs-stable) :PROPERTIES: @@ -4447,11 +4548,11 @@ This file now holds all of the "nixpkgs-changes" that I am using across the conf ]; }; - prismlauncher = _prev.prismlauncher.override { - glfw = _prev.glfw-wayland-minecraft; - }; + # prismlauncher = _prev.prismlauncher.override { + # glfw = _prev.glfw-wayland-minecraft; + # }; - # river = prev.river.overrideAttrs (oldAttrs: rec { + # #river = prev.river.overrideAttrs (oldAttrs: rec { # pname = "river"; # version = "git"; # src = prev.fetchFromGitHub { @@ -4465,7 +4566,10 @@ This file now holds all of the "nixpkgs-changes" that I am using across the conf }; nixpkgs-stable = final: _prev: { - stable = import inputs.nixpkgs-stable { inherit (final) system; }; + stable = import inputs.nixpkgs-stable { + inherit (final) system; + config.allowUnfree = true; + }; }; zjstatus = final: _prev: { @@ -4497,6 +4601,7 @@ Modules that need to be loaded on the NixOS level. Note that these will not be a setup = import ./setup.nix; impermanence = import ./impermanence.nix; filesystem = import ./filesystem.nix; + input = import ./input.nix; } #+end_src @@ -4553,6 +4658,29 @@ I usually use =mutableUsers = false= in my NixOS configuration. However, on a ne { options.swarselsystems.initialSetup = lib.mkEnableOption "initial setup (no sops keys available)"; + options.swarselsystems.server.enable = lib.mkEnableOption "is a server machine"; + options.swarselsystems.server.kavita = lib.mkEnableOption "enable kavita on server"; + options.swarselsystems.server.jellyfin = lib.mkEnableOption "enable jellyfin on server"; + options.swarselsystems.server.navidrome = lib.mkEnableOption "enable navidrome on server"; + options.swarselsystems.server.spotifyd = lib.mkEnableOption "enable spotifyd on server"; + options.swarselsystems.server.mpd = lib.mkEnableOption "enable mpd on server"; + options.swarselsystems.server.matrix = lib.mkEnableOption "enable matrix on server"; + } +#+end_src + +***** Input + + +#+begin_src nix :tangle modules/nixos/input.nix + { lib, config, ... }: + let + inherit (lib) mkOption types; + in + { + options.swarselsystems.shellAliases = mkOption { + type = types.attrsOf types.str; + default = { }; + }; } #+end_src @@ -4737,6 +4865,10 @@ This allows me to define my monitors in the machine's =default.nix=. type = types.attrsOf (types.attrsOf types.str); default = { }; }; + options.swarselsystems.sharescreen = mkOption { + type = types.str; + default = ""; + }; } #+end_src @@ -4779,7 +4911,10 @@ This allows me to configure input options. Here, I am globally defining my split type = types.attrsOf types.str; default = { }; }; - + options.swarselsystems.shellAliases = mkOption { + type = types.attrsOf types.str; + default = { }; + }; } #+end_src @@ -5686,7 +5821,7 @@ Some programs profit from being installed through dedicated NixOS settings on sy Do not touch this. #+begin_src nix :tangle profiles/common/nixos/zsh.nix - { pkgs, ... }: + { lib, config, pkgs, ... }: { programs.zsh.enable = true; users.defaultUserShell = pkgs.zsh; @@ -6344,6 +6479,689 @@ This turns off the display when the lid is closed. } #+end_src +*** Server +**** Imports, stateVersion + +First, we enable the use of =home-manager= as a NixoS module. + +Also, we disable the warnings that trigger when rebuilding with a dirty flake. At this point, I am also disabling channels and pinning the flake registry - the latter lets me use the local version of nixpkgs for commands like =nix shell= (without it, we will always download the newest version of nixpkgs for these commands). + +Also, the system state version is set here. No need to touch it. + +#+begin_src nix :tangle profiles/server/common/default.nix + { lib, config, inputs, ... }: + { + imports = [ + ../../common/nixos/xserver.nix + ../../common/nixos/gc.nix + ../../common/nixos/store.nix + ../../common/nixos/time.nix + ../../common/nixos/pipewire.nix + ./packages.nix + ./sops.nix + ./ssh.nix + ./nginx.nix + ./kavita.nix + ./jellyfin.nix + ./navidrome.nix + ./spotifyd.nix + ./mpd.nix + ./matrix.nix + ]; + + nix = + let + flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs; + in + { + settings = { + experimental-features = [ + "nix-command" + "flakes" + "ca-derivations" + ]; + trusted-users = [ "swarsel" ]; + flake-registry = ""; + warn-dirty = false; + }; + channel.enable = false; + registry = lib.mapAttrs (_: flake: { inherit flake; }) flakeInputs; + nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs; + }; + + environment.shellAliases = lib.recursiveUpdate { + npswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;"; + nswitch = "cd /.dotfiles; nixos-rebuild --flake .#$(hostname) switch; cd -;"; + } + config.swarselsystems.shellAliases; + + nixpkgs.config.permittedInsecurePackages = [ + "olm-3.2.16" + ]; + + system.stateVersion = lib.mkDefault "23.05"; + } + + #+end_src + +**** System Packages + +#+begin_src nix :tangle profiles/server/common/packages.nix + { pkgs, ... }: + { + environment.systemPackages = with pkgs; [ + gnupg + nix-index + ssh-to-age + git + ]; + } +#+end_src + +**** sops + +#+begin_src nix :tangle profiles/server/common/sops.nix + { pkgs, ... }: + { + sops = { + age.sshKeyPaths = [ "/etc/ssh/sops" ]; + defaultSopsFile = "/.dotfiles/secrets/server/secrets.yaml"; + validateSopsFiles = false; + }; + + } +#+end_src + +**** NGINX + +#+begin_src nix :tangle profiles/server/common/nginx.nix +{ pkgs, config, ... }: +{ + environment.systemPackages = with pkgs; [ + lego + ]; + sops = { + secrets.dnstokenfull = { owner = "acme"; }; + templates."certs.secret".content = '' + CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull} + ''; + }; + + security.acme = { + acceptTerms = true; + preliminarySelfsigned = false; + defaults.email = "mrswarsel@gmail.com"; + defaults.dnsProvider = "cloudflare"; + defaults.environmentFile = "${config.sops.templates."certs.secret".path}"; + }; + + services.nginx = { + enable = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + # virtualHosts are defined in the respective sections + }; + +} +#+end_src + +**** ssh + +#+begin_src nix :tangle profiles/server/common/ssh.nix + _ : + { + services.openssh = { + enable = true; + settings.PermitRootLogin = "yes"; + }; + users.users.root.openssh.authorizedKeys.keyFiles = [ + ../../../secrets/keys/authorized_keys + ]; + + } +#+end_src + +**** kavita + +#+begin_src nix :tangle profiles/server/common/kavita.nix +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.kavita { + environment.systemPackages = with pkgs; [ + calibre + ]; + + sops.secrets.kavita = { owner = "kavita"; }; + + services.kavita = { + enable = true; + user = "kavita"; + settings.Port = 8080; + tokenKeyFile = config.sops.secrets.kavita.path; + }; + + services.nginx = { + virtualHosts = { + "scroll.swarsel.win" = { + enableACME = true; + forceSSL = true; + acmeRoot = null; + locations = { + "/" = { + proxyPass = "http://192.168.1.22:8080"; + extraConfig = '' + client_max_body_size 0; + ''; + }; + }; + }; + }; + }; + }; +} +#+end_src + +**** jellyfin + +#+begin_src nix :tangle profiles/server/common/jellyfin.nix +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.jellyfin { + users.users.jellyfin = { + extraGroups = [ "video" "render" ]; + }; + nixpkgs.config.packageOverrides = pkgs: { + vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; }; + }; + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + intel-media-driver # LIBVA_DRIVER_NAME=iHD + vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium) + vaapiVdpau + libvdpau-va-gl + ]; + }; + services.jellyfin = { + enable = true; + user = "jellyfin"; + # openFirewall = true; # this works only for the default ports + }; + + services.nginx = { + virtualHosts = { + "screen.swarsel.win" = { + enableACME = true; + forceSSL = true; + acmeRoot = null; + locations = { + "/" = { + proxyPass = "http://192.168.1.16:8096"; + extraConfig = '' + client_max_body_size 0; + ''; + }; + }; + }; + }; + }; + }; + +} +#+end_src + +**** navidrome + +#+begin_src nix :tangle profiles/server/common/navidrome.nix +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.navidrome { + environment.systemPackages = with pkgs; [ + pciutils + alsa-utils + mpv + ]; + + users = { + groups = { + navidrome = { + gid = 61593; + }; + }; + + users = { + navidrome = { + isSystemUser = true; + uid = 61593; + group = "navidrome"; + extraGroups = [ "audio" "utmp" ]; + }; + }; + }; + + + hardware.enableAllFirmware = true; + + services.navidrome = { + enable = true; + settings = { + Address = "0.0.0.0"; + Port = 4040; + MusicFolder = "/media"; + EnableSharing = true; + EnableTranscodingConfig = true; + Scanner.GroupAlbumReleases = true; + ScanSchedule = "@every 1d"; + # Insert these values locally as sops-nix does not work for them + # LastFM.ApiKey = TEMPLATE; + # LastFM.Secret = TEMPLATE; + # Spotify.ID = TEMPLATE; + # Spotify.Secret = TEMPLATE; + UILoginBackgroundUrl = "https://i.imgur.com/OMLxi7l.png"; + UIWelcomeMessage = "~SwarselSound~"; + }; + }; + + services.nginx = { + virtualHosts = { + "sound.swarsel.win" = { + enableACME = true; + forceSSL = true; + acmeRoot = null; + locations = { + "/" = { + proxyPass = "http://192.168.1.13:4040"; + proxyWebsockets = true; + extraConfig = '' + proxy_redirect http:// https://; + proxy_read_timeout 600s; + proxy_send_timeout 600s; + proxy_buffering off; + proxy_request_buffering off; + client_max_body_size 0; + ''; + }; + }; + }; + }; + }; + }; + + +} +#+end_src + +**** spotifyd + +#+begin_src nix :tangle profiles/server/common/spotifyd.nix +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.spotifyd { + users.groups.spotifyd = { + gid = 65136; + }; + + users.users.spotifyd = { + isSystemUser = true; + uid = 65136; + group = "spotifyd"; + extraGroups = [ "audio" "utmp" ]; + }; + services.spotifyd = { + enable = true; + settings = { + global = { + dbus_type = "session"; + use_mpris = false; + device = "default:CARD=PCH"; + device_name = "SwarselSpot"; + mixer = "alsa"; + zeroconf_port = 1025; + }; + }; + }; + }; + +} +#+end_src + +**** mpd + +#+begin_src nix :tangle profiles/server/common/mpd.nix +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.mpd { + users = { + groups = { + mpd = { }; + }; + + users = { + mpd = { + isSystemUser = true; + group = "mpd"; + extraGroups = [ "audio" "utmp" ]; + }; + }; + }; + + sops = { + secrets.mpdpass = { owner = "mpd"; }; + }; + + environment.systemPackages = with pkgs; [ + pciutils + alsa-utils + mpv + ]; + + services.mpd = { + enable = true; + musicDirectory = "/media"; + user = "mpd"; + group = "mpd"; + network = { + port = 3254; + listenAddress = "any"; + }; + credentials = [ + { + passwordFile = config.sops.secrets.mpdpass.path; + permissions = [ + "read" + "add" + "control" + "admin" + ]; + } + ]; + }; + }; + +} +#+end_src + +**** matrix + +#+begin_src nix :tangle profiles/server/common/matrix.nix +{ config, lib, pkgs, modulesPath, sops, ... }: +let + matrixDomain = "swatrix.swarsel.win"; +in +{ + + config = lib.mkIf config.swarselsystems.server.matrix { + environment.systemPackages = with pkgs; [ + matrix-synapse + lottieconverter + ffmpeg + ]; + + sops = { + secrets = { + matrixsharedsecret = { owner = "matrix-synapse"; }; + mautrixtelegram_as = { owner = "matrix-synapse"; }; + mautrixtelegram_hs = { owner = "matrix-synapse"; }; + mautrixtelegram_api_id = { owner = "matrix-synapse"; }; + mautrixtelegram_api_hash = { owner = "matrix-synapse"; }; + }; + templates = { + "matrix_user_register.sh".content = '' + register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008 + ''; + matrixshared = { + owner = "matrix-synapse"; + content = '' + registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret} + ''; + }; + mautrixtelegram = { + owner = "matrix-synapse"; + content = '' + MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as} + MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs} + MAUTRIX_TELEGRAM_TELEGRAM_API_ID=${config.sops.placeholder.mautrixtelegram_api_id} + MAUTRIX_TELEGRAM_TELEGRAM_API_HASH=${config.sops.placeholder.mautrixtelegram_api_hash} + ''; + }; + }; + }; + + services.postgresql = { + enable = true; + initialScript = pkgs.writeText "synapse-init.sql" '' + CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; + CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + CREATE ROLE "mautrix-telegram" WITH LOGIN PASSWORD 'telegram'; + CREATE DATABASE "mautrix-telegram" WITH OWNER "mautrix-telegram" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + CREATE ROLE "mautrix-whatsapp" WITH LOGIN PASSWORD 'whatsapp'; + CREATE DATABASE "mautrix-whatsapp" WITH OWNER "mautrix-whatsapp" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + CREATE ROLE "mautrix-signal" WITH LOGIN PASSWORD 'signal'; + CREATE DATABASE "mautrix-signal" WITH OWNER "mautrix-signal" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + ''; + }; + + services.matrix-synapse = { + enable = true; + settings = { + app_service_config_files = [ + "/var/lib/matrix-synapse/telegram-registration.yaml" + "/var/lib/matrix-synapse/whatsapp-registration.yaml" + "/var/lib/matrix-synapse/signal-registration.yaml" + "/var/lib/matrix-synapse/doublepuppet.yaml" + ]; + server_name = matrixDomain; + public_baseurl = "https://${matrixDomain}"; + listeners = [ + { + port = 8008; + bind_addresses = [ "0.0.0.0" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ + { + names = [ "client" "federation" ]; + compress = true; + } + ]; + } + ]; + }; + extraConfigFiles = [ + config.sops.templates.matrixshared.path + ]; + }; + + services.mautrix-telegram = { + enable = true; + environmentFile = config.sops.templates.mautrixtelegram.path; + settings = { + homeserver = { + address = "http://localhost:8008"; + domain = matrixDomain; + }; + appservice = { + address = "http://localhost:29317"; + hostname = "0.0.0.0"; + port = "29317"; + provisioning.enabled = true; + id = "telegram"; + # ephemeral_events = true; # not needed due to double puppeting + public = { + enabled = false; + }; + database = "postgresql:///mautrix-telegram?host=/run/postgresql"; + }; + bridge = { + relaybot.authless_portals = true; + allow_avatar_remove = true; + allow_contact_info = true; + sync_channel_members = true; + startup_sync = true; + sync_create_limit = 0; + sync_direct_chats = true; + telegram_link_preview = true; + permissions = { + "*" = "relaybot"; + "@swarsel:${matrixDomain}" = "admin"; + }; + animated_sticker = { + target = "gif"; + args = { + width = 256; + height = 256; + fps = 30; # only for webm + background = "020202"; # only for gif, transparency not supported + }; + }; + }; + }; + }; + systemd.services.mautrix-telegram.path = with pkgs; [ + lottieconverter # for animated stickers conversion, unfree package + ffmpeg # if converting animated stickers to webm (very slow!) + ]; + + services.mautrix-whatsapp = { + enable = true; + settings = { + homeserver = { + address = "http://localhost:8008"; + domain = matrixDomain; + }; + appservice = { + address = "http://localhost:29318"; + hostname = "0.0.0.0"; + port = 29318; + database = { + type = "postgres"; + uri = "postgresql:///mautrix-whatsapp?host=/run/postgresql"; + }; + }; + bridge = { + displayname_template = "{{or .FullName .PushName .JID}} (WA)"; + history_sync = { + backfill = true; + max_initial_conversations = -1; + message_count = -1; + request_full_sync = true; + full_sync_config = { + days_limit = 900; + size_mb_limit = 5000; + storage_quota_mb = 5000; + }; + }; + login_shared_secret_map = { + matrixDomain = "as_token:doublepuppet"; + }; + sync_manual_marked_unread = true; + send_presence_on_typing = true; + parallel_member_sync = true; + url_previews = true; + caption_in_message = true; + extev_polls = true; + permissions = { + "*" = "relaybot"; + "@swarsel:${matrixDomain}" = "admin"; + }; + }; + }; + }; + + services.mautrix-signal = { + enable = true; + settings = { + homeserver = { + address = "http://localhost:8008"; + domain = matrixDomain; + }; + appservice = { + + address = "http://localhost:29328"; + hostname = "0.0.0.0"; + port = 29328; + database = { + type = "postgres"; + uri = "postgresql:///mautrix-signal?host=/run/postgresql"; + }; + }; + bridge = { + displayname_template = "{{or .ContactName .ProfileName .PhoneNumber}} (Signal)"; + login_shared_secret_map = { + matrixDomain = "as_token:doublepuppet"; + }; + caption_in_message = true; + permissions = { + "*" = "relaybot"; + "@swarsel:${matrixDomain}" = "admin"; + }; + }; + }; + }; + + # restart the bridges daily. this is done for the signal bridge mainly which stops carrying + # messages out after a while. + + systemd.timers."restart-bridges" = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "1d"; + OnUnitActiveSec = "1d"; + Unit = "restart-bridges.service"; + }; + }; + + systemd.services."restart-bridges" = { + script = '' + systemctl restart mautrix-whatsapp.service + systemctl restart mautrix-signal.service + systemctl restart mautrix-telegram.service + ''; + serviceConfig = { + Type = "oneshot"; + User = "root"; + }; + }; + + services.nginx = { + virtualHosts = { + "swatrix.swarsel.win" = { + enableACME = true; + forceSSL = true; + acmeRoot = null; + locations = { + "~ ^(/_matrix|/_synapse/client)" = { + proxyPass = "http://192.168.1.23:8008"; + extraConfig = '' + client_max_body_size 0; + ''; + }; + }; + }; + }; + }; + }; + + +} + +#+end_src + *** Optional :PROPERTIES: @@ -6773,6 +7591,7 @@ This is just a separate container for derivations defined in [[#h:64a5cc16-6b16- fs-diff update-checker github-notifications + screenshare (pkgs.writeScriptBin "project" '' #! ${pkgs.bash}/bin/bash @@ -7441,11 +8260,11 @@ zsh is the most convenient shell for me and it happens to be super neat to confi Here we set some aliases (some of them should be shellApplications instead) as well as some zsh plugins like =fzf-tab=. #+begin_src nix :tangle profiles/common/home/zsh.nix - { pkgs, ... }: + { config, pkgs, lib, ... }: { programs.zsh = { enable = true; - shellAliases = { + shellAliases = lib.recursiveUpdate { hg = "history | grep"; hmswitch = "cd ~/.dotfiles; home-manager --flake .#$(whoami)@$(hostname) switch; cd -;"; nswitch = "cd ~/.dotfiles; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;"; @@ -7462,7 +8281,10 @@ Here we set some aliases (some of them should be shellApplications instead) as w cdr = "cd \"$( (find /home/swarsel/Documents/GitHub -maxdepth 1 && echo /home/swarsel/.dotfiles) | fzf )\""; nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; fs-diff = "sudo mount -o subvol=/ /dev/mapper/cryptroot /mnt ; fs-diff"; - }; + lt = "ls -lath"; + oldshell = "nix shell github:nixos/nixpkgs/\"$1\" \"$2\""; + } + config.swarselsystems.shellAliases; autosuggestion.enable = true; enableCompletion = true; syntaxHighlighting.enable = true; @@ -8607,6 +9429,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se "${modifier}+o" = "exec pass-fuzzel --otp"; "${modifier}+Shift+p" = "exec pass-fuzzel --type"; "${modifier}+Shift+o" = "exec pass-fuzzel --otp --type"; + "${modifier}+Ctrl+p" = "exec 1password --quick-acces"; "${modifier}+Escape" = "mode $exit"; "${modifier}+Shift+Escape" = "exec kitty -o confirm_os_window_close=0 btm"; "${modifier}+s" = "exec grim -g \"$(slurp)\" -t png - | wl-copy -t image/png"; @@ -8711,6 +9534,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se { title = "Syncthing Tray"; } { app_id = "SchildiChat"; } { app_id = "Element"; } + { class = "1Password"; } { app_id = "com.nextcloud.desktopclient.nextcloud"; } { app_id = "gnome-system-monitor"; } { title = "(?:Open|Save) (?:File|Folder|As)"; } @@ -8961,6 +9785,7 @@ The rest of the settings is at [[#h:bbf2ecb6-c8ff-4462-b5d5-d45b28604ddf][work]] shellcheck dig docker + postman ]; programs = { @@ -9098,6 +9923,7 @@ This tangles the flake.nix file; This block only needs to be touched when updati outputs = inputs@{ self , nixpkgs + , nixpkgs-stable , home-manager , systems , ... diff --git a/flake.nix b/flake.nix index c0ca45c..f6447ec 100644 --- a/flake.nix +++ b/flake.nix @@ -98,6 +98,7 @@ outputs = inputs@{ self , nixpkgs + , nixpkgs-stable , home-manager , systems , ... @@ -214,6 +215,13 @@ ]; }; + winters = lib.nixosSystem { + specialArgs = { inherit inputs outputs; }; + modules = [ + ./profiles/server/winters + ]; + }; + nginx = nixpkgs.lib.nixosSystem { specialArgs = { inherit inputs; }; modules = [ diff --git a/modules/home/input.nix b/modules/home/input.nix index 4029dd3..53daa95 100644 --- a/modules/home/input.nix +++ b/modules/home/input.nix @@ -29,5 +29,8 @@ in type = types.attrsOf types.str; default = { }; }; - + options.swarselsystems.shellAliases = mkOption { + type = types.attrsOf types.str; + default = { }; + }; } diff --git a/modules/home/monitors.nix b/modules/home/monitors.nix index e2ad06a..d02e898 100644 --- a/modules/home/monitors.nix +++ b/modules/home/monitors.nix @@ -7,4 +7,8 @@ in type = types.attrsOf (types.attrsOf types.str); default = { }; }; + options.swarselsystems.sharescreen = mkOption { + type = types.str; + default = ""; + }; } diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 70c7978..cf79e66 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -4,4 +4,5 @@ setup = import ./setup.nix; impermanence = import ./impermanence.nix; filesystem = import ./filesystem.nix; + input = import ./input.nix; } diff --git a/modules/nixos/input.nix b/modules/nixos/input.nix new file mode 100644 index 0000000..ea94c14 --- /dev/null +++ b/modules/nixos/input.nix @@ -0,0 +1,10 @@ +{ lib, config, ... }: +let + inherit (lib) mkOption types; +in +{ + options.swarselsystems.shellAliases = mkOption { + type = types.attrsOf types.str; + default = { }; + }; +} diff --git a/modules/nixos/setup.nix b/modules/nixos/setup.nix index ce5ea41..8385c47 100644 --- a/modules/nixos/setup.nix +++ b/modules/nixos/setup.nix @@ -2,4 +2,11 @@ { options.swarselsystems.initialSetup = lib.mkEnableOption "initial setup (no sops keys available)"; + options.swarselsystems.server.enable = lib.mkEnableOption "is a server machine"; + options.swarselsystems.server.kavita = lib.mkEnableOption "enable kavita on server"; + options.swarselsystems.server.jellyfin = lib.mkEnableOption "enable jellyfin on server"; + options.swarselsystems.server.navidrome = lib.mkEnableOption "enable navidrome on server"; + options.swarselsystems.server.spotifyd = lib.mkEnableOption "enable spotifyd on server"; + options.swarselsystems.server.mpd = lib.mkEnableOption "enable mpd on server"; + options.swarselsystems.server.matrix = lib.mkEnableOption "enable matrix on server"; } diff --git a/overlays/default.nix b/overlays/default.nix index 943680a..43c5031 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -17,11 +17,11 @@ ]; }; - prismlauncher = _prev.prismlauncher.override { - glfw = _prev.glfw-wayland-minecraft; - }; + # prismlauncher = _prev.prismlauncher.override { + # glfw = _prev.glfw-wayland-minecraft; + # }; - # river = prev.river.overrideAttrs (oldAttrs: rec { + # #river = prev.river.overrideAttrs (oldAttrs: rec { # pname = "river"; # version = "git"; # src = prev.fetchFromGitHub { @@ -35,7 +35,10 @@ }; nixpkgs-stable = final: _prev: { - stable = import inputs.nixpkgs-stable { inherit (final) system; }; + stable = import inputs.nixpkgs-stable { + inherit (final) system; + config.allowUnfree = true; + }; }; zjstatus = final: _prev: { diff --git a/pkgs/default.nix b/pkgs/default.nix index 2e846be..316b23d 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -16,4 +16,5 @@ in fs-diff = callPackage ./fs-diff { }; update-checker = callPackage ./update-checker { }; github-notifications = callPackage ./github-notifications { }; + screenshare = callPackage ./screenshare { }; } diff --git a/pkgs/screenshare/default.nix b/pkgs/screenshare/default.nix new file mode 100644 index 0000000..aafd8f7 --- /dev/null +++ b/pkgs/screenshare/default.nix @@ -0,0 +1,7 @@ +{ writeShellApplication, sway }: + +writeShellApplication { + name = "screenshare"; + runtimeInputs = [ sway ]; + text = builtins.readFile ../../scripts/screenshare.sh; +} diff --git a/profiles/common/home/custom-packages.nix b/profiles/common/home/custom-packages.nix index 78cd337..69c10ae 100644 --- a/profiles/common/home/custom-packages.nix +++ b/profiles/common/home/custom-packages.nix @@ -15,6 +15,7 @@ fs-diff update-checker github-notifications + screenshare (pkgs.writeScriptBin "project" '' #! ${pkgs.bash}/bin/bash diff --git a/profiles/common/home/sway.nix b/profiles/common/home/sway.nix index bf9f301..9a49861 100644 --- a/profiles/common/home/sway.nix +++ b/profiles/common/home/sway.nix @@ -53,6 +53,7 @@ in "${modifier}+o" = "exec pass-fuzzel --otp"; "${modifier}+Shift+p" = "exec pass-fuzzel --type"; "${modifier}+Shift+o" = "exec pass-fuzzel --otp --type"; + "${modifier}+Ctrl+p" = "exec 1password --quick-acces"; "${modifier}+Escape" = "mode $exit"; "${modifier}+Shift+Escape" = "exec kitty -o confirm_os_window_close=0 btm"; "${modifier}+s" = "exec grim -g \"$(slurp)\" -t png - | wl-copy -t image/png"; @@ -157,6 +158,7 @@ in { title = "Syncthing Tray"; } { app_id = "SchildiChat"; } { app_id = "Element"; } + { class = "1Password"; } { app_id = "com.nextcloud.desktopclient.nextcloud"; } { app_id = "gnome-system-monitor"; } { title = "(?:Open|Save) (?:File|Folder|As)"; } diff --git a/profiles/common/home/zsh.nix b/profiles/common/home/zsh.nix index 090525f..16b17e9 100644 --- a/profiles/common/home/zsh.nix +++ b/profiles/common/home/zsh.nix @@ -1,25 +1,29 @@ -{ pkgs, ... }: +{ config, pkgs, lib, ... }: { programs.zsh = { enable = true; - shellAliases = { - hg = "history | grep"; - hmswitch = "cd ~/.dotfiles; home-manager --flake .#$(whoami)@$(hostname) switch; cd -;"; - nswitch = "cd ~/.dotfiles; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;"; - nswitch-stay = "cd ~/.dotfiles; git restore flake.lock; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;"; - edithome = "e -w ~/.dotfiles/SwarselSystems.org"; - magit = "emacsclient -nc -e \"(magit-status)\""; - config = "git --git-dir=$HOME/.cfg/ --work-tree=$HOME"; - g = "git"; - c = "git --git-dir=$HOME/.dotfiles/.git --work-tree=$HOME/.dotfiles/"; - passpush = "cd ~/.local/share/password-store; git add .; git commit -m 'pass file changes'; git push; cd -;"; - passpull = "cd ~/.local/share/password-store; git pull; cd -;"; - hotspot = "nmcli connection up local; nmcli device wifi hotspot;"; - cd = "z"; - cdr = "cd \"$( (find /home/swarsel/Documents/GitHub -maxdepth 1 && echo /home/swarsel/.dotfiles) | fzf )\""; - nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; - fs-diff = "sudo mount -o subvol=/ /dev/mapper/cryptroot /mnt ; fs-diff"; - }; + shellAliases = lib.recursiveUpdate + { + hg = "history | grep"; + hmswitch = "cd ~/.dotfiles; home-manager --flake .#$(whoami)@$(hostname) switch; cd -;"; + nswitch = "cd ~/.dotfiles; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;"; + nswitch-stay = "cd ~/.dotfiles; git restore flake.lock; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;"; + edithome = "e -w ~/.dotfiles/SwarselSystems.org"; + magit = "emacsclient -nc -e \"(magit-status)\""; + config = "git --git-dir=$HOME/.cfg/ --work-tree=$HOME"; + g = "git"; + c = "git --git-dir=$HOME/.dotfiles/.git --work-tree=$HOME/.dotfiles/"; + passpush = "cd ~/.local/share/password-store; git add .; git commit -m 'pass file changes'; git push; cd -;"; + passpull = "cd ~/.local/share/password-store; git pull; cd -;"; + hotspot = "nmcli connection up local; nmcli device wifi hotspot;"; + cd = "z"; + cdr = "cd \"$( (find /home/swarsel/Documents/GitHub -maxdepth 1 && echo /home/swarsel/.dotfiles) | fzf )\""; + nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; + fs-diff = "sudo mount -o subvol=/ /dev/mapper/cryptroot /mnt ; fs-diff"; + lt = "ls -lath"; + oldshell = "nix shell github:nixos/nixpkgs/\"$1\" \"$2\""; + } + config.swarselsystems.shellAliases; autosuggestion.enable = true; enableCompletion = true; syntaxHighlighting.enable = true; diff --git a/profiles/common/nixos/zsh.nix b/profiles/common/nixos/zsh.nix index db2ced4..32d72f5 100644 --- a/profiles/common/nixos/zsh.nix +++ b/profiles/common/nixos/zsh.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ lib, config, pkgs, ... }: { programs.zsh.enable = true; users.defaultUserShell = pkgs.zsh; diff --git a/profiles/nbl-imba-2/default.nix b/profiles/nbl-imba-2/default.nix index 3dd1f25..eedc025 100644 --- a/profiles/nbl-imba-2/default.nix +++ b/profiles/nbl-imba-2/default.nix @@ -92,6 +92,7 @@ { command = "teams-for-linux"; } { command = "1password"; } ]; + sharescreen = "eDP-2"; monitors = { main = { name = "BOE 0x0BC9 Unknown"; @@ -139,7 +140,7 @@ scale = "1"; position = "-1280,0"; workspace = "1:一"; - output = "DP-8"; + output = "DP-9"; }; work_middle_middle_side = { name = "Hewlett Packard HP Z24i CN44250RDT"; @@ -148,13 +149,13 @@ scale = "1"; position = "-2480,0"; workspace = "12:S"; - output = "DP-9"; + output = "DP-8"; }; work_seminary = { name = "Applied Creative Technology Transmitter QUATTRO201811"; mode = "1280x720"; scale = "1"; - position = "10000,10000"; + position = "10000,10000"; # i.e. this screen is inaccessible by moving the mouse workspace = "12:S"; output = "DP-4"; }; @@ -184,7 +185,13 @@ }; }; keybindings = { - "Mod4+Ctrl+p" = "exec wl-mirror eDP-2"; + "Mod4+Ctrl+Shift+p" = "exec screenshare"; + }; + shellAliases = { + ans2-15_3-9 = ". ~/.venvs/ansible39_2_15_0/bin/activate"; + ans3-9 = ". ~/.venvs/ansible39/bin/activate"; + ans = ". ~/.venvs/ansible/bin/activate"; + ans2-15 = ". ~/.venvs/ansible2.15.0/bin/activate"; }; }; } diff --git a/profiles/nbl-imba-2/hardware-configuration.nix b/profiles/nbl-imba-2/hardware-configuration.nix index 3ac3115..482e4d0 100644 --- a/profiles/nbl-imba-2/hardware-configuration.nix +++ b/profiles/nbl-imba-2/hardware-configuration.nix @@ -9,7 +9,7 @@ (modulesPath + "/installer/scan/not-detected.nix") ]; - boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "cryptd" "usbhid" "sd_mod" ]; + boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "cryptd" "usbhid" "sd_mod" "r8152" ]; boot.initrd.kernelModules = [ ]; boot.kernelModules = [ "kvm-amd" ]; boot.extraModulePackages = [ ]; diff --git a/profiles/optional/home/work.nix b/profiles/optional/home/work.nix index 7a3299f..796f34f 100644 --- a/profiles/optional/home/work.nix +++ b/profiles/optional/home/work.nix @@ -6,6 +6,7 @@ shellcheck dig docker + postman ]; programs = { diff --git a/profiles/server/common/calibre.nix b/profiles/server/common/calibre.nix new file mode 100644 index 0000000..c450c4c --- /dev/null +++ b/profiles/server/common/calibre.nix @@ -0,0 +1,32 @@ +{ pkgs, config, ... }: +{ + environment.systemPackages = with pkgs; [ + calibre + ]; + + sops.secrets.kavita = { owner = "kavita"; }; + + services.kavita = { + enable = true; + user = "kavita"; + port = 8080; + tokenKeyFile = config.sops.secrets.kavita.path; + }; + + services.nginx = { + "scroll.swarsel.win" = { + enableACME = true; + forceSSL = true; + acmeRoot = null; + locations = { + "/" = { + proxyPass = "http://192.168.1.22:8080"; + extraConfig = '' + client_max_body_size 0; + ''; + }; + }; + }; + }; + +} diff --git a/profiles/server/common/default.nix b/profiles/server/common/default.nix new file mode 100644 index 0000000..0cd21d8 --- /dev/null +++ b/profiles/server/common/default.nix @@ -0,0 +1,53 @@ +{ lib, config, inputs, ... }: +{ + imports = [ + ../../common/nixos/xserver.nix + ../../common/nixos/gc.nix + ../../common/nixos/store.nix + ../../common/nixos/time.nix + ../../common/nixos/pipewire.nix + ./packages.nix + ./sops.nix + ./ssh.nix + ./nginx.nix + ./kavita.nix + ./jellyfin.nix + ./navidrome.nix + ./spotifyd.nix + ./mpd.nix + ./matrix.nix + ]; + + nix = + let + flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs; + in + { + settings = { + experimental-features = [ + "nix-command" + "flakes" + "ca-derivations" + ]; + trusted-users = [ "swarsel" ]; + flake-registry = ""; + warn-dirty = false; + }; + channel.enable = false; + registry = lib.mapAttrs (_: flake: { inherit flake; }) flakeInputs; + nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs; + }; + + environment.shellAliases = lib.recursiveUpdate + { + npswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;"; + nswitch = "cd /.dotfiles; nixos-rebuild --flake .#$(hostname) switch; cd -;"; + } + config.swarselsystems.shellAliases; + + nixpkgs.config.permittedInsecurePackages = [ + "olm-3.2.16" + ]; + + system.stateVersion = lib.mkDefault "23.05"; +} diff --git a/profiles/server/common/jellyfin.nix b/profiles/server/common/jellyfin.nix new file mode 100644 index 0000000..39d0414 --- /dev/null +++ b/profiles/server/common/jellyfin.nix @@ -0,0 +1,44 @@ +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.jellyfin { + users.users.jellyfin = { + extraGroups = [ "video" "render" ]; + }; + nixpkgs.config.packageOverrides = pkgs: { + vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; }; + }; + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + intel-media-driver # LIBVA_DRIVER_NAME=iHD + vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium) + vaapiVdpau + libvdpau-va-gl + ]; + }; + services.jellyfin = { + enable = true; + user = "jellyfin"; + # openFirewall = true; # this works only for the default ports + }; + + services.nginx = { + virtualHosts = { + "screen.swarsel.win" = { + enableACME = true; + forceSSL = true; + acmeRoot = null; + locations = { + "/" = { + proxyPass = "http://192.168.1.16:8096"; + extraConfig = '' + client_max_body_size 0; + ''; + }; + }; + }; + }; + }; + }; + +} diff --git a/profiles/server/common/kavita.nix b/profiles/server/common/kavita.nix new file mode 100644 index 0000000..d901018 --- /dev/null +++ b/profiles/server/common/kavita.nix @@ -0,0 +1,35 @@ +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.kavita { + environment.systemPackages = with pkgs; [ + calibre + ]; + + sops.secrets.kavita = { owner = "kavita"; }; + + services.kavita = { + enable = true; + user = "kavita"; + settings.Port = 8080; + tokenKeyFile = config.sops.secrets.kavita.path; + }; + + services.nginx = { + virtualHosts = { + "scroll.swarsel.win" = { + enableACME = true; + forceSSL = true; + acmeRoot = null; + locations = { + "/" = { + proxyPass = "http://192.168.1.22:8080"; + extraConfig = '' + client_max_body_size 0; + ''; + }; + }; + }; + }; + }; + }; +} diff --git a/profiles/server/common/matrix.nix b/profiles/server/common/matrix.nix new file mode 100644 index 0000000..1ebc370 --- /dev/null +++ b/profiles/server/common/matrix.nix @@ -0,0 +1,273 @@ +{ config, lib, pkgs, modulesPath, sops, ... }: +let + matrixDomain = "swatrix.swarsel.win"; +in +{ + + config = lib.mkIf config.swarselsystems.server.matrix { + environment.systemPackages = with pkgs; [ + matrix-synapse + lottieconverter + ffmpeg + ]; + + sops = { + secrets = { + matrixsharedsecret = { owner = "matrix-synapse"; }; + mautrixtelegram_as = { owner = "matrix-synapse"; }; + mautrixtelegram_hs = { owner = "matrix-synapse"; }; + mautrixtelegram_api_id = { owner = "matrix-synapse"; }; + mautrixtelegram_api_hash = { owner = "matrix-synapse"; }; + }; + templates = { + "matrix_user_register.sh".content = '' + register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008 + ''; + matrixshared = { + owner = "matrix-synapse"; + content = '' + registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret} + ''; + }; + mautrixtelegram = { + owner = "matrix-synapse"; + content = '' + MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as} + MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs} + MAUTRIX_TELEGRAM_TELEGRAM_API_ID=${config.sops.placeholder.mautrixtelegram_api_id} + MAUTRIX_TELEGRAM_TELEGRAM_API_HASH=${config.sops.placeholder.mautrixtelegram_api_hash} + ''; + }; + }; + }; + + services.postgresql = { + enable = true; + initialScript = pkgs.writeText "synapse-init.sql" '' + CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; + CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + CREATE ROLE "mautrix-telegram" WITH LOGIN PASSWORD 'telegram'; + CREATE DATABASE "mautrix-telegram" WITH OWNER "mautrix-telegram" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + CREATE ROLE "mautrix-whatsapp" WITH LOGIN PASSWORD 'whatsapp'; + CREATE DATABASE "mautrix-whatsapp" WITH OWNER "mautrix-whatsapp" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + CREATE ROLE "mautrix-signal" WITH LOGIN PASSWORD 'signal'; + CREATE DATABASE "mautrix-signal" WITH OWNER "mautrix-signal" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + ''; + }; + + services.matrix-synapse = { + enable = true; + settings = { + app_service_config_files = [ + "/var/lib/matrix-synapse/telegram-registration.yaml" + "/var/lib/matrix-synapse/whatsapp-registration.yaml" + "/var/lib/matrix-synapse/signal-registration.yaml" + "/var/lib/matrix-synapse/doublepuppet.yaml" + ]; + server_name = matrixDomain; + public_baseurl = "https://${matrixDomain}"; + listeners = [ + { + port = 8008; + bind_addresses = [ "0.0.0.0" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ + { + names = [ "client" "federation" ]; + compress = true; + } + ]; + } + ]; + }; + extraConfigFiles = [ + config.sops.templates.matrixshared.path + ]; + }; + + services.mautrix-telegram = { + enable = true; + environmentFile = config.sops.templates.mautrixtelegram.path; + settings = { + homeserver = { + address = "http://localhost:8008"; + domain = matrixDomain; + }; + appservice = { + address = "http://localhost:29317"; + hostname = "0.0.0.0"; + port = "29317"; + provisioning.enabled = true; + id = "telegram"; + # ephemeral_events = true; # not needed due to double puppeting + public = { + enabled = false; + }; + database = "postgresql:///mautrix-telegram?host=/run/postgresql"; + }; + bridge = { + relaybot.authless_portals = true; + allow_avatar_remove = true; + allow_contact_info = true; + sync_channel_members = true; + startup_sync = true; + sync_create_limit = 0; + sync_direct_chats = true; + telegram_link_preview = true; + permissions = { + "*" = "relaybot"; + "@swarsel:${matrixDomain}" = "admin"; + }; + animated_sticker = { + target = "gif"; + args = { + width = 256; + height = 256; + fps = 30; # only for webm + background = "020202"; # only for gif, transparency not supported + }; + }; + }; + }; + }; + systemd.services.mautrix-telegram.path = with pkgs; [ + lottieconverter # for animated stickers conversion, unfree package + ffmpeg # if converting animated stickers to webm (very slow!) + ]; + + services.mautrix-whatsapp = { + enable = true; + settings = { + homeserver = { + address = "http://localhost:8008"; + domain = matrixDomain; + }; + appservice = { + address = "http://localhost:29318"; + hostname = "0.0.0.0"; + port = 29318; + database = { + type = "postgres"; + uri = "postgresql:///mautrix-whatsapp?host=/run/postgresql"; + }; + }; + bridge = { + displayname_template = "{{or .FullName .PushName .JID}} (WA)"; + history_sync = { + backfill = true; + max_initial_conversations = -1; + message_count = -1; + request_full_sync = true; + full_sync_config = { + days_limit = 900; + size_mb_limit = 5000; + storage_quota_mb = 5000; + }; + }; + login_shared_secret_map = { + matrixDomain = "as_token:doublepuppet"; + }; + sync_manual_marked_unread = true; + send_presence_on_typing = true; + parallel_member_sync = true; + url_previews = true; + caption_in_message = true; + extev_polls = true; + permissions = { + "*" = "relaybot"; + "@swarsel:${matrixDomain}" = "admin"; + }; + }; + }; + }; + + services.mautrix-signal = { + enable = true; + settings = { + homeserver = { + address = "http://localhost:8008"; + domain = matrixDomain; + }; + appservice = { + + address = "http://localhost:29328"; + hostname = "0.0.0.0"; + port = 29328; + database = { + type = "postgres"; + uri = "postgresql:///mautrix-signal?host=/run/postgresql"; + }; + }; + bridge = { + displayname_template = "{{or .ContactName .ProfileName .PhoneNumber}} (Signal)"; + login_shared_secret_map = { + matrixDomain = "as_token:doublepuppet"; + }; + caption_in_message = true; + permissions = { + "*" = "relaybot"; + "@swarsel:${matrixDomain}" = "admin"; + }; + }; + }; + }; + + # restart the bridges daily. this is done for the signal bridge mainly which stops carrying + # messages out after a while. + + systemd.timers."restart-bridges" = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "1d"; + OnUnitActiveSec = "1d"; + Unit = "restart-bridges.service"; + }; + }; + + systemd.services."restart-bridges" = { + script = '' + systemctl restart mautrix-whatsapp.service + systemctl restart mautrix-signal.service + systemctl restart mautrix-telegram.service + ''; + serviceConfig = { + Type = "oneshot"; + User = "root"; + }; + }; + + services.nginx = { + virtualHosts = { + "swatrix.swarsel.win" = { + enableACME = true; + forceSSL = true; + acmeRoot = null; + locations = { + "~ ^(/_matrix|/_synapse/client)" = { + proxyPass = "http://192.168.1.23:8008"; + extraConfig = '' + client_max_body_size 0; + ''; + }; + }; + }; + }; + }; + }; + + +} diff --git a/profiles/server/common/mpd.nix b/profiles/server/common/mpd.nix new file mode 100644 index 0000000..0380143 --- /dev/null +++ b/profiles/server/common/mpd.nix @@ -0,0 +1,51 @@ +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.mpd { + users = { + groups = { + mpd = { }; + }; + + users = { + mpd = { + isSystemUser = true; + group = "mpd"; + extraGroups = [ "audio" "utmp" ]; + }; + }; + }; + + sops = { + secrets.mpdpass = { owner = "mpd"; }; + }; + + environment.systemPackages = with pkgs; [ + pciutils + alsa-utils + mpv + ]; + + services.mpd = { + enable = true; + musicDirectory = "/media"; + user = "mpd"; + group = "mpd"; + network = { + port = 3254; + listenAddress = "any"; + }; + credentials = [ + { + passwordFile = config.sops.secrets.mpdpass.path; + permissions = [ + "read" + "add" + "control" + "admin" + ]; + } + ]; + }; + }; + +} diff --git a/profiles/server/common/navidrome.nix b/profiles/server/common/navidrome.nix new file mode 100644 index 0000000..fefd49b --- /dev/null +++ b/profiles/server/common/navidrome.nix @@ -0,0 +1,76 @@ +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.navidrome { + environment.systemPackages = with pkgs; [ + pciutils + alsa-utils + mpv + ]; + + users = { + groups = { + navidrome = { + gid = 61593; + }; + }; + + users = { + navidrome = { + isSystemUser = true; + uid = 61593; + group = "navidrome"; + extraGroups = [ "audio" "utmp" ]; + }; + }; + }; + + + hardware.enableAllFirmware = true; + + services.navidrome = { + enable = true; + settings = { + Address = "0.0.0.0"; + Port = 4040; + MusicFolder = "/media"; + EnableSharing = true; + EnableTranscodingConfig = true; + Scanner.GroupAlbumReleases = true; + ScanSchedule = "@every 1d"; + # Insert these values locally as sops-nix does not work for them + # LastFM.ApiKey = TEMPLATE; + # LastFM.Secret = TEMPLATE; + # Spotify.ID = TEMPLATE; + # Spotify.Secret = TEMPLATE; + UILoginBackgroundUrl = "https://i.imgur.com/OMLxi7l.png"; + UIWelcomeMessage = "~SwarselSound~"; + }; + }; + + services.nginx = { + virtualHosts = { + "sound.swarsel.win" = { + enableACME = true; + forceSSL = true; + acmeRoot = null; + locations = { + "/" = { + proxyPass = "http://192.168.1.13:4040"; + proxyWebsockets = true; + extraConfig = '' + proxy_redirect http:// https://; + proxy_read_timeout 600s; + proxy_send_timeout 600s; + proxy_buffering off; + proxy_request_buffering off; + client_max_body_size 0; + ''; + }; + }; + }; + }; + }; + }; + + +} diff --git a/profiles/server/common/nginx.nix b/profiles/server/common/nginx.nix new file mode 100644 index 0000000..75ac81e --- /dev/null +++ b/profiles/server/common/nginx.nix @@ -0,0 +1,30 @@ +{ pkgs, config, ... }: +{ + environment.systemPackages = with pkgs; [ + lego + ]; + sops = { + secrets.dnstokenfull = { owner = "acme"; }; + templates."certs.secret".content = '' + CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull} + ''; + }; + + security.acme = { + acceptTerms = true; + preliminarySelfsigned = false; + defaults.email = "mrswarsel@gmail.com"; + defaults.dnsProvider = "cloudflare"; + defaults.environmentFile = "${config.sops.templates."certs.secret".path}"; + }; + + services.nginx = { + enable = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + # virtualHosts are defined in the respective sections + }; + +} diff --git a/profiles/server/common/packages.nix b/profiles/server/common/packages.nix new file mode 100644 index 0000000..bf6098c --- /dev/null +++ b/profiles/server/common/packages.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: +{ + environment.systemPackages = with pkgs; [ + gnupg + nix-index + ssh-to-age + git + ]; +} diff --git a/profiles/server/common/sops.nix b/profiles/server/common/sops.nix new file mode 100644 index 0000000..1b7c375 --- /dev/null +++ b/profiles/server/common/sops.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: +{ + sops = { + age.sshKeyPaths = [ "/etc/ssh/sops" ]; + defaultSopsFile = "/.dotfiles/secrets/server/secrets.yaml"; + validateSopsFiles = false; + }; + +} diff --git a/profiles/server/common/spotifyd.nix b/profiles/server/common/spotifyd.nix new file mode 100644 index 0000000..09bfe42 --- /dev/null +++ b/profiles/server/common/spotifyd.nix @@ -0,0 +1,29 @@ +{ pkgs, lib, config, ... }: +{ + config = lib.mkIf config.swarselsystems.server.spotifyd { + users.groups.spotifyd = { + gid = 65136; + }; + + users.users.spotifyd = { + isSystemUser = true; + uid = 65136; + group = "spotifyd"; + extraGroups = [ "audio" "utmp" ]; + }; + services.spotifyd = { + enable = true; + settings = { + global = { + dbus_type = "session"; + use_mpris = false; + device = "default:CARD=PCH"; + device_name = "SwarselSpot"; + mixer = "alsa"; + zeroconf_port = 1025; + }; + }; + }; + }; + +} diff --git a/profiles/server/common/ssh.nix b/profiles/server/common/ssh.nix new file mode 100644 index 0000000..c3f2511 --- /dev/null +++ b/profiles/server/common/ssh.nix @@ -0,0 +1,11 @@ +_: +{ + services.openssh = { + enable = true; + settings.PermitRootLogin = "yes"; + }; + users.users.root.openssh.authorizedKeys.keyFiles = [ + ../../../secrets/keys/authorized_keys + ]; + +} diff --git a/profiles/server/winters/default.nix b/profiles/server/winters/default.nix new file mode 100644 index 0000000..0d5c4f0 --- /dev/null +++ b/profiles/server/winters/default.nix @@ -0,0 +1,54 @@ +{ inputs, outputs, config, pkgs, lib, ... }: +{ + + imports = [ + inputs.sops-nix.nixosModules.sops + + ./hardware-configuration.nix + + ../../optional/nixos/autologin.nix + ../../server/common + + ] ++ (builtins.attrValues outputs.nixosModules); + + + nixpkgs = { + inherit (outputs) overlays; + config = { + allowUnfree = true; + }; + }; + + + boot = { + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + kernelPackages = pkgs.linuxPackages_latest; + }; + + networking = { + hostName = "winters"; + firewall.enable = true; + }; + + + swarselsystems = { + hasBluetooth = false; + hasFingerprint = false; + impermanence = false; + isBtrfs = false; + server = { + enable = true; + kavita = true; + navidrome = true; + jellyfin = true; + spotifyd = true; + mpd = true; + matrix = true; + }; + shellAliases = { + nswitch = "cd /.dotfiles; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;"; + }; + }; + +} diff --git a/profiles/winters/home.nix b/profiles/winters/home.nix deleted file mode 100644 index b98dc87..0000000 --- a/profiles/winters/home.nix +++ /dev/null @@ -1,108 +0,0 @@ -{ config, pkgs, ... }: - -{ - - - - home = { - username = "swarsel"; - homeDirectory = "/home/swarsel"; - stateVersion = "23.05"; # TEMPLATE -- Please read the comment before changing. - keyboard.layout = "us"; # TEMPLATE - packages = with pkgs; [ - ]; - }; - sops.age.sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/sops" ]; - - # waybar config - TEMPLATE - update for cores and temp - programs.waybar.settings.mainBar = { - cpu.format = "{icon0} {icon1} {icon2} {icon3} {icon4} {icon5} {icon6} {icon7}"; - - temperature.hwmon-path.abs = "/sys/devices/platform/thinkpad_hwmon/hwmon/"; - temperature.input-filename = "temp1_input"; - }; - - - programs.waybar.settings.mainBar.modules-right = [ - "custom/outer-left-arrow-dark" - "mpris" - "custom/left-arrow-light" - "network" - "custom/left-arrow-dark" - "pulseaudio" - "custom/left-arrow-light" - "custom/pseudobat" - "battery" - "custom/left-arrow-dark" - "group/hardware" - "custom/left-arrow-light" - "clock#2" - "custom/left-arrow-dark" - "clock#1" - ]; - - - wayland.windowManager.sway = { - config = rec { - # update for actual inputs here, - input = { - "36125:53060:splitkb.com_Kyria_rev3" = { - xkb_layout = "us"; - xkb_variant = "altgr-intl"; - }; - "1:1:AT_Translated_Set_2_keyboard" = { - # TEMPLATE - xkb_layout = "us"; - xkb_options = "grp:win_space_toggle"; - xkb_variant = "altgr-intl"; - }; - "type:touchpad" = { - dwt = "enabled"; - tap = "enabled"; - natural_scroll = "enabled"; - middle_emulation = "enabled"; - }; - - }; - - output = { - eDP-1 = { - mode = "1920x1080"; # TEMPLATE - scale = "1"; - position = "1920,0"; - # bg = "~/.dotfiles/wallpaper/lenovowp.png fill"; - }; - # external monitor - HDMI-A-1 = { - mode = "2560x1440"; - scale = "1"; - # bg = "~/.dotfiles/wallpaper/lenovowp.png fill"; - position = "0,0"; - }; - }; - - workspaceOutputAssign = [ - { output = "eDP-1"; workspace = "1:一"; } - { output = "HDMI-A-1"; workspace = "2:二"; } - ]; - - - # keybindings = let - # inherit (config.wayland.windowManager.sway.config) modifier; - # in { - - # }; - - startup = [ - - { command = "nextcloud --background"; } - { command = "discord --start-minimized"; } - { command = "element-desktop --hidden -enable-features=UseOzonePlatform -ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; } - { command = "ANKI_WAYLAND=1 anki"; } - { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; } - { command = "nm-applet"; } - - ]; - }; - }; -} diff --git a/profiles/winters/nixos.nix b/profiles/winters/nixos.nix deleted file mode 100644 index 47cd4de..0000000 --- a/profiles/winters/nixos.nix +++ /dev/null @@ -1,142 +0,0 @@ -{ pkgs, ... }: - -{ - - # - # imports = - # [ - # ./hardware-configuration.nix - # ]; - # - imports = - [ - ./hardware-configuration.nix - ]; - - services = { - getty.autologinUser = "swarsel"; - greetd.settings.initial_session.user = "swarsel"; - }; - - boot = { - loader.systemd-boot.enable = true; - loader.efi.canTouchEfiVariables = true; - kernelPackages = pkgs.linuxPackages_latest; - }; - - networking = { - hostName = "winters"; # Define your hostname. - nftables.enable = true; - enableIPv6 = true; - firewall.checkReversePath = "strict"; - firewall = { - enable = true; - allowedUDPPorts = [ ]; - allowedTCPPorts = [ ]; - allowedTCPPortRanges = [ - ]; - allowedUDPPortRanges = [ - ]; - }; - }; - - virtualisation.virtualbox = { - host = { - enable = true; - enableExtensionPack = true; - }; - # leaving this here for future notice. setting guest.enable = true will make 'restarting sysinit-reactivation.target' take till timeout on nixos-rebuild switch - guest = { - enable = false; - }; - }; - - stylix.image = ../../wallpaper/lenovowp.png; - - enable = true; - base16Scheme = ../../../wallpaper/swarsel.yaml; - # base16Scheme = "${pkgs.base16-schemes}/share/themes/shapeshifter.yaml"; - polarity = "dark"; - opacity.popups = 0.5; - cursor = { - package = pkgs.capitaine-cursors; - name = "capitaine-cursors"; - size = 16; - }; - fonts = { - sizes = { - terminal = 10; - applications = 11; - }; - serif = { - # package = (pkgs.nerdfonts.override { fonts = [ "FiraMono" "FiraCode"]; }); - package = pkgs.cantarell-fonts; - # package = pkgs.montserrat; - name = "Cantarell"; - # name = "FiraCode Nerd Font Propo"; - # name = "Montserrat"; - }; - - sansSerif = { - # package = (pkgs.nerdfonts.override { fonts = [ "FiraMono" "FiraCode"]; }); - package = pkgs.cantarell-fonts; - # package = pkgs.montserrat; - name = "Cantarell"; - # name = "FiraCode Nerd Font Propo"; - # name = "Montserrat"; - }; - - monospace = { - package = pkgs.nerdfonts.override { fonts = [ "FiraCode" ]; }; - name = "FiraCode Nerd Font Mono"; - }; - - emoji = { - package = pkgs.noto-fonts-emoji; - name = "Noto Color Emoji"; - }; - }; - - - hardware = { - graphics = { - enable = true; - enable32Bit = true; - extraPackages = with pkgs; [ - ]; - }; - bluetooth.enable = true; - }; - - programs.steam = { - enable = true; - extraCompatPackages = [ - pkgs.proton-ge-bin - ]; - }; - - services.power-profiles-daemon.enable = true; - - users.users.swarsel = { - isNormalUser = true; - description = "Leon S"; - extraGroups = [ "networkmanager" "wheel" "lp" "audio" "video" "vboxusers" "scanner" ]; - packages = with pkgs; [ ]; - }; - - environment.systemPackages = with pkgs; [ - sbctl - teams-for-linux - # gog games installing - heroic - # minecraft - temurin-bin-17 - (prismlauncher.override { - glfw = pkgs.glfw-wayland-minecraft; - }) - ]; - - system.stateVersion = "23.05"; - - -} diff --git a/programs/swayidle/config b/programs/swayidle/config index d56ef16..d62ce8d 100644 --- a/programs/swayidle/config +++ b/programs/swayidle/config @@ -1,4 +1,4 @@ timeout 300 'swaylock -f --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2' -timeout 600 'swaymsg "output * dpms off"' -resume 'swaymsg "output * dpms on"' -before-sleep 'swaylock -f --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2' +# timeout 600 'swaymsg "output * dpms off"' +# resume 'swaymsg "output * dpms on"' +# before-sleep 'swaylock -f --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2' diff --git a/scripts/screenshare.sh b/scripts/screenshare.sh new file mode 100644 index 0000000..7674c40 --- /dev/null +++ b/scripts/screenshare.sh @@ -0,0 +1,5 @@ +SHARESCREEN="$(nix eval --raw ~/.dotfiles#nixosConfigurations."$(hostname)".config.home-manager.users."$(whoami)".swarselsystems.sharescreen)" + +wl-mirror "$SHARESCREEN" & sleep 0.1 +swaymsg '[app_id=at.yrlf.wl_mirror] move to workspace 12:S' +swaymsg '[app_id=at.yrlf.wl_mirror] fullscreen'