diff --git a/README.md b/README.md index 4ef0367..7fd56ce 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Add this repo to your flake inputs: inputs.synix.url = "git+https://git.sid.ovh/sid/synix.git"; ``` -See the [documentation](https://doc.sid.ovh) for a full setup guide. +See the [documentation](https://doc.sid.ovh/synix) for a full setup guide. ## Templates diff --git a/apps/rebuild/default.nix b/apps/rebuild/default.nix index 21242c7..1a0eb11 100644 --- a/apps/rebuild/default.nix +++ b/apps/rebuild/default.nix @@ -6,7 +6,7 @@ home-manager, hostname, nix, - nixos-rebuild-ng, + nixos-rebuild, ... }: @@ -25,6 +25,6 @@ writeShellApplication { home-manager hostname nix - nixos-rebuild-ng + nixos-rebuild ]; } diff --git a/apps/rebuild/rebuild.sh b/apps/rebuild/rebuild.sh index 0b2ad24..752b9b7 100755 --- a/apps/rebuild/rebuild.sh +++ b/apps/rebuild/rebuild.sh @@ -1,20 +1,15 @@ # NixOS and standalone Home Manager rebuild script # Defaults -FLAKE_PATH="${REBUILD_FLAKE_PATH:-${FLAKE_PATH:-$HOME/.config/nixos}}" # Default flake path -USER="${REBUILD_USER:-$(whoami)}" # Default username -HOST="${REBUILD_HOST:-$(hostname)}" # Default hostname -BUILD_HOST="${REBUILD_BUILD_HOST:-}" # Default build host -TARGET_HOST="${REBUILD_TARGET_HOST:-}" # Default target host -UPDATE="${REBUILD_UPDATE:-0}" # Default to not update -UPDATE_INPUTS="${REBUILD_UPDATE_INPUTS:-}" # Default list of inputs -ROLLBACK="${REBUILD_ROLLBACK:-0}" # Default to not rollback -SHOW_TRACE="${REBUILD_SHOW_TRACE:-0}" # Default to not show trace - -# Output functions -_status() { echo -e "\033[0;34m> $1\033[0m"; } -success() { echo -e "\033[0;32m$1\033[0m"; } -error() { echo -e "\033[0;31mError: $1\033[0m" >&2; exit 1; } +FLAKE_PATH="$HOME/.config/nixos" # Default flake path +HOME_USER="$(whoami)" # Default username. Used to identify the Home Manager configuration +NIXOS_HOST="$(hostname)" # Default hostname. Used to identify the NixOS and Home Manager configuration +BUILD_HOST="" # Default build host. Empty means localhost +TARGET_HOST="" # Default target host. Empty means localhost +UPDATE=0 # Default to not update flake repositories +UPDATE_INPUTS="" # Default list of inputs to update. Empty means all +ROLLBACK=0 # Default to not rollback +SHOW_TRACE=0 # Default to not show detailed error messages # Function to display the help message Help() { @@ -28,7 +23,7 @@ Help() { echo " help Show this help message" echo echo "Options (for NixOS and Home Manager):" - echo " -H, --host Specify the hostname (as in 'nixosConfiguraions.'). Default: $HOST" + echo " -H, --host Specify the hostname (as in 'nixosConfiguraions.'). Default: $NIXOS_HOST" echo " -p, --path Set the path to the flake directory. Default: $FLAKE_PATH" echo " -U, --update [inputs] Update all flake inputs. Optionally provide comma-separated list of inputs to update instead." echo " -r, --rollback Don't build the new configuration, but use the previous generation instead" @@ -39,50 +34,47 @@ Help() { echo " -T, --target-host Deploy the configuration to a remote host via SSH. If '--host' is specified, it will be used as the target host." echo echo "Home Manager only options:" - echo " -u, --user Specify the username (as in 'homeConfigurations.@'). Default: $USER" + echo " -u, --user Specify the username (as in 'homeConfigurations.@'). Default: $HOME_USER" +} + +# Function to handle errors +error() { + echo "Error: $1" + exit 1 } # Function to rebuild NixOS configuration Rebuild_nixos() { - local FLAKE="$FLAKE_PATH#$HOST" + local FLAKE="$FLAKE_PATH#$NIXOS_HOST" # Construct rebuild command local CMD=("nixos-rebuild" "switch" "--sudo") + [[ -n "$TARGET_HOST" || -n "$BUILD_HOST" ]] && CMD+=("--ask-sudo-password") CMD+=("--flake" "$FLAKE") [ "$ROLLBACK" = 1 ] && CMD+=("--rollback") [ "$SHOW_TRACE" = 1 ] && CMD+=("--show-trace") [ -n "$BUILD_HOST" ] && CMD+=("--build-host" "$BUILD_HOST") - if [ "$HOST" != "$(hostname)" ] && [ -z "$TARGET_HOST" ]; then - TARGET_HOST="$HOST" - _status "Using '$TARGET_HOST' as target host." + if [ "$NIXOS_HOST" != "$(hostname)" ] && [ -z "$TARGET_HOST" ]; then + TARGET_HOST="$NIXOS_HOST" + echo "Using '$TARGET_HOST' as target host." fi [ -n "$TARGET_HOST" ] && CMD+=("--target-host" "$TARGET_HOST") - [[ -n "$TARGET_HOST" || -n "$BUILD_HOST" ]] && CMD+=("--ask-sudo-password") - # Build config first so we can diff it - local BUILD_CMD=("nixos-rebuild" "build" "--no-build-output" "--flake" "$FLAKE") - [ "$SHOW_TRACE" = 1 ] && BUILD_CMD+=("--show-trace") - [ -n "$BUILD_HOST" ] && BUILD_CMD+=("--build-host" "$BUILD_HOST") - - if [ "$ROLLBACK" = 0 ]; then - _status "Building NixOS configuration '$FLAKE'..." - _status "Executing command: ${BUILD_CMD[*]}" - "${BUILD_CMD[@]}" || error "NixOS build failed" - - _status "Switching to new NixOS configuration" + # Rebuild NixOS configuration + if [ "$ROLLBACK" = 0 ]; then + echo "Rebuilding NixOS configuration '$FLAKE'..." else - _status "Rolling back to last NixOS generation" + echo "Rolling back to last NixOS generation..." fi - sudo -v - _status "Executing command: ${CMD[*]}" + echo "Executing command: ${CMD[*]}" "${CMD[@]}" || error "NixOS rebuild failed" - success "NixOS rebuild completed successfully." + echo "NixOS rebuild completed successfully." } # Function to rebuild Home Manager configuration Rebuild_home() { - local FLAKE="$FLAKE_PATH#$USER@$HOST" + local FLAKE="$FLAKE_PATH#$HOME_USER@$NIXOS_HOST" if [ -n "$BUILD_HOST" ] || [ -n "$TARGET_HOST" ]; then error "Remote building is not supported for Home Manager." @@ -99,27 +91,21 @@ Rebuild_home() { [ "$SHOW_TRACE" = 1 ] && CMD+=("--show-trace") fi - # Build config first so we can diff it - if [ "$ROLLBACK" = 0 ]; then - local BUILD_CMD=("home-manager" "build" "--no-out-link" "--flake" "$FLAKE") - [ "$SHOW_TRACE" = 1 ] && BUILD_CMD+=("--show-trace") - _status "Building Home Manager configuration '$FLAKE'..." - _status "Executing command: ${BUILD_CMD[*]}" - "${BUILD_CMD[@]}" || error "Home Manager build failed" - - _status "Switching to new Home Manager configuration" + # Rebuild Home Manager configuration + if [ "$ROLLBACK" = 0 ]; then + echo "Rebuilding Home Manager configuration '$FLAKE'..." else - _status "Rolling back to last Home Manager generation" + echo "Rolling back to last Home Manager generation..." fi - _status "Executing command: ${CMD[*]}" + echo "Executing command: ${CMD[*]}" "${CMD[@]}" || error "Home Manager rebuild failed" - success "Home Manager rebuild completed successfully." + echo "Home Manager rebuild completed successfully." } -# Function to update flake repositories +# Function to Update flake repositories Update() { - _status "Updating flake inputs..." + echo "Updating flake inputs..." # Construct update command as an array local CMD=("nix" "flake" "update" "--flake" "$FLAKE_PATH") @@ -131,18 +117,17 @@ Update() { done fi - _status "Executing command: ${CMD[*]}" + echo "Executing command: ${CMD[*]}" "${CMD[@]}" || error "Failed to update flake repositories" - success "Flake repositories updated successfully." + echo "Flake repositories updated successfully." } # Parse command-line options if [[ -z "${1:-}" ]]; then - echo -e "\033[0;31mError: No command specified. Printing help page.\033[0m" >&2 + echo "Error: No command specified. Printing help page." Help exit 1 fi - COMMAND=$1 shift @@ -156,7 +141,7 @@ while [ $# -gt 0 ]; do case "${1:-}" in -H|--host) if [ -n "${2:-}" ]; then - HOST="$2" + NIXOS_HOST="$2" shift 2 else error "-H|--host option requires an argument" @@ -164,7 +149,7 @@ while [ $# -gt 0 ]; do ;; -u|--user) if [ -n "${2:-}" ]; then - USER="$2" + HOME_USER="$2" shift 2 else error "-u|--user option requires an argument" @@ -213,7 +198,9 @@ while [ $# -gt 0 ]; do fi ;; *) - error "Unknown option '$1'" + echo "Error: Unknown option '$1'" + Help + exit 1 ;; esac done @@ -240,10 +227,10 @@ fi [ "$UPDATE" = 1 ] && Update case "$COMMAND" in - nixos|os) + nixos) Rebuild_nixos ;; - home|hm) + home) Rebuild_home ;; all) @@ -251,6 +238,9 @@ case "$COMMAND" in Rebuild_home ;; *) - error "Unknown command '$COMMAND'" + echo "Error: Unknown command '$COMMAND'" + echo "Printing help page:" + Help + exit 1 ;; esac diff --git a/docs/modules/nixos/headplane.md b/docs/modules/nixos/headplane.md index d127125..e7b29a8 100644 --- a/docs/modules/nixos/headplane.md +++ b/docs/modules/nixos/headplane.md @@ -19,7 +19,7 @@ Provide the following entries to your `secrets.yaml`: ```yaml headplane: cookie_secret: abc123 - api_key: abc123 + agent_pre_authkey: abc123 ``` Generate your cookie secret with: @@ -28,7 +28,7 @@ Generate your cookie secret with: nix-shell -p openssl --run "openssl rand -hex 16" ``` -Generate your agent `api_key` with: +Generate your agent pre-authkey with: ```bash sudo headscale users create headplane-agent diff --git a/docs/modules/nixos/tailscale.md b/docs/modules/nixos/tailscale.md new file mode 100644 index 0000000..e703fd6 --- /dev/null +++ b/docs/modules/nixos/tailscale.md @@ -0,0 +1,36 @@ +# Tailscale + +Private WireGuard networks made easy. + +View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/tailscale). + +## References + +- [Website](https://tailscale.com/) +- [GitHub](https://github.com/tailscale/tailscale) +- [Documents](https://tailscale.com/kb/1017/install) + +## Sops + +Provide the following entries to your `secrets.yaml`: + +> Replace `abc123` with your actual secrets + +```yaml +tailscale: + auth-key: abc123 +``` + +## Config + +```nix +{ + imports = [ inputs.synix.nixosModules.tailscale ]; + + services.tailscale = { + enable = true; + enableSSH = true; + loginServer = ""; + }; +} +``` diff --git a/flake.lock b/flake.lock index d484c05..f7f569a 100644 --- a/flake.lock +++ b/flake.lock @@ -202,11 +202,11 @@ }, "flake-schemas": { "locked": { - "lastModified": 1776384880, - "narHash": "sha256-28Cg9HI/IwFHUm5fZyMEGCQ94L3Il6K4OfHeRf0b+Zw=", + "lastModified": 1770913512, + "narHash": "sha256-jRC1qRoRCrMjDalVfUMHFlKSkkA2q0RZWTDW0LsquoA=", "owner": "DeterminateSystems", "repo": "flake-schemas", - "rev": "b852751d29c6e09919f25c1e10754646bdc181c9", + "rev": "3c464b0e09cb44c6e073c41dd1d834980c3e0b24", "type": "github" }, "original": { @@ -258,11 +258,11 @@ ] }, "locked": { - "lastModified": 1776796298, - "narHash": "sha256-PcRvlWayisPSjd0UcRQbhG8Oqw78AcPE6x872cPRHN8=", + "lastModified": 1772024342, + "narHash": "sha256-+eXlIc4/7dE6EcPs9a2DaSY3fTA9AE526hGqkNID3Wg=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "3cfd774b0a530725a077e17354fbdb87ea1c4aad", + "rev": "6e34e97ed9788b17796ee43ccdbaf871a5c2b476", "type": "github" }, "original": { @@ -349,11 +349,11 @@ ] }, "locked": { - "lastModified": 1777851538, - "narHash": "sha256-Gp8qwTEYNoy2yvmErVGlvLOQvrtEECCAKbonW7VJef8=", + "lastModified": 1772020340, + "narHash": "sha256-aqBl3GNpCadMoJ/hVkWTijM1Aeilc278MjM+LA3jK6g=", "owner": "nix-community", "repo": "home-manager", - "rev": "cc09c0f9b7eaa95c2d9827338a5eb03d32505ca5", + "rev": "36e38ca0d9afe4c55405fdf22179a5212243eecc", "type": "github" }, "original": { @@ -465,11 +465,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1777673416, - "narHash": "sha256-5c2POKPOjU40Kh0MirOdScBLG0bu9TAuPYAtPRNZMBs=", + "lastModified": 1771903837, + "narHash": "sha256-sdaqdnsQCv3iifzxwB22tUwN/fSHoN7j2myFW5EIkGk=", "owner": "nixos", "repo": "nixpkgs", - "rev": "26ef669cffa904b6f6832ab57b77892a37c1a671", + "rev": "e764fc9a405871f1f6ca3d1394fb422e0a0c3951", "type": "github" }, "original": { @@ -511,11 +511,11 @@ ] }, "locked": { - "lastModified": 1777906128, - "narHash": "sha256-ei9g+4pCXhacUwnYuljs9v75hwfTqnfU+J6s6s8hfvc=", + "lastModified": 1772140017, + "narHash": "sha256-wFUc9tn5Ik11oL009BkVnj4NxsY63UbZjhOyEqCsIQE=", "owner": "nix-community", "repo": "NUR", - "rev": "c278c296b010e2a32838c8d4539a2d72c1686d4d", + "rev": "be0fea0af0e8cfadb3995dd7bb3a167bc012e935", "type": "github" }, "original": { @@ -605,11 +605,11 @@ "tinted-zed": "tinted-zed" }, "locked": { - "lastModified": 1777581180, - "narHash": "sha256-JcDBTZkkz68WlZKYDoD+MZG8b3dnIJXqMvyuVx3Wkdg=", + "lastModified": 1771788390, + "narHash": "sha256-RzBpBwn93GWxLjacTte+ngwwg0L/BVOg4G/sSIeK3Rw=", "owner": "nix-community", "repo": "stylix", - "rev": "a2538cd28ae2140ffce9cee9108b8d569a9c4fed", + "rev": "ebb238f14d6f930068be4718472da3105fd5d3bf", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index e06aedd..2c658d4 100644 --- a/flake.nix +++ b/flake.nix @@ -219,9 +219,17 @@ }; in testPkgs.testers.runNixOSTest ./tests/run/synapse.nix; - open-webui-oci-test = pkgs.testers.runNixOSTest ./tests/run/open-webui-oci.nix; - # librechat-oci-test = pkgs.testers.runNixOSTest ./tests/run/librechat-oci.nix; # FIXME: unable to copy from source docker://quay.io/mongo:7.0 + + # NOTE: disabled for now since the test takes too long to execute + # open-webui-oci-test = + # let + # testPkgs = import nixpkgs { + # inherit system; + # }; + # in + # testPkgs.testers.runNixOSTest ./tests/run/open-webui-oci.nix; } + ); hydraJobs = { @@ -281,10 +289,6 @@ path = ./templates/dev/rs-hello; description = "Rust hello world template."; }; - stm32-blink = { - path = ./templates/dev/stm32-blink; - description = "STM32G4 blink template with libopencm3."; - }; }; }; } diff --git a/mkdocs.yml b/mkdocs.yml index d86ce99..8a18b20 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -58,6 +58,7 @@ nav: - radicale: modules/nixos/radicale.md - rss-bridge: modules/nixos/rss-bridge.md - sops: modules/nixos/sops.md + - tailscale: modules/nixos/tailscale.md - virtualisation: modules/nixos/virtualisation.md - webPage: modules/nixos/webpage.md - Home Manager: diff --git a/modules/home/hyprland/applications/bitwarden/default.nix b/modules/home/hyprland/applications/bitwarden/default.nix deleted file mode 100644 index bae501f..0000000 --- a/modules/home/hyprland/applications/bitwarden/default.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ - inputs, - config, - lib, - pkgs, - ... -}: - -let - cfg = config.wayland.windowManager.hyprland; - app = cfg.applications.password-manager.default; - - inherit (lib) mkDefault mkIf; -in -{ - imports = [ ../../../rofi-rbw ]; - - config = mkIf (cfg.enable && app == "rofi-rbw") { - programs.rbw = { - enable = true; - settings = { - # email = "you@example.tld"; # You have to set this in your config - pinentry = mkDefault pkgs.pinentry-gnome3; - lock_timeout = mkDefault 3600; - }; - }; - - programs.rofi-rbw = { - enable = true; - package = mkDefault pkgs.rofi-rbw-wayland; - settings = { - selector = mkDefault "bemenu"; - selector-args = mkDefault "-i -l 20"; - action = mkDefault "copy"; - typing-key-delay = mkDefault 0; - }; - }; - - programs.librewolf = mkIf config.programs.librewolf.enable { - profiles.default.extensions.packages = - with inputs.nur.legacyPackages."${pkgs.stdenv.hostPlatform.system}".repos.rycee.firefox-addons; [ - bitwarden - ]; - }; - }; -} diff --git a/modules/home/hyprland/applications/default.nix b/modules/home/hyprland/applications/default.nix index 661d47e..193c696 100644 --- a/modules/home/hyprland/applications/default.nix +++ b/modules/home/hyprland/applications/default.nix @@ -56,10 +56,8 @@ let in { imports = [ - ./bitwarden ./bemenu ./dmenu-bluetooth - ./dunst-toggle ./element-desktop ./feh ./kitty @@ -137,11 +135,6 @@ in bind = [ "$mod SHIFT, m, exec, ${terminal} -T ${musicplayer} -e ${musicplayer}" ]; }; - notifications = mkAppAttrs { - default = "dunst-toggle"; - bind = [ "$mod, Backspace, exec, ${notifications}" ]; - }; - networksettings = mkAppAttrs { default = "networkmanager_dmenu"; bind = [ "$mod SHIFT, n, exec, ${networksettings}" ]; diff --git a/modules/home/hyprland/applications/dunst-toggle/default.nix b/modules/home/hyprland/applications/dunst-toggle/default.nix deleted file mode 100644 index 69e4938..0000000 --- a/modules/home/hyprland/applications/dunst-toggle/default.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: - -let - cfg = config.wayland.windowManager.hyprland; - app = cfg.applications.notifications.default; - - inherit (lib) mkIf; -in -{ - config = mkIf (cfg.enable && app == "dunst-toggle") { - home.packages = [ (import ./dunst-toggle.nix { inherit config pkgs; }) ]; - }; -} diff --git a/modules/home/hyprland/applications/dunst-toggle/dunst-toggle.nix b/modules/home/hyprland/applications/dunst-toggle/dunst-toggle.nix deleted file mode 100644 index 248faec..0000000 --- a/modules/home/hyprland/applications/dunst-toggle/dunst-toggle.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ config, pkgs, ... }: - -let - dunst = "${pkgs.dunst}/bin/dunstctl"; - pkill = "${pkgs.procps}/bin/pkill"; - signal = "${toString config.programs.waybar.settings.mainBar."custom/notifications".signal}"; -in -(pkgs.writeShellScriptBin "dunst-toggle" '' - ${dunst} set-paused toggle - ${pkill} -RTMIN+${signal} waybar -'') diff --git a/modules/home/hyprland/settings.nix b/modules/home/hyprland/settings.nix index f9bc9af..2c61471 100644 --- a/modules/home/hyprland/settings.nix +++ b/modules/home/hyprland/settings.nix @@ -3,30 +3,15 @@ let cfg = config.wayland.windowManager.hyprland; - nonCenterFloatingClasses = [ - "Gimp" - "steam" - "KiCad" - ]; - - nonCenterFloatingClassesRegex = concatStringsSep "|" nonCenterFloatingClasses; - - inherit (builtins) concatStringsSep toString; + inherit (builtins) toString; inherit (lib) mkDefault; in { # Do not add binds here. Use `./binds/default.nix` instead. "$mod" = cfg.modifier; - exec-once = [ - "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP" # dbus package comes from NixOS module option `services.dbus.dbusPackage` [1] - "gnome-keyring-daemon --start --components=secrets" # gnome-keyring package comes from NixOS module `services.gnome.gnome-keyring` [1] - ]; - # 1: see Hyprland NixOS module - windowrule = [ - # "float, class:^(${nonCenterFloatingClassesRegex})$" - "center, floating:1, class:^(?!.*(${nonCenterFloatingClassesRegex})).*$" + "center, floating:1, not class:^(Gimp)$, not class:^(steam)$" "float, title:^(Open|Save) Files?$" "noborder, onworkspace:w[t1]" "bordersize ${toString cfg.settings.general.border_size}, floating:1" @@ -39,12 +24,6 @@ in "noblur, class:^(xwaylandvideobridge)$" ]; - gesture = [ - "3, horizontal, workspace" - "3, up, dispatcher, exec, bemenu-run" # TODO: move to hyprland.applications - "4, swipe, move" - ]; - # Layouts general.layout = mkDefault "master"; master = { diff --git a/modules/home/nixvim/keymaps.nix b/modules/home/nixvim/keymaps.nix index c791995..aaefaa0 100644 --- a/modules/home/nixvim/keymaps.nix +++ b/modules/home/nixvim/keymaps.nix @@ -1,71 +1,79 @@ [ + # cursor navigation { - options.desc = "scroll down, recenter"; + # scroll down, recenter key = ""; action = "zz"; mode = "n"; } { - options.desc = "scroll up, recenter"; + # scroll up, recenter key = ""; action = "zz"; mode = "n"; } + + # searching { - options.desc = "center cursor after search next"; + # center cursor after search next key = "n"; action = "nzzzv"; mode = "n"; } { - options.desc = "center cursor after search previous"; + # center cursor after search previous key = "N"; action = "Nzzzv"; mode = "n"; } { - options.desc = "ex command"; + # ex command key = "pv"; action = "Ex"; mode = "n"; } + + # search and replace { - options.desc = "search and replace word under cursor"; + # search and replace word under cursor key = "s"; action = ":%s///gI"; mode = "n"; } + # search and replace selected text { key = "s"; action = "y:%s/0/0/gI"; mode = "v"; } + + # clipboard operations { - options.desc = "copy to system clipboard in visual mode"; + # copy to system clipboard in visual mode key = ""; action = ''"+y ''; mode = "v"; } { - options.desc = "paste from system clipboard in visual mode"; + # paste from system clipboard in visual mode key = ""; action = ''"+p ''; mode = "v"; } { - options.desc = "yank to system clipboard"; + # yank to system clipboard key = "Y"; action = "+Y"; mode = "n"; } { - options.desc = "replace selected text with clipboard content"; + # replace selected text with clipboard content key = "p"; action = "_dP"; mode = "x"; } { - options.desc = "delete without copying to clipboard"; + # delete without copying to clipboard key = "d"; action = "_d"; mode = [ @@ -73,184 +81,267 @@ "v" ]; } + + # line operations { - options.desc = "move lines down in visual mode"; + # move lines down in visual mode key = "J"; action = ":m '>+1gv=gv"; mode = "v"; } { - options.desc = "move lines up in visual mode"; + # move lines up in visual mode key = "K"; action = ":m '<-2gv=gv"; mode = "v"; } { - options.desc = "join lines"; + # join lines key = "J"; action = "mzJ`z"; mode = "n"; } + + # quickfix { - options.desc = "Run make command"; + # Run make command key = "m"; action = ":make"; mode = "n"; } { - options.desc = "previous quickfix item"; + # previous quickfix item key = ""; action = "cprevzz"; mode = "n"; } { - options.desc = "next quickfix item"; + # next quickfix item key = ""; action = "cnextzz"; mode = "n"; } + + # location list navigation { - options.desc = "previous location list item"; + # previous location list item key = "j"; action = "lprevzz"; mode = "n"; } { - options.desc = "next location list item"; + # next location list item key = "k"; action = "lnextzz"; mode = "n"; } + + # disabling keys { - options.desc = "disable the 'Q' key"; + # disable the 'Q' key key = "Q"; action = ""; mode = "n"; } + + # text selection { - options.desc = "select whole buffer"; + # select whole buffer key = ""; action = "ggVG"; mode = "n"; } + + # window operations { - options.desc = "focus next window"; + # focus next window key = ""; action = ":wincmd W"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "focus next window"; - key = ""; - action = ":wincmd W"; - mode = "n"; - } - { - options.desc = "focus previous window"; + # focus previous window key = ""; action = ":wincmd w"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } + + # window size adjustments { - options.desc = "focus previous window"; - key = ""; - action = ":wincmd w"; - mode = "n"; - } - { - options.desc = "increase window width"; + # increase window width key = ""; action = ":vertical resize +5"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "decrease window width"; + # decrease window width key = ""; action = ":vertical resize -5"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } + + # window closing and opening { - options.desc = "close current window"; + # close current window key = "c"; action = ":q"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "new vertical split at $HOME"; + # new vertical split at $HOME key = "n"; action = ":vsp $HOME"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } + + # window split orientation toggling { - options.desc = "toggle split orientation"; + # toggle split orientation key = "t"; action = ":wincmd T"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } + + # spell checking { - options.desc = "toggle spell checking"; + # toggle spell checking key = "ss"; action = ":setlocal spell!"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "switch to english spell checking"; + # switch to english spell checking key = "se"; action = ":setlocal spelllang=en_us"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "switch to german spell checking"; + # switch to german spell checking key = "sg"; action = ":setlocal spelllang=de_20"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "move to next misspelling"; + # move to next misspelling key = "]s"; action = "]szz"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "move to previous misspelling"; + # move to previous misspelling key = "[s"; action = "[szz"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "correction suggestions for a misspelled word"; + # correction suggestions for a misspelled word key = "z="; action = "z="; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "adding words to the dictionary"; + # adding words to the dictionary key = "zg"; action = "zg"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } + + # buffer navigation { - options.desc = "next buffer"; + # next buffer key = ""; action = ":bnext"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "previous buffer"; + # previous buffer key = ""; action = ":bprevious"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } { - options.desc = "close current buffer"; + # close current buffer key = "bd"; action = ":bdelete"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } + { - options.desc = "apply code action"; + # apply code action key = "ca"; action = ":lua vim.lsp.buf.code_action()"; + options = { + noremap = true; + silent = true; + }; mode = "n"; } ] diff --git a/modules/home/nixvim/plugins/default.nix b/modules/home/nixvim/plugins/default.nix index 508d3c7..1941f43 100644 --- a/modules/home/nixvim/plugins/default.nix +++ b/modules/home/nixvim/plugins/default.nix @@ -3,17 +3,14 @@ { imports = [ ./cmp.nix - ./diffview.nix ./lsp.nix - ./gitsigns.nix ./lualine.nix ./telescope.nix - ./treesitter.nix + # ./treesitter.nix # HOTFIX: does not build ./trouble.nix ]; config.programs.nixvim.plugins = { - which-key.enable = lib.mkDefault true; markdown-preview.enable = lib.mkDefault true; # warning: Nixvim: `plugins.web-devicons` was enabled automatically because the following plugins are enabled. This behaviour is deprecated. Please explicitly define `plugins.web-devicons.enable` web-devicons.enable = true; diff --git a/modules/home/nixvim/plugins/diffview.nix b/modules/home/nixvim/plugins/diffview.nix deleted file mode 100644 index e405578..0000000 --- a/modules/home/nixvim/plugins/diffview.nix +++ /dev/null @@ -1,59 +0,0 @@ -{ config, lib, ... }: - -let - cfg = config.programs.nixvim; - plugin = cfg.plugins.diffview; - - inherit (lib) mkDefault mkIf; -in -{ - config = { - programs.nixvim = { - plugins.diffview = { - enable = mkDefault true; - }; - - # highlight = mkIf plugin.enable { - # DiffAdd = { - # bg = "#2d4a2d"; - # fg = "NONE"; - # }; - # DiffDelete = { - # bg = "#4a2d2d"; - # fg = "NONE"; - # }; - # DiffChange = { - # bg = "#2d3a4a"; - # fg = "NONE"; - # }; - # DiffText = { - # bg = "#1a5a1a"; - # fg = "NONE"; - # }; - # }; - - keymaps = mkIf plugin.enable [ - { - mode = "n"; - key = "gd"; - action.__raw = '' - function() - local lib = require("diffview.lib") - local view = lib.get_current_view() - if view then - vim.cmd("DiffviewClose") - else - vim.cmd("DiffviewOpen") - end - end - ''; - options = { - noremap = true; - silent = true; - desc = "toggle git diff"; - }; - } - ]; - }; - }; -} diff --git a/modules/home/nixvim/plugins/gitsigns.nix b/modules/home/nixvim/plugins/gitsigns.nix deleted file mode 100644 index 651b83d..0000000 --- a/modules/home/nixvim/plugins/gitsigns.nix +++ /dev/null @@ -1,104 +0,0 @@ -{ config, lib, ... }: - -let - cfg = config.programs.nixvim; - plugin = cfg.plugins.gitsigns; - - inherit (lib) mkDefault mkIf; -in -{ - config = { - programs.nixvim = { - plugins.gitsigns = { - enable = mkDefault true; - settings = { - current_line_blame = mkDefault false; - current_line_blame_opts = { - virt_text = mkDefault true; - virt_text_pos = mkDefault "eol"; - }; - signcolumn = mkDefault true; - signs = { - add.text = mkDefault "+"; - change.text = mkDefault "│"; - changedelete.text = mkDefault "~"; - delete.text = mkDefault "-"; - topdelete.text = mkDefault "-"; - untracked.text = mkDefault "?"; - }; - watch_gitdir.follow_files = mkDefault true; - }; - }; - keymaps = mkIf plugin.enable [ - { - mode = "n"; - key = "hs"; - action.__raw = "function() require('gitsigns').stage_hunk() end"; - options = { - noremap = true; - silent = true; - desc = "stage hunk"; - }; - } - { - mode = "v"; - key = "hs"; - action.__raw = '' - function() - require('gitsigns').stage_hunk({vim.fn.line('.'), vim.fn.line('v')}) - end - ''; - options = { - noremap = true; - silent = true; - desc = "stage selected hunks"; - }; - } - { - mode = "n"; - key = "hu"; - action.__raw = "function() require('gitsigns').undo_stage_hunk() end"; - options = { - noremap = true; - silent = true; - desc = "undo stage hunk"; - }; - } - { - mode = "n"; - key = "hS"; - action.__raw = "function() require('gitsigns').stage_buffer() end"; - options = { - noremap = true; - silent = true; - desc = "stage buffer"; - }; - } - { - mode = "n"; - key = "hr"; - action.__raw = "function() require('gitsigns').reset_hunk() end"; - options = { - noremap = true; - silent = true; - desc = "reset hunk"; - }; - } - { - mode = "v"; - key = "hr"; - action.__raw = '' - function() - require('gitsigns').reset_hunk({vim.fn.line('.'), vim.fn.line('v')}) - end - ''; - options = { - noremap = true; - silent = true; - desc = "reset selected hunks"; - }; - } - ]; - }; - }; -} diff --git a/modules/home/nixvim/plugins/telescope.nix b/modules/home/nixvim/plugins/telescope.nix index e1ba4b6..6e1dabc 100644 --- a/modules/home/nixvim/plugins/telescope.nix +++ b/modules/home/nixvim/plugins/telescope.nix @@ -16,31 +16,6 @@ in programs.nixvim = { plugins.telescope = { enable = mkDefault true; - settings = { - defaults = { - vimgrep_arguments = [ - "rg" - "--color=never" - "--no-heading" - "--with-filename" - "--line-number" - "--column" - "--smart-case" - "--hidden" - ]; - file_ignore_patterns = [ - "^.git/" - "^.direnv/" - "^.cache/" - "^node_modules/" - ]; - }; - pickers = { - find_files = { - hidden = true; - }; - }; - }; extensions = { file-browser.enable = mkDefault true; fzf-native.enable = mkDefault true; diff --git a/modules/home/nixvim/spellfiles.nix b/modules/home/nixvim/spellfiles.nix index 58612f9..35b4a6e 100644 --- a/modules/home/nixvim/spellfiles.nix +++ b/modules/home/nixvim/spellfiles.nix @@ -2,7 +2,7 @@ let spellDir = config.xdg.dataHome + "/nvim/site/spell"; - baseUrl = "https://vim.ftp.fu-berlin.de/runtime/spell"; + baseUrl = "http://ftp.de.vim.org/runtime/spell"; in { home.file = { @@ -12,7 +12,7 @@ in url = baseUrl + "/de.utf-8.spl"; sha256 = "sha256-c8cQfqM5hWzb6SHeuSpFk5xN5uucByYdobndGfaDo9E="; }; - target = spellDir + "/de.utf-8.spl"; + target = spellDir + "/de.utf8.spl"; }; de-sug = { enable = true; @@ -20,7 +20,7 @@ in url = baseUrl + "/de.utf-8.sug"; sha256 = "sha256-E9Ds+Shj2J72DNSopesqWhOg6Pm6jRxqvkerqFcUqUg="; }; - target = spellDir + "/de.utf-8.sug"; + target = spellDir + "/de.utf8.sug"; }; }; } diff --git a/modules/home/stylix/default.nix b/modules/home/stylix/default.nix index 04c26a8..34fd04f 100644 --- a/modules/home/stylix/default.nix +++ b/modules/home/stylix/default.nix @@ -17,7 +17,6 @@ let "moonfly" "nord" "oxocarbon" - "generate-from-image" ]; # schemes names in `pkgs.base16-schemes` that need a suffix needsSuffix = [ @@ -31,6 +30,11 @@ let ]; schemeName = if builtins.elem cfg.scheme needsSuffix then "${cfg.scheme}-${cfg.polarity}" else cfg.scheme; + scheme = + if builtins.elem cfg.scheme customSchemes then + ./schemes/${schemeName}.yaml + else + "${pkgs.base16-schemes}/share/themes/${schemeName}.yaml"; inherit (lib) mkDefault @@ -52,8 +56,6 @@ in description = '' Base16 color scheme name. Available options are: ${toString validSchemes} - - "generate-from-image" generates a color scheme from `stylix.image` ''; }; }; @@ -68,12 +70,7 @@ in stylix = { autoEnable = mkDefault true; - base16Scheme = mkIf (cfg.scheme != "generate-from-image") ( - if builtins.elem cfg.scheme customSchemes then - ./schemes/${schemeName}.yaml - else - "${pkgs.base16-schemes}/share/themes/${schemeName}.yaml" - ); + base16Scheme = scheme; fonts = { monospace = mkDefault { package = pkgs.hack-font; diff --git a/modules/home/stylix/targets/nixvim.nix b/modules/home/stylix/targets/nixvim.nix index b6dbec4..7fcdd33 100644 --- a/modules/home/stylix/targets/nixvim.nix +++ b/modules/home/stylix/targets/nixvim.nix @@ -4,13 +4,11 @@ let cfg = config.stylix; target = cfg.targets.nixvim; - inherit (lib) mkIf optionalAttrs; + inherit (lib) mkIf; in { config = mkIf cfg.enable { stylix.targets.nixvim.enable = false; - programs.nixvim.colorschemes = optionalAttrs (cfg.scheme != "generate-from-image") { - "${cfg.scheme}".enable = !target.enable; - }; + programs.nixvim.colorschemes."${cfg.scheme}".enable = !target.enable; }; } diff --git a/modules/home/stylix/targets/waybar.nix b/modules/home/stylix/targets/waybar.nix index 2f51691..a533515 100644 --- a/modules/home/stylix/targets/waybar.nix +++ b/modules/home/stylix/targets/waybar.nix @@ -71,11 +71,11 @@ in #workspaces { color: ${colors.base05}; + background: ${colors.base00}; } #workspaces button { padding: ${halfgaps}px; - color: ${colors.base05}; } #workspaces button.active { diff --git a/modules/home/waybar/default.nix b/modules/home/waybar/default.nix index 6a208a3..ea794ce 100644 --- a/modules/home/waybar/default.nix +++ b/modules/home/waybar/default.nix @@ -56,7 +56,6 @@ let }; # Add your custom modules here - "custom/notifications" = import ./modules/notifications.nix { inherit lib pkgs; }; "custom/newsboat" = import ./modules/newsboat.nix { inherit lib pkgs; }; "pulseaudio#input" = import ./modules/pulseaudio/input.nix { inherit lib pkgs; }; "pulseaudio#output" = import ./modules/pulseaudio/output.nix { inherit lib pkgs; }; @@ -96,13 +95,11 @@ in "disk" "pulseaudio#input" "pulseaudio#output" - "custom/notifications" "tray" ]; inherit "custom/newsboat" - "custom/notifications" "hyprland/language" "hyprland/workspaces" "pulseaudio#input" @@ -132,7 +129,5 @@ in }; }; }; - - services.batsignal.enable = builtins.elem "battery" cfg.settings.mainBar.modules-right; }; } diff --git a/modules/home/waybar/modules/notifications.nix b/modules/home/waybar/modules/notifications.nix deleted file mode 100644 index 1f21931..0000000 --- a/modules/home/waybar/modules/notifications.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ pkgs, lib, ... }: - -let - inherit (lib) mkDefault; - dunst = "${pkgs.dunst}/bin/dunstctl"; -in -{ - format = mkDefault "{icon}"; - format-icons = { - unmuted = mkDefault ""; - muted = mkDefault ""; - }; - return-type = mkDefault "json"; - exec = mkDefault ( - pkgs.writeShellScript "notifications" '' - is_paused=$(${dunst} is-paused) - if [ "$is_paused" = "true" ]; then - echo '{"alt": "muted", "class": "muted"}' - else - echo '{"alt": "unmuted", "class": "unmuted"}' - fi - '' - ); - on-click = mkDefault "dunst-toggle"; - interval = mkDefault "once"; - signal = mkDefault 12; -} diff --git a/modules/nixos/amd/default.nix b/modules/nixos/amd/default.nix index 4884cef..252d991 100644 --- a/modules/nixos/amd/default.nix +++ b/modules/nixos/amd/default.nix @@ -6,19 +6,19 @@ environment.systemPackages = with pkgs; [ lact nvtopPackages.amd + rocmPackages.clr.icd rocmPackages.hipcc rocmPackages.miopen rocmPackages.rocm-runtime rocmPackages.rocm-smi rocmPackages.rocminfo + ]; # environment.variables.ROC_ENABLE_PRE_VEGA = "1"; # for Polaris hardware.amdgpu.opencl.enable = true; - hardware.graphics.extraPackages = with pkgs; [ rocmPackages.clr.icd ]; - systemd.packages = with pkgs; [ lact ]; systemd.services.lactd.wantedBy = [ "multi-user.target" ]; } diff --git a/modules/nixos/common/boot.nix b/modules/nixos/common/boot.nix deleted file mode 100644 index 2eaf9cf..0000000 --- a/modules/nixos/common/boot.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ lib, pkgs, ... }: - -{ - # fix CVE-2026-31431 - boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.18.22") ( - lib.mkDefault pkgs.linuxPackages_6_18 - ); - - # fix CVE-2026-43500 - boot.extraModprobeConfig = '' - install esp4 ${pkgs.coreutils}/bin/false - install esp6 ${pkgs.coreutils}/bin/false - install rxrpc ${pkgs.coreutils}/bin/false - ''; - boot.blacklistedKernelModules = [ - "esp4" - "esp6" - "rxrpc" - ]; -} diff --git a/modules/nixos/common/default.nix b/modules/nixos/common/default.nix index bea1546..9847a07 100644 --- a/modules/nixos/common/default.nix +++ b/modules/nixos/common/default.nix @@ -1,6 +1,5 @@ { imports = [ - ./boot.nix ./environment.nix ./htop.nix ./nationalization.nix diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 89d0f42..a858430 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -14,7 +14,6 @@ i2pd = import ./i2pd; jellyfin = import ./jellyfin; jirafeau = import ./jirafeau; - librechat-oci = import ./librechat-oci; mailserver = import ./mailserver; matrix-synapse = import ./matrix-synapse; maubot = import ./maubot; @@ -22,7 +21,6 @@ miniflux = import ./miniflux; nginx = import ./nginx; normalUsers = import ./normalUsers; - nostr-relay = import ./nostr-relay; nvidia = import ./nvidia; ollama = import ./ollama; open-webui-oci = import ./open-webui-oci; @@ -35,4 +33,5 @@ virtualisation = import ./virtualisation; webPage = import ./webPage; windows-oci = import ./windows-oci; + zfs = import ./zfs; } diff --git a/modules/nixos/headplane/default.nix b/modules/nixos/headplane/default.nix index 7cf64e5..017c4e3 100644 --- a/modules/nixos/headplane/default.nix +++ b/modules/nixos/headplane/default.nix @@ -45,10 +45,10 @@ in url = "http://127.0.0.1:${toString headscale.port}"; public_url = headscale.settings.server_url; config_path = "/etc/headscale/config.yaml"; - api_key_path = config.sops.secrets."headplane/api_key".path; }; integration.agent = { enabled = mkDefault true; + pre_authkey_path = config.sops.secrets."headplane/agent_pre_authkey".path; }; }; }; @@ -70,7 +70,7 @@ in "headplane/cookie_secret" = { inherit owner group mode; }; - "headplane/api_key" = { + "headplane/agent_pre_authkey" = { inherit owner group mode; }; }; diff --git a/modules/nixos/hyprland/default.nix b/modules/nixos/hyprland/default.nix index 68e6b9c..9b33ce5 100644 --- a/modules/nixos/hyprland/default.nix +++ b/modules/nixos/hyprland/default.nix @@ -8,14 +8,11 @@ in programs.dconf.enable = true; # fixes nixvim hm module - services.flatpak.enable = true; - xdg.portal = { enable = true; extraPortals = with pkgs; [ xdg-desktop-portal-gtk ]; - config.common.default = "gtk"; }; services.gnome.gnome-keyring.enable = true; diff --git a/modules/nixos/librechat-oci/default.nix b/modules/nixos/librechat-oci/default.nix deleted file mode 100644 index d35b0ca..0000000 --- a/modules/nixos/librechat-oci/default.nix +++ /dev/null @@ -1,527 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: - -let - cfg = config.services.librechat-oci; - - defaultImages = { - librechat = pkgs.dockerTools.pullImage { - imageName = "ghcr.io/danny-avila/librechat"; - imageDigest = "sha256:a46254938507971e0d4f7ed3f9d116bd9b118f4810b5b75eb716baf575645068"; - hash = "sha256-zevUN6vrs3hymwCGFmk/YXlUzYjN37H+EO5aLxYchyc="; - finalImageName = "ghcr.io/danny-avila/librechat"; - finalImageTag = "v0.8.5"; - }; - - meilisearch = pkgs.dockerTools.pullImage { - imageName = "getmeili/meilisearch"; - imageDigest = "sha256:b839a48d008d4e67e57f78dcff5b21d5e8b8fa066bacd11f97824d6307abb0dd"; - hash = "sha256-+hypvjFDSdnnWAO4tARTnjNd/6HlF6pMg1L6UUffdYM="; - finalImageName = "getmeili/meilisearch"; - finalImageTag = "v1.44.0"; - }; - - mongodb = pkgs.dockerTools.pullImage { - imageName = "mongo"; - imageDigest = "sha256:098862b1339f031900ca66cf8fef799e616d6324fa41b9a263f2ec899552c1ef"; - hash = "sha256-XuWnvcqAAkAGshdQtnngKOOJP2Bd33FXTbGHTRX3nUc="; - finalImageName = "mongo"; - finalImageTag = "8.0.20"; - }; - - vectordb = pkgs.dockerTools.pullImage { - imageName = "pgvector/pgvector"; - imageDigest = "sha256:8809cfffff0082cf260c9ac752f1dd1afc77f6f0a55c4e6411321e78efc3d9a5"; - hash = "sha256-rc6gQLMzv8UOZVLmWKGUESNIo+iPf5DR7T79AmbzWc4="; - finalImageName = "pgvector/pgvector"; - finalImageTag = "0.8.0-pg15-trixie"; - }; - - ragApi = pkgs.dockerTools.pullImage { - imageName = "registry.librechat.ai/danny-avila/librechat-rag-api-dev-lite"; - imageDigest = "sha256:6dfb6832661ff9c26fa329c823ce266059e33567670a763e9ecb9b566b8daa68"; - hash = "sha256-k8pkEgbqT4NU2+2ZjdRFlfFvMUk/1p+pkysbELh95pM="; - finalImageName = "registry.librechat.ai/danny-avila/librechat-rag-api-dev-lite"; - finalImageTag = "latest"; - }; - }; - - defaultEnv = { - # Server - HOST = "0.0.0.0"; - PORT = toString cfg.port; - NO_INDEX = "true"; - TRUST_PROXY = "1"; - - # Logging - CONSOLE_JSON = "false"; - DEBUG_LOGGING = "true"; - DEBUG_CONSOLE = "false"; - AGENT_DEBUG_LOGGING = "false"; - DEBUG_OPENAI = "false"; - - # Node - NODE_MAX_OLD_SPACE_SIZE = "6144"; - - # Search - SEARCH = "true"; - MEILI_NO_ANALYTICS = "true"; - - # Moderation - OPENAI_MODERATION = "false"; - BAN_VIOLATIONS = "true"; - BAN_DURATION = "1000 * 60 * 60 * 2"; - BAN_INTERVAL = "20"; - LOGIN_VIOLATION_SCORE = "1"; - REGISTRATION_VIOLATION_SCORE = "1"; - CONCURRENT_VIOLATION_SCORE = "1"; - MESSAGE_VIOLATION_SCORE = "1"; - NON_BROWSER_VIOLATION_SCORE = "20"; - TTS_VIOLATION_SCORE = "0"; - STT_VIOLATION_SCORE = "0"; - FORK_VIOLATION_SCORE = "0"; - IMPORT_VIOLATION_SCORE = "0"; - FILE_UPLOAD_VIOLATION_SCORE = "0"; - LOGIN_MAX = "7"; - LOGIN_WINDOW = "5"; - REGISTER_MAX = "5"; - REGISTER_WINDOW = "60"; - LIMIT_CONCURRENT_MESSAGES = "true"; - CONCURRENT_MESSAGE_MAX = "2"; - LIMIT_MESSAGE_IP = "true"; - MESSAGE_IP_MAX = "40"; - MESSAGE_IP_WINDOW = "1"; - LIMIT_MESSAGE_USER = "false"; - MESSAGE_USER_MAX = "40"; - MESSAGE_USER_WINDOW = "1"; - ILLEGAL_MODEL_REQ_SCORE = "5"; - - # Registration and login - ALLOW_EMAIL_LOGIN = "true"; - ALLOW_REGISTRATION = "false"; - ALLOW_SOCIAL_LOGIN = "false"; - ALLOW_SOCIAL_REGISTRATION = "false"; - ALLOW_PASSWORD_RESET = "false"; - ALLOW_UNVERIFIED_EMAIL_LOGIN = "true"; - SESSION_EXPIRY = "1000 * 60 * 15"; - REFRESH_TOKEN_EXPIRY = "(1000 * 60 * 60 * 24) * 7"; - - # OpenID - OPENID_SCOPE = "openid profile email"; - OPENID_CALLBACK_URL = "/oauth/openid/callback"; - OPENID_AUTO_REDIRECT = "false"; - OPENID_USE_PKCE = "false"; - OPENID_ON_BEHALF_FLOW_USERINFO_SCOPE = "user.read"; - - # OAuth callback URLs - DISCORD_CALLBACK_URL = "/oauth/discord/callback"; - FACEBOOK_CALLBACK_URL = "/oauth/facebook/callback"; - GITHUB_CALLBACK_URL = "/oauth/github/callback"; - GOOGLE_CALLBACK_URL = "/oauth/google/callback"; - APPLE_CALLBACK_URL = "/oauth/apple/callback"; - SAML_CALLBACK_URL = "/oauth/saml/callback"; - - # Entra ID - USE_ENTRA_ID_FOR_PEOPLE_SEARCH = "false"; - ENTRA_ID_INCLUDE_OWNERS_AS_MEMBERS = "false"; - OPENID_GRAPH_SCOPES = "User.Read,People.Read,GroupMember.Read.All"; - - # Shared links - ALLOW_SHARED_LINKS = "true"; - ALLOW_SHARED_LINKS_PUBLIC = "false"; - - # UI - APP_TITLE = "LibreChat"; - HELP_AND_FAQ_URL = "https://librechat.ai"; - - # Flux - FLUX_API_BASE_URL = "https://api.us1.bfl.ai"; - - # Email - EMAIL_PORT = "25"; - EMAIL_FROM = "noreply@librechat.ai"; - - # Azure Blob Storage - AZURE_STORAGE_PUBLIC_ACCESS = "false"; - AZURE_CONTAINER_NAME = "files"; - }; - - mkImageOption = - name: description: - mkOption { - type = types.package; - default = defaultImages.${name}; - description = description; - }; - - inherit (lib) - literalExpression - mkEnableOption - mkIf - mkOption - mkOverride - optional - types - ; -in -{ - options.services.librechat-oci = { - enable = mkEnableOption "LibreChat container with Podman."; - - images = { - librechat = mkImageOption "librechat" "The LibreChat Docker image (`pkgs.dockerTools.pullImage`)."; - meilisearch = mkImageOption "meilisearch" "The Meilisearch Docker image (`pkgs.dockerTools.pullImage`)."; - mongodb = mkImageOption "mongodb" "The MongoDB Docker image (`pkgs.dockerTools.pullImage`)."; - vectordb = mkImageOption "vectordb" "The pgvector Docker image (`pkgs.dockerTools.pullImage`)."; - ragApi = mkImageOption "ragApi" "The LibreChat RAG API Docker image (`pkgs.dockerTools.pullImage`)."; - }; - - configFile = mkOption { - type = types.nullOr types.path; - default = null; - example = literalExpression "./librechat.yaml"; - description = "Path to the `librechat.yaml` configuration file."; - }; - - externalUrl = mkOption { - type = types.nullOr types.str; - default = null; - example = literalExpression ''"https://chat.example.com"''; - description = "Public URL to configure for LibreChat (sets DOMAIN_CLIENT and DOMAIN_SERVER)."; - }; - - port = mkOption { - type = types.port; - default = 3080; - description = "Which port the LibreChat server listens on."; - }; - - meiliPort = mkOption { - type = types.port; - default = 7700; - description = "Which port Meilisearch listens on."; - }; - - ragPort = mkOption { - type = types.port; - default = 8000; - description = "Which port the RAG API listens on."; - }; - - environment = mkOption { - default = { }; - type = types.attrsOf types.str; - description = '' - Extra environment variables for LibreChat. - These are merged on top of the defaults and can override them. - For secrets use instead. - See . - ''; - }; - - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - example = literalExpression "config.sops.templates.librechat-env.path"; - description = '' - Environment file passed to the LibreChat, Meilisearch, and RAG API - containers. Use this for secrets such as JWT_SECRET, CREDS_KEY, - MEILI_MASTER_KEY, and API keys. - ''; - }; - }; - - config = mkIf cfg.enable { - virtualisation.podman = { - enable = true; - autoPrune.enable = true; - dockerCompat = true; - }; - - networking.firewall.interfaces = - let - matchAll = if !config.networking.nftables.enable then "podman+" else "podman*"; - in - { - "${matchAll}".allowedUDPPorts = [ 53 ]; - }; - - virtualisation.oci-containers.backend = "podman"; - - virtualisation.oci-containers.containers.librechat-mongodb = { - image = with cfg.images.mongodb; "${imageName}:${imageTag}"; - imageFile = cfg.images.mongodb; - cmd = [ - "mongod" - "--noauth" - ]; - volumes = [ - "librechat_mongodb_data:/data/db:rw" - ]; - log-driver = "journald"; - extraOptions = [ - "--network-alias=mongodb" - "--network=librechat_default" - ]; - }; - - virtualisation.oci-containers.containers.librechat-meilisearch = { - image = with cfg.images.meilisearch; "${imageName}:${imageTag}"; - imageFile = cfg.images.meilisearch; - environment = { - MEILI_NO_ANALYTICS = "true"; - MEILI_HOST = "http://meilisearch:${toString cfg.meiliPort}"; - }; - environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile; - volumes = [ - "librechat_meili_data:/meili_data:rw" - ]; - log-driver = "journald"; - extraOptions = [ - "--network-alias=meilisearch" - "--network=librechat_default" - ]; - }; - - virtualisation.oci-containers.containers.librechat-vectordb = { - image = with cfg.images.vectordb; "${imageName}:${imageTag}"; - imageFile = cfg.images.vectordb; - environment = { - POSTGRES_DB = "mydatabase"; - POSTGRES_USER = "myuser"; - POSTGRES_PASSWORD = "mypassword"; - }; - volumes = [ - "librechat_pgdata:/var/lib/postgresql/data:rw" - ]; - log-driver = "journald"; - extraOptions = [ - "--network-alias=vectordb" - "--network=librechat_default" - ]; - }; - - virtualisation.oci-containers.containers.librechat-rag-api = { - image = with cfg.images.ragApi; "${imageName}:${imageTag}"; - imageFile = cfg.images.ragApi; - environment = { - DB_HOST = "vectordb"; - RAG_PORT = toString cfg.ragPort; - }; - environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile; - dependsOn = [ "librechat-vectordb" ]; - log-driver = "journald"; - extraOptions = [ - "--network-alias=rag_api" - "--network=librechat_default" - ]; - }; - - virtualisation.oci-containers.containers.librechat = { - image = with cfg.images.librechat; "${imageName}:${imageTag}"; - imageFile = cfg.images.librechat; - environment = - defaultEnv - // { - MONGO_URI = "mongodb://mongodb:27017/LibreChat"; - MEILI_HOST = "http://meilisearch:${toString cfg.meiliPort}"; - RAG_PORT = toString cfg.ragPort; - RAG_API_URL = "http://rag_api:${toString cfg.ragPort}"; - DOMAIN_CLIENT = - if cfg.externalUrl != null then cfg.externalUrl else "http://localhost:${toString cfg.port}"; - DOMAIN_SERVER = - if cfg.externalUrl != null then cfg.externalUrl else "http://localhost:${toString cfg.port}"; - } - // cfg.environment; - environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile; - volumes = [ - "librechat_images:/app/client/public/images:rw" - "librechat_uploads:/app/uploads:rw" - "librechat_logs:/app/logs:rw" - ] - ++ optional (cfg.configFile != null) "${cfg.configFile}:/app/librechat.yaml:ro"; - - ports = [ - "0.0.0.0:${toString cfg.port}:${toString cfg.port}/tcp" - ]; - dependsOn = [ - "librechat-mongodb" - "librechat-rag-api" - ]; - log-driver = "journald"; - extraOptions = [ - "--network-alias=api" - "--network=librechat_default" - ]; - }; - - systemd.services.podman-librechat-mongodb = { - serviceConfig.Restart = mkOverride 90 "always"; - after = [ - "podman-network-librechat_default.service" - "podman-volume-librechat_mongodb_data.service" - ]; - requires = [ - "podman-network-librechat_default.service" - "podman-volume-librechat_mongodb_data.service" - ]; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-librechat-meilisearch = { - serviceConfig.Restart = mkOverride 90 "always"; - after = [ - "podman-network-librechat_default.service" - "podman-volume-librechat_meili_data.service" - ]; - requires = [ - "podman-network-librechat_default.service" - "podman-volume-librechat_meili_data.service" - ]; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-librechat-vectordb = { - serviceConfig.Restart = mkOverride 90 "always"; - after = [ - "podman-network-librechat_default.service" - "podman-volume-librechat_pgdata.service" - ]; - requires = [ - "podman-network-librechat_default.service" - "podman-volume-librechat_pgdata.service" - ]; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-librechat-rag-api = { - serviceConfig.Restart = mkOverride 90 "always"; - after = [ - "podman-network-librechat_default.service" - "podman-librechat-vectordb.service" - ]; - requires = [ - "podman-network-librechat_default.service" - "podman-librechat-vectordb.service" - ]; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-librechat = { - serviceConfig.Restart = mkOverride 90 "always"; - after = [ - "podman-network-librechat_default.service" - "podman-volume-librechat_images.service" - "podman-volume-librechat_uploads.service" - "podman-volume-librechat_logs.service" - "podman-librechat-mongodb.service" - "podman-librechat-meilisearch.service" - "podman-librechat-rag-api.service" - ]; - requires = [ - "podman-network-librechat_default.service" - "podman-volume-librechat_images.service" - "podman-volume-librechat_uploads.service" - "podman-volume-librechat_logs.service" - "podman-librechat-mongodb.service" - "podman-librechat-meilisearch.service" - "podman-librechat-rag-api.service" - ]; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-network-librechat_default = { - path = [ pkgs.podman ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStop = "podman network rm -f librechat_default"; - }; - script = '' - podman network inspect librechat_default || podman network create librechat_default - ''; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-volume-librechat_mongodb_data = { - path = [ pkgs.podman ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = "podman volume inspect librechat_mongodb_data || podman volume create librechat_mongodb_data"; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-volume-librechat_meili_data = { - path = [ pkgs.podman ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = "podman volume inspect librechat_meili_data || podman volume create librechat_meili_data"; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-volume-librechat_pgdata = { - path = [ pkgs.podman ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = "podman volume inspect librechat_pgdata || podman volume create librechat_pgdata"; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-volume-librechat_images = { - path = [ pkgs.podman ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = "podman volume inspect librechat_images || podman volume create librechat_images"; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-volume-librechat_uploads = { - path = [ pkgs.podman ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = "podman volume inspect librechat_uploads || podman volume create librechat_uploads"; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.services.podman-volume-librechat_logs = { - path = [ pkgs.podman ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = "podman volume inspect librechat_logs || podman volume create librechat_logs"; - partOf = [ "podman-compose-librechat-root.target" ]; - wantedBy = [ "podman-compose-librechat-root.target" ]; - }; - - systemd.targets.podman-compose-librechat-root = { - unitConfig.Description = "Root target generated by compose2nix."; - wantedBy = [ "multi-user.target" ]; - }; - }; -} diff --git a/modules/nixos/mcpo/default.nix b/modules/nixos/mcpo/default.nix index 76ad953..89e0e29 100644 --- a/modules/nixos/mcpo/default.nix +++ b/modules/nixos/mcpo/default.nix @@ -28,12 +28,6 @@ in default = null; }; - port = mkOption { - type = types.port; - default = 8000; - description = "Port on which the mcpo service should listen."; - }; - user = mkOption { type = types.str; description = "The user the mcpo service will run as."; @@ -106,7 +100,7 @@ in after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { - ExecStart = "${getExe cfg.package} --port ${toString cfg.port} --config ${configFile}"; + ExecStart = "${getExe cfg.package} --config ${configFile}"; Restart = "on-failure"; User = cfg.user; Group = cfg.group; diff --git a/modules/nixos/nostr-relay/default.nix b/modules/nixos/nostr-relay/default.nix deleted file mode 100644 index 199f702..0000000 --- a/modules/nixos/nostr-relay/default.nix +++ /dev/null @@ -1,57 +0,0 @@ -{ config, lib, ... }: - -let - cfg = config.services.nostr-relay; - domain = config.networking.domain; - subdomain = cfg.reverseProxy.subdomain; - fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; - - inherit (lib) - mkDefault - mkIf - ; - - inherit (lib.utils) - mkReverseProxyOption - ; -in -{ - options.services.nostr-relay = { - reverseProxy = mkReverseProxyOption "Nostr Relay" "nostr"; - }; - - config = mkIf cfg.enable { - services.nostr-rs-relay = { - settings = { - network = { - port = mkDefault 12849; - host = mkDefault (if cfg.reverseProxy.enable then "127.0.0.1" else "0.0.0.0"); - }; - limits = { - max_event_size = mkDefault 65536; - max_subscriptions = mkDefault 20; - max_filters = mkDefault 10; - max_subid_length = mkDefault 128; - max_event_tags = mkDefault 2000; - max_content_length = mkDefault 32768; - }; - federation = { - enabled = mkDefault true; - max_message_size = mkDefault 1048576; - }; - database = { - max_query_time_ms = mkDefault 5000; - }; - }; - }; - - services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable { - "${fqdn}" = { - enableACME = cfg.reverseProxy.forceSSL; - forceSSL = cfg.reverseProxy.forceSSL; - locations."/".proxyPass = - "http://127.0.0.1:${toString config.services.nostr-rs-relay.settings.network.port}"; - }; - }; - }; -} diff --git a/modules/nixos/open-webui-oci/default.nix b/modules/nixos/open-webui-oci/default.nix index 50bb15b..a0bdbf0 100644 --- a/modules/nixos/open-webui-oci/default.nix +++ b/modules/nixos/open-webui-oci/default.nix @@ -10,10 +10,10 @@ let image = pkgs.dockerTools.pullImage { imageName = "ghcr.io/open-webui/open-webui"; - imageDigest = "sha256:a7e4796ae894d1e2a0c1824860ade472f35c507608a01c3581377b5c19b0ed49"; - hash = "sha256-uhPlVXSxY6rGbYGvlPVV3zurmbI96mAHEuKKy9FFaD4="; + imageDigest = "sha256:2deb90b0423473d8f97febced2e62b8fd898aa3eb61877bb3aa336370214c258"; + hash = "sha256-2cdKfvZGUyPUm7TFXcf5OcG9ey4BvOZPUOVim1S2C+s="; finalImageName = "ghcr.io/open-webui/open-webui"; - finalImageTag = "0.9.2"; + finalImageTag = "0.8.5"; }; defaultEnv = { diff --git a/modules/nixos/rss-bridge/default.nix b/modules/nixos/rss-bridge/default.nix index 1a5adf5..9c7757b 100644 --- a/modules/nixos/rss-bridge/default.nix +++ b/modules/nixos/rss-bridge/default.nix @@ -12,6 +12,7 @@ let inherit (lib.utils) mkReverseProxyOption + mkVirtualHost ; in { @@ -31,9 +32,8 @@ in systemd.tmpfiles.rules = [ "d ${cfg.dataDir} 0755 ${cfg.user} ${cfg.group} -" ]; services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable { - "${fqdn}" = { - enableACME = cfg.reverseProxy.forceSSL; - forceSSL = cfg.reverseProxy.forceSSL; + "${cfg.virtualHost}" = mkVirtualHost { + ssl = cfg.reverseProxy.forceSSL; }; }; }; diff --git a/modules/nixos/tailscale/default.nix b/modules/nixos/tailscale/default.nix index b437849..3e43963 100644 --- a/modules/nixos/tailscale/default.nix +++ b/modules/nixos/tailscale/default.nix @@ -1,17 +1,9 @@ -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, ... }: let cfg = config.services.tailscale; inherit (lib) - concatStrings - filterAttrs - mapAttrsToList mkIf mkOption optional @@ -20,124 +12,39 @@ let in { options.services.tailscale = { - tailnets = mkOption { - default = { }; - type = types.attrsOf ( - types.submodule { - options = { - loginServer = mkOption { - type = types.str; - description = "Login server for this tailnet."; - }; - authKeyFile = mkOption { - type = types.nullOr types.str; - default = null; - description = "Path to auth key secret."; - }; - enableSSH = mkOption { - type = types.bool; - default = false; - }; - acceptDNS = mkOption { - type = types.bool; - default = true; - }; - default = mkOption { - type = types.bool; - default = false; - description = "Connect to this tailnet on boot."; - }; - }; - } - ); + loginServer = mkOption { + type = types.str; + description = "The Tailscale login server to use."; + }; + enableSSH = mkOption { + type = types.bool; + default = false; + description = "Enable Tailscale SSH functionality."; + }; + acceptDNS = mkOption { + type = types.bool; + default = true; + description = "Enable Tailscale's MagicDNS and custom DNS configuration."; }; }; - config = - let - defaultTailnets = filterAttrs (_: t: t.default) cfg.tailnets; - defaultTailnet = - if defaultTailnets == { } then null else builtins.head (builtins.attrValues defaultTailnets); - - entries = mapAttrsToList (name: tcfg: '' - TAILNETS["${name}"]="${tcfg.loginServer}|${if tcfg.enableSSH then "true" else "false"}|${ - if tcfg.acceptDNS then "true" else "false" - }|${if tcfg.authKeyFile != null then tcfg.authKeyFile else ""}" - '') cfg.tailnets; - - tailnetSwitchCli = pkgs.writeShellScriptBin "tailnet-switch" '' - set -euo pipefail - - TAILSCALE="${cfg.package}/bin/tailscale" - - declare -A TAILNETS - ${concatStrings entries} - - CHOICE="''${1:-}" - - if [[ -z "$CHOICE" ]]; then - if [[ -t 0 ]]; then - CHOICE=$(printf '%s\n' "''${!TAILNETS[@]}" | sort | ${pkgs.fzf}/bin/fzf --prompt="Switch tailnet: ") - else - echo "Usage: tailnet-switch " >&2 - printf 'Available tailnets: %s\n' "''${!TAILNETS[@]}" >&2 - exit 1 - fi - fi - - if [[ -z "''${TAILNETS[$CHOICE]+x}" ]]; then - echo "Unknown tailnet: $CHOICE" >&2 - printf 'Available tailnets: %s\n' "''${!TAILNETS[@]}" >&2 - exit 1 - fi - - IFS='|' read -r LOGIN_SERVER ENABLE_SSH ACCEPT_DNS AUTH_KEY_FILE <<< "''${TAILNETS[$CHOICE]}" - - echo "Switching to: $CHOICE ($LOGIN_SERVER)" - - "$TAILSCALE" down --accept-risk=lose-ssh 2>/dev/null || true - "$TAILSCALE" logout 2>/dev/null || true - - UP_FLAGS=("--login-server=$LOGIN_SERVER") - [[ "$ENABLE_SSH" == "true" ]] && UP_FLAGS+=("--ssh") - [[ "$ACCEPT_DNS" == "true" ]] && UP_FLAGS+=("--accept-dns") - [[ -n "$AUTH_KEY_FILE" ]] && UP_FLAGS+=("--auth-key=$(cat "$AUTH_KEY_FILE")") - - "$TAILSCALE" up "''${UP_FLAGS[@]}" - - echo "Switched to tailnet: $CHOICE" - ''; - in - mkIf cfg.enable { - assertions = [ - { - assertion = - (builtins.length (builtins.attrValues (filterAttrs (_: t: t.default) cfg.tailnets))) <= 1; - message = "services.tailscale.tailnets: Only one tailnet can be set as default."; - } - { - assertion = cfg.tailnets != { }; - message = "services.tailscale.tailnets: At least one tailnet must be defined."; - } - ]; - - services.tailscale = mkIf (defaultTailnet != null) ( - with defaultTailnet; - { - inherit authKeyFile; - extraSetFlags = optional enableSSH "--ssh" ++ optional acceptDNS "--accept-dns"; - extraUpFlags = [ - "--login-server=${loginServer}" - ] - ++ optional enableSSH "--ssh" - ++ optional acceptDNS "--accept-dns"; - } - ); - - environment.systemPackages = [ tailnetSwitchCli ]; - - environment.shellAliases.ts = "${cfg.package}/bin/tailscale"; - - networking.firewall.trustedInterfaces = [ cfg.interfaceName ]; + config = mkIf cfg.enable { + services.tailscale = { + authKeyFile = config.sops.secrets."tailscale/auth-key".path; + extraSetFlags = optional cfg.enableSSH "--ssh" ++ optional cfg.acceptDNS "--accept-dns"; + extraUpFlags = [ + "--login-server=${cfg.loginServer}" + ] + ++ optional cfg.enableSSH "--ssh" + ++ optional cfg.acceptDNS "--accept-dns"; }; + + environment.shellAliases = { + ts = "${cfg.package}/bin/tailscale"; + }; + + networking.firewall.trustedInterfaces = [ cfg.interfaceName ]; + + sops.secrets."tailscale/auth-key" = { }; + }; } diff --git a/modules/nixos/zfs/default.nix b/modules/nixos/zfs/default.nix new file mode 100644 index 0000000..1b15583 --- /dev/null +++ b/modules/nixos/zfs/default.nix @@ -0,0 +1,55 @@ +{ + config, + pkgs, + lib, + ... +}: + +# Set `networking.hostId` to: +# $ head -c 8 /etc/machine-id + +# Mark datasets to snapshot: +# $ sudo zfs set com.sun:auto-snapshot:daily=true dpool/data/backup + +# Generate SSH key for replication (empty passphrase): +# $ sudo -i ssh-keygen -t rsa -b 4096 -f /root/.ssh/zfs-replication + +let + cfg = config.services.zfs; + + inherit (lib) mkDefault mkForce; +in +{ + boot.supportedFilesystems = [ "zfs" ]; + boot.loader.systemd-boot.enable = mkForce false; + boot.loader.grub.enable = mkForce true; + boot.loader.grub.zfsSupport = mkForce true; + + services.zfs.trim = { + enable = mkDefault true; + interval = mkDefault "weekly"; + }; + + services.zfs.scrub = { + enable = mkDefault true; + interval = mkDefault "monthly"; + }; + + services.zfs.autoSnapshot = { + enable = mkDefault true; + flags = mkDefault "-k -p --utc"; + frequent = mkDefault 0; + hourly = mkDefault 24; + daily = mkDefault 7; + weekly = mkDefault 4; + monthly = mkDefault 0; + }; + + services.zfs.autoReplication = { + username = mkDefault "root"; + identityFilePath = mkDefault "/root/.ssh/zfs-replication"; + followDelete = mkDefault true; + }; + + environment.systemPackages = with pkgs; [ lz4 ]; +} diff --git a/modules/nixos/zfs/disks.sh b/modules/nixos/zfs/disks.sh new file mode 100644 index 0000000..9f966fa --- /dev/null +++ b/modules/nixos/zfs/disks.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash +declare -a SSDs=( + # '/dev/disk/by-id/abc123' +) + +declare -a HDDs=( + # '/dev/disk/by-id/def456' +) + +declare -a DATA_DATASETS=( + # 'dataset' +) + +MNT='/mnt' +SWAP_GB=32 + +# Helper function to wait for devices +wait_for_device() { + local device=$1 + echo "Waiting for device: $device ..." + while [[ ! -e $device ]]; do + sleep 1 + done + echo "Device $device is ready." +} + +# Function to install a package if it's not already installed +install_if_missing() { + local cmd="$1" + local package="$2" + if ! command -v "$cmd" &> /dev/null; then + echo "$cmd not found, installing $package..." + nix-env -iA "nixos.$package" + fi +} + +install_if_missing "sgdisk" "gptfdisk" +install_if_missing "partprobe" "parted" + +# Ensure swap parts are off +swapoff --all +udevadm settle + +### SSDs ### +echo "Setting up SSDs..." + +# Wait for SSD devices to be ready +for ssd in "${SSDs[@]}"; do + wait_for_device "$ssd" +done + +# Wipe and partition SSDs +for i in "${!SSDs[@]}"; do + ssd="${SSDs[$i]}" + ssd_num=$((i + 1)) + + echo "Processing SSD $ssd_num: $ssd" + + # Wipe filesystems + wipefs -a "$ssd" + + # Clear part tables + sgdisk --zap-all "$ssd" + + # Partition disk + sgdisk -n1:1M:+1G -t1:EF00 -c1:BOOT$ssd_num "$ssd" + sgdisk -n2:0:+"$SWAP_GB"G -t2:8200 -c2:SWAP$ssd_num "$ssd" + sgdisk -n3:0:0 -t3:BF00 -c3:ROOT$ssd_num "$ssd" + + partprobe -s "$ssd" + udevadm settle + wait_for_device "${ssd}-part3" +done + +# Create root pool +echo "Creating root pool..." +zpool create -f -o ashift=12 -o autotrim=on -R "$MNT" -O acltype=posixacl -O canmount=off -O dnodesize=auto -O normalization=formD -O relatime=on -O xattr=sa -O mountpoint=none rpool mirror "${SSDs[0]}"-part3 "${SSDs[1]}"-part3 + +# Create and mount root system container +zfs create -o canmount=noauto -o mountpoint=legacy rpool/root +mount -o X-mount.mkdir -t zfs rpool/root "$MNT" + +# Create root datasets +declare -a ROOT_DATASETS=('home' 'nix' 'tmp' 'var') +for dataset in "${ROOT_DATASETS[@]}"; do + zfs create -o mountpoint=legacy "rpool/$dataset" + mount -o X-mount.mkdir -t zfs "rpool/$dataset" "$MNT/$dataset" +done + +# Format boot and swap partitions +for i in "${!SSDs[@]}"; do + ssd="${SSDs[$i]}" + ssd_num=$((i + 1)) + + mkfs.vfat -F 32 -n BOOT$ssd_num "${ssd}"-part1 + mkswap -L SWAP$ssd_num "${ssd}"-part2 + swapon -L SWAP$ssd_num +done + +# Mount first boot partition +mount -t vfat -o fmask=0077,dmask=0077,iocharset=iso8859-1,X-mount.mkdir -L BOOT1 "$MNT"/boot + +### HDDs ### +echo "Setting up HDDs..." + +# Wait for HDD devices to be ready +for hdd in "${HDDs[@]}"; do + wait_for_device "$hdd" +done + +# Wipe and partition HDDs +for i in "${!HDDs[@]}"; do + hdd="${HDDs[$i]}" + hdd_num=$((i + 1)) + + echo "Processing HDD $hdd_num: $hdd" + + wipefs -a "$hdd" + sgdisk --zap-all "$hdd" + sgdisk -n1:0:0 -t1:BF00 -c1:DATA$hdd_num "$hdd" +done + +udevadm settle + +# Wait for all HDD partitions to appear +for hdd in "${HDDs[@]}"; do + wait_for_device "${hdd}-part1" +done + +# Create data pool +echo "Creating data pool..." +mkdir -p "$MNT"/data + +hdd_partitions=() +for hdd in "${HDDs[@]}"; do + hdd_partitions+=("${hdd}-part1") +done + +zpool create -f -o ashift=12 -o autotrim=on -R "$MNT" -O acltype=posixacl -O xattr=sa -O dnodesize=auto -O compression=lz4 -O normalization=formD -O relatime=on -O mountpoint=none dpool raidz "${hdd_partitions[@]}" + +# Create and mount data root container +zfs create -o canmount=noauto -o mountpoint=legacy dpool/data +mount -o X-mount.mkdir -t zfs dpool/data "$MNT"/data + +# Create and mount data datasets +for dataset in "${DATA_DATASETS[@]}"; do + zfs create -o mountpoint=legacy "dpool/data/$dataset" + mount -o X-mount.mkdir -t zfs "dpool/data/$dataset" "$MNT/data/$dataset" +done + +echo "Setup complete." diff --git a/modules/shared/common/nix.nix b/modules/shared/common/nix.nix index 4d8e217..2d0daa3 100644 --- a/modules/shared/common/nix.nix +++ b/modules/shared/common/nix.nix @@ -32,8 +32,6 @@ in }; }; - nix.settings.warn-dirty = mkDefault false; - # fallback quickly if substituters are not available. nix.settings.connect-timeout = mkDefault 5; nix.settings.fallback = true; diff --git a/pkgs/arxiv-mcp-server/default.nix b/pkgs/arxiv-mcp-server/default.nix index f5b1541..744e8c4 100644 --- a/pkgs/arxiv-mcp-server/default.nix +++ b/pkgs/arxiv-mcp-server/default.nix @@ -6,13 +6,13 @@ python3.pkgs.buildPythonApplication rec { pname = "arxiv-mcp-server"; - version = "0.4.12"; + version = "0.3.1"; pyproject = true; src = fetchPypi { pname = "arxiv_mcp_server"; inherit version; - hash = "sha256-khY63SfUKgNjyACNESEQpY9q3uJSlLhuJBEaBKGmZy8="; + hash = "sha256-yGNetU7el6ZXsavD8uvO17OZtaPuYgzkxiVEk402GUs="; }; build-system = [ diff --git a/pkgs/baibot/default.nix b/pkgs/baibot/default.nix index 55bd1fb..7c8fbbc 100644 --- a/pkgs/baibot/default.nix +++ b/pkgs/baibot/default.nix @@ -11,17 +11,17 @@ rustPlatform.buildRustPackage rec { pname = "baibot"; - version = "1.18.0"; + version = "1.14.3"; src = fetchFromGitHub { owner = "etkecc"; repo = "baibot"; rev = "v${version}"; - hash = "sha256-TwtN8tEml/z0Js78jjWzEYV58Dg8a5YKxdEU9hBDtNs="; + hash = "sha256-bFUijsvwUQhISjWVoVvoDXNSDPaWZTunqUfxfgaxclM="; }; useFetchCargoVendor = true; - cargoHash = "sha256-2TJsFT+I7JG1DauEOvB8HluMDb1vW0qXD/mzzSlAfew="; + cargoHash = "sha256-/7KSCVWuxTk7gKOYxE/uQ5T0BnYlDYWOvdFXEiU9mB0="; nativeBuildInputs = [ pkg-config diff --git a/pkgs/blender-mcp/default.nix b/pkgs/blender-mcp/default.nix index eabee53..28e5625 100644 --- a/pkgs/blender-mcp/default.nix +++ b/pkgs/blender-mcp/default.nix @@ -6,13 +6,13 @@ python3.pkgs.buildPythonApplication rec { pname = "blender-mcp"; - version = "1.5.6"; + version = "1.5.5"; pyproject = true; src = fetchPypi { pname = "blender_mcp"; inherit version; - hash = "sha256-9aBGQcMC1ustj3H1WgRFCha6fk+XSASIzcZr6Rrgif4="; + hash = "sha256-n8bYnrDVLe5zPvg8rbGgh5U5AeIm/DA6aPgmxS68d7g="; }; build-system = [ diff --git a/pkgs/default.nix b/pkgs/default.nix index 899a133..2cc8b2d 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -11,20 +11,15 @@ cppman = pkgs.callPackage ./cppman { }; fetcher-mcp = pkgs.callPackage ./fetcher-mcp { }; freecad-mcp = pkgs.callPackage ./freecad-mcp { }; - jirafeau = pkgs.callPackage ./jirafeau { }; - jirafeau-cli = pkgs.callPackage ./jirafeau-cli { }; kicad-mcp = pkgs.callPackage ./kicad-mcp { }; mcpo = pkgs.callPackage ./mcpo { }; - nerdlog = pkgs.callPackage ./nerdlog { }; pass2bw = pkgs.callPackage ./pass2bw { }; pyman = pkgs.callPackage ./pyman { }; quicknote = pkgs.callPackage ./quicknote { }; synapse_change_display_name = pkgs.callPackage ./synapse_change_display_name { }; synix-docs = pkgs.callPackage ./synix-docs { }; - tinyfugue = pkgs.callPackage ./tinyfugue { }; trelis-gitingest-mcp = pkgs.callPackage ./trelis-gitingest-mcp { }; tunerstudio = pkgs.callPackage ./tunerstudio { }; # marker-pdf = pkgs.callPackage ./marker-pdf { }; # FIXME - # openmv-ide = pkgs.callPackage ./openmv-ide { }; # FIXME } diff --git a/pkgs/fetcher-mcp/default.nix b/pkgs/fetcher-mcp/default.nix index 069fa8a..00a09ab 100644 --- a/pkgs/fetcher-mcp/default.nix +++ b/pkgs/fetcher-mcp/default.nix @@ -25,9 +25,9 @@ let } ]; in -buildNpmPackage { +buildNpmPackage rec { pname = "fetcher-mcp"; - version = "0.3.9"; + version = "0.3.6"; src = fetchFromGitHub { owner = "jae-jae"; diff --git a/pkgs/freecad-mcp/default.nix b/pkgs/freecad-mcp/default.nix index 32bd61e..6c72453 100644 --- a/pkgs/freecad-mcp/default.nix +++ b/pkgs/freecad-mcp/default.nix @@ -6,13 +6,13 @@ python3.pkgs.buildPythonApplication rec { pname = "freecad-mcp"; - version = "0.1.17"; + version = "0.1.16"; pyproject = true; src = fetchPypi { pname = "freecad_mcp"; inherit version; - hash = "sha256-DugQWGZizIXO27cjzfyidNTyyahN1BTcDNTl4DHWqN0="; + hash = "sha256-eFt7UgJw56C2zY8Vznrg8L0a5nvP0xtiW1oJuJ/fL3Y="; }; build-system = [ diff --git a/pkgs/jirafeau-cli/default.nix b/pkgs/jirafeau-cli/default.nix deleted file mode 100644 index d2dc382..0000000 --- a/pkgs/jirafeau-cli/default.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - writeShellApplication, - coreutils, - curl, - ... -}: - -let - name = "jirafeau-cli"; - text = builtins.readFile ./${name}.sh; -in -writeShellApplication { - inherit name text; - meta.mainProgram = name; - - runtimeInputs = [ - coreutils - curl - ]; -} diff --git a/pkgs/jirafeau-cli/jirafeau-cli.sh b/pkgs/jirafeau-cli/jirafeau-cli.sh deleted file mode 100644 index 7e94827..0000000 --- a/pkgs/jirafeau-cli/jirafeau-cli.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/bin/bash - -# This script has been auto-generated by Jirafeau but you can still edit options below. - -# Config begin -proxy='' # Or set JIRAFEAU_PROXY. -url='' # Or set JIRAFEAU_URL. -time='month' # Or set JIRAFEAU_TIME. -one_time='' # Or set JIRAFEAU_ONE_TIME. -upload_password='' # Or set JIRAFEAU_UPLOAD_PASSWD -# Config end - -if [ -n "${JIRAFEAU_PROXY:-}" ]; then - proxy="$JIRAFEAU_PROXY" -fi - -if [ -n "${JIRAFEAU_URL:-}" ]; then - url="$JIRAFEAU_URL" -fi - -if [ -z "$url" ]; then - echo "Please set url in script parameters or export JIRAFEAU_URL" -fi - -if [ -n "${JIRAFEAU_TIME:-}" ]; then - time="$JIRAFEAU_TIME" -fi - -if [ -n "${JIRAFEAU_ONE_TIME:-}" ]; then - one_time='1' -fi - -if [ -n "${JIRAFEAU_UPLOAD_PASSWD:-}" ]; then - upload_password="$JIRAFEAU_UPLOAD_PASSWD" -fi - -if [ -z "${2:-}" ]; then - echo "Jirafeau Bash Script 4.7.1" - echo "--------------------------" - echo "Usage:" - echo " $0 OPTIONS" - echo - echo "Options:" - echo " $0 send FILE [PASSWORD]" - echo " $0 get URL [PASSWORD]" - echo " $0 delete URL" - echo - echo "Global variables to export:" - echo " JIRAFEAU_PROXY: Domain and port of proxy server, eg. »proxyserver.example.com:3128«" - echo " JIRAFEAU_URL : URI to Jirafeau installation with trailing slash, eg. »https://example.com/jirafeau/«" - echo " JIRAFEAU_TIME : expiration time, eg. »minute«, »hour«, »day«, »week«, fortnight, »month«, »quarter«, »year« or »none«" - echo " JIRAFEAU_ONE_TIME : self-destroy after first download, eg. »1« to enable or »« (empty) to disable" - echo " JIRAFEAU_UPLOAD_PASSWD : upload password" - - exit 0 -fi - -proxy_args=() -if [ -n "$proxy" ]; then - proxy_args=(-x "$proxy") -fi - -options=() -if [ -n "$one_time" ]; then - options+=(-F one_time_download=1) -fi - -if [ -n "$upload_password" ]; then - options+=(-F "upload_password=$upload_password") -fi - -password='' -if [ -n "${3:-}" ]; then - password="$3" - options+=(-F "key=$password") -fi - -apipage='script.php' -downloadpage='f.php' - -if [ "$1" == "send" ]; then - if [ ! -f "$2" ]; then - echo "File \"$2\" does not exist." - exit - fi - - # Get result - res=$(curl -X POST --http1.0 "${proxy_args[@]}" "${options[@]}" \ - -F "time=$time" \ - -F "file=@$2" \ - "${url}${apipage}") - - if [[ "$res" == Error* ]]; then - echo "Error while uploading." - echo "$res" - exit - fi - - # Not using head or tail to minimise command dependencies - code=$(cnt=0; echo "$res" | while read -r l; do - if [[ "$cnt" == "0" ]]; then - echo "$l" - fi - cnt=$(( cnt + 1 )) - done) - del_code=$(cnt=0; echo "$res" | while read -r l; do - if [[ "$cnt" == "1" ]]; then - echo "$l" - fi - cnt=$(( cnt + 1 )) - done) - key_code=$(cnt=0; echo "$res" | while read -r l; do - if [[ "$cnt" == "2" ]]; then - echo "$l" - fi - cnt=$(( cnt + 1 )) - done) - - echo - echo "Download page:" - if [[ $key_code ]]; then - echo " ${url}${downloadpage}?h=$code&k=$key_code" - else - echo " ${url}${downloadpage}?h=$code" - fi - echo "Direct download:" - if [[ $key_code ]]; then - echo " ${url}${downloadpage}?h=$code&k=$key_code&d=1" - else - echo " ${url}${downloadpage}?h=$code&d=1" - fi - echo "Delete link:" - echo " ${url}${downloadpage}?h=$code&d=$del_code" - echo - echo "Download via API:" - if [[ $key_code ]]; then - echo " ${0} get ${url}${apipage}?h=$code&k=$key_code [PASSWORD]" - else - echo " ${0} get ${url}${apipage}?h=$code [PASSWORD]" - fi - echo "Delete via API:" - echo " ${0} delete \"${url}${downloadpage}?h=$code&d=$del_code\"" - -elif [ "$1" == "get" ]; then - if [ -z "$password" ]; then - curl "${proxy_args[@]}" -OJ "$2" - else - curl "${proxy_args[@]}" -OJ -X POST -F "key=$password" "$2" - fi -elif [ "$1" == "delete" ]; then - curl "${proxy_args[@]}" "$2" --data-raw "do_delete=1%2F" | grep "div class" | sed -e "s/<[^>]\+>//g" -fi diff --git a/pkgs/jirafeau/default.nix b/pkgs/jirafeau/default.nix deleted file mode 100644 index 2826db7..0000000 --- a/pkgs/jirafeau/default.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ - lib, - stdenv, - fetchFromGitLab, - writeText, - nixosTests, -}: - -let - localConfig = writeText "config.local.php" '' - - ''; -in -stdenv.mkDerivation rec { - pname = "jirafeau"; - version = "4.7.1"; - - src = fetchFromGitLab { - owner = "jirafeau"; - repo = "Jirafeau"; - rev = version; - hash = "sha256-jXUO+tj6VFNjJkT0vkCCtG7yNWf3QeCx7izZPekAng8="; - }; - - installPhase = '' - mkdir $out - cp -r * $out/ - cp ${localConfig} $out/lib/config.local.php - ''; - - passthru.tests = { inherit (nixosTests) jirafeau; }; - - meta = { - description = "Jirafeau: a simple way to upload a file"; - homepage = "https://gitlab.com/jirafeau/Jirafeau"; - changelog = "https://gitlab.com/jirafeau/Jirafeau/-/blob/${src.rev}/CHANGELOG.md"; - license = lib.licenses.agpl3Plus; - mainProgram = "jirafeau"; - platforms = lib.platforms.all; - }; -} diff --git a/pkgs/kicad-mcp/default.nix b/pkgs/kicad-mcp/default.nix index b1b87cc..5c64741 100644 --- a/pkgs/kicad-mcp/default.nix +++ b/pkgs/kicad-mcp/default.nix @@ -35,11 +35,11 @@ buildNpmPackage rec { src = fetchFromGitHub { owner = "mixelpixx"; repo = "KiCAD-MCP-Server"; - rev = "216d3f189d194cdd539b274264b8b7ec00cbb13e"; - hash = "sha256-73yDzYlWMDnnytf/IcUuwQp/P7YYaxrNr+JsGrgMI40="; + rev = "b5a1483fc20dd1201a1d275522904aac914157e8"; + hash = "sha256-63Ef34YjniMY+ZPpDrWZpPx8bUbNA0XE+7Jlgm8KJv8="; }; - npmDepsHash = "sha256-qR43NvSK28RLt5sL9BZQzSyFRszYMt2CC0wTs9jf/hU="; + npmDepsHash = "sha256-nz73qj8CK2LyFixoF14ET2wq407YyuJUw/4VTDc80cQ="; buildScript = "build"; diff --git a/pkgs/mcpo/default.nix b/pkgs/mcpo/default.nix index 0d923f7..d4f3ee5 100644 --- a/pkgs/mcpo/default.nix +++ b/pkgs/mcpo/default.nix @@ -7,14 +7,14 @@ python3.pkgs.buildPythonApplication rec { pname = "mcpo"; - version = "0.0.20"; + version = "0.0.19"; pyproject = true; src = fetchFromGitHub { owner = "open-webui"; repo = "mcpo"; rev = "v${version}"; - hash = "sha256-tA1KdcfmNPuqPbwE66jRY85tsrOKjPImsxSoGsW5ZD4="; + hash = "sha256-ZfTVMrXXEsEKHmeG4850Hq3MEpQA/3WMpAVZS0zvp1I="; }; build-system = [ diff --git a/pkgs/nerdlog/default.nix b/pkgs/nerdlog/default.nix deleted file mode 100644 index b1b59f0..0000000 --- a/pkgs/nerdlog/default.nix +++ /dev/null @@ -1,83 +0,0 @@ -{ - lib, - buildGoModule, - fetchFromGitHub, - stdenv, - darwin, - xorg, - pkg-config, - wayland, - libGL, - libxkbcommon, - makeWrapper, -}: - -buildGoModule rec { - pname = "nerdlog"; - version = "1.10.0"; - - src = fetchFromGitHub { - owner = "dimonomid"; - repo = "nerdlog"; - rev = "v${version}"; - hash = "sha256-XlzWNeyd+Ar4ArFcN1wkQ0aod6ckAiIb12odK7cf4+s="; - }; - - vendorHash = "sha256-hvv0dsE1yz85VLaBOE7RWbux8L8kVTihcA1HyyHRYAM="; - - subPackages = [ - "cmd/nerdlog" - "cmd/generate_syslog" - ]; - - doCheck = false; - - nativeBuildInputs = [ - pkg-config - makeWrapper - ]; - - buildInputs = - lib.optionals stdenv.isDarwin [ - darwin.apple_sdk.frameworks.Cocoa - ] - ++ lib.optionals stdenv.isLinux [ - xorg.libX11 - xorg.libXext - xorg.libXfixes - wayland - libGL - libxkbcommon - ]; - - postInstall = lib.optionalString stdenv.isLinux '' - wrapProgram $out/bin/nerdlog \ - --prefix LD_LIBRARY_PATH : ${ - lib.makeLibraryPath [ - xorg.libX11 - xorg.libXext - xorg.libXfixes - wayland - libGL - libxkbcommon - ] - } - ''; - - ldflags = [ - "-s" - "-w" - "-X=github.com/dimonomid/nerdlog/version.version=${version}" - "-X=github.com/dimonomid/nerdlog/version.commit=${src.rev}" - "-X=github.com/dimonomid/nerdlog/version.date=1970-01-01T00:00:00Z" - "-X=github.com/dimonomid/nerdlog/version.builtBy=goreleaser" - ]; - - meta = { - description = "Nerdlog: fast, remote-first, multi-host TUI log viewer with timeline histogram and no central server"; - homepage = "https://github.com/dimonomid/nerdlog"; - changelog = "https://github.com/dimonomid/nerdlog/blob/${src.rev}/CHANGELOG.md"; - license = lib.licenses.bsd2; - mainProgram = "nerdlog"; - }; -} diff --git a/pkgs/openmv-ide/default.nix b/pkgs/openmv-ide/default.nix deleted file mode 100644 index bef3cc1..0000000 --- a/pkgs/openmv-ide/default.nix +++ /dev/null @@ -1,132 +0,0 @@ -{ - lib, - stdenv, - fetchurl, - - at-spi2-atk, - autoPatchelfHook, - cairo, - cups, - dbus, - fontconfig, - freetype, - gdk-pixbuf, - glib, - gtk3, - libGL, - libdrm, - libxcb-cursor, - libxkbcommon, - makeWrapper, - pango, - wayland, - xorg, - zlib, -}: - -stdenv.mkDerivation rec { - pname = "openmv-ide"; - version = "4.8.9"; - - src = fetchurl { - url = "https://github.com/openmv/openmv-ide/releases/download/v${version}/openmv-ide-linux-x86_64-${version}.tar.gz"; - hash = "sha256-D0Uunb6IIX8gkirZIISjjhvrrCsR5bgRBcXidtjN/n0="; - }; - - nativeBuildInputs = [ - autoPatchelfHook - makeWrapper - ]; - - buildInputs = [ - at-spi2-atk - cairo - cups - dbus.lib - fontconfig - freetype - gdk-pixbuf - glib - gtk3 - libGL - libdrm - libxcb-cursor - libxkbcommon - pango - stdenv.cc.cc.lib - wayland - xorg.libX11 - xorg.libxcb - xorg.xcbutil - xorg.xcbutilimage - xorg.xcbutilkeysyms - xorg.xcbutilrenderutil - xorg.xcbutilwm - zlib - ]; - - autoPatchelfIgnoreMissingDeps = [ - "libQt6Designer.so.6" - "libQt6Labs*.so.6" - "libQt6OpenGLWidgets.so.6" - "libQt6Qml*.so.6" - "libQt6Quick*.so.6" - "libQt6ShaderTools.so.6" - "libgssapi_krb5.so.2" - "libicudata.so.56" - "libicui18n.so.56" - "libicuuc.so.56" - "libmysqlclient.so.21" - "libodbc.so.2" - "libpq.so.5" - ]; - - dontAutoPatchelf = true; - dontBuild = true; - dontConfigure = true; - dontStrip = true; - - installPhase = '' - runHook preInstall - - mkdir -p $out/share/openmv-ide - cp -r bin lib share $out/share/openmv-ide/ - - chmod -R u+w $out/share/openmv-ide/ - - mkdir -p $out/share/applications - cp share/applications/io.openmv.openmvide.desktop $out/share/applications/ - - mkdir -p $out/share/icons - cp -r share/icons/hicolor $out/share/icons/ - - substituteInPlace $out/share/applications/io.openmv.openmvide.desktop \ - --replace "Exec=openmvide" "Exec=$out/bin/openmvide" - - mkdir -p $out/bin - makeWrapper $out/share/openmv-ide/bin/openmvide $out/bin/openmvide \ - --prefix LD_LIBRARY_PATH : "$out/share/openmv-ide/lib:$out/share/openmv-ide/lib/qtcreator:$out/share/openmv-ide/lib/Qt/lib" \ - --add-flags "-user-library-path \"\$LD_LIBRARY_PATH\"" - - runHook postInstall - ''; - - postFixup = '' - addAutoPatchelfSearchPath $out/share/openmv-ide/lib/Qt/lib - addAutoPatchelfSearchPath $out/share/openmv-ide/lib/qtcreator - - # skip embedded third-party toolchains and tools under share/ - autoPatchelf -- \ - $out/share/openmv-ide/bin \ - $out/share/openmv-ide/lib - ''; - - meta = { - description = "QtCreator based IDE for the OpenMV Cam"; - homepage = "https://openmv.io/"; - license = lib.licenses.gpl3Plus; - mainProgram = "openmvide"; - platforms = [ "x86_64-linux" ]; - sourceProvenance = [ lib.sourceTypes.binaryNativeCode ]; - }; -} diff --git a/pkgs/pass2bw/convert_csvs.py b/pkgs/pass2bw/convert_csvs.py index c67b842..4babb74 100644 --- a/pkgs/pass2bw/convert_csvs.py +++ b/pkgs/pass2bw/convert_csvs.py @@ -42,14 +42,6 @@ def process_csv(input_file, output_file): for col, default_val in default_values.items(): if col not in new_row: new_row[col] = default_val - - folder = new_row.get('folder', '') - name = new_row.get('name', '') - if folder.startswith('www') and name: - if not name.startswith('http://') and not name.startswith('https://'): - new_row['login_uri'] = f'https://{name}' - else: - new_row['login_uri'] = name if new_row['notes']: new_row['notes'] = new_row['notes'].replace('\n', ' ').replace('\r', ' ') @@ -57,6 +49,7 @@ def process_csv(input_file, output_file): notes = new_row['notes'] if notes: + # Look for pattern: "login: USERNAME" match = re.search(r'login:\s*(\S+)', notes, re.IGNORECASE) if match: username = match.group(1) diff --git a/pkgs/pass2bw/default.nix b/pkgs/pass2bw/default.nix index ce42f1f..349d8d1 100644 --- a/pkgs/pass2bw/default.nix +++ b/pkgs/pass2bw/default.nix @@ -2,8 +2,6 @@ stdenv, lib, makeWrapper, - pass, - pass2csv, python3, ... }: @@ -22,18 +20,13 @@ stdenv.mkDerivation rec { installPhase = '' mkdir -p $out/bin - cp ${src}/pass2bw.sh $out/bin/${pname} + sed -e "s|python ./convert_csvs.py|python $out/bin/convert_csvs.py|" \ + ${src}/${pname}.sh > $out/bin/${pname} chmod +x $out/bin/${pname} cp ${src}/convert_csvs.py $out/bin/ wrapProgram $out/bin/${pname} \ - --prefix PATH : ${ - lib.makeBinPath [ - pass - pass2csv - python3 - ] - } + --prefix PATH : ${lib.makeBinPath [ python3 ]} ''; } diff --git a/pkgs/pass2bw/pass2bw.sh b/pkgs/pass2bw/pass2bw.sh index 887a881..95cb544 100644 --- a/pkgs/pass2bw/pass2bw.sh +++ b/pkgs/pass2bw/pass2bw.sh @@ -4,5 +4,5 @@ if [ "$#" -ne 2 ]; then fi pass2csv "$1" /tmp/pass.csv -python3 "$(dirname "$0")/convert_csvs.py" /tmp/pass.csv "$2" +python ./convert_csvs.py /tmp/pass.csv "$2" rm /tmp/pass.csv diff --git a/pkgs/tinyfugue/default.nix b/pkgs/tinyfugue/default.nix deleted file mode 100644 index f675682..0000000 --- a/pkgs/tinyfugue/default.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - lib, - stdenv, - fetchFromGitHub, - ncurses, - openssl, - pcre2, - zlib, - - lua5_4, - python3, - icu, - - enableLua ? true, - enablePython ? true, - enableWidechar ? true, -}: - -stdenv.mkDerivation rec { - pname = "tinyfugue"; - version = "5.2.2"; - - src = fetchFromGitHub { - owner = "ingwarsw"; - repo = "tinyfugue"; - rev = version; - hash = "sha256-nHgu0XJ2Nd0JYrs3o/NLZ9gq1D4ubdPyowQLyhOzDDA="; - }; - - buildInputs = [ - ncurses - openssl - pcre2 - zlib - ] - ++ lib.optional enableLua lua5_4 - ++ lib.optional enablePython python3 - ++ lib.optional enableWidechar icu; - - env.NIX_CFLAGS_COMPILE = "-D_DEFAULT_SOURCE"; - - configureFlags = [ - "--enable-termcap=ncurses" - ] - ++ lib.optional enableLua "--enable-lua" - ++ lib.optional enablePython "--enable-python" - ++ lib.optional (!enableWidechar) "--disable-widechar"; - - installPhase = '' - make install - ''; - - meta = { - description = "TinyFugue - Rebirth"; - homepage = "https://github.com/ingwarsw/tinyfugue"; - changelog = "https://github.com/ingwarsw/tinyfugue/blob/${src.rev}/CHANGES"; - license = lib.licenses.gpl2Only; - mainProgram = "tf"; - platforms = lib.platforms.all; - }; -} diff --git a/templates/dev/stm32-blink/.envrc b/templates/dev/stm32-blink/.envrc deleted file mode 100644 index 3550a30..0000000 --- a/templates/dev/stm32-blink/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake diff --git a/templates/dev/stm32-blink/.gitignore b/templates/dev/stm32-blink/.gitignore deleted file mode 100644 index 5f20868..0000000 --- a/templates/dev/stm32-blink/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.cache/ -.direnv/ -build/ -compile_commands.json -result diff --git a/templates/dev/stm32-blink/Makefile b/templates/dev/stm32-blink/Makefile deleted file mode 100644 index 2a03551..0000000 --- a/templates/dev/stm32-blink/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -PREFIX ?= arm-none-eabi- -CC = $(PREFIX)gcc -OBJCOPY = $(PREFIX)objcopy -SIZE = $(PREFIX)size - -PNAME := blink -BUILD := build - -# libopencm3 is provided by the Nix shell -OPENCM3_DIR ?= "" - -SRCS := src/main.c -OBJS := $(addprefix $(BUILD)/, $(SRCS:.c=.o)) - -# STM32G4 -CPU_FLAGS := -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 - -CFLAGS := $(CPU_FLAGS) \ - -DSTM32G4 \ - -Os -Wall -Wextra \ - -ffunction-sections -fdata-sections \ - -I$(OPENCM3_DIR)/include - -LDFLAGS := $(CPU_FLAGS) \ - -nostartfiles \ - -Wl,--gc-sections \ - -L$(OPENCM3_DIR)/lib \ - -lopencm3_stm32g4 - -ELF := $(BUILD)/$(PNAME).elf -BIN := $(BUILD)/$(PNAME).bin -HEX := $(BUILD)/$(PNAME).hex - -.PHONY: all clean flash size - -all: $(BIN) $(HEX) size - -$(BUILD)/%.o: %.c - @mkdir -p $(@D) - $(CC) $(CFLAGS) -c $< -o $@ - -LDSCRIPT := $(BUILD)/stm32g474xe.ld - -$(LDSCRIPT): - @mkdir -p $(@D) - $(CC) -I$(OPENCM3_DIR)/include $(shell python3 $(OPENCM3_DIR)/scripts/genlink.py $(OPENCM3_DIR)/ld/devices.data stm32g474xe DEFS) -P -E $(OPENCM3_DIR)/ld/linker.ld.S -o $@ - -$(ELF): $(OBJS) $(LDSCRIPT) - $(CC) $(OBJS) $(LDFLAGS) -T$(LDSCRIPT) -o $@ - -$(BIN): $(ELF) - $(OBJCOPY) -O binary $< $@ - -$(HEX): $(ELF) - $(OBJCOPY) -O ihex $< $@ - -size: $(ELF) - $(SIZE) $< - -flash: $(BIN) - openocd \ - -f interface/stlink.cfg \ - -f target/stm32g4x.cfg \ - -c "program $(BIN) verify reset exit 0x08000000" - -clean: - rm -rf $(BUILD) diff --git a/templates/dev/stm32-blink/README.md b/templates/dev/stm32-blink/README.md deleted file mode 100644 index 0da9414..0000000 --- a/templates/dev/stm32-blink/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# STM32G4 blink template - -Blinks the LD2 LED (PA5) on a [Nucleo-G474RE](https://www.st.com/en/evaluation-tools/nucleo-g474re.html) using [libopencm3](https://github.com/libopencm3/libopencm3). - -Set `BLINK_PORT` / `BLINK_PIN` for your board in [`src/main.c`](./src/main.c). - -## Toolchain - -The Nix dev shell provides: - -- `arm-none-eabi-gcc` (via `gcc-arm-embedded`) -- `openocd` for flashing and debugging -- `stlink` utilities (`st-flash`, `st-info`) -- `libopencm3` built for `stm32/g4` (exposed as `$LIBOPENCM3_DIR`) - -## Build - -```bash -make -``` - -## Flash - -```bash -make flash -``` - -This uses OpenOCD with the built-in ST-Link interface config. diff --git a/templates/dev/stm32-blink/build.sh b/templates/dev/stm32-blink/build.sh deleted file mode 100755 index ae17afe..0000000 --- a/templates/dev/stm32-blink/build.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -make clean -mkdir -p build -bear -- make diff --git a/templates/dev/stm32-blink/flake.nix b/templates/dev/stm32-blink/flake.nix deleted file mode 100644 index 26b4bc7..0000000 --- a/templates/dev/stm32-blink/flake.nix +++ /dev/null @@ -1,161 +0,0 @@ -{ - description = "A blink template for STM32G4"; - - inputs = { - nixpkgs.url = "nixpkgs/nixpkgs-unstable"; - utils.url = "github:numtide/flake-utils"; - libopencm3-src = { - url = "github:libopencm3/libopencm3"; - flake = false; - }; - pre-commit-hooks = { - url = "github:cachix/pre-commit-hooks.nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; - - outputs = - { - self, - nixpkgs, - utils, - libopencm3-src, - pre-commit-hooks, - ... - }: - { - overlays.default = final: prev: { - libopencm3-stm32 = final.stdenvNoCC.mkDerivation { - pname = "libopencm3-stm32"; - version = "latest"; - - src = libopencm3-src; - - postPatch = '' - patchShebangs scripts - ''; - - nativeBuildInputs = [ - final.gcc-arm-embedded - final.python3 - final.gnumake - ]; - - enableParallelBuilding = true; - - makeFlags = [ - "PREFIX=arm-none-eabi-" - ]; - - TARGETS = "stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/f7 stm32/l0 stm32/l1 stm32/l4 stm32/g0 stm32/g4 stm32/h7 stm32/u5"; - - installPhase = '' - runHook preInstall - - mkdir -p $out - cp -r include lib mk scripts ld $out/ - - patchShebangs $out/scripts - - runHook postInstall - ''; - - meta = with final.lib; { - description = "Open source ARM Cortex-M microcontroller library (STM32 targets)"; - homepage = "http://libopencm3.org/"; - license = licenses.lgpl3Plus; - platforms = platforms.all; - }; - }; - }; - } - // utils.lib.eachDefaultSystem ( - system: - let - pkgs = import nixpkgs { - inherit system; - overlays = [ self.overlays.default ]; - }; - pname = "blink"; - version = "0.1.0"; - in - { - packages = { - inherit (pkgs) libopencm3-stm32; - default = pkgs.stdenvNoCC.mkDerivation { - inherit pname version; - src = pkgs.lib.cleanSource ./.; - - nativeBuildInputs = with pkgs; [ - gcc-arm-embedded - gnumake - python3 - ]; - - makeFlags = [ - "OPENCM3_DIR=${pkgs.libopencm3-stm32}" - "PREFIX=arm-none-eabi-" - ]; - - installPhase = '' - runHook preInstall - mkdir -p $out/bin - cp build/${pname}.elf $out/bin/ - cp build/${pname}.bin $out/bin/ - cp build/${pname}.hex $out/bin/ - runHook postInstall - ''; - }; - }; - - devShells.default = - let - # FIXME: 'gnu/stubs-32.h' file not found - clangdWrapper = pkgs.writeShellScriptBin "clangd" '' - exec ${pkgs.clang-tools}/bin/clangd \ - --query-driver=${pkgs.gcc-arm-embedded}/bin/arm-none-eabi-* \ - "$@" - ''; - in - pkgs.mkShell { - name = "stm32-blink"; - packages = self.packages.${system}.default.nativeBuildInputs ++ [ - clangdWrapper - - pkgs.bear - pkgs.openocd - pkgs.stlink - ]; - OPENCM3_DIR = pkgs.libopencm3-stm32; - PREFIX = "arm-none-eabi-"; - }; - - formatter = - let - inherit (self.checks.${system}.pre-commit-check.config) package configFile; - script = '' - ${pkgs.lib.getExe package} run --all-files --config ${configFile} - ''; - in - pkgs.writeShellScriptBin "pre-commit-run" script; - - checks = { - build-packages = pkgs.linkFarm "flake-packages-${system}" self.packages.${system}; - - pre-commit-check = pre-commit-hooks.lib.${system}.run { - src = ./.; - hooks = { - nixfmt.enable = true; - clang-format = { - enable = true; - types_or = pkgs.lib.mkForce [ - "c" - "c++" - ]; - }; - }; - }; - }; - } - ); -} diff --git a/templates/dev/stm32-blink/src/main.c b/templates/dev/stm32-blink/src/main.c deleted file mode 100644 index 4ed6e04..0000000 --- a/templates/dev/stm32-blink/src/main.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include - -/* Nucleo-G474RE: LD2 is on PA5 */ -#define BLINK_PORT GPIOA -#define BLINK_PIN GPIO5 -#define BLINK_PERIOD_MS 1000 - -static volatile uint32_t s_ticks = 0; - -void sys_tick_handler(void) { s_ticks++; } - -static void delay_ms(uint32_t ms) { - uint32_t until = s_ticks + ms; - while (s_ticks < until) - ; -} - -static void clock_setup(void) { - rcc_clock_setup_pll(&rcc_hsi_configs[RCC_CLOCK_3V3_170MHZ]); -} - -static void systick_setup(void) { - /* 1 ms tick at 170 MHz core clock */ - systick_set_reload(rcc_ahb_frequency / 1000 - 1); - systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); - systick_counter_enable(); - systick_interrupt_enable(); -} - -static void gpio_setup(void) { - rcc_periph_clock_enable(RCC_GPIOA); - gpio_mode_setup(BLINK_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, BLINK_PIN); - gpio_set_output_options(BLINK_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_LOW, - BLINK_PIN); -} - -int main(void) { - clock_setup(); - systick_setup(); - gpio_setup(); - - while (1) { - gpio_toggle(BLINK_PORT, BLINK_PIN); - delay_ms(BLINK_PERIOD_MS); - } - - return 0; -} diff --git a/tests/build/hm-hyprland/default.nix b/tests/build/hm-hyprland/default.nix index 083c68f..9b034fa 100644 --- a/tests/build/hm-hyprland/default.nix +++ b/tests/build/hm-hyprland/default.nix @@ -23,8 +23,6 @@ }; stylix.enable = true; - stylix.scheme = "generate-from-image"; - stylix.image = ./wallpaper.png; home.stateVersion = "25.11"; } diff --git a/tests/build/hm-hyprland/wallpaper.png b/tests/build/hm-hyprland/wallpaper.png deleted file mode 100644 index a9edb68..0000000 Binary files a/tests/build/hm-hyprland/wallpaper.png and /dev/null differ diff --git a/tests/run/librechat-oci.nix b/tests/run/librechat-oci.nix deleted file mode 100644 index 70aabed..0000000 --- a/tests/run/librechat-oci.nix +++ /dev/null @@ -1,38 +0,0 @@ -let - port = 3080; -in -{ - name = "librechat-oci-test"; - - nodes.machine = - { ... }: - { - imports = [ - ../../modules/nixos/librechat-oci - ]; - - config = { - virtualisation.diskSize = 32768; - virtualisation.memorySize = 8192; - - services.librechat-oci = { - enable = true; - inherit port; - }; - - networking.firewall.enable = false; - }; - }; - - testScript = '' - start_all() - - machine.wait_for_unit("default.target") - - machine.wait_for_unit("podman-librechat-mongodb.service") - machine.wait_for_unit("podman-librechat.service") - machine.wait_for_open_port(${toString port}) - - machine.succeed("curl --fail --retry 10 --retry-delay 5 --retry-connrefused http://localhost:${toString port}/") - ''; -}