diff --git a/flake.lock b/flake.lock index dc58554..c14689d 100755 --- a/flake.lock +++ b/flake.lock @@ -98,6 +98,22 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1758690382, + "narHash": "sha256-NY3kSorgqE5LMm1LqNwGne3ZLMF2/ILgLpFr1fS4X3o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e643668fd71b949c53f8626614b21ff71a07379d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "phps": { "inputs": { "flake-compat": "flake-compat", @@ -124,7 +140,8 @@ "inputs": { "agenix": "agenix", "nixpkgs": "nixpkgs", - "phps": "phps" + "phps": "phps", + "winboat": "winboat" } }, "systems": { @@ -174,6 +191,24 @@ "repo": "flake-utils", "type": "github" } + }, + "winboat": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1760183562, + "narHash": "sha256-lauscAI61WXjLTuGiRDMUAEeTqvOTSWhRoHDaor5sfE=", + "owner": "TibixDev", + "repo": "winboat", + "rev": "ae60de6c2cba7a2001fef1027d5c2e06614e6904", + "type": "github" + }, + "original": { + "owner": "TibixDev", + "repo": "winboat", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index f8c151e..19932c2 100755 --- a/flake.nix +++ b/flake.nix @@ -11,6 +11,7 @@ url = "github:ryantm/agenix"; inputs.nixpkgs.follows = "nixpkgs"; }; + winboat.url = "github:TibixDev/winboat"; }; outputs = inputs: { diff --git a/hosts/astral/links.nix b/hosts/astral/links.nix index fe836be..bbf7a7e 100644 --- a/hosts/astral/links.nix +++ b/hosts/astral/links.nix @@ -1,21 +1,39 @@ -{ pkgs, lib, ... }: +{ pkgs, ... }: let domain = "nettika.leaf.ninja"; root = "/srv/links"; + webhookHandler = pkgs.writeScript "webhook-handler.py" '' + #!${pkgs.python3}/bin/python3 + + import http.server + import socketserver + import subprocess + import os + + class WebhookHandler(http.server.SimpleHTTPRequestHandler): + def do_POST(self): + os.chdir('${root}') + subprocess.run(['${pkgs.git}/bin/git', 'pull'], check=True) + self.send_response(200) + self.end_headers() + self.wfile.write(b'OK') + + with socketserver.TCPServer(("127.0.0.1", 8081), WebhookHandler) as httpd: + httpd.serve_forever() + ''; in { - services.caddy.virtualHosts = { - ${domain}.extraConfig = '' - root * ${root} - file_server - ''; - "http://localhost:8081".extraConfig = let git = lib.getExe pkgs.git; - in '' - route { - exec { - command ${git} pull --rebase - directory ${root} - } - } - ''; - }; + # systemd.services.links-webhook = { + # wantedBy = [ "multi-user.target" ]; + # after = [ "network.target" ]; + # serviceConfig = { + # Type = "simple"; + # ExecStart = "${pkgs.python3}/bin/python3 ${webhookHandler}"; + # Restart = "always"; + # }; + # }; + + services.caddy.virtualHosts.${domain}.extraConfig = '' + root * ${root} + file_server + ''; } diff --git a/hosts/astral/radicale.nix b/hosts/astral/radicale.nix index 68d3c08..79527b7 100644 --- a/hosts/astral/radicale.nix +++ b/hosts/astral/radicale.nix @@ -1,10 +1,24 @@ -{ config, ... }: +{ pkgs, config, lib, ... }: let domain = "radicale.leaf.ninja"; in { - age.secrets.radicale-htpasswd = { - file = ./secrets/radicale-htpasswd; - mode = "400"; - owner = "radicale"; + users.users.radicale-sync = { + isSystemUser = true; + group = "radicale-sync"; + }; + + users.groups.radicale-sync = { }; + + age.secrets = { + radicale-htpasswd = { + file = ./secrets/radicale-htpasswd; + mode = "400"; + owner = "radicale"; + }; + radicale-sync-secrets = { + file = ./secrets/radicale-sync-secrets.fish; + mode = "400"; + owner = "radicale-sync"; + }; }; services.radicale = { @@ -17,9 +31,70 @@ in { htpasswd_encryption = "plain"; }; }; + rights = { + root = { + user = ".+"; + collection = ""; + permissions = "R"; + }; + principal = { + user = ".+"; + collection = "{user}"; + permissions = "RW"; + }; + calendars = { + user = ".+"; + collection = "{user}/[^/]+"; + permissions = "rw"; + }; + remote = { + user = ".+"; + collection = "remote/.+"; + permissions = "r"; + }; + }; }; services.caddy.virtualHosts.${domain}.extraConfig = '' reverse_proxy localhost:5232 ''; + + systemd.timers.radicale-sync = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "5min"; + OnCalendar = "*-*-* *:0/4:00"; + }; + }; + + systemd.services.radicale-sync = let + radicaleUrl = "http://localhost:5232"; + remoteCollections = [{ + collection = "devhack"; + url = "https://devhack.net/calendar.ics"; + }]; + remoteCollectionsFile = pkgs.writers.writeText "remote-collections" + (lib.concatMapStringsSep "\n" + ({ collection, url }: "${collection} ${url}") remoteCollections); + syncScript = pkgs.writers.writeFish "sync.fish" '' + alias curl ${lib.getExe pkgs.curl} + source ${config.age.secrets.radicale-sync-secrets.path} + while read -l name url + set tempfile (mktemp) + curl -sf $url -o $tempfile + curl -sf -u "remote:$password" \ + -X PUT "${radicaleUrl}/remote/$name" \ + -H 'Content-Type: text/calendar; charset=utf-8' \ + --data-binary @$tempfile + echo "Uploaded $name" + end < ${remoteCollectionsFile} + ''; + in { + serviceConfig = { + Type = "oneshot"; + User = "radicale-sync"; + Group = "radicale-sync"; + ExecStart = syncScript; + }; + }; } diff --git a/hosts/astral/secrets/radicale-htpasswd b/hosts/astral/secrets/radicale-htpasswd index 36c140f..c2a396c 100644 --- a/hosts/astral/secrets/radicale-htpasswd +++ b/hosts/astral/secrets/radicale-htpasswd @@ -1,9 +1,7 @@ age-encryption.org/v1 --> ssh-ed25519 f+PJrQ pKqLrqz0R7kAzNQZ3ChRsoWa63JEN2H2KHtGguF5nSc -6Mk1qDWKx26jPdEzaVMh0vgUeVWjAGcmIPpvSU8BFNE --> ssh-ed25519 nz/vnw 0PuVNQ97Qa6iCk4pPf34lgS1aPb4CeDB4Qclk5F24T4 -OwJOYMTlTY9+Pj/BwG09z4q2/QViii710Kh3xPU5FRA ---- mSdutlC3gFq8lDjeOGqi361i+DUI1Yg6Bpl7hCfznJA -tQ/rNeKeѥ~ן{_o -y_ܭ}ûP*W5F.ECZ#; -liԧ*]yT \ No newline at end of file +-> ssh-ed25519 f+PJrQ iGtaCi4amFijPCydakWm6qo6eYPiRHp5Rrr7TpnRLxo +MiFAmPkU9gDBYdNqGA9CdYike2n780nQ7o8nAZ0GGtE +-> ssh-ed25519 nz/vnw FiTGU3HNakVR1VNVyUPdiu+WhEMf9t/ONBgoQRILExA +TjDSkxA6z1ovqu2mA0G1UY1k29f35HFHDZQWA90XSzM +--- WK1KjkiLaqH1jN3zIgetSHEe5xEddBYjlt3Qu5Z/Bcg +Ϲ%slma@Oԧ> K<(Co6hӖLɠ(_hR2Ȋ"znp/MW}LNe%C̺7?#j3ҋG?ÁX{V%Ym lf \ No newline at end of file diff --git a/hosts/astral/secrets/radicale-sync-secrets.fish b/hosts/astral/secrets/radicale-sync-secrets.fish new file mode 100644 index 0000000..3cc4d6d --- /dev/null +++ b/hosts/astral/secrets/radicale-sync-secrets.fish @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 f+PJrQ f+4sexgdKNmdc7DQe3h6v8CveCiHN+dLFX0vdMzBOBQ +/nSP3nPNdxKjOUIn0xzH/ht4QC68aMxCLplP8kIeKr4 +-> ssh-ed25519 nz/vnw ejIzeXNfCDxPhho7426oR6WQWlJxDprp1j90lgCGnmM +yaq9bU726x5xtHhK7ZQc1Onlg681cSQsSxSCRU/GBAU +--- UT7B9uDmsNJwTLroGj+JQdKbsOHhgSnnlhMru4tY7/M +uK Ti,M`S4~6ϒjҫ9$H0d?pXV%IJؘ "ҾdWO \ No newline at end of file diff --git a/hosts/default.nix b/hosts/default.nix index 1b52d15..02b0866 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -1,4 +1,4 @@ -{ self, nixpkgs, phps, agenix }: +{ self, nixpkgs, phps, agenix, winboat }: let baseSpecialArgs = { inherit (self) nixosModules; @@ -11,7 +11,7 @@ in { marauder = nixosSystem { system = "x86_64-linux"; modules = [ ./marauder ]; - specialArgs = { inherit phps; }; + specialArgs = { inherit phps winboat; }; }; astral = nixosSystem { system = "x86_64-linux"; diff --git a/hosts/marauder/default.nix b/hosts/marauder/default.nix index ab09178..cf47dd2 100755 --- a/hosts/marauder/default.nix +++ b/hosts/marauder/default.nix @@ -1,4 +1,4 @@ -{ pkgs, nixosModules, phps, agenix, ... }: +{ pkgs, nixosModules, phps, agenix, winboat, ... }: let fortune = pkgs.writeShellScript "cgi" '' echo "Content-type: text/html" @@ -76,7 +76,6 @@ in { }; kernelModules = [ "kvm-amd" ]; kernelParams = [ "amd_pstate=active" ]; - binfmt.emulatedSystems = [ "aarch64-linux" ]; }; hardware = { @@ -103,7 +102,7 @@ in { environment.systemPackages = with pkgs; [ # Chat clients discord - cinny-desktop + element-desktop signal-desktop slack telegram-desktop @@ -120,7 +119,6 @@ in { krita openscad-unstable orca-slicer - plasticity # Multimedia ffcheck @@ -134,8 +132,6 @@ in { # Dev Tools fossil - just - kondo nixd nixfmt-classic nixpkgs-fmt @@ -153,6 +149,7 @@ in { dig htop jq + just unzip zip @@ -160,17 +157,14 @@ in { mullvad-vpn qbittorrent - # Utility Apps - baobab - gparted - system-config-printer - # Misc gcc intiface-central openssl pkg-config prismlauncher + system-config-printer + winboat.packages.x86_64-linux.winboat ]; programs.git = { diff --git a/secrets.nix b/secrets.nix index 33a040c..7956f39 100644 --- a/secrets.nix +++ b/secrets.nix @@ -14,4 +14,6 @@ in { "hosts/astral/secrets/forgejo-mailer-password.age".publicKeys = [ marauder astral ]; "hosts/astral/secrets/radicale-htpasswd".publicKeys = [ marauder astral ]; + "hosts/astral/secrets/radicale-sync-secrets.fish".publicKeys = + [ marauder astral ]; }