ctucx.git: nixfiles

ctucx' nixfiles

commit f5caba6226de1e2faf5d273e1989c798635039bc
parent 8727a877b7f489ab5180d5536d9cb6794c7fdc9e
Author: Leah (ctucx) <leah@ctu.cx>
Date: Fri, 20 May 2022 18:17:40 +0200

machines/osterei/websites/ctu.cx: add bikemap
5 files changed, 322 insertions(+), 1 deletion(-)
A
machines/osterei/websites/ctu.cx-bikemap/default-gpx2tiles.nix
|
114
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
machines/osterei/websites/ctu.cx-bikemap/default.nix
|
137
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
machines/osterei/websites/ctu.cx-bikemap/parse-gpx/parse-gpx
|
70
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M
machines/osterei/websites/ctu.cx.nix
|
1
-
M
machines/osterei/websites/default.nix
|
1
+
diff --git a/machines/osterei/websites/ctu.cx-bikemap/default-gpx2tiles.nix b/machines/osterei/websites/ctu.cx-bikemap/default-gpx2tiles.nix
@@ -0,0 +1,114 @@
+{ pkgs, ... }:
+
+let
+  gpx2tiles = pkgs.stdenv.mkDerivation rec {
+    name = "gpx2tiles";
+
+    src = pkgs.fetchFromGitHub {
+      owner  = "raalkml";
+      repo   = "gpx2tiles";
+      rev    = "bfe287bfdf21869212b5d095bba6979caee4a308";
+      sha256 = "0x4cparlbxvjnwhwkdz157py1bmad2sap3wjjzaq988aymxnadym";
+    };
+
+    buildInputs = with pkgs; [
+      pkgconfig
+      libxml2
+      gd
+    ];
+
+    makeFlags = [ "PREFIX=${placeholder "out"}" ];
+  };
+
+  deployScript = pkgs.writeShellScript "deploy" ''
+    systemctl start deploy-bikemap
+    systemctl status deploy-bikemap
+  '';
+
+  deployHook = pkgs.writeShellScriptBin "post-receive" ''
+    [ -t 0 ] || cat >/dev/null
+    [ -z "$GL_REPO" ] && die GL_REPO not set
+
+    #deploy bikemap
+    [ "$GL_REPO" == "bikemap" ] && sudo ${deployScript}
+  '';
+
+in {
+
+  users = {
+    users."bikemap" = {
+      home = "/var/lib/bikemap";
+      group = "git";
+      isSystemUser = true;
+    };
+  };
+
+  security.sudo.extraRules = [{
+    users    = [ "git" ];
+    commands = [
+      { command = "${deployScript}"; options = [ "SETENV" "NOPASSWD" ]; }
+    ];
+  }];
+
+  systemd = {
+    services.deploy-bikemap = {
+      script = ''
+        tmpdir=$(mktemp -d);
+
+        ${pkgs.git}/bin/git clone /var/lib/gitolite/repositories/bikemap.git $tmpdir
+
+        mkdir $tmpdir/tiles;
+        ${gpx2tiles}/bin/gpx2tiles -j 2 -t 7:2+ -t 13:4+ -z 6 -Z 16 -c ff8800 -C $tmpdir/tiles $tmpdir/tracks/*.gpx;
+
+        rm -rf ~/*;
+
+        cp -r  $tmpdir/dist/* ~/.;
+        cp -r  $tmpdir/tiles ~/.;
+        echo "{\"lastUpdated\":\"$(date +"%Y-%m-%d %H:%M")\"}" > ~/lastUpdated.json;
+
+        rm -rf $tmpdir;
+      '';
+
+      serviceConfig = {
+        Type = "oneshot";
+
+        User  = "bikemap";
+        Group = "git";
+
+        WorkingDirectory        = "~";
+        StateDirectory          = "bikemap";
+        StateDirectoryMode      = "755";
+
+        NoNewPrivileges         = true;
+        PrivateTmp              = true;
+        PrivateDevices          = true;
+
+        RestrictAddressFamilies = "none";
+        RestrictNamespaces      = true;
+        RestrictRealtime        = true;
+
+        ProtectSystem           = "full";
+        ProtectControlGroups    = true;
+        ProtectKernelModules    = true;
+        ProtectKernelTunables   = true;
+
+        DevicePolicy            = "closed";
+        LockPersonality         = true;
+      };
+    };
+  };
+
+  services = {
+    gitolite.commonHooks = [ "${deployHook}/bin/post-receive" ];
+    nginx = {
+      enable = true;
+      virtualHosts."ctu.cx" = {
+        enableACME = true;
+        forceSSL   = true;
+        locations  = {
+          "/bikemap/".alias = "/var/lib/bikemap/";
+        };
+      };
+    };
+  };
+}
diff --git a/machines/osterei/websites/ctu.cx-bikemap/default.nix b/machines/osterei/websites/ctu.cx-bikemap/default.nix
@@ -0,0 +1,137 @@
+{ pkgs, ... }:
+
+let
+  parse-gpx = pkgs.stdenv.mkDerivation rec {
+    name = "parse-gpx";
+    src  = ./parse-gpx;
+
+    nativeBuildInputs = [ pkgs.makeWrapper ];
+    buildInputs       = [ pkgs.perl ];
+
+    installPhase = ''mkdir -p $out/bin; cp parse-gpx $out/bin; chmod +x $out/bin/parse-gpx;'';
+    postFixup    = ''wrapProgram $out/bin/parse-gpx --prefix PERL5LIB : "${with pkgs.perlPackages; makePerlPath [ XMLParser ]}"'';
+  };
+
+  datamaps  = pkgs.stdenv.mkDerivation rec {
+    name = "datamaps";
+
+    src = pkgs.fetchFromGitHub {
+      owner  = "e-n-f";
+      repo   = "datamaps";
+      rev    = "76e620adabbedabd6866b23b30c145b53bae751e";
+      sha256 = "1rdqbyfmgidiv4aqy1s6llls304dxbg5226c7k622smd2rnda2jk";
+    };
+
+    buildInputs = with pkgs; [ pkgconfig libpng ];
+
+    installPhase = ''
+      mkdir -p $out/bin;
+      cp {encode,render,merge,enumerate} $out/bin;
+    '';
+  };
+
+  makeTile = pkgs.writeShellScript "makeTile" ''
+    mkdir -p tiles/$2/$3
+    echo "rendering $1 $2 $3 $4 $5 $6"
+
+    if [$2 -gt 13 ]
+    then 
+      ${datamaps}/bin/render -g -t0 -L4 -c 'ff8800' -S 'ff8800' $1 $2 $3 $4 | ${pkgs.pngquant}/bin/pngquant 256 > tiles/$2/$3/$4.png
+    else 
+      ${datamaps}/bin/render -g -t0 -L7 -c 'ff8800' -S 'ff8800' $1 $2 $3 $4 | ${pkgs.pngquant}/bin/pngquant 256 > tiles/$2/$3/$4.png
+    fi
+  '';
+
+  deployScript = pkgs.writeShellScript "deploy" ''
+    systemctl start deploy-bikemap;
+    systemctl status deploy-bikemap;
+  '';
+
+  deployHook = pkgs.writeShellScriptBin "post-receive" ''
+    [ -t 0 ] || cat >/dev/null
+    [ -z "$GL_REPO" ] && die GL_REPO not set
+
+    #deploy bikemap
+    [ "$GL_REPO" == "bikemap" ] && sudo ${deployScript}
+  '';
+
+in {
+
+  users = {
+    users."bikemap" = {
+      home = "/var/lib/bikemap";
+      group = "git";
+      isSystemUser = true;
+    };
+  };
+
+  security.sudo.extraRules = [{
+    users    = [ "git" ];
+    commands = [
+      { command = "${deployScript}"; options = [ "SETENV" "NOPASSWD" ]; }
+    ];
+  }];
+
+  systemd = {
+    services.deploy-bikemap = {
+      script = ''
+        tmpdir=$(mktemp -d);
+        cd $tmpdir
+
+        ${pkgs.git}/bin/git clone /var/lib/gitolite/repositories/bikemap.git $tmpdir
+
+        find $tmpdir/tracks -name '*.gpx' -print0 | xargs -0 ${parse-gpx}/bin/parse-gpx | ${datamaps}/bin/encode -z16 -m8 -o $tmpdir/gpx.dm
+        ${datamaps}/bin/enumerate -s -Z6 -z16 ./gpx.dm | xargs -L1 -P3 ${makeTile}
+
+        rm -rf ~/*;
+
+        cp -r  $tmpdir/dist/* ~/.;
+        cp -r  $tmpdir/tiles ~/tiles;
+        echo "{\"lastUpdated\":\"$(date +"%Y-%m-%d %H:%M")\"}" > ~/lastUpdated.json;
+
+        rm -rf $tmpdir;
+      '';
+
+      serviceConfig = {
+        Type = "oneshot";
+
+        User  = "bikemap";
+        Group = "git";
+
+        WorkingDirectory        = "~";
+        StateDirectory          = "bikemap";
+        StateDirectoryMode      = "755";
+
+        NoNewPrivileges         = true;
+        PrivateTmp              = true;
+        PrivateDevices          = true;
+
+        RestrictAddressFamilies = "none";
+        RestrictNamespaces      = true;
+        RestrictRealtime        = true;
+
+        ProtectSystem           = "full";
+        ProtectControlGroups    = true;
+        ProtectKernelModules    = true;
+        ProtectKernelTunables   = true;
+
+        DevicePolicy            = "closed";
+        LockPersonality         = true;
+      };
+    };
+  };
+
+  services = {
+    gitolite.commonHooks = [ "${deployHook}/bin/post-receive" ];
+    nginx = {
+      enable = true;
+      virtualHosts."ctu.cx" = {
+        enableACME = true;
+        forceSSL   = true;
+        locations  = {
+          "/bikemap/".alias = "/var/lib/bikemap/";
+        };
+      };
+    };
+  };
+}
diff --git a/machines/osterei/websites/ctu.cx-bikemap/parse-gpx/parse-gpx b/machines/osterei/websites/ctu.cx-bikemap/parse-gpx/parse-gpx
@@ -0,0 +1,70 @@
+#!/usr/bin/env perl
+use POSIX;
+use XML::Parser;
+
+$pi = 4 * atan2(1, 1);
+
+sub handle_start {
+	my ($expat, $element, @tags) = @_;
+	my %tags = @tags;
+
+	if ($element eq "trkpt") {
+		$lat = $tags{'lat'};
+		$lon = $tags{'lon'};
+	} elsif ($element eq "ele") {
+		$state = "ele";
+	} elsif ($element eq "time") {
+		$state = "time";
+	} else {
+		$state = "";
+	}
+}
+
+sub handle_char {
+	my ($expat, $string) = @_;
+
+	$text{$state} .= $string;
+}
+
+sub handle_end {
+	my ($expat, $element) = @_;
+
+	if ($element eq "trkseg" || $element eq "trk") {
+		$oldlat = $oldlon = "";
+	} elsif ($element eq "trkpt") {
+		if ($lat ne "" && $lon ne "" && $oldlat ne "" && $oldlon ne "") {
+			if ($lat ne $oldlat || $lon ne $oldlon) {
+				print "$oldlat,$oldlon $lat,$lon ";
+
+				$rat = cos(($lat + $oldlat) / 2 * $pi / 180);
+				$ang = atan2($lat - $oldlat, ($lon - $oldlon) * $rat);
+
+				printf("8:%d\n", ($ang + $pi) * 256 / (2 * $pi));
+			}
+		}
+
+		$oldlat = $lat;
+		$oldlon = $lon;
+		%text = ();
+	}
+}
+
+if ($#ARGV < 0) {
+	$parser = new XML::Parser(Handlers => { Start => \&handle_start,
+						End   => \&handle_end,
+						Char  => \&handle_char,
+					      });
+
+	$parser->parse(*STDIN);
+} else {
+	for $file (@ARGV) {
+		$oldwhen = 0;
+
+		$parser = new XML::Parser(Handlers => { Start => \&handle_start,
+							End   => \&handle_end,
+							Char  => \&handle_char,
+						      });
+
+		$parser->parsefile($file);
+	}
+}
diff --git a/machines/osterei/websites/ctu.cx.nix b/machines/osterei/websites/ctu.cx.nix
@@ -9,7 +9,6 @@
       forceSSL   = true;
       locations  = {
         "/".root = ./ctu.cx;
-        "/bikemap/".alias = "/var/lib/websites/bikemap/";
 
         "/vodafone-map" = {
           proxyPass   = "https://netmap.vodafone.de/arcgis/rest/services/CoKart/netzabdeckung_mobilfunk_4x/MapServer";
diff --git a/machines/osterei/websites/default.nix b/machines/osterei/websites/default.nix
@@ -4,6 +4,7 @@
 
   imports = [
     ./ctu.cx.nix
+    ./ctu.cx-bikemap
     ./photos.ctu.cx.nix
     ./flauschehorn.sexy.nix
   ];