feat(git-serving): Configure josh to serve the depot over HTTP

Previously we served the dumb git HTTP protocol from code.tvl.fyi via
cgit. This CL disables this feature and instead runs josh in the same
location (by redirecting appropriately), but while also enabling
partial cloning of all subtrees of the depot.

For example, after this CL the following would result in an
independent clone of //nix/readTree:

    git clone https://code.tvl.fyi/depot.git:/nix/readTree.git

Note that there are no josh workspaces configured at all for now,
these references are only for static depot subpaths.

Please refer to the documentation for josh for more information on
available kinds of josh filters.

Josh state is kept in a systemd state directory in /var/lib/josh and
backed up to Restic. Backing this up is necessary, as josh uses
stateful information to do things like tracking merges and rewriting
history per subtree appropriately to avoid cloned repositories ending
up in peculiar states.

Change-Id: I156f0298c2aa42e3bdbf5a0e86109070d640c56e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/3563
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
This commit is contained in:
Vincent Ambo 2021-09-16 18:46:17 +03:00 committed by tazjin
parent f35afb0e4a
commit ec38839c33
4 changed files with 73 additions and 17 deletions

View file

@ -9,6 +9,7 @@ in {
"${depot.path}/ops/modules/atward.nix" "${depot.path}/ops/modules/atward.nix"
"${depot.path}/ops/modules/automatic-gc.nix" "${depot.path}/ops/modules/automatic-gc.nix"
"${depot.path}/ops/modules/clbot.nix" "${depot.path}/ops/modules/clbot.nix"
"${depot.path}/ops/modules/git-serving.nix"
"${depot.path}/ops/modules/irccat.nix" "${depot.path}/ops/modules/irccat.nix"
"${depot.path}/ops/modules/monorepo-gerrit.nix" "${depot.path}/ops/modules/monorepo-gerrit.nix"
"${depot.path}/ops/modules/nixery.nix" "${depot.path}/ops/modules/nixery.nix"
@ -26,8 +27,8 @@ in {
"${depot.path}/ops/modules/www/cl.tvl.fyi.nix" "${depot.path}/ops/modules/www/cl.tvl.fyi.nix"
"${depot.path}/ops/modules/www/code.tvl.fyi.nix" "${depot.path}/ops/modules/www/code.tvl.fyi.nix"
"${depot.path}/ops/modules/www/cs.tvl.fyi.nix" "${depot.path}/ops/modules/www/cs.tvl.fyi.nix"
"${depot.path}/ops/modules/www/images.tvl.fyi.nix"
"${depot.path}/ops/modules/www/deploys.tvl.fyi.nix" "${depot.path}/ops/modules/www/deploys.tvl.fyi.nix"
"${depot.path}/ops/modules/www/images.tvl.fyi.nix"
"${depot.path}/ops/modules/www/login.tvl.fyi.nix" "${depot.path}/ops/modules/www/login.tvl.fyi.nix"
"${depot.path}/ops/modules/www/nixery.dev.nix" "${depot.path}/ops/modules/www/nixery.dev.nix"
"${depot.path}/ops/modules/www/status.tvl.su.nix" "${depot.path}/ops/modules/www/status.tvl.su.nix"
@ -320,6 +321,9 @@ in {
# Run a Nixery instance # Run a Nixery instance
nixery.enable = true; nixery.enable = true;
# Run cgit & josh to serve git
git-serving.enable = true;
}; };
services.postgresql = { services.postgresql = {
@ -382,22 +386,10 @@ in {
zfstools zfstools
]; ];
# Run cgit for the depot. The onion here is nginx(thttpd(cgit)).
systemd.services.cgit = {
wantedBy = [ "multi-user.target" ];
script = "${depot.web.cgit-taz}/bin/cgit-launch";
serviceConfig = {
Restart = "on-failure";
User = "git";
Group = "git";
};
};
# Regularly back up whitby to Google Cloud Storage. # Regularly back up whitby to Google Cloud Storage.
systemd.services.restic = { systemd.services.restic = {
description = "Backups to Google Cloud Storage"; description = "Backups to Google Cloud Storage";
script = "${pkgs.restic}/bin/restic backup /var/lib/gerrit /var/backup/postgresql /var/lib/grafana /var/lib/znc /var/html/deploys.tvl.fyi"; script = "${pkgs.restic}/bin/restic backup /var/lib/gerrit /var/backup/postgresql /var/lib/grafana /var/lib/znc /var/html/deploys.tvl.fyi /var/lib/josh";
environment = { environment = {
GOOGLE_PROJECT_ID = "tazjins-infrastructure"; GOOGLE_PROJECT_ID = "tazjins-infrastructure";

View file

@ -0,0 +1,54 @@
# Configures public git-serving infrastructure for TVL, this involves:
#
# 1. cgit (running at code.tvl.fyi) for web views of the repository
# 2. josh (for cloning the repository and its distinct subtrees)
#
# We also run Sourcegraph for browsing the repository, but this is
# currently configured in a separate module
# (//ops/modules/sourcegraph.nix)
#
# TODO(tazjin): Move //web/cgit-taz configuration in here instead.
{ config, depot, lib, pkgs, ... }:
let
cfg = config.services.depot.git-serving;
in {
options.services.depot.git-serving = with lib; {
enable = mkEnableOption "Enable cgit & josh configuration";
joshPort = mkOption {
description = "Port on which josh should listen";
type = types.int;
default = 5674;
};
};
config = lib.mkIf cfg.enable {
# Run cgit for the depot. The onion here is nginx(thttpd(cgit)).
systemd.services.cgit = {
wantedBy = [ "multi-user.target" ];
script = "${depot.web.cgit-taz}/bin/cgit-launch";
serviceConfig = {
Restart = "on-failure";
User = "git";
Group = "git";
};
};
# Run josh for the depot.
systemd.services.josh = {
description = "josh - partial cloning of monorepos";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.git pkgs.bash ];
serviceConfig = {
DynamicUser = true;
StateDirectory = "josh";
Restart = "always";
ExecStart = "${depot.third_party.josh}/bin/josh-proxy --no-background --local /var/lib/josh --port ${toString cfg.joshPort} --remote https://cl.tvl.fyi/";
};
};
};
}

View file

@ -1,4 +1,4 @@
{ depot, ... }: { depot, config, ... }:
{ {
imports = [ imports = [
@ -20,12 +20,22 @@
alias ${depot.tvix.docs.svg}/component-flow.svg; alias ${depot.tvix.docs.svg}/component-flow.svg;
} }
# Git operations on depot.git hit josh
location /depot.git {
proxy_pass http://localhost:${toString config.services.depot.git-serving.joshPort};
}
# Git clone operations on '/' should be redirected to josh now.
location = /info/refs {
return 302 https://code.tvl.fyi/depot.git/info/refs$is_args$args;
}
# Static assets must always hit the root. # Static assets must always hit the root.
location ~ ^/(favicon\.ico|cgit\.(css|png))$ { location ~ ^/(favicon\.ico|cgit\.(css|png))$ {
proxy_pass http://localhost:2448; proxy_pass http://localhost:2448;
} }
# Everything else hits the depot directly. # Everything else is forwarded to cgit for the web view
location / { location / {
proxy_pass http://localhost:2448/cgit.cgi/depot/; proxy_pass http://localhost:2448/cgit.cgi/depot/;
} }

View file

@ -32,7 +32,7 @@ let
repo.path=/var/lib/gerrit/git/depot.git/ repo.path=/var/lib/gerrit/git/depot.git/
repo.desc=monorepo for the virus lounge repo.desc=monorepo for the virus lounge
repo.owner=The Virus Lounge repo.owner=The Virus Lounge
repo.clone-url=https://code.tvl.fyi repo.clone-url=https://code.tvl.fyi/depot.git
''; '';
thttpdConfig = writeText "thttpd.conf" '' thttpdConfig = writeText "thttpd.conf" ''