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