diff options
author | tv <tv@shackspace.de> | 2015-07-11 19:44:12 +0200 |
---|---|---|
committer | tv <tv@shackspace.de> | 2015-07-11 19:44:12 +0200 |
commit | 2bc5c58d85990e483af8fde57ed5f2442351b69c (patch) | |
tree | 94cd29e6a98f1ce6228104055d0550e318242290 /modules/tv/git | |
parent | c5fcda1390afaba71133b2ee6ac1ddd0f559ef8c (diff) |
move old stuff
Diffstat (limited to 'modules/tv/git')
-rw-r--r-- | modules/tv/git/cgit.nix | 93 | ||||
-rw-r--r-- | modules/tv/git/config.nix | 272 | ||||
-rw-r--r-- | modules/tv/git/default.nix | 27 | ||||
-rw-r--r-- | modules/tv/git/options.nix | 93 | ||||
-rw-r--r-- | modules/tv/git/public.nix | 82 |
5 files changed, 0 insertions, 567 deletions
diff --git a/modules/tv/git/cgit.nix b/modules/tv/git/cgit.nix deleted file mode 100644 index 747a93135..000000000 --- a/modules/tv/git/cgit.nix +++ /dev/null @@ -1,93 +0,0 @@ -{ cfg, config, lib, pkgs, ... }: - -let - inherit (builtins) attrValues filter getAttr; - inherit (lib) concatMapStringsSep mkIf optionalString; - - location = lib.nameValuePair; # TODO this is also in modules/wu/default.nix - - isPublicRepo = getAttr "public"; # TODO this is also in ./default.nix -in - -{ - users.extraUsers = lib.singleton { - name = "fcgiwrap"; - uid = 2851179180; # genid fcgiwrap - group = "fcgiwrap"; - home = toString (pkgs.runCommand "empty" {} "mkdir -p $out"); - }; - - users.extraGroups = lib.singleton { - name = "fcgiwrap"; - gid = 2851179180; # genid fcgiwrap - }; - - services.fcgiwrap = { - enable = true; - user = "fcgiwrap"; - group = "fcgiwrap"; - # socketAddress = "/run/fcgiwrap.sock" (default) - # socketType = "unix" (default) - }; - - environment.etc."cgitrc".text = '' - css=/cgit-static/cgit.css - logo=/cgit-static/cgit.png - - # if you do not want that webcrawler (like google) index your site - robots=noindex, nofollow - - virtual-root=/cgit - - # TODO make this nicer (and/or somewhere else) - cache-root=/tmp/cgit - - cache-size=1000 - enable-commit-graph=1 - enable-index-links=1 - enable-index-owner=0 - enable-log-filecount=1 - enable-log-linecount=1 - enable-remote-branches=1 - - root-title=public repositories at ${config.networking.hostName} - root-desc=keep calm and engage - - snapshots=0 - max-stats=year - - ${concatMapStringsSep "\n" (repo: '' - repo.url=${repo.name} - repo.path=${cfg.dataDir}/${repo.name} - ${optionalString (repo.section != null) "repo.section=${repo.section}"} - ${optionalString (repo.desc != null) "repo.desc=${repo.desc}"} - '') (filter isPublicRepo (attrValues cfg.repos))} - ''; - - system.activationScripts.cgit = '' - mkdir -m 0700 -p /tmp/cgit - chown fcgiwrap: /tmp/cgit - ''; - - tv.nginx = { - enable = true; - retiolum-locations = [ - (location "/cgit/" '' - include ${pkgs.nginx}/conf/fastcgi_params; - fastcgi_param SCRIPT_FILENAME ${pkgs.cgit}/cgit/cgit.cgi; - fastcgi_split_path_info ^(/cgit/?)(.+)$; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param QUERY_STRING $args; - fastcgi_param HTTP_HOST $server_name; - fastcgi_pass unix:${config.services.fcgiwrap.socketAddress}; - '') - (location "= /cgit" '' - return 301 /cgit/; - '') - (location "/cgit-static/" '' - root ${pkgs.cgit}/cgit; - rewrite ^/cgit-static(/.*)$ $1 break; - '') - ]; - }; -} diff --git a/modules/tv/git/config.nix b/modules/tv/git/config.nix deleted file mode 100644 index 4f44c3839..000000000 --- a/modules/tv/git/config.nix +++ /dev/null @@ -1,272 +0,0 @@ -arg@{ cfg, lib, pkgs, ... }: - -let - inherit (builtins) head tail typeOf; - inherit (lib) - attrValues concatStringsSep concatMapStringsSep escapeShellArg filter - getAttr hasAttr hasPrefix lessThan makeSearchPath mapAttrsToList - optional optionalString removePrefix singleton sort unique; - inherit (pkgs) linkFarm writeScript; - - ensureList = x: - if typeOf x == "list" then x else [x]; - - getName = x: x.name; - - isPublicRepo = getAttr "public"; # TODO this is also in ./cgit.nix - - makeAuthorizedKey = git-ssh-command: user@{ name, pubkey }: - # TODO assert name - # TODO assert pubkey - let - options = concatStringsSep "," [ - ''command="exec ${git-ssh-command} ${name}"'' - "no-agent-forwarding" - "no-port-forwarding" - "no-pty" - "no-X11-forwarding" - ]; - in - "${options} ${pubkey}"; - - # [case-pattern] -> shell-script - # Create a shell script that succeeds (exit 0) when all its arguments - # match the case patterns (in the given order). - makeAuthorizeScript = - let - # TODO escape - to-pattern = x: concatStringsSep "|" (ensureList x); - go = i: ps: - if ps == [] - then "exit 0" - else '' - case ''$${toString i} in ${to-pattern (head ps)}) - ${go (i + 1) (tail ps)} - esac''; - in - patterns: '' - #! /bin/sh - set -euf - ${concatStringsSep "\n" (map (go 1) patterns)} - exit -1 - ''; - - reponames = rules: sort lessThan (unique (map (x: x.repo.name) rules)); - - # TODO makeGitHooks that uses runCommand instead of scriptFarm? - scriptFarm = - farm-name: scripts: - let - makeScript = script-name: script-string: { - name = script-name; - path = writeScript "${farm-name}_${script-name}" script-string; - }; - in - linkFarm farm-name (mapAttrsToList makeScript scripts); - - - git-ssh-command = writeScript "git-ssh-command" '' - #! /bin/sh - set -euf - - PATH=${makeSearchPath "bin" (with pkgs; [ - coreutils - git - gnugrep - gnused - systemd - ])} - - abort() { - echo "error: $1" >&2 - systemd-cat -p err -t git echo "error: $1" - exit -1 - } - - GIT_SSH_USER=$1 - - systemd-cat -p info -t git echo \ - "authorizing $GIT_SSH_USER $SSH_CONNECTION $SSH_ORIGINAL_COMMAND" - - # References: The Base Definitions volume of - # POSIX.1‐2013, Section 3.278, Portable Filename Character Set - portable_filename_bre="^[A-Za-z0-9._-]\\+$" - - command=$(echo "$SSH_ORIGINAL_COMMAND" \ - | sed -n 's/^\([^ ]*\) '"'"'\(.*\)'"'"'/\1/p' \ - | grep "$portable_filename_bre" \ - || abort 'cannot read command') - - GIT_SSH_REPO=$(echo "$SSH_ORIGINAL_COMMAND" \ - | sed -n 's/^\([^ ]*\) '"'"'\(.*\)'"'"'/\2/p' \ - | grep "$portable_filename_bre" \ - || abort 'cannot read reponame') - - ${cfg.etcDir}/authorize-command \ - "$GIT_SSH_USER" "$GIT_SSH_REPO" "$command" \ - || abort 'access denied' - - repodir=${escapeShellArg cfg.dataDir}/$GIT_SSH_REPO - - systemd-cat -p info -t git \ - echo "authorized exec $command $repodir" - - export GIT_SSH_USER - export GIT_SSH_REPO - exec "$command" "$repodir" - ''; - - init-script = writeScript "git-init" '' - #! /bin/sh - set -euf - - PATH=${makeSearchPath "bin" (with pkgs; [ - coreutils - findutils - gawk - git - gnugrep - gnused - ])} - - dataDir=${escapeShellArg cfg.dataDir} - mkdir -p "$dataDir" - - # Notice how the presence of hooks symlinks determine whether - # we manage a repositry or not. - - # Make sure that no existing repository has hooks. We can delete - # symlinks because we assume we created them. - find "$dataDir" -mindepth 2 -maxdepth 2 -name hooks -type l -delete - bad_hooks=$(find "$dataDir" -mindepth 2 -maxdepth 2 -name hooks) - if echo "$bad_hooks" | grep -q .; then - printf 'error: unknown hooks:\n%s\n' \ - "$(echo "$bad_hooks" | sed 's/^/ /')" \ - >&2 - exit -1 - fi - - # Initialize repositories. - ${concatMapStringsSep "\n" (repo: - let - hooks = scriptFarm "git-hooks" (makeHooks repo); - in - '' - reponame=${escapeShellArg repo.name} - repodir=$dataDir/$reponame - mode=${toString (if isPublicRepo repo then 0711 else 0700)} - if ! test -d "$repodir"; then - mkdir -m "$mode" "$repodir" - git init --bare --template=/var/empty "$repodir" - chown -R git:nogroup "$repodir" - fi - ln -s ${hooks} "$repodir/hooks" - '' - ) (attrValues cfg.repos)} - - # Warn about repositories that exist but aren't mentioned in the - # current configuration (and thus didn't receive a hooks symlink). - unknown_repos=$(find "$dataDir" -mindepth 1 -maxdepth 1 \ - -type d \! -exec test -e '{}/hooks' \; -print) - if echo "$unknown_repos" | grep -q .; then - printf 'warning: stale repositories:\n%s\n' \ - "$(echo "$unknown_repos" | sed 's/^/ /')" \ - >&2 - fi - ''; - - makeHooks = repo: removeAttrs repo.hooks [ "pre-receive" ] // { - pre-receive = '' - #! /bin/sh - set -euf - - PATH=${makeSearchPath "bin" (with pkgs; [ - coreutils # env - git - systemd - ])} - - accept() { - #systemd-cat -p info -t git echo "authorized $1" - accept_string="''${accept_string+$accept_string - }authorized $1" - } - reject() { - #systemd-cat -p err -t git echo "denied $1" - #echo 'access denied' >&2 - #exit_code=-1 - reject_string="''${reject_string+$reject_string - }access denied: $1" - } - - empty=0000000000000000000000000000000000000000 - - accept_string= - reject_string= - while read oldrev newrev ref; do - - if [ $oldrev = $empty ]; then - receive_mode=create - elif [ $newrev = $empty ]; then - receive_mode=delete - elif [ "$(git merge-base $oldrev $newrev)" = $oldrev ]; then - receive_mode=fast-forward - else - receive_mode=non-fast-forward - fi - - if ${cfg.etcDir}/authorize-push \ - "$GIT_SSH_USER" "$GIT_SSH_REPO" "$ref" "$receive_mode"; then - accept "$receive_mode $ref" - else - reject "$receive_mode $ref" - fi - done - - if [ -n "$reject_string" ]; then - systemd-cat -p err -t git echo "$reject_string" - exit -1 - fi - - systemd-cat -p info -t git echo "$accept_string" - - ${optionalString (hasAttr "post-receive" repo.hooks) '' - # custom post-receive hook - ${repo.hooks.post-receive}''} - ''; - }; - - etc-base = - assert (hasPrefix "/etc/" cfg.etcDir); - removePrefix "/etc/" cfg.etcDir; -in - -{ - system.activationScripts.git-init = "${init-script}"; - - # TODO maybe put all scripts here and then use PATH? - environment.etc."${etc-base}".source = - scriptFarm "git-ssh-authorizers" { - authorize-command = makeAuthorizeScript (map ({ repo, user, perm }: [ - (map getName (ensureList user)) - (map getName (ensureList repo)) - (map getName perm.allow-commands) - ]) cfg.rules); - - authorize-push = makeAuthorizeScript (map ({ repo, user, perm }: [ - (map getName (ensureList user)) - (map getName (ensureList repo)) - (ensureList perm.allow-receive-ref) - (map getName perm.allow-receive-modes) - ]) (filter (x: hasAttr "allow-receive-ref" x.perm) cfg.rules)); - }; - - users.extraUsers = singleton { - description = "Git repository hosting user"; - name = "git"; - shell = "/bin/sh"; - openssh.authorizedKeys.keys = - mapAttrsToList (_: makeAuthorizedKey git-ssh-command) cfg.users; - uid = 112606723; # genid git - }; -} diff --git a/modules/tv/git/default.nix b/modules/tv/git/default.nix deleted file mode 100644 index 17bc3738b..000000000 --- a/modules/tv/git/default.nix +++ /dev/null @@ -1,27 +0,0 @@ -arg@{ config, pkgs, lib, ... }: - -let - inherit (lib) mkIf mkMerge; - - cfg = config.tv.git; - arg' = arg // { inherit cfg; }; -in - -# TODO unify logging of shell scripts to user and journal -# TODO move all scripts to ${etcDir}, so ControlMaster connections -# immediately pick up new authenticators -# TODO when authorized_keys changes, then restart ssh -# (or kill already connected users somehow) - -{ - imports = [ - ../../tv/nginx - ]; - - options.tv.git = import ./options.nix arg'; - - config = mkIf cfg.enable (mkMerge [ - (import ./config.nix arg') - (mkIf cfg.cgit (import ./cgit.nix arg')) - ]); -} diff --git a/modules/tv/git/options.nix b/modules/tv/git/options.nix deleted file mode 100644 index c251d7d4c..000000000 --- a/modules/tv/git/options.nix +++ /dev/null @@ -1,93 +0,0 @@ -{ lib, ... }: - -let - inherit (lib) literalExample mkOption types; -in - -{ - enable = mkOption { - type = types.bool; - default = false; - description = "Enable Git repository hosting."; - }; - cgit = mkOption { - type = types.bool; - default = true; - description = "Enable cgit."; # TODO better desc; talk about nginx - }; - dataDir = mkOption { - type = types.str; - default = "/var/lib/git"; - description = "Directory used to store repositories."; - }; - etcDir = mkOption { - type = types.str; - default = "/etc/git"; - }; - rules = mkOption { - type = types.unspecified; - }; - repos = mkOption { - type = types.attrsOf (types.submodule ({ - options = { - desc = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Repository description. - ''; - }; - section = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Repository section. - ''; - }; - name = mkOption { - type = types.str; - description = '' - Repository name. - ''; - }; - hooks = mkOption { - type = types.attrsOf types.str; - description = '' - Repository-specific hooks. - ''; - }; - public = mkOption { - type = types.bool; - default = false; - description = '' - Allow everybody to read the repository via HTTP if cgit enabled. - ''; - # TODO allow every configured user to fetch the repository via SSH. - }; - }; - })); - - default = {}; - - example = literalExample '' - { - testing = { - name = "testing"; - hooks.post-update = ''' - #! /bin/sh - set -euf - echo post-update hook: $* >&2 - '''; - }; - testing2 = { name = "testing2"; }; - } - ''; - - description = '' - Repositories. - ''; - }; - users = mkOption { - type = types.unspecified; - }; -} diff --git a/modules/tv/git/public.nix b/modules/tv/git/public.nix deleted file mode 100644 index de6ed7fdf..000000000 --- a/modules/tv/git/public.nix +++ /dev/null @@ -1,82 +0,0 @@ -{ config, lib, pkgs, ... }: - -let - inherit (builtins) map readFile; - inherit (lib) concatMap listToAttrs; - # TODO lib should already include our stuff - inherit (import ../../../lib { inherit lib pkgs; }) addNames git; - - public-git-repos = [ - (public "cgserver") - (public "crude-mail-setup") - (public "dot-xmonad") - (public "hack") - (public "load-env") - (public "make-snapshot") - (public "mime") - (public "much") - (public "nixos-infest") - (public "nixpkgs") - (public "painload") - (public "regfish") - (public' { - name = "shitment"; - desc = "turn all the computers into one computer!"; - }) - (public "wai-middleware-time") - (public "web-routes-wai-custom") - ]; - - users = addNames { - tv = { pubkey = readFile <pubkeys/tv_wu.ssh.pub>; }; - lass = { pubkey = readFile <pubkeys/lass.ssh.pub>; }; - uriel = { pubkey = readFile <pubkeys/uriel.ssh.pub>; }; - makefu = { pubkey = readFile <pubkeys/makefu.ssh.pub>; }; - }; - - repos = listToAttrs (map ({ repo, ... }: { name = repo.name; value = repo; }) public-git-repos); - - rules = concatMap ({ rules, ... }: rules) public-git-repos; - - public' = { name, desc }: - let - x = public name; - in - x // { repo = x.repo // { inherit desc; }; }; - - public = repo-name: - rec { - repo = { - name = repo-name; - hooks = { - post-receive = git.irc-announce { - nick = config.networking.hostName; # TODO make this the default - channel = "#retiolum"; - server = "ire.retiolum"; - }; - }; - public = true; - }; - rules = with git; with users; [ - { user = tv; - repo = [ repo ]; - perm = push "refs/*" [ non-fast-forward create delete merge ]; - } - { user = [ lass makefu uriel ]; - repo = [ repo ]; - perm = fetch; - } - ]; - }; - -in - -{ - imports = [ - ./. - ]; - tv.git = { - enable = true; - inherit repos rules users; - }; -} |