From cf289c8c48ebea72ceef3cd1805ab0aca72ad61f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sat, 28 Mar 2026 15:07:00 +0100 Subject: [PATCH] feat: monolith --- flake.nix | 1 + home/jonas@monolith/configuration.nix | 90 +++++++++++++++ home/jonas@monolith/default.nix | 27 +++++ hosts/monolith/default.nix | 1 + modules/desktop/plasma-fix.nix | 58 ++++++++++ modules/programs/gotify.nix | 155 ++++++++++++++++++++++++++ 6 files changed, 332 insertions(+) create mode 100644 home/jonas@monolith/configuration.nix create mode 100644 home/jonas@monolith/default.nix create mode 100644 modules/desktop/plasma-fix.nix create mode 100644 modules/programs/gotify.nix diff --git a/flake.nix b/flake.nix index ed7965e..3510761 100644 --- a/flake.nix +++ b/flake.nix @@ -45,6 +45,7 @@ ./hosts/comfy-station ./hosts/monolith (./home + "/jonas@comfy-station") + (./home + "/jonas@monolith") (import-tree ./modules) ]; }; diff --git a/home/jonas@monolith/configuration.nix b/home/jonas@monolith/configuration.nix new file mode 100644 index 0000000..3bcba0e --- /dev/null +++ b/home/jonas@monolith/configuration.nix @@ -0,0 +1,90 @@ +{ + config, + lib, + ... +}: rec { + # Home Manager needs a bit of information about you and the paths it should + # manage. + home.username = "jonas"; + home.homeDirectory = "/home/jonas"; + + sops = { + age.keyFile = "${home.homeDirectory}/.config/sops/age/keys.txt"; + }; + sops.secrets.gotifyDaemonToken = { + sopsFile = ../../secrets/jonas/gotify.yaml; + key = "monolithDesktopToken"; + }; + sops.secrets.gotifyCLIToken = { + sopsFile = ../../secrets/jonas/gotify.yaml; + key = "cliToken"; + }; + + # hive moduless + hive.doom.enable = true; + hive.doom.asDefaultEditor = true; + hive.doom.enableCopilot = false; + hive.doom.enableTidal = false; + hive.doom.withNixPkgs = true; + hive.doom.withShellPkgs = true; + hive.doom.withPythonPkgs = true; + hive.gotify = { + daemon.enable = true; + cli.tokenSopsKey = config.sops.secrets.gotifyCLIToken.name; + daemon.tokenSopsKey = config.sops.secrets.gotifyDaemonToken.name; + host = "gotify.jroeger.de"; + }; + + # Make session variables available in systemd units + # SEE: https://github.com/nix-community/home-manager/pull/5543 + # systemd.user.settings.Manager.DefaultEnvironment = + # lib.mapAttrs (_: lib.mkDefault) config.home.sessionVariables; + + xdg.mimeApps = { + enable = true; + + defaultApplications = { + "text/html" = "firefox.desktop"; + "x-scheme-handler/http" = "firefox.desktop"; + "x-scheme-handler/https" = "firefox.desktop"; + "x-scheme-handler/about" = "firefox.desktop"; + "x-scheme-handler/unknown" = "firefox.desktop"; + }; + }; + xdg.userDirs.enable = true; + xdg.userDirs.createDirectories = true; + xdg.userDirs.extraConfig = { + XDG_WORKSPACES_DIR = "${config.home.homeDirectory}/Workspaces"; + XDG_NEXTCLOUD_DIR = "${config.home.homeDirectory}/Nextcloud"; + XDG_NOTES_DIR = "${config.home.homeDirectory}/Notes"; + }; + + # This value determines the Home Manager release that your configuration is + # compatible with. This helps avoid breakage when a new Home Manager release + # introduces backwards incompatible changes. + # + # You should not change this value, even if you update Home Manager. If you do + # want to update the value, then make sure to first check the Home Manager + # release notes. + home.stateVersion = "24.11"; # Please read the comment before changing. + + home.sessionVariables = { + EDITOR = lib.mkDefault "vim"; + }; + + # Let Home Manager install and manage itself. + programs.home-manager.enable = true; + + # Git + programs.difftastic.enable = true; + programs.difftastic.git.enable = true; + programs.git = { + enable = true; + settings.user.name = "Jonas Röger"; + settings.user.email = "jonas.roeger@tu-dortmund.de"; + signing = { + signByDefault = true; + key = "4000EB35E1AE0F07"; + }; + }; +} diff --git a/home/jonas@monolith/default.nix b/home/jonas@monolith/default.nix new file mode 100644 index 0000000..0a23898 --- /dev/null +++ b/home/jonas@monolith/default.nix @@ -0,0 +1,27 @@ +{ + self, + inputs, + ... +}: { + flake.homeConfigurations."jonas@monolith" = inputs.home-manager.lib.homeManagerConfiguration { + pkgs = import inputs.nixpkgs {system = "x86_64-linux";}; + modules = [ + ({...}: {nixpkgs.config.allowUnfree = true;}) + + ./configuration.nix + + inputs.sops-nix.homeManagerModules.sops + self.homeModules.layan + self.homeModules.nextcloud-client + self.homeModules.firefox + self.homeModules.kdeconnect + self.homeModules.ranger + self.homeModules.yubikey + self.homeModules.zsh + self.homeModules.nix-scripts + self.homeModules.doom + self.homeModules.jj + self.homeModules.gotify + ]; + }; +} diff --git a/hosts/monolith/default.nix b/hosts/monolith/default.nix index 5a4bffd..f23bebb 100644 --- a/hosts/monolith/default.nix +++ b/hosts/monolith/default.nix @@ -17,6 +17,7 @@ self.nixosModules.nvidia self.nixosModules.ckb-next self.nixosModules.plasma + self.nixosModules.plasma-fix self.nixosModules.layan self.nixosModules.nix-scripts self.nixosModules.kwallet diff --git a/modules/desktop/plasma-fix.nix b/modules/desktop/plasma-fix.nix new file mode 100644 index 0000000..60f31fa --- /dev/null +++ b/modules/desktop/plasma-fix.nix @@ -0,0 +1,58 @@ +{ + # https://github.com/NixOS/nixpkgs/issues/126590#issuecomment-3194531220 + flake.nixosModules.plasma-fix = { + pkgs, + lib, + ... + }: { + nixpkgs.overlays = lib.singleton (final: prev: { + kdePackages = + prev.kdePackages + // { + plasma-workspace = let + # the package we want to override + basePkg = prev.kdePackages.plasma-workspace; + + # a helper package that merges all the XDG_DATA_DIRS into a single directory + xdgdataPkg = pkgs.stdenv.mkDerivation { + name = "${basePkg.name}-xdgdata"; + buildInputs = [basePkg]; + dontUnpack = true; + dontFixup = true; + dontWrapQtApps = true; + installPhase = '' + mkdir -p $out/share + ( IFS=: + for DIR in $XDG_DATA_DIRS; do + if [[ -d "$DIR" ]]; then + cp -r $DIR/. $out/share/ + chmod -R u+w $out/share + fi + done + ) + ''; + }; + + # undo the XDG_DATA_DIRS injection that is usually done in the qt wrapper + # script and instead inject the path of the above helper package + derivedPkg = basePkg.overrideAttrs { + preFixup = '' + for index in "''${!qtWrapperArgs[@]}"; do + if [[ ''${qtWrapperArgs[$((index+0))]} == "--prefix" ]] && [[ ''${qtWrapperArgs[$((index+1))]} == "XDG_DATA_DIRS" ]]; then + unset -v "qtWrapperArgs[$((index+0))]" + unset -v "qtWrapperArgs[$((index+1))]" + unset -v "qtWrapperArgs[$((index+2))]" + unset -v "qtWrapperArgs[$((index+3))]" + fi + done + qtWrapperArgs=("''${qtWrapperArgs[@]}") + qtWrapperArgs+=(--prefix XDG_DATA_DIRS : "${xdgdataPkg}/share") + qtWrapperArgs+=(--prefix XDG_DATA_DIRS : "$out/share") + ''; + }; + in + derivedPkg; + }; + }); + }; +} diff --git a/modules/programs/gotify.nix b/modules/programs/gotify.nix new file mode 100644 index 0000000..450f265 --- /dev/null +++ b/modules/programs/gotify.nix @@ -0,0 +1,155 @@ +{ + flake.homeModules.gotify = { + config, + lib, + pkgs, + ... + }: let + cfg = config.hive.gotify; + cli-config = { + token = config.sops.placeholder.${cfg.cli.tokenSopsKey}; + inherit (cfg.cli) url defaultPriority; + }; + daemon-config = { + gotify = + { + inherit (cfg.daemon) url; + token = config.sops.placeholder.${cfg.daemon.tokenSopsKey}; + auto_delete = cfg.daemon.autoDelete; + min_priority = cfg.daemon.minPriority; + } + // lib.optionalAttrs (cfg.daemon.onMsgCommand != null) { + on_msg_command = cfg.daemon.onMsgCommand; + }; + }; + + valueToString = val: + if (builtins.typeOf val == "string") + then "\"${val}\"" + else + ( + if (builtins.typeOf val == "int") + then "${toString val}" + else + ( + if (builtins.typeOf val == "bool") + then + ( + if val + then "true" + else "false" + ) + else (abort "Expected string int or bool, got ${builtins.typeOf val} with value ${toString val}") + ) + ); + + toTOML = attrs: + lib.concatStrings ( + lib.attrValues ( + lib.mapAttrs ( + name: config: '' + [${name}] + ${lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs (k: v: "${k} = ${valueToString v}") config))} + '' + ) + attrs + ) + ); + in { + options.hive.gotify = { + cli = { + enable = lib.mkEnableOption "Enable Gotify cli tool"; + url = lib.mkOption { + type = lib.types.singleLineStr; + default = "https://${cfg.host}:${toString cfg.port}"; + example = "http://gotify.example.com"; + description = "The http url of the gotify server (for the cli tool)"; + }; + tokenSopsKey = lib.mkOption { + type = lib.types.singleLineStr; + description = "The sops key of the token secret"; + }; + defaultPriority = lib.mkOption { + type = lib.types.int; + default = 0; + example = 3; + description = "The default priority of the dispatched messages"; + }; + }; + daemon = { + enable = lib.mkEnableOption "Enable the Gotify desktop notification daemon"; + url = lib.mkOption { + type = lib.types.singleLineStr; + default = "wss://${cfg.host}:${toString cfg.port}"; + example = "ws://gotify.example.com"; + description = "The websocket url of the gotify server (for the desktop tool)"; + }; + tokenSopsKey = lib.mkOption { + type = lib.types.singleLineStr; + description = "The sops key of the token secret"; + }; + autoDelete = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = "Delete messages that have been handled"; + }; + minPriority = lib.mkOption { + type = lib.types.int; + default = 0; + example = 1; + description = "Ignore messages with priority lower than given value"; + }; + onMsgCommand = lib.mkOption { + type = lib.types.nullOr lib.types.singleLineStr; + default = null; + example = "/usr/bin/beep"; + description = '' A command to tun for each message with env vars + GOTIFY_MSG_PRIORITY, GOTIFY_MSG_TITLE and GOTIFY_MSG_TEXTs + If unset use the standard desktop notification passing + ''; + }; + }; + host = lib.mkOption { + type = lib.types.singleLineStr; + example = "example.com"; + description = "The hostname of the gotify server"; + }; + port = lib.mkOption { + type = lib.types.int; + default = 443; + example = 443; + description = "The port of the gotify server"; + }; + }; + + config = let + cli = lib.mkIf cfg.cli.enable { + home.packages = [pkgs.gotify-cli]; + sops.templates."gotify-cli-json" = { + content = lib.generators.toJSON {} cli-config; + path = "${config.xdg.configHome}/gotify/cli.json"; + }; + }; + daemon = lib.mkIf cfg.daemon.enable { + systemd.user.services.gotify-desktop = { + Unit = { + Description = "Gotify Desktop notification service"; + After = ["sops-nix.service"]; # After the secrets have been rendered + }; + Service = { + ExecStart = "${pkgs.gotify-desktop}/bin/gotify-desktop"; + }; + Install = { + WantedBy = ["multi-user.target"]; + }; + }; + sops.templates."gotify-daemon-toml" = { + content = toTOML daemon-config; + path = "${config.xdg.configHome}/gotify-desktop/config.toml"; + }; + }; + in + lib.mkMerge [cli daemon]; + }; +}