============================ Continuous testing of xsuite ============================ Since GitHub do not yet support GPU on their own Actions runners, we set up our own self-hosted runner on OpenStack for this purpose. The configuration of the test workflow can be found in `.github/test_gpu.yaml` of the xsuite repository. However, the test machine needs to first be prepared. As we use Docker to run the tests in an isolated and controlled environment, some dependencies need to be installed. These are Docker and Nvidia drivers and Container Toolkit (assuming the test machine uses an Nvidia GPU). The steps to accomplish this are listed below. Setup of the test runner machine (Ubuntu) ========================================= An OpenStack GPU-capable machine -------------------------------- This can be set up largely following the guide `here `_. .. code-block:: bash # Find the image uuid you want openstack image list --community | grep -i ubuntu # Commands to be passed during the setup of our machine cat > ubuntu-bootcmd.txt <<- EOF #cloud-config bootcmd: - printf "[Resolve]\nDNS=137.138.16.5 137.138.17.5\n" > /etc/systemd/resolved.conf - [systemctl, restart, systemd-resolved] EOF # Create the VM openstack server create \ --image \ --user-data ubuntu-bootcmd.txt \ --flavor g2.5xlarge \ --key-name lxplus xsuite-ubuntu-tests Configure the test machine -------------------------- Once we ssh to the machine (as user `ubuntu`) we need to install Docker and suitable Nvidia drivers. We can use the convenience script provided by the Docker people, as described `here `_. .. code-block:: bash # Install docker curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh # Set up rootless for good practice dockerd-rootless-setuptool.sh install To be able to run containers with GPU support we need the Nvidia container toolkit. A prerequisite for that are the Nvidia drivers. The up-to-date install instructions for the toolking can be found `here `_. There is also a useful page available on the topic on the `CERN OpenStack guide `_. .. code-block:: bash # Install cuda drivers wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-keyring_1.0-1_all.deb sudo dpkg -i cuda-keyring_1.0-1_all.deb sudo apt-get update sudo apt-get -y install cuda # Install the container toolkit curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sudo apt-get install -y nvidia-container-toolkit After restarting the Docker daemon with `sudo systemctl restart docker`, we can check that everything works by running a sample image from Nvidia: .. code-block:: docker run --rm --gpus all nvidia/cuda:11.0.3-base-ubuntu20.04 nvidia-smi Install the GitHub Actions runner --------------------------------- We can follow the steps listed under *xsuite/xsuite > Settings > Actions > Runners > New self-hosted runner*. This involves downloading and configuring the runner with the repository. Afterwards, we install and run the runner as a service with user `ubuntu`: .. code-block:: ./svc.sh install ubuntu ./svc.sh start Setup of the test runner machine (Alma 8) ========================================= Synopsis -------- On the AlmaLinux 8 virtual machine (the “host”) will be running a GitHub runner executing Xsuite tests in a containerised environment. In order to support GPU execution contexts, Nvidia drivers and the Nvidia Container Toolkit will need to be installed. At the time of writing this guide, the Nvidia guide states that Docker is not supported under RHEL 8/CentOS 8 (and so effectively Alma 8 as well), and that is why we will use Podman instead of Docker. Podman is a container environment similar to Docker, however it does not require a separate daemon to run containers, which makes it more lighweight. Setup a user account -------------------- We can set up an appropriate GPU-capable OpenStack VM in the same way as in the previous section (Ubuntu), or simply by following the GUI wizard on openstack.cern.ch. On the fresh Alma VM we first set up a user account which we will use to run our actions: .. code:: bash adduser xsuite We add the user to the sudoers file, by appending a line to ``/etc/sudoers``: ``echo 'xsuite ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers``. If necessary, copy the authorised SSH key from the root account to the new account: ``cp /root/.ssh/authorized_keys /home/xsuite/.ssh/``. Fix permissions with ``sudo chown -R xsuite:xsuite .ssh`` and ``chmod -R +rw .ssh``. From now on we reconnect with SSH using the ``xsuite`` account or switch to it with ``su xsuite``. Install a Container Engine -------------------------- We will need a container engine to run the tests. In this case we install Podman as it is more lightweight: .. code:: bash sudo dnf install podman Let's make a link called ``docker`` pointing to ``podman``, so that the workflows (which presume Docker) work on the new machine: .. code:: bash sudo ln -s /usr/bin/podman /usr/bin/docker Installing Nvidia drivers (can be skipped for CPU-only VM) ---------------------------------------------------------- We will largely be following the official Nvidia guide [1]_, however only as far as installing the drivers. CUDA is not necessary on the host machine, only inside the containers. First, some prerequisites are necessary. In this guide, we will be installing the drivers using the “network RPM” method in Nvidia’s guide. We will perform a DKMS installation, so that the drivers get recompiled whenever there is a kernel update, so that it does not need to be done manually. To this end, we need to install kernel headers: .. code:: bash sudo dnf install kernel-devel-$(uname -r) kernel-headers-$(uname -r) To satisfy other requirements of the Nvidia driver package, we enable the third party repository EPEL: .. code:: bash sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm Then we can enable the network repo and install the drivers: .. code:: bash sudo dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo sudo dnf clean all sudo dnf -y module install nvidia-driver:latest-dkms sudo dnf clean expire-cache # clean dnf cache afterwards To check if everything works, we can ``sudo reboot``, then run the following command, which, if all went well, should return a summary of the available GPUs: .. code:: bash nvidia-smi .. note:: **Troubleshooting Note:** If at this stage the driver is not working, it could be that it was not picked up by DKMS. We can verify this by running ``dkms status``: if there is no ``nvidia/...`` entry, or if to the right of it its status is not listed as ``installed``, we can run ``dkms autoinstall`` to attempt to recompile the drivers. Installing the Nvidia Container Toolkit (can be skipped for a CPU-only VM) -------------------------------------------------------------------------- We will follow the instruction of the official Nvidia guide [2]_, the steps of which are summarised below. A container environment is a prerequisite for installing the NCT: earlier we have installed Podman. Podman is compatible with the Container Device Interface specification, which means that only the base components of the Nvidia Container Toolkit are needed. We install the required package: .. code:: bash sudo dnf clean expire-cache sudo dnf install -y nvidia-container-toolkit-base Check that it works: .. code:: bash nvidia-ctk --version And generate the CDI specification with: .. code:: bash sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml To be able to run rootless containers with ``podman``, we change the following configuration: .. code:: bash sudo sed -i 's/^#no-cgroups = false/no-cgroups = true/;' /etc/nvidia-container-runtime/config.toml When running rootless, we may also encounter permission issues with SELinux. We need to add an appropriate label ``container_file_t`` to the Nvidia device files: .. code:: bash sudo semanage fcontext -a -t container_file_t '/dev/nvidia.*' restorecon -v /dev/* Note that it may be necessary to relabel the device files with the ``restorecon`` command in the case of changes/updates to the hypervisor. .. note:: **Troubleshooting Note:** It may be necessary to run ``sudo dnf install policycoreutils-python-utils`` for ``semanage`` to work, as after a certain update to Alma it stopped being provided by default. Check that everything works with: .. code:: bash podman run --rm --gpus all cupy/cupy:latest nvidia-smi Setup the GitHub runner ----------------------- Navigate to *Settings > Actions > Runners* on GitHub and follow the instructions for creating the new runner. Once this is done, there are three final steps that need to be done before we enable the runner service. Take care to replace ``{runner-name}`` in the subsequent commands with the chosen name of your runner. Set the right container format ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Since we are using a docker Dockerfile format, which is slightly different to the OCI format, to which podman defaults, we need to change the setting for podman to use the Docker format. To achieve this, we add an environment variable to the runner service file: .. code:: bash sudo ./svc.sh install xsuite && sudo ./svc.sh stop # create but don't start the service sudo systemctl edit actions.runner.xsuite-xsuite.{runner-name}.service In the opened editor (which may be empty), we paste the following: .. code:: ini [Service] Environment="BUILDAH_FORMAT=docker" Configure SELinux ~~~~~~~~~~~~~~~~~ We need to label the service script as an executable to SELinux, otherwise it will prevent us from launching the service. .. code:: bash sudo semanage fcontext -a -t bin_t '/home/xsuite/actions-runner/runsvc.sh' sudo semanage fcontext -a -t bin_t '/home/xsuite/actions-runner/bin(/.*)?' sudo restorecon -v -R /home/xsuite/actions-runner/ Enable account lingering ~~~~~~~~~~~~~~~~~~~~~~~~ In order for Podman to be able to function headless, we need to enable account lingering, as otherwise, systemd will kill any user process when there is no login session for the user. .. code:: bash sudo loginctl enable-linger xsuite Enable and start the service ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Finally, we can start the runner service, which will immediately begin listening for new jobs: .. code:: bash sudo ./svc.sh start .. note:: **Troubleshooting Note**: The status of the runner service can be checked with ``sudo ./svc.sh status`` which is an alias to ``systemctl status actions.runner.xsuite-xsuite.{runner-name}`` More logs for the service can be viewed with ``sudo journalctl -x -u actions.runner.xsuite-xsuite.{runner-name}``. In case of errors it can be useful to also consult SELinux logs: ``sudo cat /var/log/audit/audit.log | grep 'denied'``. .. [1] https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html .. [2] https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html