enforce new flake schema. formatting.
Some checks failed
Build tests / build-hosts (pull_request) Failing after 3s
Flake check / flake-check (pull_request) Failing after 13s

This commit is contained in:
sid 2026-05-31 18:50:41 +02:00
parent 4b0a90e00d
commit ecf5132cbb
121 changed files with 1606 additions and 1554 deletions

1
.envrc
View file

@ -1 +1,2 @@
# shellcheck shell=bash
use flake use flake

View file

@ -1,3 +1,4 @@
---
name: Build tests name: Build tests
on: on:

View file

@ -1,3 +1,4 @@
---
name: Deploy docs name: Deploy docs
on: on:

View file

@ -1,6 +1,8 @@
---
name: Flake check name: Flake check
on: [pull_request] on:
pull_request:
jobs: jobs:
flake-check: flake-check:
@ -11,5 +13,8 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Check formatting
run: nix fmt -- --check
- name: Run flake check - name: Run flake check
run: nix flake check --impure run: nix flake check --impure --all-systems

View file

@ -11,9 +11,6 @@ HOSTNAME=""
# Templates with Home Manager configurations # Templates with Home Manager configurations
HM_CONFIGS=("hyprland") HM_CONFIGS=("hyprland")
# This will get overwritten by the derivation
TEMPLATES_DIR=""
# Print usage information # Print usage information
usage() { usage() {
cat <<EOF cat <<EOF

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
# NixOS and standalone Home Manager rebuild script # NixOS and standalone Home Manager rebuild script
# Defaults # Defaults

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
SYSTEM="x86_64-linux" SYSTEM="x86_64-linux"
IGNORE_PACKAGES=( IGNORE_PACKAGES=(
"pyman" "pyman"

View file

@ -114,7 +114,8 @@ git clone YOUR_GIT_REPO_URL ~/.config/nixos
Home Manager is not installed by default. Enter the development shell to apply the configuration: Home Manager is not installed by default. Enter the development shell to apply the configuration:
```bash ```bash
nix-shell ~/.config/nixos/shell.nix --run 'rebuild home' nix --experimental-features "nix-command flakes" develop git+https://git.sid.ovh/sid/synix#devShells.x86_64-linux.install-hm \
--command "rebuild home"
``` ```
### 8. Reboot your System ### 8. Reboot your System

210
flake.nix
View file

@ -3,7 +3,6 @@
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
nix.url = "github:DeterminateSystems/nix-src/flake-schemas"; nix.url = "github:DeterminateSystems/nix-src/flake-schemas";
flake-schemas.url = "github:DeterminateSystems/flake-schemas"; flake-schemas.url = "github:DeterminateSystems/flake-schemas";
git-hooks.url = "github:cachix/git-hooks.nix"; git-hooks.url = "github:cachix/git-hooks.nix";
@ -29,50 +28,69 @@
... ...
}@inputs: }@inputs:
let let
supportedSystems = [ inherit (self) outputs;
systems = [
"x86_64-linux" "x86_64-linux"
"aarch64-linux" # For testing only. Use at your own risk. "aarch64-linux" # For testing only. Use at your own risk.
]; ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems; lib = nixpkgs.lib.extend (_final: _prev: self.lib.utils or { });
nixpkgsFor = forAllSystems ( mkPkgs =
system: {
system,
config ? { },
}:
import nixpkgs { import nixpkgs {
inherit system; inherit system;
inherit config;
overlays = [ overlays = [
self.overlays.default self.overlays.modifications
self.overlays.additions
inputs.nix.overlays.default inputs.nix.overlays.default
(final: prev: { synix = self.overlays.additions final prev; })
]; ];
}
);
test = {
system = "x86_64-linux";
lib = nixpkgs.lib.extend (final: prev: self.outputs.lib or { });
inputs = inputs // {
synix = self;
}; };
outputs = { };
overlays = [ forAllSystems =
self.overlays.default function:
self.overlays.additions lib.genAttrs systems (
self.overlays.modifications system:
(final: prev: { synix = self.packages."${final.system}"; }) function (mkPkgs {
]; inherit system;
}; })
);
mkNixosConfiguration =
system: modules:
nixpkgs.lib.nixosSystem {
inherit system modules;
specialArgs = {
inherit inputs outputs lib;
};
};
mkHomeConfiguration =
system: modules:
inputs.home-manager.lib.homeManagerConfiguration {
pkgs = mkPkgs { inherit system; };
inherit modules;
extraSpecialArgs = {
inherit inputs outputs;
};
};
in in
{ {
inherit (inputs.flake-schemas) schemas; inherit (inputs.flake-schemas) schemas;
apps = forAllSystems ( apps = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgs.legacyPackages.${system}; mkApp = name: description: {
mkApp = name: desc: {
type = "app"; type = "app";
program = pkgs.lib.getExe (pkgs.callPackage ./apps/${name} { }); program = pkgs.lib.getExe (pkgs.callPackage ./apps/${name} { });
meta.description = desc; meta.description = description;
}; };
in in
{ {
@ -86,13 +104,17 @@
); );
lib = { lib = {
utils = import ./lib/utils.nix { lib = nixpkgs.lib; }; utils = import ./lib/utils.nix { inherit (nixpkgs) lib; };
helpers = {
inherit mkPkgs;
};
}; };
packages = forAllSystems ( packages = forAllSystems (
system: pkgs:
let let
allArchs = import ./pkgs { pkgs = nixpkgs.legacyPackages.${system}; }; inherit (pkgs.stdenv.hostPlatform) system;
allArchs = import ./pkgs { inherit pkgs; };
x64only = x64only =
if system == "x86_64-linux" then if system == "x86_64-linux" then
{ {
@ -111,109 +133,89 @@
# test configs # test configs
nixosConfigurations = { nixosConfigurations = {
nixos-hyprland = nixpkgs.lib.nixosSystem { nixos-hyprland = mkNixosConfiguration "x86_64-linux" [ ./tests/build/nixos-hyprland ];
inherit (test) system; nixos-server = mkNixosConfiguration "x86_64-linux" [ ./tests/build/nixos-server ];
modules = [
./tests/build/nixos-hyprland
{ nixpkgs.overlays = test.overlays; }
];
specialArgs = {
inherit (test) inputs outputs lib;
};
};
nixos-server = nixpkgs.lib.nixosSystem {
inherit (test) system;
modules = [
./tests/build/nixos-server
{ nixpkgs.overlays = test.overlays; }
];
specialArgs = {
inherit (test) inputs outputs lib;
};
};
}; };
homeConfigurations = { homeConfigurations = {
hm-hyprland = inputs.home-manager.lib.homeManagerConfiguration { hm-hyprland = mkHomeConfiguration "x86_64-linux" [ ./tests/build/hm-hyprland ];
pkgs = import nixpkgs {
inherit (test) overlays system;
};
extraSpecialArgs = {
inherit (test) inputs outputs;
};
modules = [
./tests/build/hm-hyprland
];
};
}; };
devShells = forAllSystems ( devShells = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgsFor.${system}; inherit (pkgs.stdenv.hostPlatform) system;
inherit (self.checks.${system}.pre-commit-check) shellHook enabledPackages;
in in
{ {
default = default = pkgs.mkShell {
let inherit shellHook;
inherit (self.checks.${system}.pre-commit-check) shellHook enabledPackages; nativeBuildInputs = [
in enabledPackages
pkgs.mkShell { pkgs.nix
inherit shellHook; ]
nativeBuildInputs = [ ++ (with pkgs; [
enabledPackages (python313.withPackages (
pkgs.nix p: with p; [
] mkdocs
++ (with pkgs; [ mkdocs-material
(python313.withPackages ( mkdocs-material-extensions
p: with p; [ pygments
mkdocs ]
mkdocs-material ))
mkdocs-material-extensions ]);
pygments };
] nix-config = pkgs.mkShell {
)) inherit shellHook;
]); nativeBuildInputs = [ enabledPackages ];
}; };
install-hm = pkgs.mkShell {
NIX_CONFIG = "extra-experimental-features = nix-command flakes";
nativeBuildInputs = [ pkgs.home-manager ];
};
} }
); );
formatter = forAllSystems ( formatter = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgs.legacyPackages.${system}; inherit (pkgs.stdenv.hostPlatform) system;
config = self.checks.${system}.pre-commit-check.config; inherit (self.checks.${system}.pre-commit-check.config) package configFile;
inherit (config) package configFile;
script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile}
'';
in in
pkgs.writeShellScriptBin "pre-commit-run" script pkgs.writeShellScriptBin "pre-commit-run" "${pkgs.lib.getExe package} run --all-files --config ${configFile}"
); );
checks = forAllSystems ( checks = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgs.legacyPackages.${system}; inherit (pkgs.stdenv.hostPlatform) system;
flakePkgs = self.packages.${system};
overlaidPkgs = import nixpkgs {
inherit system;
overlays = [ self.overlays.modifications ];
};
in in
{ {
pre-commit-check = inputs.git-hooks.lib.${system}.run { pre-commit-check = inputs.git-hooks.lib.${system}.run {
src = ./.; src = ./.;
hooks = { hooks = {
nixfmt.enable = true; actionlint.enable = true;
nixfmt = {
enable = true;
settings.width = 120;
};
shellcheck.enable = true;
statix.enable = true;
yamllint = {
enable = true;
excludes = [ "secrets.yaml" ];
settings.configData = "{rules: {line-length: {max: 120}}}";
};
}; };
}; };
build-packages = pkgs.linkFarm "flake-packages-${system}" flakePkgs;
build-overlays = pkgs.linkFarm "flake-overlays-${system}" { build-additions = pkgs.linkFarm "added-packages-${system}" self.packages.${system};
kicad = overlaidPkgs.kicad; build-modifications = pkgs.linkFarm "modified-packages-${system}" (
}; lib.filterAttrs (_: v: lib.isDerivation v) (self.overlays.modifications pkgs pkgs)
);
synapse-test = synapse-test =
let let
testPkgs = import nixpkgs { testPkgs = mkPkgs {
inherit system; inherit system;
config.permittedInsecurePackages = [ "olm-3.2.16" ]; config.permittedInsecurePackages = [ "olm-3.2.16" ];
}; };

View file

@ -1,3 +1,4 @@
---
site_name: synix docs site_name: synix docs
repo_url: https://git.sid.ovh/sid/synix repo_url: https://git.sid.ovh/sid/synix
site_url: https://doc.sid.ovh/synix site_url: https://doc.sid.ovh/synix
@ -20,7 +21,7 @@ markdown_extensions:
- pymdownx.superfences - pymdownx.superfences
nav: nav:
- Home: index.md # do not change - Home: index.md # do not change
- Introduction to Nix: - Introduction to Nix:
- Overview: introduction-to-nix/overview.md - Overview: introduction-to-nix/overview.md
- Install Nix: introduction-to-nix/install-nix.md - Install Nix: introduction-to-nix/install-nix.md

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
# change directory with fzf # change directory with fzf
# Usage: cdf [optional_relative_path] # Usage: cdf [optional_relative_path]
# - If no argument, searches from $HOME. # - If no argument, searches from $HOME.
@ -67,7 +68,8 @@ function cdf() {
"--preview=tree -C {} | head -50" "--preview=tree -C {} | head -50"
"--preview-window=right:50%:wrap" "--preview-window=right:50%:wrap"
) )
local selected=$(find "${find_args[@]}" 2>/dev/null | fzf "${fzf_args[@]}") local selected
selected=$(find "${find_args[@]}" 2>/dev/null | fzf "${fzf_args[@]}")
if [[ -n "$selected" ]]; then if [[ -n "$selected" ]]; then
cd "$selected" || echo "Failed to cd into '$selected'" cd "$selected" || echo "Failed to cd into '$selected'"

View file

@ -16,31 +16,33 @@ in
imports = [ ../../../rofi-rbw ]; imports = [ ../../../rofi-rbw ];
config = mkIf (cfg.enable && app == "rofi-rbw") { config = mkIf (cfg.enable && app == "rofi-rbw") {
programs.rbw = { programs = {
enable = true; rbw = {
settings = { enable = true;
# email = "you@example.tld"; # You have to set this in your config settings = {
pinentry = mkDefault pkgs.pinentry-gnome3; # email = "you@example.tld"; # You have to set this in your config
lock_timeout = mkDefault 3600; pinentry = mkDefault pkgs.pinentry-gnome3;
lock_timeout = mkDefault 3600;
};
}; };
};
programs.rofi-rbw = { rofi-rbw = {
enable = true; enable = true;
package = mkDefault pkgs.rofi-rbw-wayland; package = mkDefault pkgs.rofi-rbw-wayland;
settings = { settings = {
selector = mkDefault "bemenu"; selector = mkDefault "bemenu";
selector-args = mkDefault "-i -l 20"; selector-args = mkDefault "-i -l 20";
action = mkDefault "copy"; action = mkDefault "copy";
typing-key-delay = mkDefault 0; typing-key-delay = mkDefault 0;
};
}; };
};
programs.librewolf = mkIf config.programs.librewolf.enable { librewolf = mkIf config.programs.librewolf.enable {
profiles.default.extensions.packages = profiles.default.extensions.packages =
with inputs.nur.legacyPackages."${pkgs.stdenv.hostPlatform.system}".repos.rycee.firefox-addons; [ with inputs.nur.legacyPackages."${pkgs.stdenv.hostPlatform.system}".repos.rycee.firefox-addons; [
bitwarden bitwarden
]; ];
};
}; };
}; };
} }

View file

@ -22,7 +22,7 @@ let
{ {
default = mkOption { default = mkOption {
type = types.str; type = types.str;
default = default; inherit default;
description = "The default application to use for the ${default}."; description = "The default application to use for the ${default}.";
}; };
bind = mkOption { bind = mkOption {
@ -38,12 +38,8 @@ let
}; };
# generate lists of all binds and window rules and remove empty strings # generate lists of all binds and window rules and remove empty strings
binds = filter (s: s != "") ( binds = filter (s: s != "") (builtins.concatLists (map (app: app.bind or [ "" ]) (attrValues apps)));
builtins.concatLists (map (app: app.bind or [ "" ]) (attrValues apps)) windowrules = filter (s: s != "") (builtins.concatLists (map (app: app.windowrule or [ "" ]) (attrValues apps)));
);
windowrules = filter (s: s != "") (
builtins.concatLists (map (app: app.windowrule or [ "" ]) (attrValues apps))
);
inherit (lib) inherit (lib)
attrValues attrValues

View file

@ -5,7 +5,7 @@ let
pkill = "${pkgs.procps}/bin/pkill"; pkill = "${pkgs.procps}/bin/pkill";
signal = "${toString config.programs.waybar.settings.mainBar."custom/notifications".signal}"; signal = "${toString config.programs.waybar.settings.mainBar."custom/notifications".signal}";
in in
(pkgs.writeShellScriptBin "dunst-toggle" '' pkgs.writeShellScriptBin "dunst-toggle" ''
${dunst} set-paused toggle ${dunst} set-paused toggle
${pkill} -RTMIN+${signal} waybar ${pkill} -RTMIN+${signal} waybar
'') ''

View file

@ -9,7 +9,7 @@ let
cfg = config.wayland.windowManager.hyprland; cfg = config.wayland.windowManager.hyprland;
app = cfg.applications.rssreader.default; app = cfg.applications.rssreader.default;
reloadTime = "${toString config.programs.newsboat.reloadTime}"; reloadTime = "${toString config.programs.newsboat.reloadTime}";
newsboat-reload = (import ./newsboat-reload.nix { inherit config pkgs; }); newsboat-reload = import ./newsboat-reload.nix { inherit config pkgs; };
inherit (lib) mkIf; inherit (lib) mkIf;
in in
@ -27,9 +27,11 @@ in
timers.newsboat-reload = { timers.newsboat-reload = {
Unit.Description = "Reload newsboat every ${reloadTime} minutes"; Unit.Description = "Reload newsboat every ${reloadTime} minutes";
Timer.OnBootSec = "10sec"; Timer = {
Timer.OnUnitActiveSec = "${reloadTime}min"; OnBootSec = "10sec";
Timer.Unit = "newsboat-reload.service"; OnUnitActiveSec = "${reloadTime}min";
Unit = "newsboat-reload.service";
};
Install.WantedBy = [ "timers.target" ]; Install.WantedBy = [ "timers.target" ];
}; };

View file

@ -5,6 +5,6 @@ let
notify = "${pkgs.libnotify}/bin/notify-send"; notify = "${pkgs.libnotify}/bin/notify-send";
signal = "${toString config.programs.waybar.settings.mainBar."custom/newsboat".signal}"; signal = "${toString config.programs.waybar.settings.mainBar."custom/newsboat".signal}";
in in
(pkgs.writeShellScriptBin "newsboat-reload" '' pkgs.writeShellScriptBin "newsboat-reload" ''
${notify} -u low 'Newsboat' 'Reloading RSS feeds...' && ${newsboat} -x reload && ${notify} -u low 'Newsboat' 'RSS feeds reloaded.' && pkill -RTMIN+${signal} waybar ${notify} -u low 'Newsboat' 'Reloading RSS feeds...' && ${newsboat} -x reload && ${notify} -u low 'Newsboat' 'RSS feeds reloaded.' && pkill -RTMIN+${signal} waybar
'') ''

View file

@ -14,9 +14,7 @@ in
{ {
config = mkIf (cfg.enable && app == "presentation-mode-bemenu") { config = mkIf (cfg.enable && app == "presentation-mode-bemenu") {
home.packages = [ home.packages = [
(pkgs.writeShellScriptBin "presentation-mode-bemenu" ( (pkgs.writeShellScriptBin "presentation-mode-bemenu" (builtins.readFile ./presentation-mode-bemenu.sh))
builtins.readFile ./presentation-mode-bemenu.sh
))
]; ];
}; };
} }

View file

@ -1,5 +1,6 @@
#!/usr/bin/env bash
# Variables # Variables
DISPLAYS=( $(hyprctl monitors | grep -E '^Monitor' | awk '{print $2}') ) mapfile -t DISPLAYS < <(hyprctl monitors | grep -E '^Monitor' | awk '{print $2}')
EXTEND_RIGHT="Extend to right of main" EXTEND_RIGHT="Extend to right of main"
EXTEND_LEFT="Extend to left of main" EXTEND_LEFT="Extend to left of main"
MIRROR="Mirror main" MIRROR="Mirror main"

View file

@ -5,7 +5,7 @@
let let
screenshotDir = "${config.xdg.userDirs.pictures}/screenshots"; screenshotDir = "${config.xdg.userDirs.pictures}/screenshots";
in in
(pkgs.writeShellScriptBin "screenshot" '' pkgs.writeShellScriptBin "screenshot" ''
mkdir -p ${screenshotDir} mkdir -p ${screenshotDir}
${pkgs.hyprshot}/bin/hyprshot --mode $1 --output-folder ${screenshotDir} --filename screenshot_$(date +"%Y-%m-%d_%H-%M-%S").png ${pkgs.hyprshot}/bin/hyprshot --mode $1 --output-folder ${screenshotDir} --filename screenshot_$(date +"%Y-%m-%d_%H-%M-%S").png
'') ''

View file

@ -27,7 +27,7 @@ in
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
settings = { settings = {
bind = binds; bind = binds;
bindm = (import ./mouse.nix); bindm = import ./mouse.nix;
}; };
}; };
}; };

View file

@ -9,17 +9,19 @@ let
inherit (lib) mkForce; inherit (lib) mkForce;
in in
{ {
home.pointerCursor = { home = {
name = mkForce "Bibata-Original-Ice"; pointerCursor = {
size = mkForce 24; name = mkForce "Bibata-Original-Ice";
package = mkForce pkgs.bibata-cursors; size = mkForce 24;
}; package = mkForce pkgs.bibata-cursors;
};
home.packages = [ pkgs.hyprcursor ]; packages = [ pkgs.hyprcursor ];
home.sessionVariables = { sessionVariables = {
HYPRCURSOR_THEME = config.home.pointerCursor.name; HYPRCURSOR_THEME = config.home.pointerCursor.name;
HYPRCURSOR_SIZE = toString config.home.pointerCursor.size; HYPRCURSOR_SIZE = toString config.home.pointerCursor.size;
};
}; };
# wayland.windowManager.hyprland.cursor.no_hardware_cursors = true; # wayland.windowManager.hyprland.cursor.no_hardware_cursors = true;

View file

@ -78,12 +78,6 @@ in
# auto discover fonts in `home.packages` # auto discover fonts in `home.packages`
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;
# notifications
services.dunst = {
enable = mkDefault true;
waylandDisplay = config.home.sessionVariables.WAYLAND_DISPLAY;
};
# install some applications # install some applications
home.packages = import ./packages.nix { inherit pkgs; }; # use programs.PACKAGE or services.SERVICE when possible home.packages = import ./packages.nix { inherit pkgs; }; # use programs.PACKAGE or services.SERVICE when possible
@ -94,11 +88,19 @@ in
fi fi
''; '';
services.udiskie = { # notifications
enable = mkDefault true; services = {
tray = mkDefault "never"; dunst = {
}; enable = mkDefault true;
waylandDisplay = config.home.sessionVariables.WAYLAND_DISPLAY;
};
services.network-manager-applet.enable = mkDefault true; udiskie = {
enable = mkDefault true;
tray = mkDefault "never";
};
network-manager-applet.enable = mkDefault true;
};
}; };
} }

View file

@ -20,8 +20,10 @@ in
enable = mkDefault true; enable = mkDefault true;
createDirectories = mkDefault true; createDirectories = mkDefault true;
}; };
portal.enable = mkDefault true; portal = {
portal.extraPortals = [ portal ]; enable = mkDefault true;
portal.configPackages = [ portal ]; extraPortals = [ portal ];
configPackages = [ portal ];
};
}; };
} }

