From 6c17018a6029dc478c699f74161bde267184de58 Mon Sep 17 00:00:00 2001 From: Patrick Spek Date: Wed, 22 Jan 2020 14:41:16 +0100 Subject: Publish 'Running cgit on Gentoo' post --- _posts/2020-01-08-running-cgit-on-gentoo.md | 301 ++++++++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 _posts/2020-01-08-running-cgit-on-gentoo.md (limited to '_posts') diff --git a/_posts/2020-01-08-running-cgit-on-gentoo.md b/_posts/2020-01-08-running-cgit-on-gentoo.md new file mode 100644 index 0000000..d666fda --- /dev/null +++ b/_posts/2020-01-08-running-cgit-on-gentoo.md @@ -0,0 +1,301 @@ +--- +title: Running cgit on Gentoo +layout: post +tags: Git Cgit Gentoo +description: > + Recently, I've setup cgit on my desktop, running Gentoo. This post covers the + installation and configuration I've undertaken to get it running as desired. +--- + +[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. + +{% highlight sh %} +emerge dev-python/pygments www-apps/cgit www-servers/nginx www-servers/uwsgi +{% endhighlight %} + +## 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. + +{% highlight text %} +# 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 +{% endhighlight %} + +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. + +{% highlight 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 +{% endhighlight %} + +#### 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. + +{% highlight 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" +{% endhighlight %} + +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. + +{% highlight 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 +{% endhighlight %} + +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`. + +{% highlight sh %} +cd /etc/conf.d +ln -s uwsgi uwsgi.cgit +{% endhighlight %} + +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. + +{% highlight sh %} +rc-service uwsgi.cgit start +rc-service uwsgi.cgit service + +# Start this after boot +rc-update add uwsgi.cgit +{% endhighlight %} + +### 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. + +{% highlight 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; +} +{% endhighlight %} + +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://home.tyil.nl/git/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. -- cgit v1.1