This commit is contained in:
Christoph Schmatzler
2025-08-14 09:09:56 +02:00
parent c1fcf33afa
commit 2926d7412b
7 changed files with 377 additions and 364 deletions

24
flake.lock generated
View File

@@ -100,11 +100,11 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1755107032, "lastModified": 1755121891,
"narHash": "sha256-ckb/RX9rJ/FslBA3K4hYAXgVW/7JdQ50Z+28XZT96zg=", "narHash": "sha256-UtYkukiGnPRJ5rpd4W/wFVrLMh8fqtNkqHTPgHEtrqU=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "4b6dd06c6a92308c06da5e0e55f2c505237725c9", "rev": "279ca5addcdcfa31ac852b3ecb39fc372684f426",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -132,11 +132,11 @@
"homebrew-cask": { "homebrew-cask": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1755104931, "lastModified": 1755147939,
"narHash": "sha256-jtXcymAnYH/hCvEGaUlt5vpFwqx00/r5Wly9UCqy7vQ=", "narHash": "sha256-PD93pCq6q6xtWxtFwK9WCugELrcy50Om7/VLgpV0raM=",
"owner": "homebrew", "owner": "homebrew",
"repo": "homebrew-cask", "repo": "homebrew-cask",
"rev": "53dc289ce38d2561d853b482d0f03914a7f2f985", "rev": "5fd00a85f58743b2ac654bfbdda762b8e7d4fbcb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -148,11 +148,11 @@
"homebrew-core": { "homebrew-core": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1755104716, "lastModified": 1755152577,
"narHash": "sha256-6jp9InEQfaVJR4kSdwb0+D6603DanSUEFF3uYYPIQVM=", "narHash": "sha256-ix1DIoJEn4V0dOErK12AkIL/iPHtGmGR+/HjyNLwnXQ=",
"owner": "homebrew", "owner": "homebrew",
"repo": "homebrew-core", "repo": "homebrew-core",
"rev": "8aa4cd22422bcb03de07c08c24773257d928e988", "rev": "b3da0366f58c2f89d8c0d1cabdc7cd5bdc732313",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -240,11 +240,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1755109924, "lastModified": 1755154419,
"narHash": "sha256-2xroOWuRFMLvqknLQJ8gmpdXuvg9t5qDUJ3KQKq5/GE=", "narHash": "sha256-m8tJUveXe6y73A2wvXRomSC5WwBsNfLgZI3qteAAqyU=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b7f46264dd0a1891d52c9a8b919c2eebbc527638", "rev": "1a58620315b9d6d3c8110ec35ee46bbacb2fe633",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -43,8 +43,7 @@
]; ];
flake.darwinConfigurations = inputs.nixpkgs.lib.genAttrs darwinHosts ( flake.darwinConfigurations = inputs.nixpkgs.lib.genAttrs darwinHosts (
hostname: hostname: let
let
syncthingOverlay = import ./overlays/syncthing-darwin.nix; syncthingOverlay = import ./overlays/syncthing-darwin.nix;
syncthingModule = (syncthingOverlay null {}).darwinSyncthingModule; syncthingModule = (syncthingOverlay null {}).darwinSyncthingModule;
in in

View File

@@ -1,7 +1,4 @@
{ {user, ...}: {
user,
...
}: {
imports = [ imports = [
../shared.nix ../shared.nix
]; ];

View File

@@ -65,7 +65,6 @@
}; };
}; };
services.postgresql = { services.postgresql = {
enable = true; enable = true;
package = pkgs.postgresql_17; package = pkgs.postgresql_17;

View File

@@ -1,10 +1,14 @@
{ pkgs, lib, ... }:
{ {
services.tailscale = { pkgs,
lib,
...
}: {
services.tailscale =
{
enable = true; enable = true;
} // lib.optionalAttrs pkgs.stdenv.isLinux { }
useRoutingFeatures = "server"; // lib.optionalAttrs pkgs.stdenv.isLinux {
openFirewall = true; openFirewall = true;
useRoutingFeatures = "server";
}; };
} }

View File

@@ -1,7 +1,11 @@
final: prev: { final: prev: {
darwinSyncthingModule = { config, lib, pkgs, ... }: darwinSyncthingModule = {
with lib; config,
let lib,
pkgs,
...
}:
with lib; let
cfg = config.services.syncthing; cfg = config.services.syncthing;
defaultUser = "syncthing"; defaultUser = "syncthing";
defaultGroup = defaultUser; defaultGroup = defaultUser;
@@ -18,18 +22,21 @@ final: prev: {
devices = mapAttrsToList (_: device: device // {deviceID = device.id;}) cfg.settings.devices; devices = mapAttrsToList (_: device: device // {deviceID = device.id;}) cfg.settings.devices;
anyAutoAccept = builtins.any (dev: dev.autoAcceptFolders) devices; anyAutoAccept = builtins.any (dev: dev.autoAcceptFolders) devices;
folders = mapAttrsToList (_: folder: folder // { folders = mapAttrsToList (_: folder:
folder
// {
devices = let devices = let
folderDevices = folder.devices; folderDevices = folder.devices;
in in
map (device: map (
if builtins.isString device then device:
{ deviceId = cfg.settings.devices.${device}.id; } if builtins.isString device
else if builtins.isAttrs device then then {deviceId = cfg.settings.devices.${device}.id;}
{ deviceId = cfg.settings.devices.${device.name}.id; } // device else if builtins.isAttrs device
else then {deviceId = cfg.settings.devices.${device.name}.id;} // device
throw "Invalid type for devices in folder; expected list or attrset." else throw "Invalid type for devices in folder; expected list or attrset."
) folderDevices; )
folderDevices;
}) (filterAttrs (_: folder: folder.enable) cfg.settings.folders); }) (filterAttrs (_: folder: folder.enable) cfg.settings.folders);
jq = "${pkgs.jq}/bin/jq"; jq = "${pkgs.jq}/bin/jq";
@@ -67,15 +74,17 @@ final: prev: {
baseAddress = curlAddressArgs "/rest/config/folders"; baseAddress = curlAddressArgs "/rest/config/folders";
}; };
} [ } [
(mapAttrs (conf_type: s: (mapAttrs (
conf_type: s:
lib.pipe s.conf [ lib.pipe s.conf [
(map (new_cfg: (map (
let new_cfg: let
jsonPreSecretsFile = pkgs.writeTextFile { jsonPreSecretsFile = pkgs.writeTextFile {
name = "${conf_type}-${new_cfg.id}-conf-pre-secrets.json"; name = "${conf_type}-${new_cfg.id}-conf-pre-secrets.json";
text = builtins.toJSON new_cfg; text = builtins.toJSON new_cfg;
}; };
injectSecretsJqCmd = { injectSecretsJqCmd =
{
"devs" = "${jq} ."; "devs" = "${jq} .";
"dirs" = let "dirs" = let
folder = new_cfg; folder = new_cfg;
@@ -87,7 +96,8 @@ final: prev: {
secretPath = device.encryptionPasswordFile; secretPath = device.encryptionPasswordFile;
})) }))
]; ];
jqUpdates = map (device: '' jqUpdates =
map (device: ''
.devices[] |= ( .devices[] |= (
if .deviceId == "${device.deviceId}" then if .deviceId == "${device.deviceId}" then
del(.encryptionPasswordFile) | del(.encryptionPasswordFile) |
@@ -96,13 +106,14 @@ final: prev: {
. .
end end
) )
'') devicesWithSecrets; '')
devicesWithSecrets;
jqRawFiles = map (device: "--rawfile ${device.variableName} ${lib.escapeShellArg device.secretPath}") devicesWithSecrets; jqRawFiles = map (device: "--rawfile ${device.variableName} ${lib.escapeShellArg device.secretPath}") devicesWithSecrets;
in in "${jq} ${lib.concatStringsSep " " jqRawFiles} ${lib.escapeShellArg (lib.concatStringsSep "|" (["."] ++ jqUpdates))}";
"${jq} ${lib.concatStringsSep " " jqRawFiles} ${lib.escapeShellArg (lib.concatStringsSep "|" ([ "." ] ++ jqUpdates))}"; }.${
}.${conf_type}; conf_type
in };
'' in ''
${injectSecretsJqCmd} ${jsonPreSecretsFile} | curl --json @- -X POST ${s.baseAddress} ${injectSecretsJqCmd} ${jsonPreSecretsFile} | curl --json @- -X POST ${s.baseAddress}
'' ''
)) ))
@@ -138,8 +149,7 @@ final: prev: {
fi fi
'' ''
); );
in in {
{
options = { options = {
services.syncthing = { services.syncthing = {
enable = mkEnableOption "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync"; enable = mkEnableOption "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync";
@@ -342,7 +352,11 @@ final: prev: {
ProgramArguments = [ ProgramArguments = [
"${cfg.package}/bin/syncthing" "${cfg.package}/bin/syncthing"
"-no-browser" "-no-browser"
"-gui-address=${if isUnixGui then "unix://" else ""}${cfg.guiAddress}" "-gui-address=${
if isUnixGui
then "unix://"
else ""
}${cfg.guiAddress}"
"-config=${cfg.configDir}" "-config=${cfg.configDir}"
"-data=${cfg.configDir}" "-data=${cfg.configDir}"
]; ];