View file

@ -19,13 +19,13 @@ let
in in
{ {
urls = [ { template = engine.url; } ]; urls = [ { template = engine.url; } ];
icon = engine.icon; inherit (engine) icon;
updateInterval = if (isUrl engine.icon) then every_day else null; updateInterval = if (isUrl engine.icon) then every_day else null;
definedAliases = optional (engine ? alias) engine.alias; definedAliases = optional (engine ? alias) engine.alias;
}; };
transformedEngines = mapAttrs' (name: engine: { transformedEngines = mapAttrs' (name: engine: {
name = name; inherit name;
value = transformEngine engine; value = transformEngine engine;
}) engines; }) engines;
@ -79,7 +79,7 @@ in
profiles.default.search.engines = mapAttrs (_: name: transformedEngines.${name}) ( profiles.default.search.engines = mapAttrs (_: name: transformedEngines.${name}) (
listToAttrs ( listToAttrs (
map (name: { map (name: {
name = name; inherit name;
value = name; value = name;
}) cfg.searchEngines }) cfg.searchEngines
) )

View file

@ -16,17 +16,19 @@ in
{ {
config = { config = {
programs.nixvim = { programs.nixvim = {
plugins.treesitter = { plugins = {
enable = mkDefault true; treesitter = {
nixvimInjections = mkDefault true; enable = mkDefault true;
settings = { nixvimInjections = mkDefault true;
folding.enable = mkDefault true; settings = {
highlight.enable = mkDefault true; folding.enable = mkDefault true;
indent.enable = mkDefault true; highlight.enable = mkDefault true;
indent.enable = mkDefault true;
};
}; };
treesitter-context = mkIf plugin.enable { enable = mkDefault true; };
treesitter-textobjects = mkIf plugin.enable { enable = mkDefault true; };
}; };
plugins.treesitter-context = mkIf plugin.enable { enable = mkDefault true; };
plugins.treesitter-textobjects = mkIf plugin.enable { enable = mkDefault true; };
}; };
# Fix for: ERROR `cc` executable not found. # Fix for: ERROR `cc` executable not found.

View file

@ -9,7 +9,7 @@
let let
cfg = config.programs.passwordManager; cfg = config.programs.passwordManager;
passmenuScript = pkgs.writeShellScriptBin "passmenu-bemenu" (builtins.readFile ./passmenu); # TODO: override original passmenu script coming from pass itself passmenuScript = pkgs.writeShellScriptBin "passmenu-bemenu" (builtins.readFile ./passmenu); # TODO: override original passmenu script coming from pass itself
passff-host = pkgs.passff-host; inherit (pkgs) passff-host;
inherit (lib) inherit (lib)
mkDefault mkDefault

View file

@ -29,8 +29,7 @@ let
"moonfly" "moonfly"
"oxocarbon" "oxocarbon"
]; ];
schemeName = schemeName = if builtins.elem cfg.scheme needsSuffix then "${cfg.scheme}-${cfg.polarity}" else cfg.scheme;
if builtins.elem cfg.scheme needsSuffix then "${cfg.scheme}-${cfg.polarity}" else cfg.scheme;
inherit (lib) inherit (lib)
mkDefault mkDefault

View file

@ -1,3 +1,4 @@
---
system: "base16" system: "base16"
name: "Moonfly" name: "Moonfly"
description: "A dark theme inspired by the Moonfly color scheme." description: "A dark theme inspired by the Moonfly color scheme."

View file

@ -1,3 +1,4 @@
---
system: "base16" system: "base16"
name: "Oxocarbon" name: "Oxocarbon"
description: "A dark theme inspired by the Oxocarbon Dark color scheme." description: "A dark theme inspired by the Oxocarbon Dark color scheme."

View file

@ -10,13 +10,13 @@ let
let let
newsboat = "${pkgs.newsboat}/bin/newsboat"; newsboat = "${pkgs.newsboat}/bin/newsboat";
in in
(pkgs.writeShellScriptBin "newsboat-print-unread" '' pkgs.writeShellScriptBin "newsboat-print-unread" ''
UNREAD=$(${newsboat} -x print-unread | awk '{print $1}') UNREAD=$(${newsboat} -x print-unread | awk '{print $1}')
if [[ $UNREAD -gt 0 ]]; then if [[ $UNREAD -gt 0 ]]; then
printf " %i" "$UNREAD" printf " %i" "$UNREAD"
fi fi
''); '';
inherit (lib) mkDefault; inherit (lib) mkDefault;
in in

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
TIMER_FILE="/tmp/timer" # file to store the current time TIMER_FILE="/tmp/timer" # file to store the current time
SIGNAL=11 # signal number to send to status bar SIGNAL=11 # signal number to send to status bar
STATUS_BAR="waybar" # Support for more status bars? STATUS_BAR="waybar" # Support for more status bars?
@ -16,7 +17,7 @@ start_timer() {
notify-send "Timer Started" "Your countdown timer has been started." notify-send "Timer Started" "Your countdown timer has been started."
trap "exit" INT TERM trap "exit" INT TERM
trap "rm -f -- '$TIMER_FILE'" EXIT trap 'rm -f -- "$TIMER_FILE"' EXIT
while [ $total_seconds -gt 0 ]; do while [ $total_seconds -gt 0 ]; do
hours=$(( total_seconds / 3600 )) hours=$(( total_seconds / 3600 ))
@ -62,7 +63,7 @@ if [ "$1" = "start" ]; then
MINUTES=${MINUTES:-0} MINUTES=${MINUTES:-0}
SECONDS=${SECONDS:-0} SECONDS=${SECONDS:-0}
start_timer $HOURS $MINUTES $SECONDS start_timer "$HOURS" "$MINUTES" "$SECONDS"
elif [ "$1" = "stop" ]; then elif [ "$1" = "stop" ]; then
notify-send "Timer Stopped" "Your countdown timer has been stopped." notify-send "Timer Stopped" "Your countdown timer has been stopped."

View file

@ -4,10 +4,16 @@ let
inherit (lib) mkDefault; inherit (lib) mkDefault;
in in
{ {
hardware.bluetooth.enable = mkDefault true; hardware = {
hardware.bluetooth.powerOnBoot = mkDefault false; bluetooth = {
hardware.bluetooth.settings.General.Enable = mkDefault "Source,Sink,Media,Socket"; enable = mkDefault true;
hardware.bluetooth.settings.General.Experimental = mkDefault true; powerOnBoot = mkDefault false;
settings.General = {
Enable = mkDefault "Source,Sink,Media,Socket";
Experimental = mkDefault true;
};
};
};
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
blueman blueman

View file

@ -84,8 +84,6 @@ in
) { } cfg.remotes; ) { } cfg.remotes;
# Ensure that all cifs-mount services are started with the graphical session # Ensure that all cifs-mount services are started with the graphical session
systemd.user.targets.graphical-session.wants = map ( systemd.user.targets.graphical-session.wants = map (remote: "cifs-mount-${remote.shareName}.service") cfg.remotes;
remote: "cifs-mount-${remote.shareName}.service"
) cfg.remotes;
}; };
} }

View file

@ -1,20 +1,20 @@
{ lib, pkgs, ... }: { lib, pkgs, ... }:
{ {
# fix CVE-2026-31431 boot = {
boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.18.22") ( # fix CVE-2026-31431
lib.mkDefault pkgs.linuxPackages_6_18 kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.18.22") (lib.mkDefault pkgs.linuxPackages_6_18);
);
# fix CVE-2026-43500 # fix CVE-2026-43500
boot.extraModprobeConfig = '' extraModprobeConfig = ''
install esp4 ${pkgs.coreutils}/bin/false install esp4 ${pkgs.coreutils}/bin/false
install esp6 ${pkgs.coreutils}/bin/false install esp6 ${pkgs.coreutils}/bin/false
install rxrpc ${pkgs.coreutils}/bin/false install rxrpc ${pkgs.coreutils}/bin/false
''; '';
boot.blacklistedKernelModules = [ blacklistedKernelModules = [
"esp4" "esp4"
"esp6" "esp6"
"rxrpc" "rxrpc"
]; ];
};
} }

