Compare commits

..

1 commit

Author SHA1 Message Date
f1f2043fba WIP 2025-10-15 14:26:28 -07:00
9 changed files with 173 additions and 43 deletions

37
flake.lock generated
View file

@ -98,6 +98,22 @@
"type": "github" "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": { "phps": {
"inputs": { "inputs": {
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
@ -124,7 +140,8 @@
"inputs": { "inputs": {
"agenix": "agenix", "agenix": "agenix",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"phps": "phps" "phps": "phps",
"winboat": "winboat"
} }
}, },
"systems": { "systems": {
@ -174,6 +191,24 @@
"repo": "flake-utils", "repo": "flake-utils",
"type": "github" "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", "root": "root",

View file

@ -11,6 +11,7 @@
url = "github:ryantm/agenix"; url = "github:ryantm/agenix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
winboat.url = "github:TibixDev/winboat";
}; };
outputs = inputs: { outputs = inputs: {

View file

@ -1,21 +1,39 @@
{ pkgs, lib, ... }: { pkgs, ... }:
let let
domain = "nettika.leaf.ninja"; domain = "nettika.leaf.ninja";
root = "/srv/links"; 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 { in {
services.caddy.virtualHosts = { # systemd.services.links-webhook = {
${domain}.extraConfig = '' # 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} root * ${root}
file_server file_server
''; '';
"http://localhost:8081".extraConfig = let git = lib.getExe pkgs.git;
in ''
route {
exec {
command ${git} pull --rebase
directory ${root}
}
}
'';
};
} }

View file

@ -1,11 +1,25 @@
{ config, ... }: { pkgs, config, lib, ... }:
let domain = "radicale.leaf.ninja"; let domain = "radicale.leaf.ninja";
in { in {
age.secrets.radicale-htpasswd = { users.users.radicale-sync = {
isSystemUser = true;
group = "radicale-sync";
};
users.groups.radicale-sync = { };
age.secrets = {
radicale-htpasswd = {
file = ./secrets/radicale-htpasswd; file = ./secrets/radicale-htpasswd;
mode = "400"; mode = "400";
owner = "radicale"; owner = "radicale";
}; };
radicale-sync-secrets = {
file = ./secrets/radicale-sync-secrets.fish;
mode = "400";
owner = "radicale-sync";
};
};
services.radicale = { services.radicale = {
enable = true; enable = true;
@ -17,9 +31,70 @@ in {
htpasswd_encryption = "plain"; 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 = '' services.caddy.virtualHosts.${domain}.extraConfig = ''
reverse_proxy localhost:5232 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;
};
};
} }

View file

@ -1,9 +1,7 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 f+PJrQ pKqLrqz0R7kAzNQZ3ChRsoWa63JEN2H2KHtGguF5nSc -> ssh-ed25519 f+PJrQ iGtaCi4amFijPCydakWm6qo6eYPiRHp5Rrr7TpnRLxo
6Mk1qDWKx26jPdEzaVMh0vgUeVWjAGcmIPpvSU8BFNE MiFAmPkU9gDBYdNqGA9CdYike2n780nQ7o8nAZ0GGtE
-> ssh-ed25519 nz/vnw 0PuVNQ97Qa6iCk4pPf34lgS1aPb4CeDB4Qclk5F24T4 -> ssh-ed25519 nz/vnw FiTGU3HNakVR1VNVyUPdiu+WhEMf9t/ONBgoQRILExA
OwJOYMTlTY9+Pj/BwG09z4q2/QViii710Kh3xPU5FRA TjDSkxA6z1ovqu2mA0G1UY1k29f35HFHDZQWA90XSzM
--- mSdutlC3gFq8lDjeOGqi361i+DUI1Yg6Bpl7hCfznJA --- WK1KjkiLaqH1jN3zIgetSHEe5xEddBYjlt3Qu5Z/Bcg
“ÜtQÆ/í rNeKeíé¸Ñ¥Äè~ˆý¾×Ÿ{_¡o „™æ¤Ï¹%sçlmaæ†á@OÔ§ë> K<ç(<28>š†©CoÕ6ªLÁëÉ (ö_h”ð¶R2ð²ÈŠ"®znp/M¿W}—æÕLòNàe»ª˜%²’ÂC̺•¡7?#jè3—ÒG? Ã<>X{­V%Ym¯æ  lf™Õ
y_Ü­}¸Ã»P*W5<57>»´õFû.ECø¡Z©å#;
£¢ð§Ûli…Ô§±*´Î]yT

View file

@ -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<EFBFBD>÷~š™6Ï¿jÓÑçÒ«9­Õï$H0dô¡?ñ<>ÒpƒXV%ÙIËJؘ "Ò¾dËùâÓWO¹ÓÄ

View file

@ -1,4 +1,4 @@
{ self, nixpkgs, phps, agenix }: { self, nixpkgs, phps, agenix, winboat }:
let let
baseSpecialArgs = { baseSpecialArgs = {
inherit (self) nixosModules; inherit (self) nixosModules;
@ -11,7 +11,7 @@ in {
marauder = nixosSystem { marauder = nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
modules = [ ./marauder ]; modules = [ ./marauder ];
specialArgs = { inherit phps; }; specialArgs = { inherit phps winboat; };
}; };
astral = nixosSystem { astral = nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";

View file

@ -1,4 +1,4 @@
{ pkgs, nixosModules, phps, agenix, ... }: { pkgs, nixosModules, phps, agenix, winboat, ... }:
let let
fortune = pkgs.writeShellScript "cgi" '' fortune = pkgs.writeShellScript "cgi" ''
echo "Content-type: text/html" echo "Content-type: text/html"
@ -76,7 +76,6 @@ in {
}; };
kernelModules = [ "kvm-amd" ]; kernelModules = [ "kvm-amd" ];
kernelParams = [ "amd_pstate=active" ]; kernelParams = [ "amd_pstate=active" ];
binfmt.emulatedSystems = [ "aarch64-linux" ];
}; };
hardware = { hardware = {
@ -103,7 +102,7 @@ in {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
# Chat clients # Chat clients
discord discord
cinny-desktop element-desktop
signal-desktop signal-desktop
slack slack
telegram-desktop telegram-desktop
@ -120,7 +119,6 @@ in {
krita krita
openscad-unstable openscad-unstable
orca-slicer orca-slicer
plasticity
# Multimedia # Multimedia
ffcheck ffcheck
@ -134,8 +132,6 @@ in {
# Dev Tools # Dev Tools
fossil fossil
just
kondo
nixd nixd
nixfmt-classic nixfmt-classic
nixpkgs-fmt nixpkgs-fmt
@ -153,6 +149,7 @@ in {
dig dig
htop htop
jq jq
just
unzip unzip
zip zip
@ -160,17 +157,14 @@ in {
mullvad-vpn mullvad-vpn
qbittorrent qbittorrent
# Utility Apps
baobab
gparted
system-config-printer
# Misc # Misc
gcc gcc
intiface-central intiface-central
openssl openssl
pkg-config pkg-config
prismlauncher prismlauncher
system-config-printer
winboat.packages.x86_64-linux.winboat
]; ];
programs.git = { programs.git = {

View file

@ -14,4 +14,6 @@ in {
"hosts/astral/secrets/forgejo-mailer-password.age".publicKeys = "hosts/astral/secrets/forgejo-mailer-password.age".publicKeys =
[ marauder astral ]; [ marauder astral ];
"hosts/astral/secrets/radicale-htpasswd".publicKeys = [ marauder astral ]; "hosts/astral/secrets/radicale-htpasswd".publicKeys = [ marauder astral ];
"hosts/astral/secrets/radicale-sync-secrets.fish".publicKeys =
[ marauder astral ];
} }