From: Lucas Werkmeister Date: Sat, 11 Mar 2017 20:53:17 +0000 (+0100) Subject: add: gitweb service X-Git-Url: https://code.wpia.club/?p=infra.git;a=commitdiff_plain;h=6e69c87b067707acfaa1b526697b9d5c855eee47 add: gitweb service Serves all repositories in /data/git on the code. subdomain with gitweb, and allows cloning them via https:// and git://. NOTE: For clone over HTTP(S), git update-server-info needs to be run in the repositories; this is expected to be done via a post-update hook in the repositories, and not configured here. Change-Id: I8b5666fd54031447ddfdd098504aa46ad29285b3 --- diff --git a/commands b/commands index 269100b..0a62514 100755 --- a/commands +++ b/commands @@ -45,6 +45,7 @@ if [[ "$com" == "ask quiz certs" ]]; then update_cert "modules/quiz/files/client" update_cert "modules/gigi/files/gigi" update_cert "modules/gigi/files/client" + update_cert "modules/gitweb/files/web" echo "DONE" [[ -f $folder/web.crt ]] && rm $folder/web.crt [[ -f $folder/web.req ]] && rm $folder/web.req diff --git a/environments/production/manifests/gitweb.pp b/environments/production/manifests/gitweb.pp new file mode 100644 index 0000000..fc13d5f --- /dev/null +++ b/environments/production/manifests/gitweb.pp @@ -0,0 +1,56 @@ +node gitweb { + include container::contained; + include container::no_ssh; + package{ 'git': + ensure => 'installed' + } + package{ 'libcgi-fast-perl': + ensure => 'installed' + } + user{'git': + ensure => 'present', + system => 'yes', + comment => 'git repository owner' + } -> + file{ '/gitweb-socket': + owner => 'git', + group => 'git', + before => Service['gitweb.service'] + } + file{ '/etc/systemd/system/git.socket': + ensure => 'file', + source => 'puppet:///modules/gitweb/git.socket', + before => Service['git.socket'] + } + file{ '/etc/systemd/system/git@.service': + ensure => 'file', + source => 'puppet:///modules/gitweb/git@.service', + before => Service['git.socket'] + } + service{'git.socket': + ensure => 'running', + provider => 'systemd', + enable => true + } + file{ '/etc/systemd/system/gitweb.service': + ensure => 'file', + source => 'puppet:///modules/gitweb/gitweb.service', + notify => Service['gitweb.service'] + } + file{ '/usr/local/bin/gitweb.cgi': + ensure => 'file', + mode => '+x', + source => 'puppet:///modules/gitweb/gitweb-wrapper.cgi', + notify => Service['gitweb.service'] + } + file{ '/etc/gitweb.conf': + ensure => 'file', + content => epp('gitweb/gitweb.conf'), + notify => Service['gitweb.service'] + } + service{'gitweb.service': + ensure => 'running', + provider => 'systemd', + enable => true + } +} diff --git a/environments/production/manifests/ip.pp b/environments/production/manifests/ip.pp index 8cc4856..8c13733 100644 --- a/environments/production/manifests/ip.pp +++ b/environments/production/manifests/ip.pp @@ -5,7 +5,8 @@ $ips = { exim => '10.0.3.17', hop => '10.0.3.18', quiz => '10.0.3.19', - postgres => '10.0.3.14'} + postgres => '10.0.3.14', + gitweb => '10.0.3.20'} $passwords = { postgres => { diff --git a/environments/production/manifests/nginx.pp b/environments/production/manifests/nginx.pp index 021c5d4..373e2a8 100644 --- a/environments/production/manifests/nginx.pp +++ b/environments/production/manifests/nginx.pp @@ -65,4 +65,13 @@ node front-nginx { service {'nginx': ensure => 'running' } + #for gitweb hosting + package{'git': + ensure=>'installed' + } + front_vhost{'gitweb': + source => 'gitweb/nginx.epp', + notify => Service['nginx'], + crt => 'gitweb/web' + } } diff --git a/environments/production/manifests/root.pp b/environments/production/manifests/root.pp index d51c17d..e2b5d6b 100644 --- a/environments/production/manifests/root.pp +++ b/environments/production/manifests/root.pp @@ -24,6 +24,15 @@ class my_fw::post { table => 'nat', chain => 'PREROUTING', } -> + firewall { '80 dnat-git': + proto => 'tcp', + dport => '9418', + jump => 'DNAT', + todest => "${$ips[gitweb]}:9418", + iniface => $internet_iface, + table => 'nat', + chain => 'PREROUTING', + } -> firewall { '80 dnat-htop-ssh': proto => 'tcp', dport => '2222', @@ -92,11 +101,13 @@ if $signerLocation == 'self' { lxc::container { 'front-nginx': contname => 'front-nginx', ip => $ips[front-nginx], - dir => ["/data", "/data-crl", '/data-crl-gigi'], + dir => ["/data", "/data-crl", '/data-crl-gigi', '/gitweb-socket', '/srv/git'], bind => { "/data/nginx" => {target => "data", option => ",ro"}, "/data/crl" => {target => "data-crl", option => ",ro"}, - "/data/gigi-crl" => {target => "data-crl-gigi", option => ",ro"} + "/data/gigi-crl" => {target => "data-crl-gigi", option => ",ro"}, + "/run/gitweb-socket" => {target => 'gitweb-socket'}, + "/data/git" => { 'target' => "srv/git", option => ",ro"} }, require => File['/data/nginx', '/data/crl/htdocs', '/data/gigi-crl'] } @@ -110,6 +121,10 @@ if $signerLocation == 'self' { ensure => 'directory', owner => $administrativeUser } + file { '/data/git': + ensure => 'directory', + owner => $administrativeUser, + } file { '/data/gigi-crl': ensure => 'directory', owner => $administrativeUser @@ -174,6 +189,19 @@ if $signerLocation == 'self' { contname => 'quiz', ip => $ips[quiz] } + file{'/run/gitweb-socket': + ensure => 'directory' + } + lxc::container { 'gitweb': + require => File['/data/git', '/run/gitweb-socket'], + contname => 'gitweb', + dir => ['/gitweb-socket', '/srv/git'], + bind => { + "/run/gitweb-socket" => { 'target' => "gitweb-socket"}, + "/data/git" => { 'target' => "srv/git", option => ",ro"} + }, + ip => $ips[gitweb] + } # Required for bootstrap-user package {'acl': ensure => 'installed' diff --git a/modules/gitweb/files/git.socket b/modules/gitweb/files/git.socket new file mode 100644 index 0000000..efd5705 --- /dev/null +++ b/modules/gitweb/files/git.socket @@ -0,0 +1,10 @@ +[Unit] +Description=Socket for git daemon +Documentation=man:git-daemon(1) + +[Socket] +ListenStream=9418 +Accept=yes + +[Install] +WantedBy=sockets.target diff --git a/modules/gitweb/files/git@.service b/modules/gitweb/files/git@.service new file mode 100644 index 0000000..0dcbf7f --- /dev/null +++ b/modules/gitweb/files/git@.service @@ -0,0 +1,22 @@ +[Unit] +Description=git daemon +Documentation=man:git-daemon(1) + +[Service] +ExecStart=/usr/bin/git daemon --inetd --verbose --export-all --base-path=/srv/git +StandardInput=socket +StandardOutput=socket +StandardError=journal +User=git + +# sandboxing options, see systemd.exec(5) +NoNewPrivileges=yes +PrivateNetwork=yes +PrivateDevices=yes +PrivateTmp=yes +ProtectHome=yes +ReadOnlyDirectories=/ +SystemCallArchitectures=native +RestrictRealtime=yes +ProtectControlGroups=yes +ProtectKernelModules=yes diff --git a/modules/gitweb/files/gitweb-wrapper.cgi b/modules/gitweb/files/gitweb-wrapper.cgi new file mode 100644 index 0000000..6c8597b --- /dev/null +++ b/modules/gitweb/files/gitweb-wrapper.cgi @@ -0,0 +1,22 @@ +#!/usr/bin/perl +# gitweb.cgi wrapper that fixes the UTF-8 problem with fastcgi + +# Local redefinition of FCGI::Stream::PRINT +use Encode; +use FCGI; + +our $enc = Encode::find_encoding('UTF-8'); +our $org = \&FCGI::Stream::PRINT; +no warnings 'redefine'; + +local *FCGI::Stream::PRINT = sub { + my @OUTPUT = @_; + for (my $i = 1; $i < @_; $i++) { + $OUTPUT[$i] = $enc->encode($_[$i], Encode::FB_CROAK|Encode::LEAVE_SRC); + } + @_ = @OUTPUT; + goto $org; +}; + +# Execute original script +do "/usr/share/gitweb/gitweb.cgi"; diff --git a/modules/gitweb/files/gitweb.service b/modules/gitweb/files/gitweb.service new file mode 100644 index 0000000..b1ee811 --- /dev/null +++ b/modules/gitweb/files/gitweb.service @@ -0,0 +1,32 @@ +[Unit] +Description=git web server +Documentation=man:gitweb(1) man:gitweb.conf(5) + +[Service] +ExecStart=/usr/local/bin/gitweb.cgi --fastcgi +# gitweb kills itself every 100 requests or so, expects to be restarted externally +Restart=on-success +# place the socket in the bind-mounted directory that’s also bind-mounted into nginx’ container +Environment=FCGI_SOCKET_PATH=/gitweb-socket/gitweb +# set UTF-8 locale +Environment=LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 +# don’t run gitweb as root +User=git +# allow web server to read the socket by making it world-accessible +UMask=0000 + +# sandboxing options, see systemd.exec(5) +NoNewPrivileges=yes +PrivateNetwork=yes +PrivateDevices=yes +PrivateTmp=yes +ProtectHome=yes +ReadOnlyPaths=/ +ReadWritePaths=/gitweb-socket/ +SystemCallArchitectures=native +RestrictRealtime=yes +ProtectControlGroups=yes +ProtectKernelModules=yes + +[Install] +WantedBy=multi-user.target diff --git a/modules/gitweb/templates/gitweb.conf.epp b/modules/gitweb/templates/gitweb.conf.epp new file mode 100644 index 0000000..b2e0185 --- /dev/null +++ b/modules/gitweb/templates/gitweb.conf.epp @@ -0,0 +1,9 @@ +our $projectroot = "/srv/git"; +our $project_maxdepth = 1; +our $GIT = "/usr/bin/git"; +our @git_base_url_list = qw(https://code.<%=$systemDomain%> git://code.<%=$systemDomain%>); +our $site_name = "WPIA source code repositories"; +our $omit_owner = true; # all repositories are owned by the git user – useless information +our $default_text_plain_charset = "utf-8"; +our $fallback_encoding = "utf-8"; +our $projects_list_description_width = 50; diff --git a/modules/gitweb/templates/nginx.epp b/modules/gitweb/templates/nginx.epp new file mode 100644 index 0000000..b7db2d4 --- /dev/null +++ b/modules/gitweb/templates/nginx.epp @@ -0,0 +1,21 @@ +server { + listen 0.0.0.0:80; + listen 0.0.0.0:443 ssl; + server_name code.<%=$systemDomain%>; + + ssl_certificate /etc/ssl/private/gitweb.crt; + ssl_certificate_key /etc/ssl/private/gitweb.key; + + location ~ "^/$" { + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_pass unix:/gitweb-socket/gitweb; + } + location /static { + alias /usr/share/gitweb/static; + } + location / { + root /srv/git; + } +}