From 5d69851df2cb01394ddfdc136fcc753febde3b38 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sun, 13 Nov 2022 23:52:17 +0100 Subject: add cgit support for gitolite repos --- roles/acmetool/cert/tasks/main.yml | 18 +++--- roles/gitolite/base/defaults/main.yml | 3 - roles/gitolite/base/tasks/main.yml | 12 ++-- roles/gitolite/http/tasks/main.yml | 61 +++++++++++++++++++ roles/gitolite/http/templates/cgitrc.j2 | 31 ++++++++++ roles/gitolite/http/templates/fcgiwrap.service.j2 | 12 ++++ roles/gitolite/http/templates/fcgiwrap.socket.j2 | 11 ++++ roles/gitolite/http/templates/nginx-vhost.conf.j2 | 72 +++++++++++++++++++++++ 8 files changed, 203 insertions(+), 17 deletions(-) create mode 100644 roles/gitolite/http/tasks/main.yml create mode 100644 roles/gitolite/http/templates/cgitrc.j2 create mode 100644 roles/gitolite/http/templates/fcgiwrap.service.j2 create mode 100644 roles/gitolite/http/templates/fcgiwrap.socket.j2 create mode 100644 roles/gitolite/http/templates/nginx-vhost.conf.j2 (limited to 'roles') diff --git a/roles/acmetool/cert/tasks/main.yml b/roles/acmetool/cert/tasks/main.yml index e97aab84..4d8d7eb3 100644 --- a/roles/acmetool/cert/tasks/main.yml +++ b/roles/acmetool/cert/tasks/main.yml @@ -1,10 +1,10 @@ --- -- name: add acmetool desired file - vars: - acmetool_cert_satisfy: - satisfy: - names: "{{ acmetool_cert_hostnames | default([acmetool_cert_name]) }}" - ansible.builtin.copy: - content: "{{ acmetool_cert_config | default({}) | combine(acmetool_cert_satisfy) | to_nice_yaml }}" - dest: "/var/lib/acme/desired/{{ acmetool_cert_name }}" - notify: reconcile acmetool +# - name: add acmetool desired file +# vars: +# acmetool_cert_satisfy: +# satisfy: +# names: "{{ acmetool_cert_hostnames | default([acmetool_cert_name]) }}" +# ansible.builtin.copy: +# content: "{{ acmetool_cert_config | default({}) | combine(acmetool_cert_satisfy) | to_nice_yaml }}" +# dest: "/var/lib/acme/desired/{{ acmetool_cert_name }}" +# notify: reconcile acmetool diff --git a/roles/gitolite/base/defaults/main.yml b/roles/gitolite/base/defaults/main.yml index 8016135a..1c5962cc 100644 --- a/roles/gitolite/base/defaults/main.yml +++ b/roles/gitolite/base/defaults/main.yml @@ -11,9 +11,6 @@ gitolite_base_path: /srv/git # http: # hostnames: # - git.example.com -# authentication: basic -# users: -# user1: password # enable_git_backend: yes # title: cgit root title # description: this will be shown by cgit below the title diff --git a/roles/gitolite/base/tasks/main.yml b/roles/gitolite/base/tasks/main.yml index 440d9f52..fe552b00 100644 --- a/roles/gitolite/base/tasks/main.yml +++ b/roles/gitolite/base/tasks/main.yml @@ -91,10 +91,12 @@ regexp: "^(\\s*)#?\\s*('daemon'.*)$" line: '\1\2' -## TODO: -# - name: enable http -# when: "'http' in gitolite_instance" -# include_role: -# name: gitolite/http +- name: enable http + loop: "{{ gitolite_instances | list }}" + loop_control: + loop_var: gitolite_instance + when: "'http' in gitolite_instances[gitolite_instance]" + include_role: + name: gitolite/http ## TODO: add systemd-timer for `git fsck` diff --git a/roles/gitolite/http/tasks/main.yml b/roles/gitolite/http/tasks/main.yml new file mode 100644 index 00000000..a3055902 --- /dev/null +++ b/roles/gitolite/http/tasks/main.yml @@ -0,0 +1,61 @@ +--- +- name: install cgit and fcgiwrap + apt: + name: + - cgit + - python3-pygments + - fcgiwrap + state: present + +### TODO: this might break stuff.. +- name: mask default fcgiwrap systemd units + loop: + - socket + - service + systemd: + name: "fcgiwrap.{{ item }}" + state: stopped + masked: yes + +- name: install fcgiwrap systemd units + loop: + - socket + - service + template: + src: "fcgiwrap.{{ item }}.j2" + dest: "/etc/systemd/system/fcgiwrap-gitolite-{{ gitolite_instance }}.{{ item }}" + +- name: make sure fcgiwrap systemd socket unit is enabled and started + systemd: + daemon_reload: yes + name: "fcgiwrap-gitolite-{{ gitolite_instance }}.socket" + state: started + enabled: yes + +- name: generate cgitrc + template: + src: cgitrc.j2 + dest: "{{ gitolite_base_path }}/{{ gitolite_instance }}/cgitrc" + +- name: install custom logo + when: "'logo' in gitolite_instances[gitolite_instance].http" + block: + - name: create logo base directory + file: + path: /usr/local/share/cgit + state: directory + + - name: copy logo file + copy: + src: "{{ gitolite_instances[gitolite_instance].http.logo }}" + dest: "/usr/local/share/cgit/{{ gitolite_instance }}.png" + +- name: install nginx vhost + vars: + nginx_vhost: + name: "gitolite-{{ gitolite_instance }}" + acme: true + hostnames: "{{ gitolite_instances[gitolite_instance].http.hostnames }}" + content: "{{ lookup('template', 'nginx-vhost.conf.j2') }}" + include_role: + name: nginx/vhost diff --git a/roles/gitolite/http/templates/cgitrc.j2 b/roles/gitolite/http/templates/cgitrc.j2 new file mode 100644 index 00000000..fd3a4681 --- /dev/null +++ b/roles/gitolite/http/templates/cgitrc.j2 @@ -0,0 +1,31 @@ +## {{ ansible_managed }} + +css=/cgit-css/cgit.css +{% if 'logo' in gitolite_instances[gitolite_instance].http %} +logo=/logo.png +{% else %} +logo=/cgit-css/cgit.png +{% endif %} +{% if 'title' in gitolite_instances[gitolite_instance].http %} +root-title={{ gitolite_instances[gitolite_instance].http.title }} +{% endif %} +{% if 'description' in gitolite_instances[gitolite_instance].http %} +root-desc={{ gitolite_instances[gitolite_instance].http.description }} +{% endif %} + +enable-blame=1 +enable-commit-graph=1 +enable-git-config=1 +enable-index-links=1 +enable-log-filecount=1 +enable-log-linecount=1 +enable-subject-links=1 +enable-tree-linenumbers=1 + +virtual-root=/cgit/ +source-filter=/usr/lib/cgit/filters/syntax-highlighting.py + +clone-url=ssh://git-{{ gitolite_instance }}@{{ gitolite_instances[gitolite_instance].http.hostnames[0] }}{% if ansible_port is defined %}:{{ ansible_port }}{% endif %}/$CGIT_REPO_URL{% if gitolite_instances[gitolite_instance].http.enable_git_backend | default(false) %} https://{{ gitolite_instances[gitolite_instance].http.hostnames[0] }}/$CGIT_REPO_URL{% endif %} + +strict-export=git-daemon-export-ok +scan-path={{ gitolite_base_path }}/{{ gitolite_instance }}/repositories diff --git a/roles/gitolite/http/templates/fcgiwrap.service.j2 b/roles/gitolite/http/templates/fcgiwrap.service.j2 new file mode 100644 index 00000000..92fa3209 --- /dev/null +++ b/roles/gitolite/http/templates/fcgiwrap.service.j2 @@ -0,0 +1,12 @@ +[Unit] +Description=Simple CGI Server +After=nss-user-lookup.target +Requires=fcgiwrap-gitolite-{{ gitolite_instance }}.socket + +[Service] +ExecStart=/usr/sbin/fcgiwrap -f +User=git-{{ gitolite_instance }} +Group=git-{{ gitolite_instance }} + +[Install] +Also=fcgiwrap-gitolite-{{ gitolite_instance }}.socket diff --git a/roles/gitolite/http/templates/fcgiwrap.socket.j2 b/roles/gitolite/http/templates/fcgiwrap.socket.j2 new file mode 100644 index 00000000..6a4c58e7 --- /dev/null +++ b/roles/gitolite/http/templates/fcgiwrap.socket.j2 @@ -0,0 +1,11 @@ +[Unit] +Description=fcgiwrap Socket + +[Socket] +SocketMode=0600 +SocketUser=www-data +SocketGroup=www-data +ListenStream=/run/fcgiwrap/gitolite-{{ gitolite_instance }}.sock + +[Install] +WantedBy=sockets.target diff --git a/roles/gitolite/http/templates/nginx-vhost.conf.j2 b/roles/gitolite/http/templates/nginx-vhost.conf.j2 new file mode 100644 index 00000000..add7a719 --- /dev/null +++ b/roles/gitolite/http/templates/nginx-vhost.conf.j2 @@ -0,0 +1,72 @@ + server { + listen 80; + listen [::]:80; + server_name {{ gitolite_instances[gitolite_instance].http.hostnames | join(' ') }}; + + access_log /var/log/nginx/git-{{ gitolite_instance }}_access.log; + error_log /var/log/nginx/git-{{ gitolite_instance }}_error.log; + + include snippets/acmetool.conf; + + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name {{ gitolite_instances[gitolite_instance].http.hostnames | join(' ') }}; + + access_log /var/log/nginx/git-{{ gitolite_instance }}_access.log; + error_log /var/log/nginx/git-{{ gitolite_instance }}_error.log; + + include snippets/acmetool.conf; + include snippets/tls.conf; + ssl_certificate /var/lib/acme/live/{{ gitolite_instances[gitolite_instance].http.hostnames[0] }}/fullchain; + ssl_certificate_key /var/lib/acme/live/{{ gitolite_instances[gitolite_instance].http.hostnames[0] }}/privkey; + include snippets/hsts.conf; + + location = / { + return 303 /cgit/; + } + + location /cgit-css/ { + alias /usr/share/cgit/; + } +{% if 'logo' in gitolite_instances[gitolite_instance].http %} + + location = /logo.png { + alias /usr/local/share/cgit/{{ gitolite_instance }}.png; + } +{% endif %} + + location /cgit/ { + include fastcgi_params; + fastcgi_split_path_info ^(/cgit)(.*)$; + + fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param QUERY_STRING $args; + fastcgi_param HTTP_HOST $server_name; + fastcgi_param CGIT_CONFIG {{ gitolite_base_path }}/{{ gitolite_instance }}/cgitrc; + + fastcgi_pass unix:/run/fcgiwrap/gitolite-{{ gitolite_instance }}.sock; + } +{% if 'enable_git_backend' in gitolite_instances[gitolite_instance].http and gitolite_instances[gitolite_instance].http.enable_git_backend %} + + location ~ ^.*/git-receive-pack$ { + return 403; + } + + location ~ ^.*/(HEAD|info/refs|objects/(info/.*|[0-9a-f]+/[0-9a-f]+|pack/pack-[0-9a-f]+.(pack|idx))|git-upload-pack)$ { + include fastcgi_params; + + fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; + fastcgi_param PATH_INFO $uri; + fastcgi_param GIT_PROJECT_ROOT {{ gitolite_base_path }}/{{ gitolite_instance }}/repositories; + + fastcgi_pass unix:/run/fcgiwrap/gitolite-{{ gitolite_instance }}.sock; + } +{% endif %} +} -- cgit v1.2.3