aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCullum Smith <cullum@sacredheartsc.com>2024-11-12 23:50:18 -0500
committerCullum Smith <cullum@sacredheartsc.com>2024-11-12 23:50:18 -0500
commit5aa2283f9951b3e035824b54bd0277ebf4394ffa (patch)
treedf93cef70ce1d49576b9a98f165e8dfc6aaa52f7
parent6512242bc03acf2bdaa4fea6fcc7fe51c2330f03 (diff)
downloadinfrastructure-5aa2283f9951b3e035824b54bd0277ebf4394ffa.tar.gz
add gitolite/cgit
-rw-r--r--.gitignore1
-rw-r--r--files/etc/login.access.freebsd2
-rw-r--r--files/usr/local/etc/cgitrc.git_server66
-rw-r--r--files/usr/local/etc/nginx/fastcgi_params.git_server32
-rw-r--r--files/usr/local/etc/nginx/vhosts.conf.git_server49
-rw-r--r--files/usr/local/etc/ssh/sshd_config.d/gitolite.conf.git_server12
-rw-r--r--files/usr/local/etc/sudoers.d/acme.git_server1
-rw-r--r--files/usr/local/git/.gitolite.rc.git_server28
-rw-r--r--files/usr/local/git/.gitolite/conf/gitolite.conf.git_server11
-rw-r--r--files/usr/local/lib/cgit/filters/syntax-highlighting-custom.py.git_server34
-rw-r--r--files/usr/local/libexec/gitolite-authorizedkeys.git_server52
-rw-r--r--files/usr/local/libexec/gitolite-grouplist.git_server51
-rw-r--r--files/usr/local/www/cgit/custom-favicon.ico.git_serverbin0 -> 1078 bytes
-rw-r--r--files/usr/local/www/cgit/custom-head-include.html.git_server0
-rw-r--r--files/usr/local/www/cgit/custom-header.html.git_server0
-rw-r--r--files/usr/local/www/cgit/custom-logo.png.git_serverbin0 -> 1366 bytes
-rw-r--r--files/usr/local/www/cgit/custom-robots.txt.git_server3
-rw-r--r--files/usr/local/www/cgit/custom-style.css.git_server895
-rw-r--r--scripts/hostclass/git_server163
m---------site0
-rw-r--r--vars/hostclass/git_server7
-rw-r--r--vars/hostname/git14
22 files changed, 1410 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index eac3be3..2c49e71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,3 @@
*.swp
*.swo
.nfs*
-site
diff --git a/files/etc/login.access.freebsd b/files/etc/login.access.freebsd
index ee83dd5..7b125db 100644
--- a/files/etc/login.access.freebsd
+++ b/files/etc/login.access.freebsd
@@ -1,5 +1,7 @@
# Always allow root logins.
+:root:ALL
+
+# Allow icinga user for monitoring via SSH.
+:${icinga_local_user}:ALL
$(if [ -n "${acmeproxy_client_group:-}" ]; then
diff --git a/files/usr/local/etc/cgitrc.git_server b/files/usr/local/etc/cgitrc.git_server
new file mode 100644
index 0000000..5cebd6c
--- /dev/null
+++ b/files/usr/local/etc/cgitrc.git_server
@@ -0,0 +1,66 @@
+clone-prefix=${cgit_clone_urls}
+enable-http-clone=0
+enable-blame=1
+enable-commit-graph=1
+enable-log-filecount=1
+enable-log-linecount=1
+branch-sort=name
+
+max-stats=none
+root-title=${cgit_root_title}
+root-desc=${cgit_root_desc}
+remove-suffix=1
+repository-sort=name
+snapshots=tar.gz
+local-time=1
+robots=index, nofollow
+
+cache-root=${cgit_cache_dir}
+cache-size=${cgit_cache_size}
+
+source-filter=/usr/local/lib/cgit/filters/syntax-highlighting-custom.py
+about-filter=/usr/local/lib/cgit/filters/about-formatting.sh
+
+favicon=/custom-favicon.ico
+logo=/custom-logo.png
+css=/custom-style.css
+robots=/custom-robots.txt
+head-include=${cgit_webroot}/custom-head-include.html
+header=${cgit_webroot}/custom-header.html
+
+mimetype.gif=image/gif
+mimetype.html=text/html
+mimetype.jpg=image/jpeg
+mimetype.jpeg=image/jpeg
+mimetype.pdf=application/pdf
+mimetype.png=image/png
+mimetype.svg=image/svg+xml
+
+readme=:README.md
+readme=:readme.md
+readme=:README.mkd
+readme=:readme.mkd
+readme=:README.html
+readme=:readme.html
+readme=:README.htm
+readme=:readme.htm
+readme=:README.txt
+readme=:readme.txt
+readme=:README
+readme=:readme
+readme=:INSTALL.md
+readme=:install.md
+readme=:INSTALL.mkd
+readme=:install.mkd
+readme=:INSTALL.html
+readme=:install.html
+readme=:INSTALL.htm
+readme=:install.htm
+readme=:INSTALL.txt
+readme=:install.txt
+readme=:INSTALL
+readme=:install
+
+enable-git-config=1
+project-list=${gitolite_home}/projects.list
+scan-path=${gitolite_home}/repositories
diff --git a/files/usr/local/etc/nginx/fastcgi_params.git_server b/files/usr/local/etc/nginx/fastcgi_params.git_server
new file mode 100644
index 0000000..49201e8
--- /dev/null
+++ b/files/usr/local/etc/nginx/fastcgi_params.git_server
@@ -0,0 +1,32 @@
+fastcgi_param QUERY_STRING $query_string;
+fastcgi_param REQUEST_METHOD $request_method;
+fastcgi_param CONTENT_TYPE $content_type;
+fastcgi_param CONTENT_LENGTH $content_length;
+
+# Intentionally omitted here for cgit:
+# SCRIPT_FILENAM0E
+# SCRIPT_NAME
+# PATH_INFO
+# PATH_TRANSLATED
+fastcgi_param REQUEST_URI $request_uri;
+fastcgi_param DOCUMENT_URI $document_uri;
+fastcgi_param DOCUMENT_ROOT $document_root;
+fastcgi_param SERVER_PROTOCOL $server_protocol;
+fastcgi_param REQUEST_SCHEME $scheme;
+fastcgi_param HTTPS $https if_not_empty;
+
+fastcgi_param GATEWAY_INTERFACE CGI/1.1;
+fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
+
+fastcgi_param REMOTE_ADDR $remote_addr;
+fastcgi_param REMOTE_PORT $remote_port;
+fastcgi_param SERVER_ADDR $server_addr;
+fastcgi_param SERVER_PORT $server_port;
+fastcgi_param SERVER_NAME $host;
+fastcgi_param REMOTE_USER $remote_user if_not_empty;
+
+# PHP only, required if PHP was built with --enable-force-cgi-redirect
+fastcgi_param REDIRECT_STATUS 200;
+
+# Protect against HTTPoxy vuln
+fastcgi_param HTTP_PROXY "";
diff --git a/files/usr/local/etc/nginx/vhosts.conf.git_server b/files/usr/local/etc/nginx/vhosts.conf.git_server
new file mode 100644
index 0000000..fdd5f53
--- /dev/null
+++ b/files/usr/local/etc/nginx/vhosts.conf.git_server
@@ -0,0 +1,49 @@
+server {
+ listen 443 ssl default_server;
+ listen [::]:443 ssl default_server;
+ http2 on;
+
+$(if [ "$git_public_fqdn" != "$fqdn" ]; then
+ cat <<EOF
+ ssl_certificate ${acme_cert_dir}/nginx.crt;
+ ssl_certificate_key ${acme_cert_dir}/nginx.key;
+ ssl_trusted_certificate ${acme_cert_dir}/nginx.ca.crt;
+EOF
+ else
+ cat <<EOF
+ ssl_certificate ${git_https_cert};
+ ssl_certificate_key ${git_https_key};
+EOF
+fi)
+
+ auth_gss_keytab ${git_keytab};
+ auth_gss_allow_basic_fallback ${git_basic_auth};
+
+ add_header Strict-Transport-Security "max-age=63072000" always;
+
+ root ${cgit_webroot};
+ try_files \$uri @cgit;
+
+ location ~ '^.+/(HEAD|info/refs|objects/(info/[^/]+|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))|git-(upload|receive)-pack)$' {
+ auth_gss on;
+ satisfy any;
+$(printf ' deny %s;\n' $kerberized_cidrs)
+ allow all;
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME /usr/local/libexec/gitolite/gitolite-shell;
+ fastcgi_param PATH_INFO \$uri;
+ fastcgi_param GIT_HTTP_EXPORT_ALL '';
+ fastcgi_param GIT_PROJECT_ROOT ${gitolite_home}/repositories;
+ fastcgi_param GITOLITE_HTTP_HOME ${gitolite_home};
+ fastcgi_param PATH /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin;
+ fastcgi_pass unix:${gitolite_fcgiwrap_socket};
+ }
+
+ location @cgit {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME ${cgit_webroot}/cgit.cgi;
+ fastcgi_param SCRIPT_NAME '';
+ fastcgi_param PATH_INFO \$uri;
+ fastcgi_pass unix:${cgit_fcgiwrap_socket};
+ }
+}
diff --git a/files/usr/local/etc/ssh/sshd_config.d/gitolite.conf.git_server b/files/usr/local/etc/ssh/sshd_config.d/gitolite.conf.git_server
new file mode 100644
index 0000000..33b9282
--- /dev/null
+++ b/files/usr/local/etc/ssh/sshd_config.d/gitolite.conf.git_server
@@ -0,0 +1,12 @@
+Match User ${gitolite_local_user}
+ GSSAPIAuthentication no
+ KbdInteractiveAuthentication no
+ PasswordAuthentication no
+ PubkeyAuthentication yes
+ AuthenticationMethods publickey
+ AuthorizedKeysFile none
+ AuthorizedKeysCommand /usr/local/libexec/gitolite-authorizedkeys ${gitolite_admin_role} ${gitolite_access_role}
+ AuthorizedKeysCommandUser ${gitolite_local_user}
+ DisableForwarding yes
+ PermitUserRC no
+ PermitTTY no
diff --git a/files/usr/local/etc/sudoers.d/acme.git_server b/files/usr/local/etc/sudoers.d/acme.git_server
new file mode 100644
index 0000000..9ca89b8
--- /dev/null
+++ b/files/usr/local/etc/sudoers.d/acme.git_server
@@ -0,0 +1 @@
+${acme_user} ALL=(root) NOPASSWD: /usr/sbin/service nginx reload
diff --git a/files/usr/local/git/.gitolite.rc.git_server b/files/usr/local/git/.gitolite.rc.git_server
new file mode 100644
index 0000000..9e86021
--- /dev/null
+++ b/files/usr/local/git/.gitolite.rc.git_server
@@ -0,0 +1,28 @@
+%RC = (
+ UMASK => 0027,
+ GIT_CONFIG_KEYS => '.*',
+ LOG_DEST => 'syslog',
+ LOG_FACILITY => 'daemon',
+ ROLES => {
+ READERS => 1,
+ WRITERS => 1,
+ },
+ ENABLE => [
+ 'help',
+ 'desc',
+ 'info',
+ 'perms',
+ 'writable',
+ 'fork',
+ 'D',
+ 'git-config',
+ 'gitweb',
+ 'set-default-roles',
+ 'upstream',
+ 'cgit',
+ ],
+ GROUPLIST_PGM => '/usr/local/libexec/gitolite-grouplist',
+ HTTP_ANON_USER => 'nobody',
+);
+
+1;
diff --git a/files/usr/local/git/.gitolite/conf/gitolite.conf.git_server b/files/usr/local/git/.gitolite/conf/gitolite.conf.git_server
new file mode 100644
index 0000000..c51d21a
--- /dev/null
+++ b/files/usr/local/git/.gitolite/conf/gitolite.conf.git_server
@@ -0,0 +1,11 @@
+repo gitolite-admin
+ RW+ = @${gitolite_admin_role}
+
+repo CREATOR/[A-Za-z0-9/_-]+
+ C = @${gitolite_admin_role} @${gitolite_access_role}
+ RW+ = CREATOR
+ RW = WRITERS
+ R = READERS
+ option default.roles-1 = READERS @all
+ config gitweb.owner = %GL_CREATOR
+ config gitweb.category = user repositories
diff --git a/files/usr/local/lib/cgit/filters/syntax-highlighting-custom.py.git_server b/files/usr/local/lib/cgit/filters/syntax-highlighting-custom.py.git_server
new file mode 100644
index 0000000..1d71275
--- /dev/null
+++ b/files/usr/local/lib/cgit/filters/syntax-highlighting-custom.py.git_server
@@ -0,0 +1,34 @@
+#!/usr/local/bin/python
+
+import sys
+import io
+from pygments import highlight
+from pygments.util import ClassNotFound
+from pygments.lexers import TextLexer
+from pygments.lexers import guess_lexer
+from pygments.lexers import guess_lexer_for_filename
+from pygments.formatters import HtmlFormatter
+
+sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8', errors='replace')
+sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
+data = sys.stdin.read()
+filename = sys.argv[1]
+formatter = HtmlFormatter(style='${cgit_pygments_style}', nobackground=True)
+
+try:
+ lexer = guess_lexer_for_filename(filename, data)
+except ClassNotFound:
+ # check if there is any shebang
+ if data[0:2] == '#!':
+ lexer = guess_lexer(data)
+ else:
+ lexer = TextLexer()
+except TypeError:
+ lexer = TextLexer()
+
+# highlight! :-)
+# printout pygments' css definitions as well
+sys.stdout.write('<style>')
+sys.stdout.write(formatter.get_style_defs('.highlight'))
+sys.stdout.write('</style>')
+sys.stdout.write(highlight(data, lexer, formatter, outfile=None))
diff --git a/files/usr/local/libexec/gitolite-authorizedkeys.git_server b/files/usr/local/libexec/gitolite-authorizedkeys.git_server
new file mode 100644
index 0000000..a1b2cfe
--- /dev/null
+++ b/files/usr/local/libexec/gitolite-authorizedkeys.git_server
@@ -0,0 +1,52 @@
+#!/usr/local/bin/perl
+
+use strict;
+use warnings;
+
+use Net::LDAP;
+use Net::LDAP::Util qw(ldap_explode_dn escape_filter_value);
+use Authen::SASL;
+
+open my $fh, '<', '/usr/local/etc/openldap/ldap.conf' or die($!);
+my %config;
+while (<$fh>) {
+ chomp;
+ next if /^#/;
+ my @pair = split(' ', $_, 2);
+ next unless (@pair == 2);
+ $config{$pair[0]} = $pair[1];
+}
+close($fh);
+
+my $mech = $config{SASL_MECH} // 'GSSAPI';
+my $uri = $config{URI} // die("URI not specified\n");
+my $user_basedn = $config{USERS_BASE} // die("USERS_BASE not specified\n");
+my $group_basedn = $config{GROUPS_BASE} // die("GROUPS_BASE not specified\n");
+my $role_basedn = $config{ROLES_BASE} // die("ROLES_BASE not specified\n");
+
+my $GITOLITE_SHELL = '/usr/local/libexec/gitolite/gitolite-shell';
+
+my $conn = Net::LDAP->new($uri, version => '3') or die "$0: $@";
+my $sasl = Authen::SASL->new($mech);
+my $status = $conn->bind(sasl => $sasl);
+$status->code and die "$0: ".$status->error;
+
+my $filter = '(sshPublicKey=*)';
+if (@ARGV) {
+ $filter = '(&(sshPublicKey=*)(|('.join(')(', map { 'memberOf=cn='.escape_filter_value($_).",$role_basedn" } @ARGV).')))';
+}
+
+my $search = $conn->search(
+ scope => 'sub',
+ base => $user_basedn,
+ filter => $filter,
+ attrs => ['uid', 'sshPublicKey']);
+$search->code and die "$0: ".$search->error;
+
+foreach my $entry ($search->entries) {
+ my $uid = ($entry->get_value('uid'))[0];
+ foreach my $pubkey ($entry->get_value('sshPublicKey')) {
+ next unless rindex($pubkey, 'ssh-', 0) == 0;
+ print "command=\"$GITOLITE_SHELL $uid\",restrict $pubkey\n";
+ }
+}
diff --git a/files/usr/local/libexec/gitolite-grouplist.git_server b/files/usr/local/libexec/gitolite-grouplist.git_server
new file mode 100644
index 0000000..3f90971
--- /dev/null
+++ b/files/usr/local/libexec/gitolite-grouplist.git_server
@@ -0,0 +1,51 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Net::LDAP;
+use Net::LDAP::Util qw(ldap_explode_dn escape_filter_value);
+use Authen::SASL;
+
+open my $fh, '<', '/usr/local/etc/openldap/ldap.conf' or die($!);
+my %config;
+while (<$fh>) {
+ chomp;
+ next if /^#/;
+ my @pair = split(' ', $_, 2);
+ next unless (@pair == 2);
+ $config{$pair[0]} = $pair[1];
+}
+close($fh);
+
+my $mech = $config{SASL_MECH} // 'GSSAPI';
+my $uri = $config{URI} // die("URI not specified\n");
+my $user_basedn = $config{USERS_BASE} // die("USERS_BASE not specified\n");
+my $group_basedn = $config{GROUPS_BASE} // die("GROUPS_BASE not specified\n");
+
+@ARGV == 1 or die "usage: $0 USERNAME\n";
+my $username = $ARGV[0];
+
+my $conn = Net::LDAP->new($uri, version => '3') or die "$0: $@";
+my $sasl = Authen::SASL->new($mech);
+my $status = $conn->bind(sasl => $sasl);
+$status->code and die "$0: ".$status->error;
+
+my $search = $conn->search(
+ scope => 'sub',
+ base => $user_basedn,
+ filter => '(uid='.escape_filter_value($username).')',
+ attrs => ['memberOf']);
+$search->code and die "$0: ".$search->error;
+
+$search->entries == 0 and die "no such user: $username\n";
+$search->entries > 1 and die "multiple results returned for user: $username\n";
+
+foreach my $group_dn (($search->entries)[0]->get_value('memberOf')) {
+ next unless $group_dn =~ /,\Q$group_basedn\E$/;
+
+ my $parts = ldap_explode_dn($group_dn);
+ next unless exists $parts->[0]{'CN'};
+
+ print $parts->[0]{'CN'} =~ s/\s/_/gr . "\n";
+}
diff --git a/files/usr/local/www/cgit/custom-favicon.ico.git_server b/files/usr/local/www/cgit/custom-favicon.ico.git_server
new file mode 100644
index 0000000..56ff593
--- /dev/null
+++ b/files/usr/local/www/cgit/custom-favicon.ico.git_server
Binary files differ
diff --git a/files/usr/local/www/cgit/custom-head-include.html.git_server b/files/usr/local/www/cgit/custom-head-include.html.git_server
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/files/usr/local/www/cgit/custom-head-include.html.git_server
diff --git a/files/usr/local/www/cgit/custom-header.html.git_server b/files/usr/local/www/cgit/custom-header.html.git_server
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/files/usr/local/www/cgit/custom-header.html.git_server
diff --git a/files/usr/local/www/cgit/custom-logo.png.git_server b/files/usr/local/www/cgit/custom-logo.png.git_server
new file mode 100644
index 0000000..425528e
--- /dev/null
+++ b/files/usr/local/www/cgit/custom-logo.png.git_server
Binary files differ
diff --git a/files/usr/local/www/cgit/custom-robots.txt.git_server b/files/usr/local/www/cgit/custom-robots.txt.git_server
new file mode 100644
index 0000000..4ce948f
--- /dev/null
+++ b/files/usr/local/www/cgit/custom-robots.txt.git_server
@@ -0,0 +1,3 @@
+User-agent: *
+Disallow: /*/snapshot/*
+Allow: /
diff --git a/files/usr/local/www/cgit/custom-style.css.git_server b/files/usr/local/www/cgit/custom-style.css.git_server
new file mode 100644
index 0000000..d4aadbf
--- /dev/null
+++ b/files/usr/local/www/cgit/custom-style.css.git_server
@@ -0,0 +1,895 @@
+div#cgit {
+ padding: 0em;
+ margin: 0em;
+ font-family: sans-serif;
+ font-size: 10pt;
+ color: #333;
+ background: white;
+ padding: 4px;
+}
+
+div#cgit a {
+ color: blue;
+ text-decoration: none;
+}
+
+div#cgit a:hover {
+ text-decoration: underline;
+}
+
+div#cgit table {
+ border-collapse: collapse;
+}
+
+div#cgit table#header {
+ width: 100%;
+ margin-bottom: 1em;
+}
+
+div#cgit table#header td.logo {
+ width: 96px;
+ vertical-align: top;
+}
+
+div#cgit table#header td.main {
+ font-size: 250%;
+ padding-left: 10px;
+ white-space: nowrap;
+}
+
+div#cgit table#header td.main a {
+ color: #000;
+}
+
+div#cgit table#header td.form {
+ text-align: right;
+ vertical-align: bottom;
+ padding-right: 1em;
+ padding-bottom: 2px;
+ white-space: nowrap;
+}
+
+div#cgit table#header td.form form,
+div#cgit table#header td.form input,
+div#cgit table#header td.form select {
+ font-size: 90%;
+}
+
+div#cgit table#header td.sub {
+ color: #777;
+ border-top: solid 1px #ccc;
+ padding-left: 10px;
+}
+
+div#cgit table.tabs {
+ border-bottom: solid 3px #ccc;
+ border-collapse: collapse;
+ margin-top: 2em;
+ margin-bottom: 0px;
+ width: 100%;
+}
+
+div#cgit table.tabs td {
+ padding: 0px 1em;
+ vertical-align: bottom;
+}
+
+div#cgit table.tabs td a {
+ padding: 2px 0.75em;
+ color: #777;
+ font-size: 110%;
+}
+
+div#cgit table.tabs td a.active {
+ color: #000;
+ background-color: #ccc;
+}
+
+div#cgit table.tabs a[href^="http://"]:after, div#cgit table.tabs a[href^="https://"]:after {
+ content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgAhcJDQY+gm2TAAAAHWlUWHRDb21tZW50AAAAAABDcmVhdGVkIHdpdGggR0lNUGQuZQcAAABbSURBVAhbY2BABs4MU4CwhYHBh2Erww4wrGFQZHjI8B8IgUIscJWyDHcggltQhI4zGDCcRwhChPggHIggP1QoAVmQkSETrGoHsiAEsACtBYN0oDAMbgU6EBcAAL2eHUt4XUU4AAAAAElFTkSuQmCC);
+ opacity: 0.5;
+ margin: 0 0 0 5px;
+}
+
+div#cgit table.tabs td.form {
+ text-align: right;
+}
+
+div#cgit table.tabs td.form form {
+ padding-bottom: 2px;
+ font-size: 90%;
+ white-space: nowrap;
+}
+
+div#cgit table.tabs td.form input,
+div#cgit table.tabs td.form select {
+ font-size: 90%;
+}
+
+div#cgit div.path {
+ margin: 0px;
+ padding: 5px 2em 2px 2em;
+ color: #000;
+ background-color: #eee;
+}
+
+div#cgit div.content {
+ margin: 0px;
+ padding: 2em;
+ border-bottom: solid 3px #ccc;
+}
+
+
+div#cgit table.list {
+ width: 100%;
+ border: none;
+ border-collapse: collapse;
+}
+
+div#cgit table.list tr {
+ background: white;
+}
+
+div#cgit table.list tr.logheader {
+ background: #eee;
+}
+
+div#cgit table.list tr:nth-child(even) {
+ background: #f7f7f7;
+}
+
+div#cgit table.list tr:nth-child(odd) {
+ background: white;
+}
+
+div#cgit table.list tr:hover {
+ background: #eee;
+}
+
+div#cgit table.list tr.nohover {
+ background: white;
+}
+
+div#cgit table.list tr.nohover:hover {
+ background: white;
+}
+
+div#cgit table.list tr.nohover-highlight:hover:nth-child(even) {
+ background: #f7f7f7;
+}
+
+div#cgit table.list tr.nohover-highlight:hover:nth-child(odd) {
+ background: white;
+}
+
+div#cgit table.list th {
+ font-weight: bold;
+ /* color: #888;
+ border-top: dashed 1px #888;
+ border-bottom: dashed 1px #888;
+ */
+ padding: 0.1em 0.5em 0.05em 0.5em;
+ vertical-align: baseline;
+}
+
+div#cgit table.list td {
+ border: none;
+ padding: 0.1em 0.5em 0.1em 0.5em;
+}
+
+div#cgit table.list td.commitgraph {
+ font-family: monospace;
+ white-space: pre;
+}
+
+div#cgit table.list td.commitgraph .column1 {
+ color: #a00;
+}
+
+div#cgit table.list td.commitgraph .column2 {
+ color: #0a0;
+}
+
+div#cgit table.list td.commitgraph .column3 {
+ color: #aa0;
+}
+
+div#cgit table.list td.commitgraph .column4 {
+ color: #00a;
+}
+
+div#cgit table.list td.commitgraph .column5 {
+ color: #a0a;
+}
+
+div#cgit table.list td.commitgraph .column6 {
+ color: #0aa;
+}
+
+div#cgit table.list td.logsubject {
+ font-family: monospace;
+ font-weight: bold;
+}
+
+div#cgit table.list td.logmsg {
+ font-family: monospace;
+ white-space: pre;
+ padding: 0 0.5em;
+}
+
+div#cgit table.list td a {
+ color: black;
+}
+
+div#cgit table.list td a.ls-dir {
+ font-weight: bold;
+ color: #00f;
+}
+
+div#cgit table.list td a:hover {
+ color: #00f;
+}
+
+div#cgit img {
+ border: none;
+}
+
+div#cgit input#switch-btn {
+ margin: 2px 0px 0px 0px;
+}
+
+div#cgit td#sidebar input.txt {
+ width: 100%;
+ margin: 2px 0px 0px 0px;
+}
+
+div#cgit table#grid {
+ margin: 0px;
+}
+
+div#cgit td#content {
+ vertical-align: top;
+ padding: 1em 2em 1em 1em;
+ border: none;
+}
+
+div#cgit div#summary {
+ vertical-align: top;
+ margin-bottom: 1em;
+}
+
+div#cgit table#downloads {
+ float: right;
+ border-collapse: collapse;
+ border: solid 1px #777;
+ margin-left: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+div#cgit table#downloads th {
+ background-color: #ccc;
+}
+
+div#cgit div#blob {
+ border: solid 1px black;
+}
+
+div#cgit div.error {
+ color: red;
+ font-weight: bold;
+ margin: 1em 2em;
+}
+
+div#cgit a.ls-blob, div#cgit a.ls-dir, div#cgit .ls-mod {
+ font-family: monospace;
+}
+
+div#cgit td.ls-size {
+ text-align: right;
+ font-family: monospace;
+ width: 10em;
+}
+
+div#cgit td.ls-mode {
+ font-family: monospace;
+ width: 10em;
+}
+
+div#cgit table.blob {
+ margin-top: 0.5em;
+ border-top: solid 1px black;
+}
+
+div#cgit table.blob td.hashes,
+div#cgit table.blob td.lines {
+ margin: 0; padding: 0 0 0 0.5em;
+ vertical-align: top;
+ color: black;
+}
+
+div#cgit table.blob td.linenumbers {
+ margin: 0; padding: 0 0.5em 0 0.5em;
+ vertical-align: top;
+ text-align: right;
+ border-right: 1px solid gray;
+}
+
+div#cgit table.blob pre {
+ padding: 0; margin: 0;
+}
+
+div#cgit table.blob td.linenumbers a,
+div#cgit table.ssdiff td.lineno a {
+ color: gray;
+ text-align: right;
+ text-decoration: none;
+}
+
+div#cgit table.blob td.linenumbers a:hover,
+div#cgit table.ssdiff td.lineno a:hover {
+ color: black;
+}
+
+div#cgit table.blame td.hashes,
+div#cgit table.blame td.lines,
+div#cgit table.blame td.linenumbers {
+ padding: 0;
+}
+
+div#cgit table.blame td.hashes div.alt,
+div#cgit table.blame td.lines div.alt {
+ padding: 0 0.5em 0 0.5em;
+}
+
+div#cgit table.blame td.linenumbers div.alt {
+ padding: 0 0.5em 0 0;
+}
+
+div#cgit table.blame div.alt:nth-child(even) {
+ background: #eee;
+}
+
+div#cgit table.blame div.alt:nth-child(odd) {
+ background: white;
+}
+
+div#cgit table.blame td.lines > div {
+ position: relative;
+}
+
+div#cgit table.blame td.lines > div > pre {
+ padding: 0 0 0 0.5em;
+ position: absolute;
+ top: 0;
+}
+
+div#cgit table.bin-blob {
+ margin-top: 0.5em;
+ border: solid 1px black;
+}
+
+div#cgit table.bin-blob th {
+ font-family: monospace;
+ white-space: pre;
+ border: solid 1px #777;
+ padding: 0.5em 1em;
+}
+
+div#cgit table.bin-blob td {
+ font-family: monospace;
+ white-space: pre;
+ border-left: solid 1px #777;
+ padding: 0em 1em;
+}
+
+div#cgit table.nowrap td {
+ white-space: nowrap;
+}
+
+div#cgit table.commit-info {
+ border-collapse: collapse;
+ margin-top: 1.5em;
+}
+
+div#cgit div.cgit-panel {
+ float: right;
+ margin-top: 1.5em;
+}
+
+div#cgit div.cgit-panel table {
+ border-collapse: collapse;
+ border: solid 1px #aaa;
+ background-color: #eee;
+}
+
+div#cgit div.cgit-panel th {
+ text-align: center;
+}
+
+div#cgit div.cgit-panel td {
+ padding: 0.25em 0.5em;
+}
+
+div#cgit div.cgit-panel td.label {
+ padding-right: 0.5em;
+}
+
+div#cgit div.cgit-panel td.ctrl {
+ padding-left: 0.5em;
+}
+
+div#cgit table.commit-info th {
+ text-align: left;
+ font-weight: normal;
+ padding: 0.1em 1em 0.1em 0.1em;
+ vertical-align: top;
+}
+
+div#cgit table.commit-info td {
+ font-weight: normal;
+ padding: 0.1em 1em 0.1em 0.1em;
+}
+
+div#cgit div.commit-subject {
+ font-weight: bold;
+ font-size: 125%;
+ margin: 1.5em 0em 0.5em 0em;
+ padding: 0em;
+}
+
+div#cgit div.commit-msg {
+ white-space: pre;
+ font-family: monospace;
+}
+
+div#cgit div.notes-header {
+ font-weight: bold;
+ padding-top: 1.5em;
+}
+
+div#cgit div.notes {
+ white-space: pre;
+ font-family: monospace;
+ border: solid 1px #ee9;
+ background-color: #ffd;
+ padding: 0.3em 2em 0.3em 1em;
+ float: left;
+}
+
+div#cgit div.notes-footer {
+ clear: left;
+}
+
+div#cgit div.diffstat-header {
+ font-weight: bold;
+ padding-top: 1.5em;
+}
+
+div#cgit table.diffstat {
+ border-collapse: collapse;
+ border: solid 1px #aaa;
+ background-color: #eee;
+}
+
+div#cgit table.diffstat th {
+ font-weight: normal;
+ text-align: left;
+ text-decoration: underline;
+ padding: 0.1em 1em 0.1em 0.1em;
+ font-size: 100%;
+}
+
+div#cgit table.diffstat td {
+ padding: 0.2em 0.2em 0.1em 0.1em;
+ font-size: 100%;
+ border: none;
+}
+
+div#cgit table.diffstat td.mode {
+ white-space: nowrap;
+}
+
+div#cgit table.diffstat td span.modechange {
+ padding-left: 1em;
+ color: red;
+}
+
+div#cgit table.diffstat td.add a {
+ color: green;
+}
+
+div#cgit table.diffstat td.del a {
+ color: red;
+}
+
+div#cgit table.diffstat td.upd a {
+ color: blue;
+}
+
+div#cgit table.diffstat td.graph {
+ width: 500px;
+ vertical-align: middle;
+}
+
+div#cgit table.diffstat td.graph table {
+ border: none;
+}
+
+div#cgit table.diffstat td.graph td {
+ padding: 0px;
+ border: 0px;
+ height: 7pt;
+}
+
+div#cgit table.diffstat td.graph td.add {
+ background-color: #5c5;
+}
+
+div#cgit table.diffstat td.graph td.rem {
+ background-color: #c55;
+}
+
+div#cgit div.diffstat-summary {
+ color: #888;
+ padding-top: 0.5em;
+}
+
+div#cgit table.diff {
+ width: 100%;
+}
+
+div#cgit table.diff td {
+ font-family: monospace;
+ white-space: pre;
+}
+
+div#cgit table.diff td div.head {
+ font-weight: bold;
+ margin-top: 1em;
+ color: black;
+}
+
+div#cgit table.diff td div.hunk {
+ color: #009;
+}
+
+div#cgit table.diff td div.add {
+ color: green;
+}
+
+div#cgit table.diff td div.del {
+ color: red;
+}
+
+div#cgit .sha1 {
+ font-family: monospace;
+ font-size: 90%;
+}
+
+div#cgit .left {
+ text-align: left;
+}
+
+div#cgit .right {
+ text-align: right;
+}
+
+div#cgit table.list td.reposection {
+ font-style: italic;
+ color: #888;
+}
+
+div#cgit a.button {
+ font-size: 80%;
+ padding: 0em 0.5em;
+}
+
+div#cgit a.primary {
+ font-size: 100%;
+}
+
+div#cgit a.secondary {
+ font-size: 90%;
+}
+
+div#cgit td.toplevel-repo {
+
+}
+
+div#cgit table.list td.sublevel-repo {
+ padding-left: 1.5em;
+}
+
+div#cgit ul.pager {
+ list-style-type: none;
+ text-align: center;
+ margin: 1em 0em 0em 0em;
+ padding: 0;
+}
+
+div#cgit ul.pager li {
+ display: inline-block;
+ margin: 0.25em 0.5em;
+}
+
+div#cgit ul.pager a {
+ color: #777;
+}
+
+div#cgit ul.pager .current {
+ font-weight: bold;
+}
+
+div#cgit span.age-mins {
+ font-weight: bold;
+ color: #080;
+}
+
+div#cgit span.age-hours {
+ color: #080;
+}
+
+div#cgit span.age-days {
+ color: #040;
+}
+
+div#cgit span.age-weeks {
+ color: #444;
+}
+
+div#cgit span.age-months {
+ color: #888;
+}
+
+div#cgit span.age-years {
+ color: #bbb;
+}
+
+div#cgit span.insertions {
+ color: #080;
+}
+
+div#cgit span.deletions {
+ color: #800;
+}
+
+div#cgit div.footer {
+ margin-top: 0.5em;
+ text-align: center;
+ font-size: 80%;
+ color: #ccc;
+}
+
+div#cgit div.footer a {
+ color: #ccc;
+ text-decoration: none;
+}
+
+div#cgit div.footer a:hover {
+ text-decoration: underline;
+}
+
+div#cgit a.branch-deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #88ff88;
+ border: solid 1px #007700;
+}
+
+div#cgit a.tag-deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #ffff88;
+ border: solid 1px #777700;
+}
+
+div#cgit a.tag-annotated-deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #ffcc88;
+ border: solid 1px #777700;
+}
+
+div#cgit a.remote-deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #ccccff;
+ border: solid 1px #000077;
+}
+
+div#cgit a.deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #ff8888;
+ border: solid 1px #770000;
+}
+
+div#cgit div.commit-subject a.branch-deco,
+div#cgit div.commit-subject a.tag-deco,
+div#cgit div.commit-subject a.tag-annotated-deco,
+div#cgit div.commit-subject a.remote-deco,
+div#cgit div.commit-subject a.deco {
+ margin-left: 1em;
+ font-size: 75%;
+}
+
+div#cgit table.stats {
+ border: solid 1px black;
+ border-collapse: collapse;
+}
+
+div#cgit table.stats th {
+ text-align: left;
+ padding: 1px 0.5em;
+ background-color: #eee;
+ border: solid 1px black;
+}
+
+div#cgit table.stats td {
+ text-align: right;
+ padding: 1px 0.5em;
+ border: solid 1px black;
+}
+
+div#cgit table.stats td.total {
+ font-weight: bold;
+ text-align: left;
+}
+
+div#cgit table.stats td.sum {
+ color: #c00;
+ font-weight: bold;
+/* background-color: #eee; */
+}
+
+div#cgit table.stats td.left {
+ text-align: left;
+}
+
+div#cgit table.vgraph {
+ border-collapse: separate;
+ border: solid 1px black;
+ height: 200px;
+}
+
+div#cgit table.vgraph th {
+ background-color: #eee;
+ font-weight: bold;
+ border: solid 1px white;
+ padding: 1px 0.5em;
+}
+
+div#cgit table.vgraph td {
+ vertical-align: bottom;
+ padding: 0px 10px;
+}
+
+div#cgit table.vgraph div.bar {
+ background-color: #eee;
+}
+
+div#cgit table.hgraph {
+ border: solid 1px black;
+ width: 800px;
+}
+
+div#cgit table.hgraph th {
+ background-color: #eee;
+ font-weight: bold;
+ border: solid 1px black;
+ padding: 1px 0.5em;
+}
+
+div#cgit table.hgraph td {
+ vertical-align: middle;
+ padding: 2px 2px;
+}
+
+div#cgit table.hgraph div.bar {
+ background-color: #eee;
+ height: 1em;
+}
+
+div#cgit table.ssdiff {
+ width: 100%;
+}
+
+div#cgit table.ssdiff td {
+ font-size: 75%;
+ font-family: monospace;
+ white-space: pre;
+ padding: 1px 4px 1px 4px;
+ border-left: solid 1px #aaa;
+ border-right: solid 1px #aaa;
+}
+
+div#cgit table.ssdiff td.add {
+ color: black;
+ background: #cfc;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff td.add_dark {
+ color: black;
+ background: #aca;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff span.add {
+ background: #cfc;
+ font-weight: bold;
+}
+
+div#cgit table.ssdiff td.del {
+ color: black;
+ background: #fcc;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff td.del_dark {
+ color: black;
+ background: #caa;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff span.del {
+ background: #fcc;
+ font-weight: bold;
+}
+
+div#cgit table.ssdiff td.changed {
+ color: black;
+ background: #ffc;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff td.changed_dark {
+ color: black;
+ background: #cca;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff td.lineno {
+ color: black;
+ background: #eee;
+ text-align: right;
+ width: 3em;
+ min-width: 3em;
+}
+
+div#cgit table.ssdiff td.hunk {
+ color: black;
+ background: #ccf;
+ border-top: solid 1px #aaa;
+ border-bottom: solid 1px #aaa;
+}
+
+div#cgit table.ssdiff td.head {
+ border-top: solid 1px #aaa;
+ border-bottom: solid 1px #aaa;
+}
+
+div#cgit table.ssdiff td.head div.head {
+ font-weight: bold;
+ color: black;
+}
+
+div#cgit table.ssdiff td.foot {
+ border-top: solid 1px #aaa;
+ border-left: none;
+ border-right: none;
+ border-bottom: none;
+}
+
+div#cgit table.ssdiff td.space {
+ border: none;
+}
+
+div#cgit table.ssdiff td.space div {
+ min-height: 3em;
+}
diff --git a/scripts/hostclass/git_server b/scripts/hostclass/git_server
new file mode 100644
index 0000000..c7ac63d
--- /dev/null
+++ b/scripts/hostclass/git_server
@@ -0,0 +1,163 @@
+#!/bin/sh
+
+: ${git_public_fqdn:="$fqdn"}
+: ${git_basic_auth:='on'}
+: ${gitolite_username:='s-gitolite'}
+: ${gitolite_access_role:='gitolite-access'}
+: ${gitolite_admin_role:='gitolite-admin'}
+: ${cgit_clone_urls:="https://${fqdn} ssh://git@${fqdn}"}
+: ${cgit_root_title:="${site} Git Repo"}
+: ${cgit_root_desc:="Source code for various ${site} projects."}
+: ${cgit_pygments_style:='xcode'}
+: ${cgit_cache_size:='16000'}
+
+gitolite_dn="uid=${gitolite_username},${robots_basedn}"
+git_keytab="${keytab_dir}/nginx.keytab"
+git_https_cert="${nginx_conf_dir}/git.crt"
+git_https_key="${nginx_conf_dir}/git.key"
+gitolite_home=/usr/local/git
+gitolite_client_keytab="${keytab_dir}/gitolite.client.keytab"
+gitolite_fcgiwrap_socket=/var/run/fcgiwrap/gitolite.sock
+cgit_cache_dir=/var/cache/cgit
+cgit_fcgiwrap_socket=/var/run/fcgiwrap/cgit.sock
+cgit_webroot=/usr/local/www/cgit
+
+# Install packages.
+pkg install -y \
+ python \
+ nginx \
+ cgit \
+ gitolite \
+ fcgiwrap \
+ py${python_version}-pygments \
+ py${python_version}-docutils \
+ py${python_version}-markdown
+
+# Create ZFS dataset for gitolite repositories.
+create_dataset -o "mountpoint=${gitolite_home}" "${state_dataset}/git"
+zfs set \
+ com.sun:auto-snapshot:hourly=true \
+ com.sun:auto-snapshot:daily=true \
+ com.sun:auto-snapshot:weekly=true \
+ com.sun:auto-snapshot:monthly=true \
+ "${state_dataset}/git"
+
+# Set ownership on gitolite dataset.
+install_directory -o "$gitolite_local_user" -g "$gitolite_local_user" -m 0700 "$gitolite_home"
+
+# Add www user to git group, so it can read git repositories.
+pw groupmod "$gitolite_local_user" -m "$nginx_user"
+
+# Create gitolite principal and keytab.
+ldap_add "$gitolite_dn" <<EOF
+objectClass: account
+uid: ${gitolite_username}
+EOF
+add_principal -nokey -x "dn=${gitolite_dn}" "$gitolite_username"
+
+ktadd -k "$gitolite_client_keytab" "$gitolite_username"
+chgrp "$gitolite_local_user" "$gitolite_client_keytab"
+chmod 640 "$gitolite_client_keytab"
+
+gitolite_uid=$(id -u "$gitolite_local_user")
+install_directory -o "$gitolite_local_user" -m 0700 "/var/krb5/user/${gitolite_uid}"
+ln -snfv "$gitolite_client_keytab" "/var/krb5/user/${gitolite_uid}/client.keytab"
+
+# Generate gitolite configuration.
+install_directory -o "$gitolite_local_user" -g "$gitolite_local_user" -m 0750 \
+ "$gitolite_home" \
+ "${gitolite_home}/.gitolite" \
+ "${gitolite_home}/.gitolite/conf" \
+ "${gitolite_home}/.gitolite/logs"
+install_file -o "$gitolite_local_user" -g "$gitolite_local_user" -m 0600 "${gitolite_home}/.gitolite.rc"
+
+[ -f "${gitolite_home}/.gitolite/conf/gitolite.conf" ] \
+ || install_template -o "$gitolite_local_user" -g "$gitolite_local_user" -m 0640 "${gitolite_home}/.gitolite/conf/gitolite.conf"
+
+[ -f "${gitolite_home}/.gitolite/conf/gitolite.conf-compiled.pm" ] \
+ || su "$gitolite_local_user" -c 'gitolite setup'
+
+install_file -m 0555 \
+ /usr/local/libexec/gitolite-grouplist \
+ /usr/local/libexec/gitolite-authorizedkeys
+
+# Generate cgit configuration.
+install_template -m 0644 /usr/local/etc/cgitrc
+install_template -m 0555 /usr/local/lib/cgit/filters/syntax-highlighting-custom.py
+
+# Create cgit cache directory.
+install_directory -o root -g "$nginx_user" -m 0770 "$cgit_cache_dir"
+
+# Copy custom assets.
+install_file -m 0644 \
+ "${cgit_webroot}/custom-style.css" \
+ "${cgit_webroot}/custom-favicon.ico" \
+ "${cgit_webroot}/custom-logo.png" \
+ "${cgit_webroot}/custom-robots.txt" \
+ "${cgit_webroot}/custom-head-include.html" \
+ "${cgit_webroot}/custom-header.html"
+
+# Generate nginx configuration.
+install_file -m 0644 /usr/local/etc/nginx/fastcgi_params
+install_template -m 0644 /usr/local/etc/nginx/nginx.conf
+[ -f "${nginx_conf_dir}/vhosts.conf" ] || install -Cv -m 0644 /dev/null "${nginx_conf_dir}/vhosts.conf"
+sysrc -v nginx_enable=YES
+service nginx restart
+
+if [ "$git_public_fqdn" != "$fqdn" ]; then
+ # Acquire public TLS certificate.
+ install_template -m 0600 /usr/local/etc/sudoers.d/acme
+ acme_install_certificate \
+ -g "$nginx_user" \
+ -r 'sudo service nginx reload' \
+ nginx \
+ "$git_public_fqdn"
+else
+ # Copy local TLS certificate for nginx.
+ install_certificate -m 0644 nginx "$git_https_cert"
+ install_certificate_key -m 0600 nginx "$git_https_key"
+fi
+
+# Generate nginx vhosts (once certificate is acquired).
+install_template -m 0644 /usr/local/etc/nginx/vhosts.conf
+service nginx restart
+
+# Create HTTP principal and keytab.
+nginx_uid=$(id -u "$nginx_user")
+add_principal -nokey -x "containerdn=${services_basedn}" "HTTP/${fqdn}"
+ktadd -k "$git_keytab" "HTTP/${fqdn}"
+chgrp "$nginx_user" "$git_keytab"
+chmod 640 "$git_keytab"
+install_directory -o "$nginx_user" -m 0700 "/var/krb5/user/${nginx_uid}"
+ln -snfv "$git_keytab" "/var/krb5/user/${nginx_uid}/keytab"
+
+# Generate sshd configuration.
+install_template -m 0600 /usr/local/etc/ssh/sshd_config.d/gitolite.conf
+
+# Enable and start daemons.
+sysrc -v \
+ fcgiwrap_enable=YES \
+ fcgiwrap_profiles+='cgit gitolite' \
+ fcgiwrap_cgit_flags='-f' \
+ fcgiwrap_cgit_user="$nginx_user" \
+ fcgiwrap_cgit_group="$nginx_user" \
+ fcgiwrap_cgit_socket_owner="$nginx_user" \
+ fcgiwrap_cgit_socket_group="$nginx_user" \
+ fcgiwrap_cgit_socket="unix:${cgit_fcgiwrap_socket}" \
+ fcgiwrap_gitolite_flags='-f' \
+ fcgiwrap_gitolite_user="$gitolite_local_user" \
+ fcgiwrap_gitolite_group="$gitolite_local_user" \
+ fcgiwrap_gitolite_socket_owner="$nginx_user" \
+ fcgiwrap_gitolite_socket_group="$nginx_user" \
+ fcgiwrap_gitolite_socket="unix:${gitolite_fcgiwrap_socket}"
+
+service fcgiwrap restart
+service openssh restart
+
+# Create access role.
+for role in "$gitolite_access_role" "$gitolite_admin_role"; do
+ ldap_add "cn=${role},${roles_basedn}" <<EOF
+objectClass: groupOfMembers
+cn: ${role}
+EOF
+done
diff --git a/site b/site
-Subproject a9208d8e96190479bf4bf9dd03d0e6bb38a102b
+Subproject 981b2d2a832669309961f5e55433aa4f2d61aa4
diff --git a/vars/hostclass/git_server b/vars/hostclass/git_server
new file mode 100644
index 0000000..1625d52
--- /dev/null
+++ b/vars/hostclass/git_server
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+gitolite_local_user=git
+
+allowed_tcp_ports='ssh http https'
+nginx_gssapi=true
+login_access_users="${login_access_users:-} ${gitolite_local_user}"
diff --git a/vars/hostname/git1 b/vars/hostname/git1
new file mode 100644
index 0000000..b9aa2d6
--- /dev/null
+++ b/vars/hostname/git1
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cnames=git
+cgit_clone_urls="https://git.${domain} ssh://git@git.${domain}"}