0a6b387738
All repositories under code.sterni.lv are mirrors, so there's no value in AI startups endlessly crawling the nixpkgs git history on code.sterni.lv… Change-Id: Iaac296315f325ced3cfd0852ae1d8d3f3815ea5b Reviewed-on: https://cl.tvl.fyi/c/depot/+/12803 Reviewed-by: sterni <sternenseemann@systemli.org> Autosubmit: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
287 lines
8 KiB
Nix
287 lines
8 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";
|
|
cgit.defbranch = "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";
|
|
cgit.enable-commit-graph = "0"; # too slow
|
|
};
|
|
"mirror/vuizvui" = {
|
|
description = "Nix(OS) expressions used by the OpenLab and its members";
|
|
upstream = "https://github.com/openlab-aux/vuizvui.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";
|
|
cgit.defbranch = "main";
|
|
};
|
|
buchstabensuppe = {
|
|
description = "toy font rendering for low pixelcount, high contrast displays";
|
|
upstream = "https://github.com/sternenseemann/buchstabensuppe.git";
|
|
cgit.defbranch = "main";
|
|
};
|
|
"mirror/saneterm" = {
|
|
description = "modern line-oriented terminal emulator without support for TUIs";
|
|
upstream = "https://git.8pit.net/saneterm.git";
|
|
};
|
|
};
|
|
}
|
|
{
|
|
# TODO(sterni): resisort, klammeraffe, cl-ca, ponify, tinyrl
|
|
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.mapAttrsToList (n: v: "repo.${n}=${v}") repo.cgit or { }
|
|
);
|
|
|
|
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
|
|
|
|
robots=noindex,nofollow
|
|
|
|
root-title=code.sterni.lv
|
|
root-desc=
|
|
css=/cgit.css
|
|
head-include=${cgitHead}
|
|
|
|
mimetype-file=${pkgs.mime-types}/etc/mime.types
|
|
|
|
noplainemail=1
|
|
|
|
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
|
|
];
|
|
|
|
config = {
|
|
services.fcgiwrap.instances.cgit = {
|
|
process = {
|
|
user = "http";
|
|
group = "http";
|
|
};
|
|
socket = {
|
|
user = "http";
|
|
group = "http";
|
|
};
|
|
};
|
|
|
|
services.nginx.virtualHosts."${virtualHost}" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
root = "${pkgs.cgit-pink}/cgit/";
|
|
extraConfig = ''
|
|
try_files $uri @cgit;
|
|
|
|
# Note this overrides the default robots.txt cgit-pink ships
|
|
location = /robots.txt {
|
|
add_header Content-Type text/plain;
|
|
return 200 "User-agent: *\nDisallow: /\n";
|
|
}
|
|
|
|
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.instances.cgit.socket.address};
|
|
}
|
|
'';
|
|
};
|
|
|
|
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";
|
|
RandomizedDelaySec = "6h";
|
|
Persistent = true;
|
|
};
|
|
};
|
|
}
|
|
)
|
|
reposToMirror;
|
|
|
|
systemd.services = lib.mapAttrs'
|
|
(
|
|
name: repo:
|
|
{
|
|
name = unitName name;
|
|
value = {
|
|
description = "mirror git repository ${name}";
|
|
wants = [ "network-online.target" ];
|
|
after = [ "network-online.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
|
|
|
|
# no auto gc here and we're not pruning for nothing…
|
|
git gc
|
|
'';
|
|
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
User = mirroredReposOwner;
|
|
Group = mirroredReposOwner;
|
|
};
|
|
};
|
|
}
|
|
)
|
|
reposToMirror;
|
|
};
|
|
}
|