summaryrefslogtreecommitdiff
path: root/hosts
diff options
context:
space:
mode:
authorLinnnus <[email protected]>2024-10-02 20:09:36 +0200
committerLinnnus <[email protected]>2024-10-02 20:09:36 +0200
commita8a572f7a16a431100a984a2f571c93396db93c9 (patch)
tree7949f83d7cc54e1dc2214fad0cc388341ecde7cd /hosts
parent404f6847236b3dc82199b8810979b25c3b435804 (diff)
ahmed: Rebuild linus.onl on webhook instead of timer
Diffstat (limited to 'hosts')
-rw-r--r--hosts/ahmed/linus.onl/default.nix79
1 files changed, 68 insertions, 11 deletions
diff --git a/hosts/ahmed/linus.onl/default.nix b/hosts/ahmed/linus.onl/default.nix
index 3c4f7a6..f176228 100644
--- a/hosts/ahmed/linus.onl/default.nix
+++ b/hosts/ahmed/linus.onl/default.nix
@@ -1,6 +1,7 @@
{
pkgs,
lib,
+ config,
...
}: let
# The domain to serve. Also kinda embedded in the name of the module??
@@ -8,6 +9,12 @@
# Enable HTTPS stuff.
useACME = true;
+
+ # When run, this command causes a rebuild of the website source. See the service defintion for how the site is rebuilt.
+ startServiceCommand = "/run/current-system/sw/bin/systemctl start ${domain}-source.service";
+
+ # Name of the "production" branch where the live content goes.
+ mainBranch = "main";
in {
config = {
# Create a user to run the build script under.
@@ -26,7 +33,7 @@ in {
chmod 0755 /var/www/${domain}
'';
- # Create a systemd service which rebuild the site regularly.
+ # Create a systemd service which rebuild the site.
#
# This can't be done using Nix because the site relies on the git build and
# there are some inherent difficulties with including .git/ in the
@@ -34,8 +41,6 @@ in {
#
# See: https://github.com/NixOS/nix/issues/6900
# See: https://github.com/NixOS/nixpkgs/issues/8567
- #
- # TODO: Integrate rebuilding with GitHub webhooks to rebuild on push.
systemd.services."${domain}-source" = {
description = "generate https://${domain} source";
@@ -58,8 +63,7 @@ in {
tmpdir="$(mktemp -d -t linus.onl-source.XXXXXXXXXXXX)"
cd "$tmpdir"
trap 'rm -rf $tmpdir' EXIT
- # TODO: Only do minimal possible cloning
- git clone https://github.com/linnnus/${domain} .
+ git clone --depth=1 --branch=${mainBranch} https://github.com/linnnus/${domain} .
make _build
rsync --archive --delete _build/ /var/www/${domain}
'';
@@ -76,14 +80,60 @@ in {
wantedBy = ["nginx.service"];
};
- # Start the source fetching shit only after network acess has been achieved.
- systemd.timers."${domain}-source" = {
- after = ["network-online.target"];
- requires = ["network-online.target"];
- wantedBy = ["timers.target"];
- timerConfig.OnCalendar = ["*-*-* *:00/5:00"];
+ # This service will listen for webhook events from GitHub's API. Whenever
+ # it receives a "push" event, it will start the rebuild service.
+ services.webhook-listener = {
+ enable = true;
+
+ commands = [
+ {
+ event = "push";
+ command = toString (pkgs.writeShellScript "handle-push-event.sh" ''
+ ${pkgs.jq}/bin/jq --exit-status '.ref == "refs/heads/${mainBranch}"' >/dev/null
+ case $? in
+ 0)
+ ${config.security.wrapperDir}/sudo ${startServiceCommand}
+ ;;
+ 1)
+ echo "Not the target ref. Exciting"
+ exit 0
+ ;;
+ *)
+ echo "Got jq error. Exiting." >&2
+ exit 1
+ ;;
+ esac
+ '');
+ }
+ ];
+
+ max-idle-time = "10min";
+
+ secret-path = config.age.secrets."linus.onl-github-secret".path;
};
+ # We have shared a secret with GitHub, which we use to verify requests. Here we decrypt that secret.
+ age.secrets."linus.onl-github-secret" = {
+ file = ../../../secrets/linus.onl-github-secret.txt.age;
+
+ owner = config.services.webhook-listener.user;
+ group = config.services.webhook-listener.group;
+ };
+
+ # Commands run by `webhook-listener` are run as an inpriviledged user for
+ # security reasons. We have to specifically give that user permission to start this one service.
+ security.sudo.extraRules = [
+ {
+ users = [config.services.webhook-listener.user];
+ commands = [
+ {
+ command = startServiceCommand;
+ options = ["NOPASSWD"];
+ }
+ ];
+ }
+ ];
+
# Register domain name with ddns.
services.cloudflare-dyndns.domains = [domain];
@@ -94,6 +144,13 @@ in {
enableACME = useACME;
forceSSL = useACME;
root = "/var/www/${domain}";
+
+ # I have pointed the GitHub webhook requests at <https://linus.onl/webhook>.
+ # These should be forwarded to `/` on the listening socket server.
+ locations."= /webhook" = {
+ recommendedProxySettings = true;
+ proxyPass = "http://unix:${config.services.webhook-listener.socket-path}:/";
+ };
};
};
};