View file

@ -9,55 +9,59 @@ let
inherit (lib) mkDefault optionals; inherit (lib) mkDefault optionals;
in in
{ {
environment.systemPackages = environment = {
with pkgs; systemPackages =
[ with pkgs;
cryptsetup [
curl cryptsetup
dig curl
dnsutils dig
fzf dnsutils
gptfdisk fzf
iproute2 gptfdisk
jq iproute2
lm_sensors jq
lsof lm_sensors
netcat-openbsd lsof
nettools netcat-openbsd
nixos-container nettools
nmap nixos-container
nurl nmap
p7zip nurl
pciutils p7zip
psmisc pciutils
rclone psmisc
rsync rclone
tcpdump rsync
tmux tcpdump
tree tmux
unzip tree
usbutils unzip
wget usbutils
xxd wget
zip xxd
zip
(callPackage ../../../apps/rebuild { }) (callPackage ../../../apps/rebuild { })
] ]
++ optionals (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) [ ++ optionals (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) [
pkgs.kitty.terminfo pkgs.kitty.terminfo
]; ];
environment.shellAliases = { shellAliases = {
l = "ls -lh"; l = "ls -lh";
ll = "ls -lAh"; ll = "ls -lAh";
ports = "ss -tulpn"; ports = "ss -tulpn";
publicip = "curl ifconfig.me/all"; publicip = "curl ifconfig.me/all";
sudo = "sudo "; # make aliases work with `sudo` sudo = "sudo "; # make aliases work with `sudo`
};
# saves one instance of nixpkgs.
ldso32 = null;
}; };
# saves one instance of nixpkgs. boot = {
environment.ldso32 = null; tmp.cleanOnBoot = mkDefault true;
initrd.systemd.enable = mkDefault (!config.boot.swraid.enable && !config.boot.isContainer);
boot.tmp.cleanOnBoot = mkDefault true; };
boot.initrd.systemd.enable = mkDefault (!config.boot.swraid.enable && !config.boot.isContainer);
} }

View file

@ -2,16 +2,13 @@
# avoid TOFU MITM # avoid TOFU MITM
programs.ssh.knownHosts = { programs.ssh.knownHosts = {
"github.com".hostNames = [ "github.com" ]; "github.com".hostNames = [ "github.com" ];
"github.com".publicKey = "github.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
"gitlab.com".hostNames = [ "gitlab.com" ]; "gitlab.com".hostNames = [ "gitlab.com" ];
"gitlab.com".publicKey = "gitlab.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
"git.sr.ht".hostNames = [ "git.sr.ht" ]; "git.sr.ht".hostNames = [ "git.sr.ht" ];
"git.sr.ht".publicKey = "git.sr.ht".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60";
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60";
}; };
# TODO: add synix # TODO: add synix
} }

View file

@ -42,12 +42,8 @@ in
static-auth-secret-file = mkIf cfg.sops config.sops.secrets."coturn/static-auth-secret".path; static-auth-secret-file = mkIf cfg.sops config.sops.secrets."coturn/static-auth-secret".path;
realm = mkDefault "turn.${config.networking.domain}"; realm = mkDefault "turn.${config.networking.domain}";
cert = cert = mkIf (!cfg.no-tls && cfg.sops) "${config.security.acme.certs.${cfg.realm}.directory}/full.pem";
mkIf (!cfg.no-tls && cfg.sops) pkey = mkIf (!cfg.no-tls && cfg.sops) "${config.security.acme.certs.${cfg.realm}.directory}/key.pem";
"${config.security.acme.certs.${cfg.realm}.directory}/full.pem";
pkey =
mkIf (!cfg.no-tls && cfg.sops)
"${config.security.acme.certs.${cfg.realm}.directory}/key.pem";
extraConfig = '' extraConfig = ''
# ban private IP ranges # ban private IP ranges

View file

@ -33,11 +33,13 @@ in
fonts.fontconfig.enable = mkDefault false; fonts.fontconfig.enable = mkDefault false;
xdg.autostart.enable = mkDefault false; xdg = {
xdg.icons.enable = mkDefault false; autostart.enable = mkDefault false;
xdg.menus.enable = mkDefault false; icons.enable = mkDefault false;
xdg.mime.enable = mkDefault false; menus.enable = mkDefault false;
xdg.sounds.enable = mkDefault false; mime.enable = mkDefault false;
sounds.enable = mkDefault false;
};
programs.git.package = mkDefault pkgs.gitMinimal; programs.git.package = mkDefault pkgs.gitMinimal;
@ -48,22 +50,25 @@ in
viAlias = mkDefault true; viAlias = mkDefault true;
}; };
# emergency mode is useless on headless machines systemd = {
systemd.enableEmergencyMode = false; # emergency mode is useless on headless machines
enableEmergencyMode = false;
sleep.extraConfig = ''
AllowSuspend=no
AllowHibernation=no
'';
# force reboots
settings.Manager = {
RuntimeWatchdogSec = mkDefault "15s";
RebootWatchdogSec = mkDefault "30s";
KExecWatchdogSec = mkDefault "1m";
};
};
boot.initrd.systemd.suppressedUnits = mkIf config.systemd.enableEmergencyMode [ boot.initrd.systemd.suppressedUnits = mkIf config.systemd.enableEmergencyMode [
"emergency.service" "emergency.service"
"emergency.target" "emergency.target"
]; ];
systemd.sleep.extraConfig = ''
AllowSuspend=no
AllowHibernation=no
'';
# force reboots
systemd.settings.Manager = {
RuntimeWatchdogSec = mkDefault "15s";
RebootWatchdogSec = mkDefault "30s";
KExecWatchdogSec = mkDefault "1m";
};
} }

View file

@ -4,7 +4,9 @@ let
inherit (lib) mkDefault; inherit (lib) mkDefault;
in in
{ {
services.qemuGuest.enable = mkDefault true; services = {
services.spice-vdagentd.enable = mkDefault true; qemuGuest.enable = mkDefault true;
services.spice-webdavd.enable = mkDefault true; spice-vdagentd.enable = mkDefault true;
spice-webdavd.enable = mkDefault true;
};
} }

View file

