b9e3db35b2
This fixes cgit's ability to infer the idle time on the repo overview properly. While we're at it, use the proper remote URL, so the redirection warning doesn't clutter the logs. Change-Id: Ie3a75886bdf9c704c18950290b1f7115d0ca0c02 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7496 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: tazjin <tazjin@tvl.su> Autosubmit: sterni <sternenseemann@systemli.org>
255 lines
7.1 KiB
Nix
255 lines
7.1 KiB
Nix
{ depot, pkgs, lib, config, ... }:
|
|
|
|
let
|
|
virtualHost = "code.sterni.lv";
|
|
|
|
repoSections = [
|
|
{
|
|
section = "active";
|
|
repos = {
|
|
spacecookie = {
|
|
description = "gopher server (and library for Haskell)";
|
|
upstream = "https://github.com/sternenseemann/spacecookie.git";
|
|
};
|
|
"mirror/depot" = {
|
|
description = "monorepo for the virus lounge";
|
|
upstream = "https://code.tvl.fyi/depot.git";
|
|
defaultBranch = "canon";
|
|
};
|
|
"mirror/flipdot-gschichtler" = {
|
|
description = "message queue system for OpenLab's flipdot display";
|
|
upstream = "https://github.com/openlab-aux/flipdot-gschichtler.git";
|
|
};
|
|
"mirror/nixpkgs" = {
|
|
description = "Nix packages collection";
|
|
upstream = "https://github.com/nixos/nixpkgs.git";
|
|
};
|
|
};
|
|
}
|
|
{
|
|
section = "poc";
|
|
repos = {
|
|
emoji-generic = {
|
|
description = "generic emoji library for Haskell";
|
|
upstream = "https://github.com/sternenseemann/emoji-generic.git";
|
|
};
|
|
grav2ty = {
|
|
description = "“realistic” 2d space game";
|
|
upstream = "https://github.com/sternenseemann/grav2ty.git";
|
|
};
|
|
haskell-dot-time = {
|
|
description = "UTC-centric time library for haskell with dot time support";
|
|
defaultBranch = "main";
|
|
};
|
|
buchstabensuppe = {
|
|
description = "toy font rendering for low pixelcount, high contrast displays";
|
|
defaultBranch = "main";
|
|
upstream = "https://github.com/sternenseemann/buchstabensuppe.git";
|
|
};
|
|
"mirror/saneterm" = {
|
|
description = "modern line-oriented terminal emulator without support for TUIs";
|
|
upstream = "git://git.8pit.net/saneterm.git";
|
|
};
|
|
};
|
|
}
|
|
{
|
|
section = "archive";
|
|
repos = {
|
|
gopher-proxy = {
|
|
description = "Gopher over HTTP proxy";
|
|
upstream = "https://github.com/sternenseemann/gopher-proxy.git";
|
|
};
|
|
likely-music = {
|
|
description = "experimental application for probabilistic music composition";
|
|
upstream = "https://github.com/sternenseemann/likely-music.git";
|
|
};
|
|
logbook = {
|
|
description = "file format for keeping a personal log";
|
|
upstream = "https://github.com/sternenseemann/logbook.git";
|
|
};
|
|
sternenblog = {
|
|
description = "file based cgi blog software";
|
|
upstream = "https://github.com/sternenseemann/sternenblog.git";
|
|
};
|
|
};
|
|
}
|
|
];
|
|
|
|
repoPath = name: repo: repo.path or "/srv/git/${name}.git";
|
|
|
|
cgitRepoEntry = name: repo:
|
|
lib.concatStringsSep "\n" (
|
|
[
|
|
"repo.url=${name}"
|
|
"repo.path=${repoPath name repo}"
|
|
]
|
|
++ lib.optional (repo ? description) "repo.desc=${repo.description}"
|
|
++ lib.optional (repo ? defaultBranch) "repo.defbranch=${repo.defaultBranch}"
|
|
);
|
|
|
|
cgitHead = pkgs.writeText "cgit-head.html" ''
|
|
<style>
|
|
#summary {
|
|
max-width: 80em;
|
|
}
|
|
|
|
#summary * {
|
|
max-width: 100%;
|
|
}
|
|
</style>
|
|
'';
|
|
|
|
cgitConfig = pkgs.writeText "cgitrc" ''
|
|
virtual-root=/
|
|
|
|
enable-http-clone=1
|
|
clone-url=https://${virtualHost}/$CGIT_REPO_URL
|
|
|
|
enable-blame=1
|
|
enable-log-filecount=1
|
|
enable-log-linecount=1
|
|
enable-index-owner=0
|
|
enable-blame=1
|
|
enable-commit-graph=1
|
|
|
|
root-title=code.sterni.lv
|
|
css=/cgit.css
|
|
head-include=${cgitHead}
|
|
|
|
mimetype-file=${pkgs.mime-types}/etc/mime.types
|
|
|
|
about-filter=${depot.tools.cheddar.about-filter}/bin/cheddar-about
|
|
source-filter=${depot.tools.cheddar}/bin/cheddar
|
|
readme=:README.md
|
|
readme=:readme.md
|
|
|
|
section-sort=0
|
|
${
|
|
lib.concatMapStringsSep "\n" (section:
|
|
''
|
|
section=${section.section}
|
|
''
|
|
+ builtins.concatStringsSep "\n\n" (lib.mapAttrsToList cgitRepoEntry section.repos)
|
|
) repoSections
|
|
}
|
|
'';
|
|
|
|
/* Merge a list of attrs, but fail when the same attribute occurs twice.
|
|
|
|
Type: [ attrs ] -> attrs
|
|
*/
|
|
mergeManyDistinctAttrs = lib.foldAttrs
|
|
(
|
|
val: nul:
|
|
if nul == null then val else throw "Every attribute name may occur only once"
|
|
)
|
|
null;
|
|
|
|
flatRepos = mergeManyDistinctAttrs
|
|
(builtins.map (section: section.repos) repoSections);
|
|
|
|
reposToMirror = lib.filterAttrs (_: repo: repo ? upstream) flatRepos;
|
|
|
|
# User and group name used for running the mirror scripts
|
|
mirroredReposOwner = "git";
|
|
|
|
# Make repo name suitable for systemd unit/timer
|
|
unitName = name: "mirror-${lib.strings.sanitizeDerivationName name}";
|
|
in
|
|
|
|
{
|
|
imports = [
|
|
./nginx.nix
|
|
./fcgiwrap.nix
|
|
];
|
|
|
|
config = {
|
|
services.nginx.virtualHosts."${virtualHost}" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
root = "${pkgs.cgit-pink}/cgit/";
|
|
extraConfig = ''
|
|
try_files $uri @cgit;
|
|
|
|
location @cgit {
|
|
include ${pkgs.nginx}/conf/fastcgi_params;
|
|
fastcgi_param SCRIPT_FILENAME ${pkgs.cgit-pink}/cgit/cgit.cgi;
|
|
fastcgi_param PATH_INFO $uri;
|
|
fastcgi_param QUERY_STRING $args;
|
|
fastcgi_param HTTP_HOST $server_name;
|
|
fastcgi_param CGIT_CONFIG ${cgitConfig};
|
|
fastcgi_pass unix:${toString config.services.fcgiwrap.socketAddress};
|
|
}
|
|
'';
|
|
};
|
|
|
|
users = {
|
|
users.${mirroredReposOwner} = {
|
|
group = mirroredReposOwner;
|
|
isSystemUser = true;
|
|
};
|
|
|
|
groups.${mirroredReposOwner} = { };
|
|
};
|
|
|
|
|
|
systemd.timers = lib.mapAttrs'
|
|
(
|
|
name: repo:
|
|
{
|
|
name = unitName name;
|
|
value = {
|
|
description = "regularly update mirror git repository ${name}";
|
|
wantedBy = [ "timers.target" ];
|
|
enable = true;
|
|
timerConfig = {
|
|
# Fire every 6h and distribute the workload over next 6h randomly
|
|
OnCalendar = "*-*-* 00/6:00:00";
|
|
AccuracySec = "6h";
|
|
RandomizedDelaySec = "6h";
|
|
Persistent = true;
|
|
};
|
|
};
|
|
}
|
|
)
|
|
reposToMirror;
|
|
|
|
systemd.services = lib.mapAttrs'
|
|
(
|
|
name: repo:
|
|
{
|
|
name = unitName name;
|
|
value = {
|
|
description = "mirror git repository ${name}";
|
|
after = [ "network.target" ];
|
|
script =
|
|
let
|
|
path = repoPath name repo;
|
|
in
|
|
''
|
|
set -euo pipefail
|
|
|
|
export PATH="${lib.makeBinPath [ pkgs.coreutils pkgs.git ]}"
|
|
|
|
if test ! -d "${path}"; then
|
|
mkdir -p "$(dirname "${path}")"
|
|
git clone --mirror "${repo.upstream}" "${path}"
|
|
exit 0
|
|
fi
|
|
|
|
cd "${path}"
|
|
|
|
git fetch "${repo.upstream}" '+refs/*:refs/*' --prune
|
|
'';
|
|
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
User = mirroredReposOwner;
|
|
Group = mirroredReposOwner;
|
|
};
|
|
};
|
|
}
|
|
)
|
|
reposToMirror;
|
|
};
|
|
}
|