summaryrefslogtreecommitdiff
path: root/content/posts/2020/2020-01-08-running-cgit-on-gentoo.md
diff options
context:
space:
mode:
Diffstat (limited to 'content/posts/2020/2020-01-08-running-cgit-on-gentoo.md')
-rw-r--r--content/posts/2020/2020-01-08-running-cgit-on-gentoo.md301
1 files changed, 301 insertions, 0 deletions
diff --git a/content/posts/2020/2020-01-08-running-cgit-on-gentoo.md b/content/posts/2020/2020-01-08-running-cgit-on-gentoo.md
new file mode 100644
index 0000000..085da26
--- /dev/null
+++ b/content/posts/2020/2020-01-08-running-cgit-on-gentoo.md
@@ -0,0 +1,301 @@
+---
+title: Running cgit on Gentoo
+date: 2020-01-08
+tags:
+- git
+- cgit
+- Gentoo
+---
+
+[cgit](https://git.zx2c4.com/cgit/about/), a web interface for git
+repositories, allows you to easily share your projects' source code over a web
+interface. It's running on my desktop right now, so you can [see for
+yourself](https://home.tyil.nl/git) what it looks like. On
+[Gentoo](https://www.gentoo.org/), the ebuild for this software can be found as
+`www-apps/cgit`. However, after installation, a number of configuration steps
+should be performed to make it accessible on `$HOSTNAME/git`, and index your
+repositories. This post will guide you through the steps I took.
+
+## Filesystem layout
+
+In my setup, my (bare) git repositories reside in `$HOME/.local/git`. But, some
+of the repositories should not be public, such as the
+[`pass`](https://www.passwordstore.org/) store. So, a different directory
+for cgit to look in exists, at `$HOME/.local/srv/cgit`. This directory contains
+symlinks to the actual repositories I want publicly available.
+
+## Installing the required software
+
+For this to work, there is more than just cgit to install. There are a number
+of ways to set this up, but I chose for Nginx as web server, and `uwsgi` as the
+handler for the fastcgi requests.
+
+```txt
+emerge dev-python/pygments www-apps/cgit www-servers/nginx www-servers/uwsgi
+```
+
+## Configuring all elements
+
+After installation, each of these packages needs to be configured.
+
+### cgit
+
+The configuration file for cgit resides in `/etc/cgitrc`. After removing all
+the comments, the contents of my `/etc/cgitrc` can be found below.
+
+```txt
+# Fixes for running cgit in a subdirectory
+css=/git/cgit.css
+logo=/git/cgit.png
+virtual-root=/git
+remove-suffix=1
+
+# Customization
+root-desc=All public repos from tyil
+enable-index-owner=0
+cache-size=1000
+snapshots=tar.gz tar.bz2
+clone-prefix=https://home.tyil.nl/git
+robots=index, follow
+
+readme=master:README.md
+readme=master:README.pod6
+
+# Add filters before repos (or filters won't work)
+about-filter=/usr/lib64/cgit/filters/about-formatting.sh
+source-filter=/usr/lib64/cgit/filters/syntax-highlighting.py
+
+# Scan paths for repos
+scan-path=/home/tyil/.local/srv/cgit
+```
+
+You should probably update the values of `root-desc`, `clone-prefix` and
+`scan-path`. The first describes the small line of text at the top of the web
+interface. `clone-prefix` is the prefix URL used for `git clone` URLs. The
+`scan-path` is the directory `cgit` will look for repositories in.
+
+Additionally, the `readme=master:README.pod6` only positively affects
+your setup if you also use my [Raku](https://raku.org/) customizations,
+outlined in the next section.
+
+For more information on the available settings and their impact, consult `man
+cgitrc`.
+
+#### Raku customizations
+
+Since I love working with Raku, I made some changes and a couple modules to get
+`README.pod6` files rendered on the *about* tab on projects. You should ensure
+the `cgit` user can run `raku` and has the
+[`Pod::To::Anything`](https://home.tyil.nl/git/raku/Pod::To::Anything/) and
+[`Pod::To::HTML::Section`](https://home.tyil.nl/git/raku/Pod::To::HTML::Section/)
+modules installed (including any dependencies). How to achieve this depends on
+how you installed Raku. Feel free to send me an email if you need help on this
+part!
+
+Once this works, however, the remaining step is quite simple. The
+`about-filter` configuration item in `/etc/cgitrc` points to a small shell
+script that invokes the required program to convert a document to HTML. In my
+case, this file is at `/usr/lib64/cgit/filters/about-formatting.sh`. Open up
+this file in your favorite `$EDITOR` and add another entry to the `case` for
+[Pod6](https://docs.raku.org/language/pod) to call Raku.
+
+```sh
+case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in
+ *.markdown|*.mdown|*.md|*.mkd) exec ./md2html; ;;
+ *.pod6) exec raku --doc=HTML::Section; ;;
+ *.rst) exec ./rst2html; ;;
+ *.[1-9]) exec ./man2html; ;;
+ *.htm|*.html) exec cat; ;;
+ *.txt|*) exec ./txt2html; ;;
+esac
+```
+
+#### Highlighting style
+
+The `syntax-highlighting.py` filter carries the responsibility to get your code
+highlighted. This uses the Python library [pygments](https://pygments.org/),
+which comes with a number of styles. cgit uses *Pastie* by default. To change
+this, open the Python script, and look for the `HtmlFormatter`, which contains
+a `style='Pastie'` bit. You can change `Pastie` for any other style name. These
+styles are available in my version (2.4.2):
+
+- default
+- emacs
+- friendly
+- colorful
+- autumn
+- murphy
+- manni
+- monokai
+- perldoc
+- pastie
+- borland
+- trac
+- native
+- fruity
+- bw
+- vim
+- vs
+- tango
+- rrt
+- xcode
+- igor
+- paraiso-light
+- paraiso-dark
+- lovelace
+- algol
+- algol_nu
+- arduino
+- rainbow_dash
+- abap
+- solarized-dark
+- solarized-light
+- sas
+- stata
+- stata-light
+- stata-dark
+
+For those interested, I use the `emacs` theme.
+
+### uwsgi
+
+Next up, `uwsgi`. This needs configuration, which on Gentoo exists in
+`/etc/conf.d/uwsgi`. However, this file itself shouldn't be altered. Instead,
+make a copy of it, and call it `/etc/conf.d/uwsgi.cgit`. The standard file
+exists solely as a base template. For brevity, I left out all the comments in
+the contents below.
+
+```sh
+UWSGI_SOCKET=
+UWSGI_THREADS=0
+UWSGI_PROGRAM=
+UWSGI_XML_CONFIG=
+UWSGI_PROCESSES=1
+UWSGI_LOG_FILE=
+UWSGI_CHROOT=
+UWSGI_DIR=/home/tyil
+UWSGI_PIDPATH_MODE=0750
+UWSGI_USER=
+UWSGI_GROUP=
+UWSGI_EMPEROR_PATH=
+UWSGI_EMPEROR_PIDPATH_MODE=0770
+UWSGI_EMPEROR_GROUP=
+UWSGI_EXTRA_OPTIONS="--ini /etc/uwsgi.d/cgit.ini"
+```
+
+That covers the service configuration file. When things don't work the way you
+expect, specify a path in `UWSGI_LOG_FILE` to see its logs. Additionally, you
+may want to alter the value of `UWSGI_DIR`. This specifies the working
+directory from which the process starts.
+
+Now comes the application configuration, which will be read from
+`/etc/uwsgi.d/cgit.ini`, according to `UWSGI_EXTRA_OPTIONS`. Create that file
+with the following contents.
+
+```ini
+[uwsgi]
+master = true
+plugins = cgi
+socket = 127.0.0.1:1234
+uid = cgit
+gid = cgit
+procname-master = uwsgi cgit
+processes = 1
+threads = 2
+cgi = /usr/share/webapps/cgit/1.2.1/hostroot/cgi-bin/cgit.cgi
+```
+
+Note that the `cgi` value contains the version number of `www-apps/cgit`. You
+may need to come back after an upgrade and update it accordingly.
+
+As last step for `uwsgi` configuration, a service script, to manage it with
+`rc-service`. These scripts all exist in `/etc/conf.d`, and the package
+installed a script called `uwsgi` in there. Just like with the `conf.d`
+variant, its just a template. This time, however, don't make a copy of it, but
+a symlink. It does not need to be edited, but the name must be the same as the
+`conf.d` entry name. That would be `uwsgi.cgit`.
+
+```txt
+cd /etc/conf.d
+ln -s uwsgi uwsgi.cgit
+```
+
+Now you can start the service with `rc-service uwsgi.cgit start`. If a
+consequent `status` notes the state as *Started*, you're all good. If the state
+says *Crashed*, you should go back and double-check all configuration files.
+When those are correct and you can't figure out why, feel free to reach out to
+me via email.
+
+```txt
+rc-service uwsgi.cgit start
+rc-service uwsgi.cgit service
+
+# Start this after boot
+rc-update add uwsgi.cgit
+```
+
+### nginx
+
+The final element to make it accessible, the web server, `nginx`. How you
+organize the configuration files here is largely up to you. Explaining how to
+set up nginx from scratch is beyond the scope of this post. Assuming you know
+how to configure this, add the following `location` blocks to the `server`
+definition for the vhost you want to make `cgit` available on.
+
+```nginx
+location "/git" {
+ alias /usr/share/webapps/cgit/1.2.1/htdocs;
+ try_files $uri @cgit;
+}
+
+location @cgit {
+ include uwsgi_params;
+
+ gzip off;
+
+ uwsgi_modifier1 9;
+ uwsgi_pass 127.0.0.1:1234;
+
+ fastcgi_split_path_info ^(/git/?)(.+)$;
+ uwsgi_param PATH_INFO $fastcgi_path_info;
+}
+```
+
+Once saved, you can reload `nginx`, and the `$HOSTNAME/git` endpoint can be
+reached, and should display an cgit page, detailing there are no repositories.
+That can be easily solved by making some available in `$HOME/.local/srv/cgit`,
+through the power of symlinks.
+
+## Symlinking the repositories
+
+Go nuts with making symlinks to the various repositories you have gathered over
+the years. You don't need to use bare repositories, `cgit` will also handle
+regular repositories that you actively work in. As with the `nginx`
+configuration, explaining how to make symlinks is out of scope. In dire
+situations, consult `man ln`.
+
+### `git-mkbare`
+
+While making the symlinks is easy, I found that it sheepishly boring to do. I go
+to `$HOME/.local/git`, make a directory, `cd` to it, and create a bare
+repository. Then off to `$HOME/.local/srv/cgit` to make a symlink back to the
+newly created bare repository. I think you can see this will get tedious very
+quickly.
+
+So, to combat this, I made a small shell script to do all of that for me. I
+called it `git-mkbare`, and put it somewhere in my `$PATH`. This allows me to
+call it as `git mkbare repo-name`. It will ask for a small description as well,
+so I that can also be skipped as a manual task. This script may be of use to
+you if you want to more quickly start a new project.
+
+You can find this script [in my dotfiles
+repository](https://git.tyil.nl/dotfiles/tree/.local/bin/git-mkbare).
+
+## Wrapping up
+
+Now you should have cgit available from your site, allowing you to share the
+sources of all your projects easily with the world. No need to make use of a
+(proprietary) third-party service!
+
+If you have questions or comments on my setup, or the post in general, please
+contact me through email or irc.