@ -2,9 +2,9 @@
let let
cfg = config.services.ftp-webserver; cfg = config.services.ftp-webserver;
domain = config.networking.domain; inherit (config.networking) domain;
fqdn = if (cfg.subdomain != "") then "${cfg.subdomain}.${domain}" else domain; fqdn = if (cfg.subdomain != "") then "${cfg.subdomain}.${domain}" else domain;
nginx = config.services.nginx; inherit (config.services) nginx;
inherit (lib) inherit (lib)
mkEnableOption mkEnableOption
@ -35,7 +35,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.nginx.virtualHosts."${fqdn}" = { services.nginx.virtualHosts."${fqdn}" = {
root = cfg.root; inherit (cfg) root;
locations."/" = { locations."/" = {
extraConfig = '' extraConfig = ''
autoindex on; autoindex on;
@ -43,7 +43,7 @@ in
autoindex_localtime on; autoindex_localtime on;
''; '';
}; };
forceSSL = cfg.forceSSL; inherit (cfg) forceSSL;
enableACME = cfg.forceSSL; enableACME = cfg.forceSSL;
sslCertificate = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/cert.pem"; sslCertificate = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/cert.pem";
sslCertificateKey = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/key.pem"; sslCertificateKey = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/key.pem";

View file

@ -7,10 +7,10 @@
let let
cfg = config.services.headplane; cfg = config.services.headplane;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
headscale = config.services.headscale; inherit (config.services) headscale;
inherit (lib) inherit (lib)
mkDefault mkDefault
@ -55,7 +55,7 @@ in
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable { services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
"${fqdn}" = mkVirtualHost { "${fqdn}" = mkVirtualHost {
port = cfg.settings.server.port; inherit (cfg.settings.server) port;
ssl = cfg.reverseProxy.forceSSL; ssl = cfg.reverseProxy.forceSSL;
}; };
}; };
@ -63,7 +63,7 @@ in
sops.secrets = sops.secrets =
let let
owner = headscale.user; owner = headscale.user;
group = headscale.group; inherit (headscale) group;
mode = "0400"; mode = "0400";
in in
{ {

View file

@ -6,8 +6,8 @@
let let
cfg = config.services.headscale; cfg = config.services.headscale;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
acl = "headscale/acl.hujson"; acl = "headscale/acl.hujson";

View file

@ -8,23 +8,9 @@ in
programs.dconf.enable = true; # fixes nixvim hm module programs.dconf.enable = true; # fixes nixvim hm module
services.flatpak.enable = true; services = {
flatpak.enable = true;
xdg.portal = { gnome.gnome-keyring.enable = true;
enable = true; udisks2.enable = mkDefault true;
extraPortals = with pkgs; [
xdg-desktop-portal-gtk
];
config.common.default = "gtk";
}; };
services.gnome.gnome-keyring.enable = true;
security.pam.services = {
login = {
enableGnomeKeyring = true;
};
hyprlock = { };
};
services.udisks2.enable = mkDefault true;
} }

View file

@ -7,8 +7,8 @@
let let
cfg = config.services.jellyfin; cfg = config.services.jellyfin;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
inherit (lib) inherit (lib)
@ -48,9 +48,7 @@ in
]; ];
systemd.tmpfiles.rules = systemd.tmpfiles.rules =
(map ( (map (library: "d ${cfg.dataDir}/libraries/${library} 0770 ${cfg.user} ${cfg.group} -") cfg.libraries)
library: "d ${cfg.dataDir}/libraries/${library} 0770 ${cfg.user} ${cfg.group} -"
) cfg.libraries)
++ [ ++ [
"z ${cfg.dataDir} 0770 ${cfg.user} ${cfg.group} -" "z ${cfg.dataDir} 0770 ${cfg.user} ${cfg.group} -"
"Z ${cfg.dataDir}/libraries 0770 ${cfg.user} ${cfg.group} -" "Z ${cfg.dataDir}/libraries 0770 ${cfg.user} ${cfg.group} -"

View file

@ -2,8 +2,8 @@
let let
cfg = config.services.jirafeau; cfg = config.services.jirafeau;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
inherit (lib) inherit (lib)

View file

@ -155,7 +155,7 @@ let
mkOption { mkOption {
type = types.package; type = types.package;
default = defaultImages.${name}; default = defaultImages.${name};
description = description; inherit description;
}; };
inherit (lib) inherit (lib)
@ -236,10 +236,123 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
virtualisation.podman = { virtualisation = {
enable = true; podman = {
autoPrune.enable = true; enable = true;
dockerCompat = true; autoPrune.enable = true;
dockerCompat = true;
};
oci-containers = {
backend = "podman";
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"
];
};
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"
];
};
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"
];
};
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"
];
};
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"
];
};
};
};
}; };
networking.firewall.interfaces = networking.firewall.interfaces =
@ -250,278 +363,173 @@ in
"${matchAll}".allowedUDPPorts = [ 53 ]; "${matchAll}".allowedUDPPorts = [ 53 ];
}; };
virtualisation.oci-containers.backend = "podman"; 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" ];
};
virtualisation.oci-containers.containers.librechat-mongodb = { podman-librechat-meilisearch = {
image = with cfg.images.mongodb; "${imageName}:${imageTag}"; serviceConfig.Restart = mkOverride 90 "always";
imageFile = cfg.images.mongodb; after = [
cmd = [ "podman-network-librechat_default.service"
"mongod" "podman-volume-librechat_meili_data.service"
"--noauth" ];
]; requires = [
volumes = [ "podman-network-librechat_default.service"
"librechat_mongodb_data:/data/db:rw" "podman-volume-librechat_meili_data.service"
]; ];
log-driver = "journald"; partOf = [ "podman-compose-librechat-root.target" ];
extraOptions = [ wantedBy = [ "podman-compose-librechat-root.target" ];
"--network-alias=mongodb" };
"--network=librechat_default"
];
};
virtualisation.oci-containers.containers.librechat-meilisearch = { podman-librechat-vectordb = {
image = with cfg.images.meilisearch; "${imageName}:${imageTag}"; serviceConfig.Restart = mkOverride 90 "always";
imageFile = cfg.images.meilisearch; after = [
environment = { "podman-network-librechat_default.service"
MEILI_NO_ANALYTICS = "true"; "podman-volume-librechat_pgdata.service"
MEILI_HOST = "http://meilisearch:${toString cfg.meiliPort}"; ];
requires = [
"podman-network-librechat_default.service"
"podman-volume-librechat_pgdata.service"
];
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
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" ];
};
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" ];
};
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" ];
};
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" ];
};
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" ];
};
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" ];
};
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" ];
};
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" ];
};
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" ];
};
}; };
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 = { targets.podman-compose-librechat-root = {
image = with cfg.images.vectordb; "${imageName}:${imageTag}"; unitConfig.Description = "Root target generated by compose2nix.";
imageFile = cfg.images.vectordb; wantedBy = [ "multi-user.target" ];
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" ];
}; };
}; };
} }

View file

@ -8,7 +8,7 @@
let let
cfg = config.mailserver; cfg = config.mailserver;
domain = config.networking.domain; inherit (config.networking) domain;
fqdn = "${cfg.subdomain}.${domain}"; fqdn = "${cfg.subdomain}.${domain}";
inherit (lib) inherit (lib)
@ -74,7 +74,7 @@ in
nameValuePair "${user}@${domain}" { nameValuePair "${user}@${domain}" {
name = "${user}@${domain}"; name = "${user}@${domain}";
aliases = map (alias: "${alias}@${domain}") (accConf.aliases or [ ]); aliases = map (alias: "${alias}@${domain}") (accConf.aliases or [ ]);
sendOnly = accConf.sendOnly; inherit (accConf) sendOnly;
quota = mkDefault "5G"; quota = mkDefault "5G";
hashedPasswordFile = config.sops.secrets."mailserver/accounts/${user}".path; hashedPasswordFile = config.sops.secrets."mailserver/accounts/${user}".path;
} }

View file

