init git-daemon module
This commit is contained in:
@@ -200,6 +200,54 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
git-daemon = {
|
||||||
|
module = {
|
||||||
|
name = "git-daemon";
|
||||||
|
input = "self";
|
||||||
|
};
|
||||||
|
roles.default.machines.neptune = {
|
||||||
|
settings.repositories =
|
||||||
|
let
|
||||||
|
defaults = rec {
|
||||||
|
write-access = [
|
||||||
|
"10.0.0.0/24"
|
||||||
|
"200:d7b1:c5d5:ea7:27ad:6837:40f6:404d/128"
|
||||||
|
];
|
||||||
|
read-access = write-access;
|
||||||
|
};
|
||||||
|
PUBLIC = {
|
||||||
|
read-access = [
|
||||||
|
"10.0.0.0/24"
|
||||||
|
"0200::/7"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
builtins.mapAttrs (_: override: defaults // override) {
|
||||||
|
"9e" = PUBLIC;
|
||||||
|
archive-dl = { };
|
||||||
|
barrytown = { };
|
||||||
|
cleanroom = PUBLIC;
|
||||||
|
community-memory = { };
|
||||||
|
eris = { };
|
||||||
|
ftdi-sd-spi = { };
|
||||||
|
go-go-gadget = { };
|
||||||
|
hacking-the-kindle = { };
|
||||||
|
islands = { };
|
||||||
|
kt = { };
|
||||||
|
legba = { };
|
||||||
|
llb = PUBLIC;
|
||||||
|
llc = PUBLIC;
|
||||||
|
lora = { };
|
||||||
|
mute = { };
|
||||||
|
navi = { };
|
||||||
|
notmuch-memoryhole = PUBLIC;
|
||||||
|
pms5003 = { };
|
||||||
|
thinc = { };
|
||||||
|
toad = { };
|
||||||
|
yggdrasil-erlang = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
172
modules/clan/git-daemon/default.nix
Normal file
172
modules/clan/git-daemon/default.nix
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
_class = "clan.service";
|
||||||
|
manifest.name = "git-daemon";
|
||||||
|
manifest.description = "a really simple server for git repositories";
|
||||||
|
manifest.categories = [ "System" ];
|
||||||
|
|
||||||
|
roles.default = {
|
||||||
|
interface =
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
options = with lib; {
|
||||||
|
directory = lib.mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/var/git";
|
||||||
|
};
|
||||||
|
repositories = lib.mkOption {
|
||||||
|
type =
|
||||||
|
with lib.types;
|
||||||
|
attrsOf (
|
||||||
|
submodule (
|
||||||
|
{ name, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
name = lib.mkOption {
|
||||||
|
type = str;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
read-access = lib.mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
write-access = lib.mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
perInstance =
|
||||||
|
{
|
||||||
|
settings,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
nixosModule =
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
systemd.services.git-init = {
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = config.services.gitDaemon.user;
|
||||||
|
Group = config.services.gitDaemon.group;
|
||||||
|
ExecStartPre = toString [
|
||||||
|
"+${pkgs.coreutils}/bin/install"
|
||||||
|
"--directory"
|
||||||
|
"--owner=${config.services.gitDaemon.user}"
|
||||||
|
"--group=${config.services.gitDaemon.group}"
|
||||||
|
"--mode=0750"
|
||||||
|
settings.directory
|
||||||
|
];
|
||||||
|
ExecStart =
|
||||||
|
let
|
||||||
|
git-template = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "git-template";
|
||||||
|
buildCommand = ''
|
||||||
|
cp --no-preserve=mode,ownership --recursive \
|
||||||
|
${pkgs.git}/share/git-core/templates $out
|
||||||
|
install -m550 $out/hooks/post-update{.sample,}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
init-script =
|
||||||
|
{ name, ... }:
|
||||||
|
pkgs.writeShellScript "git-init-${name}" ''
|
||||||
|
${pkgs.git}/bin/git init \
|
||||||
|
--bare --template=${git-template} --shared=0660 \
|
||||||
|
${settings.directory}/${name}.git
|
||||||
|
${pkgs.git}/bin/git \
|
||||||
|
-C ${settings.directory}/${name}.git \
|
||||||
|
config set receive.denyNonFastforwards false
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
map init-script (lib.attrValues settings.repositories);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.gitDaemon = {
|
||||||
|
enable = true;
|
||||||
|
user = "git";
|
||||||
|
group = "git";
|
||||||
|
options =
|
||||||
|
let
|
||||||
|
firewall = pkgs.writeText "git-daemon-firewall.json" (
|
||||||
|
builtins.toJSON (builtins.attrValues settings.repositories)
|
||||||
|
);
|
||||||
|
hook = pkgs.writers.writePython3 "hook.py" { flakeIgnore = [ "E" ]; } ''
|
||||||
|
import os, sys, enum, pathlib, ipaddress, json
|
||||||
|
|
||||||
|
class Service(enum.Enum):
|
||||||
|
UploadPack = enum.auto()
|
||||||
|
ReceivePack = enum.auto()
|
||||||
|
UploadArchive = enum.auto()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def parse(cls, string):
|
||||||
|
return {
|
||||||
|
'upload-pack': cls.UploadPack,
|
||||||
|
'receive-pack': cls.ReceivePack,
|
||||||
|
'upload-archive': cls.UploadArchive
|
||||||
|
}[string]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def service(self):
|
||||||
|
return {
|
||||||
|
UploadPack: 'read-access',
|
||||||
|
ReceivePack: 'write-access'
|
||||||
|
}[self]
|
||||||
|
UploadPack = Service.UploadPack
|
||||||
|
ReceivePack = Service.ReceivePack
|
||||||
|
|
||||||
|
def parse_remote_addr(remote_addr):
|
||||||
|
if remote_addr.startswith('[') and remote_addr.endswith(']'):
|
||||||
|
return ipaddress.ip_address(remote_addr[1:-1])
|
||||||
|
return ipaddress.ip_address(remote_addr)
|
||||||
|
|
||||||
|
service = Service.parse(sys.argv[1])
|
||||||
|
repo = pathlib.Path(sys.argv[2]).stem
|
||||||
|
client = parse_remote_addr(os.environ['REMOTE_ADDR'])
|
||||||
|
|
||||||
|
with open("${firewall}", 'r') as f:
|
||||||
|
firewall = json.load(f)
|
||||||
|
|
||||||
|
for rule in firewall:
|
||||||
|
if rule["name"] == repo:
|
||||||
|
for network in rule[service.service]:
|
||||||
|
if client in ipaddress.ip_network(network):
|
||||||
|
sys.exit(0)
|
||||||
|
print('stairway denied')
|
||||||
|
sys.exit(1)
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
toString [
|
||||||
|
"--enable=upload-pack"
|
||||||
|
"--enable=receive-pack"
|
||||||
|
"--disable=upload-archive"
|
||||||
|
"--access-hook=${hook}"
|
||||||
|
"--informative-errors"
|
||||||
|
];
|
||||||
|
exportAll = true;
|
||||||
|
basePath = settings.directory;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.git-daemon = {
|
||||||
|
requires = [ "git-init.service" ];
|
||||||
|
after = [ "git-init.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 9418 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
9
modules/clan/git-daemon/flake-module.nix
Normal file
9
modules/clan/git-daemon/flake-module.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
module = lib.modules.importApply ./default.nix { };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
clan.modules = {
|
||||||
|
git-daemon = module;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user