January 10, 2025
At OpenBSD Amsterdam we like “simple” things. When it’s related to version control systems, things are rarely simple. Luckily there is (now) got(1), Game of Trees, and all the tooling which comes with it.
This post will, hopefully, be able to help you with getting gotd(8) and gotwebd(8) running.
First there need to be packages installed.
# pkg_add got gotd gotwebd #
When there will be more than one user it’s wise to create a new group, and use the group as a reference for the permissions the repository has.
# groupadd -g 1999 developers #
You can then create users who can use the repository. These users will have gotsh(1) as their shell, which is not a normal shell. Our recommendation is to use different usernames from the users who can access the host.
# useradd -d /home/dev1 -g developers -c "gotd account" -m -s /usr/local/bin/gotsh dev1 #
You can add the ssh key to the dev1 ~/.ssh/authorized_keys.
Using gotsh(1) properly requires additional configuration in sshd_config(5), described further below.
When you would like to have anonymous, read-only, access to the repositories you can create an additional group.
# groupadd -g 32765 anonymous #
This will also require a dedicated user, either with a known password or empty password. Use of an empty password must be explicitly allowed in sshd_config(5).
# useradd -p '' -d /home/anonymous -g anonymous -c "gotd account" -m -s /usr/local/bin/gotsh anonymous #
The configuration required in /etc/sshd_config(5):
Match Group developers
PasswordAuthentication yes
DisableForwarding yes
PermitTTY no
Match User anonymous
PasswordAuthentication yes
AuthenticationMethods none
PermitEmptyPasswords yes
DisableForwarding yes
PermitTTY no
The repositories are configured in /etc/gotd.conf(5), the example below also includes the option to send out notifications on commits via email and an http request. Check gotd.conf(5) for more examples.
user _gotd
listen on "/var/run/gotd.sock"
connection request timeout 2h
connection {
limit user anonymous 32
}
repository 'myrepo' {
path '/var/got/myrepo.git'
permit ro anonymous
permit rw :developers
notify {
email to notification@example.com relay mail.example.com port 25
url http://example.com/notification hmac developers
}
}
Create an empty repository to be served by gotd, ensuring that it can only be accessed by the _gotd user.
# mkdir -p /var/got/myrepo.git # chmod 700 /var/got/myrepo.git # chown _gotd /var/got/myrepo.git # su -m _gotd -c 'gotadmin init /var/got/myrepo.git' #
The hmac type represents shared secrets for use with HMAC signatures of HTTP request bodies. A suitable secret can be generated with openssl(1) as follows:
# openssl rand -base64 32 #
You can store this shared secret in /etc/gotd-secrets.conf(5). This file must be owned by the root user and must not be readable by any other users.
hmac developers nTF8Z5OhysK8VflVHk82DCisuBGdbOa4oKJj5k1HOIU=
Once that is all done you need to enable and start/restart gotd(8).
# rcctl enable gotd # rcctl restart gotd #
When you only need the ability to interact with your repositories with got(1), you are done.
If you would like to have a webfrontend for the repositories, continue reading.
There are two ways you can run gotwebd(8), either in the root of the webserver or an alternate path.
The configuration for root in /etc/httpd.conf(5) is as follows:
# gotwebd
location "/" {
root "/htdocs/gotwebd"
request strip 1
fastcgi socket "/run/gotweb.sock"
}
If you are considering a different path use:
# gotwebd
location "/got/" {
fastcgi socket "/run/gotweb.sock"
}
location "/got/*" {
root "/htdocs/gotwebd"
request strip 1
}
By default gotwebd(8) looks in
/got/publicwhich needs to exist.
# mkdir -p /var/www/got/public # chown -R www:www /var/www/got/public #
To make sure gotwebd(8) know what to do we need some config in /etc/gotwebd.conf(5).
For when you are running in root:
server "got.example.com" {
site_name "Example Code"
site_owner "Example Foundation"
site_link "Example Code"
logo_url "/"
}
Or in a different path:
server "got.example.com" {
site_name "Example Code"
site_owner "Example Foundation"
site_link "Example Code"
logo_url "/got/"
}
As you might have noticed the path used in gotd(8) and gotwebd(8) are different, and need to be synced.
You need to setup a clone with, for example, got clone -m, which sets up a mirror of the orignial got repository.
# got clone -m ssh://anonymous@example.com/myrepo /var/www/got/public/myrepo.git #
# echo "Description for myrepo" > /var/www/got/public/myrepo.git/description # echo "ssh://anonymous@example.com/myrepo" > /var/www/got/public/myrepo.git/cloneurl # chown -R www:www /var/www/got/public/myrepo.git # chmod 700 /var/www/got/public/myrepo.git #
The actual sync of the repo is then done with got fetch.
# /usr/local/bin/got fetch -r /var/www/got/public/myrepo.git #
Easiest would be to add these to a script and/or to add this to your crontab(5).
Lastly you need to enable and start/restart all the things.
# rcctl enable httpd gotwebd # rcctl restart httpd gotwebd #
It is a good idea to run maintenance on the repositires every once in while, suggested to do this weekly from crontab(5). You can do this with gotadmin(1), mainly gotadmin pack and gotadmin cleanup.
# /usr/local/bin/gotadmin pack -a -r /var/got/myrepo.git # /usr/local/bin/gotadmin cleanup -r /var/got/myrepo.git # /usr/local/bin/gotadmin pack -a -r /var/www/got/public/myrepo.git # /usr/local/bin/gotadmin cleanup -r /var/www/got/public/myrepo.git #