@ -23,7 +23,7 @@ let
services."mautrix-${name}" = { services."mautrix-${name}" = {
enable = true; enable = true;
package = cfg.bridges.${name}.package; inherit (cfg.bridges.${name}) package;
environmentFile = mkIf cfg.sops config.sops.templates."mautrix-${name}/env-file".path; environmentFile = mkIf cfg.sops config.sops.templates."mautrix-${name}/env-file".path;
settings = { settings = {
bridge = { bridge = {
@ -71,33 +71,29 @@ let
mode = "0400"; mode = "0400";
in in
{ {
secrets."mautrix-${name}/encryption-pickle-key" = { secrets = {
inherit owner group mode; "mautrix-${name}/encryption-pickle-key" = {
}; inherit owner group mode;
secrets."mautrix-${name}/provisioning-shared-secret" = { };
inherit owner group mode; "mautrix-${name}/provisioning-shared-secret" = {
}; inherit owner group mode;
secrets."mautrix-${name}/public-media-signing-key" = { };
inherit owner group mode; "mautrix-${name}/public-media-signing-key" = {
}; inherit owner group mode;
secrets."mautrix-${name}/direct-media-server-key" = { };
inherit owner group mode; "mautrix-${name}/direct-media-server-key" = {
inherit owner group mode;
};
}; };
templates."mautrix-${name}/env-file" = { templates."mautrix-${name}/env-file" = {
inherit owner group mode; inherit owner group mode;
content = '' content = ''
MAUTRIX_${toUpper name}_ENCRYPTION_PICKLE_KEY=${ MAUTRIX_${toUpper name}_ENCRYPTION_PICKLE_KEY=${config.sops.placeholder."mautrix-${name}/encryption-pickle-key"}
config.sops.placeholder."mautrix-${name}/encryption-pickle-key"
}
MAUTRIX_${toUpper name}_PROVISIONING_SHARED_SECRET=${ MAUTRIX_${toUpper name}_PROVISIONING_SHARED_SECRET=${
config.sops.placeholder."mautrix-${name}/provisioning-shared-secret" config.sops.placeholder."mautrix-${name}/provisioning-shared-secret"
} }
MAUTRIX_${toUpper name}_PUBLIC_MEDIA_SIGNING_KEY=${ MAUTRIX_${toUpper name}_PUBLIC_MEDIA_SIGNING_KEY=${config.sops.placeholder."mautrix-${name}/public-media-signing-key"}
config.sops.placeholder."mautrix-${name}/public-media-signing-key" MAUTRIX_${toUpper name}_DIRECT_MEDIA_SERVER_KEY=${config.sops.placeholder."mautrix-${name}/direct-media-server-key"}
}
MAUTRIX_${toUpper name}_DIRECT_MEDIA_SERVER_KEY=${
config.sops.placeholder."mautrix-${name}/direct-media-server-key"
}
''; '';
}; };
} }

View file

@ -84,77 +84,74 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.postgresql = { services = {
enable = true; postgresql = {
initialScript = pkgs.writeText "synapse-init.sql" '' enable = true;
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; initialScript = pkgs.writeText "synapse-init.sql" ''
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
TEMPLATE template0 CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
LC_COLLATE = 'C' TEMPLATE template0
LC_CTYPE = 'C'; LC_COLLATE = 'C'
''; LC_CTYPE = 'C';
}; '';
};
services.matrix-synapse = mkMerge [ matrix-synapse = mkMerge [
{ {
settings = { settings = {
registration_shared_secret_path = registration_shared_secret_path = mkIf cfg.sops config.sops.secrets."matrix/registration-shared-secret".path;
mkIf cfg.sops server_name = config.networking.domain;
config.sops.secrets."matrix/registration-shared-secret".path; public_baseurl = baseUrl;
server_name = config.networking.domain; listeners = [
public_baseurl = baseUrl; {
listeners = [ inherit (cfg) port;
{ bind_addresses = [ "127.0.0.1" ];
inherit (cfg) port; resources = [
bind_addresses = [ "127.0.0.1" ]; {
resources = [ compress = true;
{ names = [ "client" ];
compress = true; }
names = [ "client" ]; {
} compress = false;
{ names = [ "federation" ];
compress = false; }
names = [ "federation" ]; ];
} tls = false;
]; type = "http";
tls = false; x_forwarded = true;
type = "http"; }
x_forwarded = true; ];
} };
]; }
(mkIf cfg.coturn.enable {
settings = {
turn_uris = with cfg.coturn; [
"turn:${realm}:${toString listening-port}?transport=udp"
"turn:${realm}:${toString listening-port}?transport=tcp"
"turn:${realm}:${toString tls-listening-port}?transport=udp"
"turn:${realm}:${toString tls-listening-port}?transport=tcp"
"turn:${realm}:${toString alt-listening-port}?transport=udp"
"turn:${realm}:${toString alt-listening-port}?transport=tcp"
"turn:${realm}:${toString alt-tls-listening-port}?transport=udp"
"turn:${realm}:${toString alt-tls-listening-port}?transport=tcp"
];
extraConfigFiles = mkIf cfg.sops [ config.sops.templates."coturn/static-auth-secret.env".path ];
turn_user_lifetime = "1h";
};
})
];
nginx.virtualHosts."${cfg.settings.server_name}" = {
enableACME = true;
forceSSL = true;
locations = {
"= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
"= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
"/_matrix".proxyPass = "http://127.0.0.1:${toString cfg.port}";
"/_synapse".proxyPass = "http://127.0.0.1:${toString cfg.port}";
}; };
} };
(mkIf cfg.coturn.enable {
settings = {
turn_uris = with cfg.coturn; [
"turn:${realm}:${toString listening-port}?transport=udp"
"turn:${realm}:${toString listening-port}?transport=tcp"
"turn:${realm}:${toString tls-listening-port}?transport=udp"
"turn:${realm}:${toString tls-listening-port}?transport=tcp"
"turn:${realm}:${toString alt-listening-port}?transport=udp"
"turn:${realm}:${toString alt-listening-port}?transport=tcp"
"turn:${realm}:${toString alt-tls-listening-port}?transport=udp"
"turn:${realm}:${toString alt-tls-listening-port}?transport=tcp"
];
extraConfigFiles = mkIf cfg.sops [ config.sops.templates."coturn/static-auth-secret.env".path ];
turn_user_lifetime = "1h";
};
})
];
environment.shellAliases = mkIf cfg.sops {
register_new_matrix_user = "${cfg.package}/bin/register_new_matrix_user -k $(sudo cat ${cfg.settings.registration_shared_secret_path})";
};
services.nginx.virtualHosts."${cfg.settings.server_name}" = {
enableACME = true;
forceSSL = true;
locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
locations."/_matrix".proxyPass = "http://127.0.0.1:${toString cfg.port}";
locations."/_synapse".proxyPass = "http://127.0.0.1:${toString cfg.port}";
}; };
sops = mkIf cfg.sops { sops = mkIf cfg.sops {

View file

@ -6,51 +6,53 @@
let let
cfg = config.services.matrix-synapse; cfg = config.services.matrix-synapse;
domain = config.networking.domain; inherit (config.networking) domain;
inherit (lib) mkIf mkDefault; inherit (lib) mkIf mkDefault;
in in
{ {
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.livekit = { services = {
enable = true; livekit = {
settings.port = mkDefault 7880; enable = true;
settings.room.auto_create = mkDefault false; settings.port = mkDefault 7880;
openFirewall = mkDefault true; settings.room.auto_create = mkDefault false;
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path; openFirewall = mkDefault true;
}; keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
};
services.lk-jwt-service = { lk-jwt-service = {
enable = true; enable = true;
port = mkDefault 8080; port = mkDefault 8080;
livekitUrl = "wss://${domain}/livekit/sfu"; livekitUrl = "wss://${domain}/livekit/sfu";
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path; keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
}; };
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = domain; nginx.virtualHosts = {
"${domain}".locations = {
services.nginx.virtualHosts = { "^~ /livekit/jwt/" = {
"${domain}".locations = { priority = 400;
"^~ /livekit/jwt/" = { proxyPass = "http://127.0.0.1:${toString config.services.lk-jwt-service.port}/";
priority = 400; };
proxyPass = "http://127.0.0.1:${toString config.services.lk-jwt-service.port}/"; "^~ /livekit/sfu/" = {
}; priority = 400;
"^~ /livekit/sfu/" = { proxyPass = "http://127.0.0.1:${toString config.services.livekit.settings.port}/";
priority = 400; proxyWebsockets = true;
proxyPass = "http://127.0.0.1:${toString config.services.livekit.settings.port}/"; extraConfig = ''
proxyWebsockets = true; proxy_send_timeout 120;
extraConfig = '' proxy_read_timeout 120;
proxy_send_timeout 120; proxy_buffering off;
proxy_read_timeout 120; proxy_set_header Accept-Encoding gzip;
proxy_buffering off; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Accept-Encoding gzip; proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade; '';
proxy_set_header Connection "upgrade"; };
'';
}; };
}; };
}; };
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = domain;
sops = mkIf cfg.sops { sops = mkIf cfg.sops {
secrets."livekit/key" = { }; secrets."livekit/key" = { };
templates."livekit/key".content = '' templates."livekit/key".content = ''

View file

@ -76,7 +76,7 @@ in
sops = mkIf cfg.sops ( sops = mkIf cfg.sops (
let let
owner = user.name; owner = user.name;
group = user.group; inherit (user) group;
mode = "0400"; mode = "0400";
in in
{ {
@ -98,9 +98,7 @@ in
'' ''
admins: admins:
'' ''
+ concatLines ( + concatLines (map (admin: " ${admin}: ${config.sops.placeholder."maubot/admins/${admin}"}") cfg.admins)
map (admin: " ${admin}: ${config.sops.placeholder."maubot/admins/${admin}"}") cfg.admins
)
); );
}; };
} }

View file

@ -96,7 +96,7 @@ in
users.users."${cfg.user}" = { users.users."${cfg.user}" = {
isSystemUser = true; isSystemUser = true;
group = cfg.group; inherit (cfg) group;
}; };
users.groups."${cfg.group}" = { }; users.groups."${cfg.group}" = { };

View file

@ -6,8 +6,8 @@
let let
cfg = config.services.miniflux; cfg = config.services.miniflux;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
port = 8085; port = 8085;

View file

@ -50,8 +50,7 @@ in
"1.1.1.1" "1.1.1.1"
"2606:4700:4700::1111" "2606:4700:4700::1111"
]; ];
resolvers = resolvers = if config.networking.nameservers == [ ] then cloudflare else config.networking.nameservers;
if config.networking.nameservers == [ ] then cloudflare else config.networking.nameservers;
in in
map escapeIPv6 resolvers; map escapeIPv6 resolvers;
@ -60,7 +59,7 @@ in
virtualHosts = { virtualHosts = {
"${config.networking.domain}" = mkDefault { "${config.networking.domain}" = mkDefault {
enableACME = cfg.forceSSL; enableACME = cfg.forceSSL;
forceSSL = cfg.forceSSL; inherit (cfg) forceSSL;
}; };
}; };
}; };

View file

@ -21,7 +21,7 @@ in
types.submodule { types.submodule {
options = { options = {
extraGroups = mkOption { extraGroups = mkOption {
type = (types.listOf types.str); type = types.listOf types.str;
default = [ ]; default = [ ];
description = "Extra groups for the user"; description = "Extra groups for the user";
example = [ "wheel" ]; example = [ "wheel" ];
@ -37,7 +37,7 @@ in
description = "Initial password for the user"; description = "Initial password for the user";
}; };
sshKeyFiles = mkOption { sshKeyFiles = mkOption {
type = (types.listOf types.path); type = types.listOf types.path;
default = [ ]; default = [ ];
description = "SSH key files for the user"; description = "SSH key files for the user";
example = [ "/path/to/id_rsa.pub" ]; example = [ "/path/to/id_rsa.pub" ];

View file

@ -2,8 +2,8 @@
let let
cfg = config.services.nostr-relay; cfg = config.services.nostr-relay;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
inherit (lib) inherit (lib)
@ -48,9 +48,8 @@ in
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable { services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
"${fqdn}" = { "${fqdn}" = {
enableACME = cfg.reverseProxy.forceSSL; enableACME = cfg.reverseProxy.forceSSL;
forceSSL = cfg.reverseProxy.forceSSL; inherit (cfg.reverseProxy) forceSSL;
locations."/".proxyPass = locations."/".proxyPass = "http://127.0.0.1:${toString config.services.nostr-rs-relay.settings.network.port}";
"http://127.0.0.1:${toString config.services.nostr-rs-relay.settings.network.port}";
}; };
}; };
}; };

View file

@ -9,20 +9,26 @@ let
inherit (lib) mkDefault; inherit (lib) mkDefault;
in in
{ {
boot.blacklistedKernelModules = [ "nouveau" ]; boot = {
boot.extraModulePackages = [ config.hardware.nvidia.package ]; blacklistedKernelModules = [ "nouveau" ];
boot.initrd.kernelModules = [ "nvidia" ]; extraModulePackages = [ config.hardware.nvidia.package ];
initrd.kernelModules = [ "nvidia" ];
};
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
nvtopPackages.nvidia nvtopPackages.nvidia
]; ];
hardware.enableRedistributableFirmware = true; hardware = {
hardware.graphics.enable = true; enableRedistributableFirmware = true;
hardware.nvidia.modesetting.enable = true; graphics.enable = true;
hardware.nvidia.nvidiaSettings = true; nvidia = {
hardware.nvidia.open = false; modesetting.enable = true;
hardware.nvidia.package = mkDefault config.boot.kernelPackages.nvidiaPackages.latest; nvidiaSettings = true;
open = false;
package = mkDefault config.boot.kernelPackages.nvidiaPackages.latest;
};
};
nixpkgs.config.cudaSupport = true; nixpkgs.config.cudaSupport = true;

View file

@ -2,8 +2,8 @@
let let
cfg = config.services.ollama; cfg = config.services.ollama;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
inherit (lib) inherit (lib)
@ -31,7 +31,7 @@ in
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable { services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
"${fqdn}" = mkVirtualHost { "${fqdn}" = mkVirtualHost {
port = cfg.port; inherit (cfg) port;
ssl = cfg.reverseProxy.forceSSL; ssl = cfg.reverseProxy.forceSSL;
recommendedProxySettings = mkForce false; recommendedProxySettings = mkForce false;
extraConfig = '' extraConfig = ''

View file

@ -83,10 +83,43 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
virtualisation.podman = { virtualisation = {
enable = true; podman = {
autoPrune.enable = true; enable = true;
dockerCompat = true; autoPrune.enable = true;
dockerCompat = true;
};
oci-containers = {
backend = "podman";
containers."open-webui" = {
image = with cfg.image; imageName + ":" + imageTag;
imageFile = cfg.image;
environment =
defaultEnv
// cfg.environment
// {
PORT = "${toString cfg.port}";
CORS_ALLOW_ORIGIN = concatStringsSep ";" (
[
"http://localhost:${toString cfg.port}"
"http://127.0.0.1:${toString cfg.port}"
"http://0.0.0.0:${toString cfg.port}"
]
++ optional (cfg.externalUrl != null) cfg.externalUrl
);
};
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
volumes = [
"open-webui_open-webui:/app/backend/data:rw"
];
log-driver = "journald";
extraOptions = [
"--network=host"
];
};
};
}; };
networking.firewall.interfaces = networking.firewall.interfaces =
@ -97,70 +130,44 @@ in
"${matchAll}".allowedUDPPorts = [ 53 ]; "${matchAll}".allowedUDPPorts = [ 53 ];
}; };
virtualisation.oci-containers.backend = "podman"; systemd = {
services."podman-open-webui" = {
virtualisation.oci-containers.containers."open-webui" = { serviceConfig = {
image = with cfg.image; imageName + ":" + imageTag; Restart = mkOverride 90 "always";
imageFile = cfg.image;
environment =
defaultEnv
// cfg.environment
// {
PORT = "${toString cfg.port}";
CORS_ALLOW_ORIGIN = concatStringsSep ";" (
[
"http://localhost:${toString cfg.port}"
"http://127.0.0.1:${toString cfg.port}"
"http://0.0.0.0:${toString cfg.port}"
]
++ optional (cfg.externalUrl != null) cfg.externalUrl
);
}; };
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile; after = [
volumes = [ "podman-volume-open-webui_open-webui.service"
"open-webui_open-webui:/app/backend/data:rw" ];
]; requires = [
log-driver = "journald"; "podman-volume-open-webui_open-webui.service"
extraOptions = [ ];
"--network=host" partOf = [
]; "podman-compose-open-webui-root.target"
}; ];
systemd.services."podman-open-webui" = { wantedBy = [
serviceConfig = { "podman-compose-open-webui-root.target"
Restart = mkOverride 90 "always"; ];
}; };
after = [
"podman-volume-open-webui_open-webui.service"
];
requires = [
"podman-volume-open-webui_open-webui.service"
];
partOf = [
"podman-compose-open-webui-root.target"
];
wantedBy = [
"podman-compose-open-webui-root.target"
];
};
systemd.services."podman-volume-open-webui_open-webui" = { services."podman-volume-open-webui_open-webui" = {
path = [ pkgs.podman ]; path = [ pkgs.podman ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true; RemainAfterExit = true;
};
script = ''
podman volume inspect open-webui_open-webui || podman volume create open-webui_open-webui
'';
partOf = [ "podman-compose-open-webui-root.target" ];
wantedBy = [ "podman-compose-open-webui-root.target" ];
}; };
script = ''
podman volume inspect open-webui_open-webui || podman volume create open-webui_open-webui
'';
partOf = [ "podman-compose-open-webui-root.target" ];
wantedBy = [ "podman-compose-open-webui-root.target" ];
};
systemd.targets."podman-compose-open-webui-root" = { targets."podman-compose-open-webui-root" = {
unitConfig = { unitConfig = {
Description = "Root target generated by compose2nix."; Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
}; };
wantedBy = [ "multi-user.target" ];
}; };
}; };
} }

View file

@ -7,8 +7,8 @@
let let
cfg = config.services.print-server; cfg = config.services.print-server;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
port = 631; port = 631;
@ -36,47 +36,49 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.printing = { services = {
enable = true; printing = {
listenAddresses = [ "*:${builtins.toString port}" ]; enable = true;
webInterface = true; listenAddresses = [ "*:${builtins.toString port}" ];
tempDir = "/tmp/cups"; webInterface = true;
allowFrom = [ "all" ]; tempDir = "/tmp/cups";
snmpConf = '' allowFrom = [ "all" ];
Address @LOCAL snmpConf = ''
''; Address @LOCAL
clientConf = ""; '';
openFirewall = cfg.openFirewall; clientConf = "";
drivers = with pkgs; [ inherit (cfg) openFirewall;
brlaser drivers = with pkgs; [
brgenml1lpr brlaser
brgenml1cupswrapper # Brother brgenml1lpr
postscript-lexmark # Lexmark brgenml1cupswrapper # Brother
hplip postscript-lexmark # Lexmark
hplipWithPlugin # HP hplip
splix hplipWithPlugin # HP
samsung-unified-linux-driver # Samsung splix
gutenprint samsung-unified-linux-driver # Samsung
gutenprintBin # different vendors gutenprint
]; gutenprintBin # different vendors
defaultShared = true; ];
browsing = true; defaultShared = true;
browsedConf = '' browsing = true;
BrowsePoll ${fqdn} browsedConf = ''
''; BrowsePoll ${fqdn}
}; '';
};
# autodiscovery of network printers # autodiscovery of network printers
services.avahi = { avahi = {
enable = true; enable = true;
nssmdns4 = true; nssmdns4 = true;
openFirewall = cfg.openFirewall; inherit (cfg) openFirewall;
}; };
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable { nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
${fqdn} = mkVirtualHost { ${fqdn} = mkVirtualHost {
inherit port; inherit port;
ssl = cfg.reverseProxy.forceSSL; ssl = cfg.reverseProxy.forceSSL;
};
}; };
}; };
}; };

View file

@ -7,8 +7,8 @@
let let
cfg = config.services.radicale; cfg = config.services.radicale;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
port = 5232; port = 5232;
@ -63,7 +63,7 @@ in
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable { services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
"${fqdn}" = { "${fqdn}" = {
forceSSL = cfg.reverseProxy.forceSSL; inherit (cfg.reverseProxy) forceSSL;
enableACME = cfg.reverseProxy.forceSSL; enableACME = cfg.reverseProxy.forceSSL;
locations = { locations = {
"/" = { "/" = {

View file

@ -2,8 +2,8 @@
let let
cfg = config.services.rss-bridge; cfg = config.services.rss-bridge;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
inherit (lib) inherit (lib)
@ -33,7 +33,7 @@ in
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable { services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
"${fqdn}" = { "${fqdn}" = {
enableACME = cfg.reverseProxy.forceSSL; enableACME = cfg.reverseProxy.forceSSL;
forceSSL = cfg.reverseProxy.forceSSL; inherit (cfg.reverseProxy) forceSSL;
}; };
}; };
}; };

View file

@ -56,8 +56,7 @@ in
config = config =
let let
defaultTailnets = filterAttrs (_: t: t.default) cfg.tailnets; defaultTailnets = filterAttrs (_: t: t.default) cfg.tailnets;
defaultTailnet = defaultTailnet = if defaultTailnets == { } then null else builtins.head (builtins.attrValues defaultTailnets);
if defaultTailnets == { } then null else builtins.head (builtins.attrValues defaultTailnets);
entries = mapAttrsToList (name: tcfg: '' entries = mapAttrsToList (name: tcfg: ''
TAILNETS["${name}"]="${tcfg.loginServer}|${if tcfg.enableSSH then "true" else "false"}|${ TAILNETS["${name}"]="${tcfg.loginServer}|${if tcfg.enableSSH then "true" else "false"}|${
@ -111,8 +110,7 @@ in
mkIf cfg.enable { mkIf cfg.enable {
assertions = [ assertions = [
{ {
assertion = assertion = (builtins.length (builtins.attrValues (filterAttrs (_: t: t.default) cfg.tailnets))) <= 1;
(builtins.length (builtins.attrValues (filterAttrs (_: t: t.default) cfg.tailnets))) <= 1;
message = "services.tailscale.tailnets: Only one tailnet can be set as default."; message = "services.tailscale.tailnets: Only one tailnet can be set as default.";
} }
{ {

View file

@ -58,16 +58,18 @@ in
enable = mkDefault true; enable = mkDefault true;
onBoot = mkDefault "ignore"; onBoot = mkDefault "ignore";
onShutdown = mkDefault "shutdown"; onShutdown = mkDefault "shutdown";
qemu.runAsRoot = mkDefault false; qemu = {
qemu.verbatimConfig = '' runAsRoot = mkDefault false;
clear_emulation_capabilities = ${boolToZeroOne cfg.libvirtd.clearEmulationCapabilities} verbatimConfig = ''
'' clear_emulation_capabilities = ${boolToZeroOne cfg.libvirtd.clearEmulationCapabilities}
+ optionalString (cfg.libvirtd.deviceACL != [ ]) '' ''
cgroup_device_acl = [ + optionalString (cfg.libvirtd.deviceACL != [ ]) ''
${aclString} cgroup_device_acl = [
] ${aclString}
''; ]
qemu.swtpm.enable = mkDefault true; # TPM 2.0 '';
swtpm.enable = mkDefault true; # TPM 2.0
};
}; };
spiceUSBRedirection.enable = mkDefault true; spiceUSBRedirection.enable = mkDefault true;
}; };

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
shopt -s nullglob shopt -s nullglob
for d in /sys/kernel/iommu_groups/*/devices/*; do for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*} n=${d#*/iommu_groups/*}; n=${n%%/*}

View file

@ -78,34 +78,32 @@ let
}; };
}; };
deviceType = ( deviceType = types.submodule (
types.submodule ( { config, options, ... }:
{ config, options, ... }: {
{ options = {
options = { resolution = mkOption {
resolution = mkOption { type = types.nullOr resolutionType;
type = types.nullOr resolutionType; default = null;
default = null; description = "Automatically calculate the minimum device size for a specific resolution. Overrides `size` if set.";
description = "Automatically calculate the minimum device size for a specific resolution. Overrides `size` if set.";
};
size = mkOption {
type = types.number;
description = "Size for the kvmfr device in megabytes.";
};
permissions = mkOption {
type = permissionsType;
default = { };
description = "Permissions of the kvmfr device.";
};
}; };
config = { size = mkOption {
size = mkIf (config.resolution != null) (sizeFromResolution config.resolution); type = types.number;
description = "Size for the kvmfr device in megabytes.";
}; };
}
) permissions = mkOption {
type = permissionsType;
default = { };
description = "Permissions of the kvmfr device.";
};
};
config = {
size = mkIf (config.resolution != null) (sizeFromResolution config.resolution);
};
}
); );
inherit (lib) inherit (lib)
@ -144,7 +142,7 @@ in
''; '';
"modprobe.d/kvmfr.conf".text = '' "modprobe.d/kvmfr.conf".text = ''
options kvmfr static_size_mb=${concatStringsSep "," (map (size: toString size) deviceSizes)} options kvmfr static_size_mb=${concatStringsSep "," (map toString deviceSizes)}
''; '';
"apparmor.d/local/abstractions/libvirt-qemu" = mkIf config.security.apparmor.enable { "apparmor.d/local/abstractions/libvirt-qemu" = mkIf config.security.apparmor.enable {

View file

@ -2,7 +2,7 @@
let let
cfg = config.services.webPage; cfg = config.services.webPage;
domain = config.networking.domain; inherit (config.networking) domain;
fqdn = if (cfg.subdomain != "") then "${cfg.subdomain}.${domain}" else domain; fqdn = if (cfg.subdomain != "") then "${cfg.subdomain}.${domain}" else domain;
nginxUser = config.services.nginx.user; nginxUser = config.services.nginx.user;
@ -41,7 +41,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.nginx.virtualHosts."${fqdn}" = { services.nginx.virtualHosts."${fqdn}" = {
enableACME = cfg.forceSSL; enableACME = cfg.forceSSL;
forceSSL = cfg.forceSSL; inherit (cfg) forceSSL;
root = cfg.webRoot; root = cfg.webRoot;
locations."/".index = "index.html"; locations."/".index = "index.html";
sslCertificate = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/cert.pem"; sslCertificate = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/cert.pem";

View file

@ -81,90 +81,97 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.tmpfiles.rules = [ "d ${cfg.volume} 0755 root podman -" ]; systemd = {
tmpfiles.rules = [ "d ${cfg.volume} 0755 root podman -" ];
virtualisation.podman = { services = {
enable = true; "podman-windows" = {
autoPrune.enable = true; serviceConfig = {
dockerCompat = true; Restart = mkOverride 90 "always";
defaultNetwork.settings = { };
dns_enabled = true; after = [
"podman-network-windows_default.service"
];
requires = [
"podman-network-windows_default.service"
];
partOf = [
"podman-compose-windows-root.target"
];
wantedBy = [
"podman-compose-windows-root.target"
];
};
"podman-network-windows_default" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStop = "podman network rm -f windows_default";
};
script = ''
podman network inspect windows_default || podman network create windows_default
'';
partOf = [ "podman-compose-windows-root.target" ];
wantedBy = [ "podman-compose-windows-root.target" ];
};
};
targets."podman-compose-windows-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
};
};
virtualisation = {
podman = {
enable = true;
autoPrune.enable = true;
dockerCompat = true;
defaultNetwork.settings = {
dns_enabled = true;
};
};
oci-containers = {
backend = "podman";
containers."windows" = {
image = "dockurr/windows";
environment = with cfg.settings; {
"VERSION" = version;
"RAM_SIZE" = ramSize;
"CPU_CORES" = cpuCores;
"DISK_SIZE" = diskSize;
"USERNAME" = username;
"PASSWORD" = password;
"REGION" = region;
"KEYBOARD" = keyboard;
};
volumes = [
"${cfg.volume}:/storage:rw"
]
++ optional (cfg.sharedVolume != null) "${cfg.sharedVolume}:/shared:rw";
ports = [
"8006:8006/tcp"
"3389:3389/tcp"
"3389:3389/udp"
];
log-driver = "journald";
extraOptions = [
"--cap-add=NET_ADMIN"
"--device=/dev/kvm:/dev/kvm:rwm"
"--device=/dev/net/tun:/dev/net/tun:rwm"
"--network-alias=windows"
"--network=windows_default"
];
};
}; };
}; };
# https://github.com/NixOS/nixpkgs/issues/226365 # https://github.com/NixOS/nixpkgs/issues/226365
networking.firewall.interfaces."podman+".allowedUDPPorts = [ 53 ]; networking.firewall.interfaces."podman+".allowedUDPPorts = [ 53 ];
virtualisation.oci-containers.backend = "podman";
virtualisation.oci-containers.containers."windows" = {
image = "dockurr/windows";
environment = with cfg.settings; {
"VERSION" = version;
"RAM_SIZE" = ramSize;
"CPU_CORES" = cpuCores;
"DISK_SIZE" = diskSize;
"USERNAME" = username;
"PASSWORD" = password;
"LANGUAGE" = language;
"REGION" = region;
"KEYBOARD" = keyboard;
};
volumes = [
"${cfg.volume}:/storage:rw"
]
++ optional (cfg.sharedVolume != null) "${cfg.sharedVolume}:/shared:rw";
ports = [
"8006:8006/tcp"
"3389:3389/tcp"
"3389:3389/udp"
];
log-driver = "journald";
extraOptions = [
"--cap-add=NET_ADMIN"
"--device=/dev/kvm:/dev/kvm:rwm"
"--device=/dev/net/tun:/dev/net/tun:rwm"
"--network-alias=windows"
"--network=windows_default"
];
};
systemd.services."podman-windows" = {
serviceConfig = {
Restart = mkOverride 90 "always";
};
after = [
"podman-network-windows_default.service"
];
requires = [
"podman-network-windows_default.service"
];
partOf = [
"podman-compose-windows-root.target"
];
wantedBy = [
"podman-compose-windows-root.target"
];
};
systemd.services."podman-network-windows_default" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStop = "podman network rm -f windows_default";
};
script = ''
podman network inspect windows_default || podman network create windows_default
'';
partOf = [ "podman-compose-windows-root.target" ];
wantedBy = [ "podman-compose-windows-root.target" ];
};
systemd.targets."podman-compose-windows-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
};
}; };
} }

View file

@ -14,74 +14,78 @@ let
; ;
in in
{ {
nix.package = mkDefault pkgs.nix; nix = {
package = mkDefault pkgs.nix;
# for `nix run synix#foo`, `nix build synix#bar`, etc # for `nix run synix#foo`, `nix build synix#bar`, etc
nix.registry = { registry = {
synix = { synix = {
from = { from = {
id = "synix"; id = "synix";
type = "indirect"; type = "indirect";
}; };
to = { to = {
owner = "sid"; owner = "sid";
repo = "synix"; repo = "synix";
host = "git.sid.ovh"; host = "git.sid.ovh";
type = "gitea"; type = "gitea";
};
}; };
}; };
};
nix.settings.warn-dirty = mkDefault false; settings = {
warn-dirty = mkDefault false;
# fallback quickly if substituters are not available. # fallback quickly if substituters are not available.
nix.settings.connect-timeout = mkDefault 5; connect-timeout = mkDefault 5;
nix.settings.fallback = true; fallback = true;
nix.settings.experimental-features = [ experimental-features = [
"nix-command" "nix-command"
"flakes" "flakes"
] ]
++ optional ( ++ optional (
config.nix.package != null && versionOlder (versions.majorMinor config.nix.package.version) "2.22" config.nix.package != null && versionOlder (versions.majorMinor config.nix.package.version) "2.22"
) "repl-flake"; ) "repl-flake";
nix.settings.log-lines = mkDefault 25; log-lines = mkDefault 25;
# avoid disk full issues # avoid disk full issues
nix.settings.max-free = mkDefault (3000 * 1024 * 1024); max-free = mkDefault (3000 * 1024 * 1024);
nix.settings.min-free = mkDefault (512 * 1024 * 1024); min-free = mkDefault (512 * 1024 * 1024);
# avoid copying unnecessary stuff over SSH # avoid copying unnecessary stuff over SSH
nix.settings.builders-use-substitutes = true; builders-use-substitutes = true;
# workaround for https://github.com/NixOS/nix/issues/9574 # workaround for https://github.com/NixOS/nix/issues/9574
nix.settings.nix-path = config.nix.nixPath; nix-path = config.nix.nixPath;
nix.settings.download-buffer-size = 524288000; # 500 MiB download-buffer-size = 524288000; # 500 MiB
# add all wheel users to the trusted-users group # add all wheel users to the trusted-users group
nix.settings.trusted-users = [ trusted-users = [
"@wheel" "@wheel"
]; ];
# binary caches # binary caches
nix.settings.substituters = [ substituters = [
"https://cache.nixos.org" "https://cache.nixos.org"
"https://nix-community.cachix.org" "https://nix-community.cachix.org"
"https://cache.garnix.io" "https://cache.garnix.io"
"https://numtide.cachix.org" "https://numtide.cachix.org"
]; ];
nix.settings.trusted-public-keys = [ trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g=" "cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="
"numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE=" "numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE="
]; ];
};
nix.gc = { gc = {
automatic = true; automatic = true;
dates = "weekly"; dates = "weekly";
options = "--delete-older-than 30d"; options = "--delete-older-than 30d";
};
}; };
} }

View file

@ -9,11 +9,15 @@
modifications = final: prev: { modifications = final: prev: {
# https://github.com/NixOS/nixpkgs/issues/335003#issuecomment-2755803376 # https://github.com/NixOS/nixpkgs/issues/335003#issuecomment-2755803376
kicad = ( kicad = prev.kicad.override {
prev.kicad.override { stable = true;
stable = true; };
}
); python312Packages = prev.python312Packages // {
arxiv = prev.python312Packages.arxiv.overridePythonAttrs (old: {
pythonRemoveDeps = (old.pythonRemoveDeps or [ ]) ++ [ "requests" ];
});
};
# bemenu is not a valid selector in v1.5.1 # bemenu is not a valid selector in v1.5.1
rofi-rbw-wayland = prev.rofi-rbw-wayland.overrideAttrs (oldAttrs: { rofi-rbw-wayland = prev.rofi-rbw-wayland.overrideAttrs (oldAttrs: {

View file

@ -1,10 +1,13 @@
{ {
lib, lib,
python3, python312,
fetchPypi, fetchPypi,
}: }:
python3.pkgs.buildPythonApplication rec { let
python = python312;
in
python.pkgs.buildPythonApplication rec {
pname = "arxiv-mcp-server"; pname = "arxiv-mcp-server";
version = "0.5.0"; version = "0.5.0";
pyproject = true; pyproject = true;
@ -16,10 +19,10 @@ python3.pkgs.buildPythonApplication rec {
}; };
build-system = [ build-system = [
python3.pkgs.hatchling python.pkgs.hatchling
]; ];
dependencies = with python3.pkgs; [ dependencies = with python.pkgs; [
aiofiles aiofiles
aiohttp aiohttp
anyio anyio
@ -36,7 +39,7 @@ python3.pkgs.buildPythonApplication rec {
uvicorn uvicorn
]; ];
optional-dependencies = with python3.pkgs; { optional-dependencies = with python.pkgs; {
test = [ test = [
aioresponses aioresponses
pytest pytest
@ -48,6 +51,7 @@ python3.pkgs.buildPythonApplication rec {
pythonRemoveDeps = [ pythonRemoveDeps = [
"black" "black"
"mcp"
]; ];
pythonImportsCheck = [ pythonImportsCheck = [

View file

@ -20,9 +20,11 @@ rustPlatform.buildRustPackage rec {
hash = "sha256-Fr1CvFocb/VAYQGykXXZ6CCfvC31bKB/tr1aoA4oIME="; hash = "sha256-Fr1CvFocb/VAYQGykXXZ6CCfvC31bKB/tr1aoA4oIME=";
}; };
useFetchCargoVendor = true;
cargoHash = "sha256-CNEkge585bzUUPMHCSJ1CAH5wx3Wttq9I3A3oqfBzis="; cargoHash = "sha256-CNEkge585bzUUPMHCSJ1CAH5wx3Wttq9I3A3oqfBzis=";
cargoBuildFlags = "--ignore-rust-version";
cargoTestFlags = "--ignore-rust-version";
nativeBuildInputs = [ nativeBuildInputs = [
pkg-config pkg-config
]; ];

View file

@ -12,11 +12,9 @@
let let
revision = "1161"; revision = "1161";
chromium-headless-shell = chromium-headless-shell = playwright-driver.passthru.components."chromium-headless-shell".overrideAttrs (old: {
playwright-driver.passthru.components."chromium-headless-shell".overrideAttrs inherit revision;
(old: { });
inherit revision;
});
browsers-headless-only = linkFarm "playwright-browsers-headless-only" [ browsers-headless-only = linkFarm "playwright-browsers-headless-only" [
{ {

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
if [ "$#" -ne 2 ]; then if [ "$#" -ne 2 ]; then
echo "Usage: $0 <pass_storepath> <output_csv>" echo "Usage: $0 <pass_storepath> <output_csv>"
exit 1 exit 1

5
templates/container/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
.direnv/
.envrc
.pre-commit-config.yaml
result
target

View file

@ -2,10 +2,10 @@
description = "Container NixOS configurations"; description = "Container NixOS configurations";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
synix.url = "git+https://git.sid.ovh/sid/synix.git?ref=release-25.11"; synix.url = "git+https://git.sid.ovh/sid/synix.git?ref=release-25.11";
synix.imputs.nixpkgs.follows = "nixpkgs"; synix.inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = outputs =
@ -17,42 +17,62 @@
let let
inherit (self) outputs; inherit (self) outputs;
system = "x86_64-linux"; systems = [
"x86_64-linux"
];
lib = nixpkgs.lib.extend (final: prev: inputs.synix.lib or { }); lib = nixpkgs.lib.extend (_final: _prev: inputs.synix.lib or { });
in
{
packages =
let
pkgs = nixpkgs.legacyPackages.${system};
in
import ./pkgs { inherit pkgs; };
overlays = import ./overlays { inherit (self) inputs; }; inherit (lib.helpers) mkPkgs;
devShells = forAllSystems =
let function:
pkgs = nixpkgs.legacyPackages.${system}; lib.genAttrs systems (
in system:
{ function (mkPkgs {
default = pkgs.mkShell { inherit system;
buildInputs = with pkgs; [ })
nixos-container );
tmux
];
};
};
nixosModules = import ./modules; mkNixosConfiguration =
system: modules:
nixosConfigurations = { nixpkgs.lib.nixosSystem {
container = nixpkgs.lib.nixosSystem { inherit system modules;
inherit system;
modules = [ ./config ];
specialArgs = { specialArgs = {
inherit inputs outputs lib; inherit inputs outputs lib;
}; };
}; };
in
{
packages = forAllSystems (pkgs: import ./pkgs { inherit pkgs; });
overlays = import ./overlays { inherit (self) inputs; };
devShells = forAllSystems (pkgs: {
default = pkgs.mkShell {
buildInputs = with pkgs; [
nixos-container
tmux
];
};
});
nixosModules = import ./modules;
nixosConfigurations = {
container = mkNixosConfiguration "x86_64-linux" [ ./config ];
}; };
checks = forAllSystems (
pkgs:
let
inherit (pkgs.stdenv.hostPlatform) system;
in
{
inherit (inputs.synix.checks.${system}) pre-commit-check build-additions build-modifications;
}
);
inherit (inputs.synix) formatter;
}; };
} }

View file

@ -1 +1,2 @@
# shellcheck shell=bash
use flake use flake

View file

@ -1,23 +1,20 @@
---
name: C Nix Pipeline name: C Nix Pipeline
on: on: # yamllint disable-line
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs: jobs:
build-and-test: build-and-test:
name: Build and Test name: Build and Test
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set up Nix - name: Set up Nix
uses: cachix/install-nix-action@v18 uses: cachix/install-nix-action@v18
with: with:
nix_path: nixpkgs=channel:nixos-unstable nix_path: nixpkgs=channel:nixos-unstable
- name: Run nix flake check - name: Run nix flake check
run: nix flake check run: nix flake check

View file

@ -1,2 +1,3 @@
#!/usr/bin/env bash
make clean make clean
bear --output build/compile_commands.json -- make all bear --output build/compile_commands.json -- make all

View file

@ -81,7 +81,7 @@
system: system:
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
config = self.checks.${system}.pre-commit-check.config; inherit (self.checks.${system}.pre-commit-check) config;
inherit (config) package configFile; inherit (config) package configFile;
script = '' script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile} ${pkgs.lib.getExe package} run --all-files --config ${configFile}

View file

@ -1 +1,2 @@
# shellcheck shell=bash
use flake use flake

View file

@ -56,7 +56,7 @@
pkgs = nixpkgsFor.${system}; pkgs = nixpkgsFor.${system};
in in
{ {
default = esp.devShells."${system}".default; inherit (esp.devShells."${system}") default;
} }
); );
@ -64,7 +64,7 @@
system: system:
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
config = self.checks.${system}.pre-commit-check.config; inherit (self.checks.${system}.pre-commit-check) config;
inherit (config) package configFile; inherit (config) package configFile;
script = '' script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile} ${pkgs.lib.getExe package} run --all-files --config ${configFile}

View file

@ -1,2 +1,3 @@
---
dependencies: dependencies:
espressif/led_strip: "^3.0.0" espressif/led_strip: "^3.0.0"

View file

@ -1 +1,2 @@
# shellcheck shell=bash
use flake use flake

View file

@ -1,23 +1,20 @@
---
name: Python Nix Pipeline name: Python Nix Pipeline
on: on: # yamllint disable-line
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs: jobs:
build-and-test: build-and-test:
name: Build and Test name: Build and Test
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set up Nix - name: Set up Nix
uses: cachix/install-nix-action@v18 uses: cachix/install-nix-action@v18
with: with:
nix_path: nixpkgs=channel:nixos-unstable nix_path: nixpkgs=channel:nixos-unstable
- name: Run nix flake check - name: Run nix flake check
run: nix flake check run: nix flake check

View file

@ -54,7 +54,7 @@
system: system:
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
config = self.checks.${system}.pre-commit-check.config; inherit (self.checks.${system}.pre-commit-check) config;
inherit (config) package configFile; inherit (config) package configFile;
script = '' script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile} ${pkgs.lib.getExe package} run --all-files --config ${configFile}

View file

@ -8,7 +8,7 @@
let let
cfg = config.services.flask_hello; cfg = config.services.flask_hello;
domain = config.networking.domain; inherit (config.networking) domain;
fqdn = if (cfg.nginx.subdomain != "") then "${cfg.nginx.subdomain}.${domain}" else domain; fqdn = if (cfg.nginx.subdomain != "") then "${cfg.nginx.subdomain}.${domain}" else domain;
python-with-packages = pkgs.python3.withPackages ( python-with-packages = pkgs.python3.withPackages (
@ -109,7 +109,7 @@ in
users.users."${cfg.user}" = { users.users."${cfg.user}" = {
home = "/var/lib/${cfg.user}"; home = "/var/lib/${cfg.user}";
isSystemUser = true; isSystemUser = true;
group = cfg.group; inherit (cfg) group;
}; };
users.groups."${cfg.group}" = { }; users.groups."${cfg.group}" = { };

View file

@ -1,23 +1,20 @@
---
name: Python Nix Pipeline name: Python Nix Pipeline
on: on: # yamllint disable-line
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs: jobs:
build-and-test: build-and-test:
name: Build and Test name: Build and Test
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set up Nix - name: Set up Nix
uses: cachix/install-nix-action@v18 uses: cachix/install-nix-action@v18
with: with:
nix_path: nixpkgs=channel:nixos-unstable nix_path: nixpkgs=channel:nixos-unstable
- name: Run nix flake check - name: Run nix flake check
run: nix flake check run: nix flake check

View file

@ -105,7 +105,7 @@
system: system:
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
config = self.checks.${system}.pre-commit-check.config; inherit (self.checks.${system}.pre-commit-check) config;
inherit (config) package configFile; inherit (config) package configFile;
script = '' script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile} ${pkgs.lib.getExe package} run --all-files --config ${configFile}

View file

@ -1,26 +1,23 @@
---
name: Rust Nix Pipeline name: Rust Nix Pipeline
on: on: # yamllint disable-line
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs: jobs:
build-and-test: build-and-test:
name: Build and Test name: Build and Test
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set up Nix - name: Set up Nix
uses: cachix/install-nix-action@v18 uses: cachix/install-nix-action@v18
with: with:
nix_path: nixpkgs=channel:nixos-unstable nix_path: nixpkgs=channel:nixos-unstable
- name: Run cargo tests in dev shell - name: Run cargo tests in dev shell
run: nix develop --command bash -c "cargo test" run: nix develop --command bash -c "cargo test"
- name: Run nix flake check - name: Run nix flake check
run: nix flake check run: nix flake check

View file

@ -76,7 +76,7 @@
system: system:
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
config = self.checks.${system}.pre-commit-check.config; inherit (self.checks.${system}.pre-commit-check) config;
inherit (config) package configFile; inherit (config) package configFile;
script = '' script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile} ${pkgs.lib.getExe package} run --all-files --config ${configFile}

View file

@ -1 +1,2 @@
# shellcheck shell=bash
use flake use flake

View file

@ -1 +1,2 @@
# shellcheck shell=bash
use flake use flake

View file

@ -2,13 +2,13 @@
description = "MicroVM NixOS configurations"; description = "MicroVM NixOS configurations";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
microvm.url = "github:microvm-nix/microvm.nix"; microvm.url = "github:microvm-nix/microvm.nix";
microvm.inputs.nixpkgs.follows = "nixpkgs"; microvm.inputs.nixpkgs.follows = "nixpkgs";
synix.url = "git+https://git.sid.ovh/sid/synix.git?ref=release-25.11"; synix.url = "git+https://git.sid.ovh/sid/synix.git?ref=release-25.11";
synix.imputs.nixpkgs.follows = "nixpkgs"; synix.inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = outputs =
@ -20,20 +20,22 @@
let let
inherit (self) outputs; inherit (self) outputs;
supportedSystems = [ systems = [
"x86_64-linux" "x86_64-linux"
"aarch64-linux"
]; ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems; lib = nixpkgs.lib.extend (_final: _prev: inputs.synix.lib or { });
lib = nixpkgs.lib.extend (final: prev: inputs.synix.lib or { }); inherit (lib.helpers) mkPkgs;
mkApp = program: description: { forAllSystems =
type = "app"; function:
inherit program; lib.genAttrs systems (
meta.description = description; system:
}; function (mkPkgs {
inherit system;
})
);
mkNixosConfiguration = mkNixosConfiguration =
system: modules: system: modules:
@ -43,13 +45,20 @@
inherit inputs outputs lib; inherit inputs outputs lib;
}; };
}; };
mkApp = program: description: {
type = "app";
inherit program;
meta.description = description;
};
in in
{ {
apps = forAllSystems ( apps = forAllSystems (
system: pkgs:
let let
microvm = self.nixosConfigurations."microvm-${system}".config.microvm; inherit (pkgs.stdenv.hostPlatform) system;
inherit (nixpkgs.lib) getExe; inherit (self.nixosConfigurations."microvm-${system}".config) microvm;
inherit (pkgs.lib) getExe;
in in
{ {
rebuild = mkApp (getExe microvm.deploy.rebuild) "Rebuild the VM."; rebuild = mkApp (getExe microvm.deploy.rebuild) "Rebuild the VM.";
@ -57,34 +66,22 @@
} }
); );
packages = forAllSystems ( packages = forAllSystems (pkgs: import ./pkgs { inherit pkgs; });
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
import ./pkgs { inherit pkgs; }
);
overlays = import ./overlays { inherit (self) inputs; }; overlays = import ./overlays { inherit (self) inputs; };
devShells = forAllSystems ( devShells = forAllSystems (pkgs: {
system: default = pkgs.mkShell {
let buildInputs = with pkgs; [
pkgs = nixpkgs.legacyPackages.${system}; tmux
in ];
{ };
default = pkgs.mkShell { # FIXME: `microvm.deploy.rebuild` does not seem to care about askpass
buildInputs = with pkgs; [ # shellHook = ''
tmux # export SSH_ASKPASS="pass <SUDO_BUILD_HOST_PASSWORD>"
]; # export SSH_ASKPASS_REQUIRE="force"
}; # '';
# FIXME: `microvm.deploy.rebuild` does not seem to care about askpass });
# shellHook = ''
# export SSH_ASKPASS="pass <SUDO_BUILD_HOST_PASSWORD>"
# export SSH_ASKPASS_REQUIRE="force"
# '';
}
);
nixosModules = import ./modules; nixosModules = import ./modules;
@ -92,5 +89,17 @@
microvm-x86_64-linux = mkNixosConfiguration "x86_64-linux" [ ./config ]; microvm-x86_64-linux = mkNixosConfiguration "x86_64-linux" [ ./config ];
microvm-aarch64-linux = mkNixosConfiguration "aarch64-linux" [ ./config ]; microvm-aarch64-linux = mkNixosConfiguration "aarch64-linux" [ ./config ];
}; };
checks = forAllSystems (
pkgs:
let
inherit (pkgs.stdenv.hostPlatform) system;
in
{
inherit (inputs.synix.checks.${system}) pre-commit-check build-additions build-modifications;
}
);
inherit (inputs.synix) formatter;
}; };
} }

View file

@ -0,0 +1,5 @@
.direnv/
.envrc
.pre-commit-config.yaml
result
target

View file

@ -5,10 +5,7 @@
nixpkgs-old-stable.url = "github:nixos/nixpkgs/nixos-25.05"; nixpkgs-old-stable.url = "github:nixos/nixpkgs/nixos-25.05";
synix.url = "git+https://git.sid.ovh/sid/synix.git?ref=release-25.11"; synix.url = "git+https://git.sid.ovh/sid/synix.git?ref=release-25.11";
synix.imputs.nixpkgs.follows = "nixpkgs"; synix.inputs.nixpkgs.follows = "nixpkgs";
git-hooks.url = "github:cachix/git-hooks.nix";
git-hooks.inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = outputs =
@ -20,14 +17,22 @@
let let
inherit (self) outputs; inherit (self) outputs;
supportedSystems = [ systems = [
"x86_64-linux" "x86_64-linux"
"aarch64-linux"
]; ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems; lib = nixpkgs.lib.extend (_final: _prev: inputs.synix.lib or { });
lib = nixpkgs.lib.extend (final: prev: inputs.synix.lib or { }); inherit (lib.helpers) mkPkgs;
forAllSystems =
function:
lib.genAttrs systems (
system:
function (mkPkgs {
inherit system;
})
);
mkNixosConfiguration = mkNixosConfiguration =
system: modules: system: modules:
@ -39,7 +44,7 @@
}; };
in in
{ {
packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system}); packages = forAllSystems (pkgs: import ./pkgs { inherit pkgs; });
overlays = import ./overlays { inherit inputs; }; overlays = import ./overlays { inherit inputs; };
@ -49,41 +54,26 @@
HOSTNAME = mkNixosConfiguration "x86_64-linux" [ ./hosts/HOSTNAME ]; HOSTNAME = mkNixosConfiguration "x86_64-linux" [ ./hosts/HOSTNAME ];
}; };
formatter = forAllSystems ( devShells = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgs.legacyPackages.${system}; inherit (pkgs.stdenv.hostPlatform) system;
config = self.checks.${system}.pre-commit-check.config;
inherit (config) package configFile;
script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile}
'';
in in
pkgs.writeShellScriptBin "pre-commit-run" script {
default = inputs.synix.devShells.${system}.nix-config;
}
); );
checks = forAllSystems ( checks = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgs.legacyPackages.${system}; inherit (pkgs.stdenv.hostPlatform) system;
flakePkgs = self.packages.${system};
overlaidPkgs = import nixpkgs {
inherit system;
overlays = [ self.overlays.modifications ];
};
in in
{ {
pre-commit-check = inputs.git-hooks.lib.${system}.run { inherit (inputs.synix.checks.${system}) pre-commit-check build-additions build-modifications;
src = ./.;
hooks = {
nixfmt.enable = true;
};
};
build-packages = pkgs.linkFarm "flake-packages-${system}" flakePkgs;
build-overlays = pkgs.linkFarm "flake-overlays-${system}" {
# package = overlaidPkgs.package;
};
} }
); );
inherit (inputs.synix) formatter;
}; };
} }

View file

@ -11,20 +11,22 @@
(modulesPath + "/installer/scan/not-detected.nix") (modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = [ boot = {
"ahci" initrd.availableKernelModules = [
"nvme" "ahci"
"sd_mod" "nvme"
"sdhci_pci" "sd_mod"
"sr_mod" "sdhci_pci"
"usb_storage" "sr_mod"
"virtio_pci" "usb_storage"
"virtio_scsi" "virtio_pci"
"xhci_pci" "virtio_scsi"
]; "xhci_pci"
boot.initrd.kernelModules = [ ]; ];
boot.kernelModules = [ ]; initrd.kernelModules = [ ];
boot.extraModulePackages = [ ]; kernelModules = [ ];
extraModulePackages = [ ];
};
fileSystems."/" = { fileSystems."/" = {
device = "/dev/disk/by-label/ROOT"; device = "/dev/disk/by-label/ROOT";

View file

@ -0,0 +1,5 @@
.direnv/
.envrc
.pre-commit-config.yaml
result
target

View file

@ -5,7 +5,7 @@
nixpkgs-old-stable.url = "github:nixos/nixpkgs/nixos-25.05"; nixpkgs-old-stable.url = "github:nixos/nixpkgs/nixos-25.05";
synix.url = "git+https://git.sid.ovh/sid/synix.git?ref=release-25.11"; synix.url = "git+https://git.sid.ovh/sid/synix.git?ref=release-25.11";
synix.imputs.nixpkgs.follows = "nixpkgs"; synix.inputs.nixpkgs.follows = "nixpkgs";
home-manager.url = "github:nix-community/home-manager"; home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs"; home-manager.inputs.nixpkgs.follows = "nixpkgs";
@ -18,29 +18,33 @@
stylix.url = "github:danth/stylix"; stylix.url = "github:danth/stylix";
stylix.inputs.nixpkgs.follows = "nixpkgs"; stylix.inputs.nixpkgs.follows = "nixpkgs";
git-hooks.url = "github:cachix/git-hooks.nix";
git-hooks.inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = outputs =
{ {
self, self,
nixpkgs, nixpkgs,
home-manager,
... ...
}@inputs: }@inputs:
let let
inherit (self) outputs; inherit (self) outputs;
supportedSystems = [ systems = [
"x86_64-linux" "x86_64-linux"
"aarch64-linux"
]; ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems; lib = nixpkgs.lib.extend (_final: _prev: inputs.synix.lib or { });
lib = nixpkgs.lib.extend (final: prev: inputs.synix.lib or { }); inherit (lib.helpers) mkPkgs;
forAllSystems =
function:
lib.genAttrs systems (
system:
function (mkPkgs {
inherit system;
})
);
mkNixosConfiguration = mkNixosConfiguration =
system: modules: system: modules:
@ -50,76 +54,53 @@
inherit inputs outputs lib; inherit inputs outputs lib;
}; };
}; };
mkHomeConfiguration =
system: modules:
inputs.home-manager.lib.homeManagerConfiguration {
pkgs = mkPkgs { inherit system; };
modules = [ ./users/USERNAME/home ] ++ modules;
extraSpecialArgs = {
inherit inputs outputs;
};
};
in in
{ {
devShells = forAllSystems ( packages = forAllSystems (pkgs: import ./pkgs { inherit pkgs; });
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
default = import ./shell.nix { inherit pkgs; };
}
);
packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system});
overlays = import ./overlays { inherit inputs; }; overlays = import ./overlays { inherit inputs; };
nixosModules = import ./modules/nixos; nixosModules = import ./modules/nixos;
homeModules = import ./modules/home;
devShells = forAllSystems (
pkgs:
let
inherit (pkgs.stdenv.hostPlatform) system;
in
{
default = inputs.synix.devShells.${system}.nix-config;
}
);
nixosConfigurations = { nixosConfigurations = {
HOSTNAME = mkNixosConfiguration "x86_64-linux" [ ./hosts/HOSTNAME ]; HOSTNAME = mkNixosConfiguration "x86_64-linux" [ ./hosts/HOSTNAME ];
}; };
homeConfigurations = { homeConfigurations = {
"USERNAME@HOSTNAME" = home-manager.lib.homeManagerConfiguration { "USERNAME@HOSTNAME" = mkHomeConfiguration "x86_64-linux" [ ./users/USERNAME/home/hosts/HOSTNAME ];
pkgs = nixpkgs.legacyPackages.x86_64-linux; # FIXME: Set architecture
extraSpecialArgs = {
inherit inputs outputs;
};
modules = [
./users/USERNAME/home
./users/USERNAME/home/hosts/HOSTNAME
];
};
}; };
formatter = forAllSystems (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
config = self.checks.${system}.pre-commit-check.config;
inherit (config) package configFile;
script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile}
'';
in
pkgs.writeShellScriptBin "pre-commit-run" script
);
checks = forAllSystems ( checks = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgs.legacyPackages.${system}; inherit (pkgs.stdenv.hostPlatform) system;
flakePkgs = self.packages.${system};
overlaidPkgs = import nixpkgs {
inherit system;
overlays = [ self.overlays.modifications ];
};
in in
{ {
pre-commit-check = inputs.git-hooks.lib.${system}.run { inherit (inputs.synix.checks.${system}) pre-commit-check build-additions build-modifications;
src = ./.;
hooks = {
nixfmt.enable = true;
};
};
build-packages = pkgs.linkFarm "flake-packages-${system}" flakePkgs;
build-overlays = pkgs.linkFarm "flake-overlays-${system}" {
# package = overlaidPkgs.package;
};
} }
); );
inherit (inputs.synix) formatter;
}; };
} }

View file

@ -11,20 +11,22 @@
(modulesPath + "/installer/scan/not-detected.nix") (modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = [ boot = {
"ahci" initrd.availableKernelModules = [
"nvme" "ahci"
"sd_mod" "nvme"
"sdhci_pci" "sd_mod"
"sr_mod" "sdhci_pci"
"usb_storage" "sr_mod"
"virtio_pci" "usb_storage"
"virtio_scsi" "virtio_pci"
"xhci_pci" "virtio_scsi"
]; "xhci_pci"
boot.initrd.kernelModules = [ ]; ];
boot.kernelModules = [ ]; initrd.kernelModules = [ ];
boot.extraModulePackages = [ ]; kernelModules = [ ];
extraModulePackages = [ ];
};
fileSystems."/" = { fileSystems."/" = {
device = "/dev/disk/by-label/ROOT"; device = "/dev/disk/by-label/ROOT";

Some files were not shown because too many files have changed in this diff Show more