Setup a Gitlab runner containing Guix

Table of content

This tutorial describes how to setup a Gitlab runner that can be used to run Guix commands, i.e. for CI/CD or pages generation.

VM creation

We use the infrastructure provided by https://ci.inria.fr but the instructions below can be adapted to another provider.

The first step is to create a new project: Projects+ Create new project.

In the project creation window, fill the name of your project and select None in the Software part in order to use gitlab-runner.

Click on Create project and then go to Dashboard, where the new project should appear.

Click on Manage project. You should get an overview of the project, with no virtual machines (so called slaves) so far.

Click on Manage slaves, which leads you to the list of configured VMs. Add a new VM by clicking on + add slave.

Select Ubuntu 22.04 LTS amd64 server (ubuntu-22.04-amd64) as a template and configure the resources you need, depending on your usage of the VM. As a good starting point, 8GB of RAM, 4 cores and 50 GB of disk space will allow you to use Guix comfortably.

When you're done, click on Create slave. The newly created VM should appear in the VM list.

Keep the webpage open in your browser.

Gitlab runner configuration

In your Gitlab project, you should activate CI/CD in SettingsGeneral under the Visibility submenu.

Once CI/CD is activated, you should see a new CI/CD item in the Settings menu. Click on it.

Now, in the Runners submenu, you can create a new runner for your project by clicking New project runner.

If you want to setup tagged jobs, add tags information, otherwise it is safe to check the Run untagged jobs box.

Click on Create runner and you should see the Register runner page.

Keep the webpage open in your browser and follow with the instructions below.

VM configuration

Before being able to use the VM as a Gitlab runner, we have to install both Guix and Gitlab runner related software.

Connexion to the VM

Click on the Connect button in the VM summary list on https://ci.inria.fr website (DashboardManage projectManage slaves) to display the commands needed to log into the VM using SSH.

It boils down to:

  ssh <user>@ci-ssh.inria.fr
  # From within the new shell
  ssh ci@<machine_name_or_ip>
  # It is a good time to change default root password...
  sudo passwd
  # ...and ci user password.
  passwd

Increasing the disk space on /

The default template comes with a somehow tight root filesystem as an LVM logical volume, but with unallocated space in the corresponding LVM volume group.

  # Display the free space in the volume group.
  sudo vgdisplay
  # Display the logical volumes (only one in the template).
  sudo lvdisplay
  # Add 10GB to the logical volume containing the root filesystem.
  sudo lvextend -L +10G /dev/ubuntu-vg/ubuntu-lv
  # Online resize the underlying filesystem.
  sudo resize2fs

Installing gitlab-runner

Here is a summary of the required commands. More details in the documentation.

  # This prevents issues where unattended-upgrades takes a lock on the package DB.
  sudo systemctl stop unattended-upgrades.service
  # Get the Debian/Ubuntu installation script from Gitlab.
  curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
  # Install the Ubuntu package.
  sudo apt install gitlab-runner
  # Don't forget to restart unattended-upgrades.
  sudo systemctl start unattended-upgrades.service

Installing Guix in the VM

Here is a summary of the required commands. More details in the documentation.

  #
  # Guix installation from the script. The version packaged in Ubuntu is outdated
  # and is not compatible with the substitute server at Guix HPC.
  cd /tmp
  wget https://guix.gnu.org/install.sh -O guix-install.sh
  chmod +x guix-install.sh
  # Answer No to "Discover substitute servers locally", Yes elsewhere.
  sudo ./guix-install.sh
  # Configure Guix to use Guix HPC substitute server.
  wget https://guix.bordeaux.inria.fr/signing-key.pub
  sudo guix archive --authorize < signing-key.pub
  rm signing-key.pub
  sudo sed -i.bak -e "s@\(ExecStart.*guix-daemon\)@\1 --substitute-urls='https://guix.bordeaux.inria.fr https://ci.guix.gnu.org https://bordeaux.guix.gnu.org'@" /etc/systemd/system/guix-daemon.service
  # Restart =guix-daemon=
  sudo systemctl daemon-reload
  sudo systemctl restart guix-daemon.service
  # Log in as user gitlab-runner, which is used by the CI
  sudo -u gitlab-runner -s
  # Add Guix HPC configuration
  mkdir -p $HOME/.config/guix
  cat > $HOME/.config/guix <<EOF
  (append
       (list
         (channel
           (name 'guix-hpc-non-free)
           (url "https://gitlab.inria.fr/guix-hpc/guix-hpc-non-free.git")
           (branch "master")
           (commit "23d5f240e10f6431e8b6feb57bf20b4def78baa2")))
        %default-channels)
  EOF
  # Update the channels.
  guix pull

Configuring gitlab-runner

Go back to the Register runner webpage and follow the instructions there.

It boils down to executing the following command (use sudo to execute it as root):

  gitlab-runner register --url https://gitlab.inria.fr --token <TOKEN>

and selecting the right instance (https://gitlab.inria.fr in our case) and the right executor (shell in our case, see the documentation for more details).

Once in the Runners submenu of SettingsCI/CD, you should see a new runner up and running.

Using the runner

Here is a sample .gitlab-ci.yaml file running a helloworld stage:

  stages:
    - helloworld

  helloworld:
    script:
      - guix shell -C hello -- hello

When pushed to your repo, this file should spawn a successful CI job and you should be able to see the result of a helloworld command in the corresponding log.