Skip to content

Installing and configuring a Fedora virtual machine for continuous integration with GitHub Actions

Nathan Chancellor edited this page Jun 3, 2022 · 2 revisions

This repo provides two scripts to help create and configure a Fedora virtual machine using libvirt for self-hosted GitHub Actions.

The first is ci/install-vm.py, which will install a Fedora virtual machine using virt-install. The installation process will happen through the virtual machine's serial console, which can look a little wonky at times; hitting "r" then Enter once the machine is fully booted will show the first page of the Anaconda text installer, where you can hit "2" to proceed with text mode.

From there, I recommend the following settings:

  • Change the time zone to UTC and add an NTP server; I use time.google.com because it is easy to remember.
  • Stick with the default partitioning scheme, as it is what ci/configure-vm.sh expects.
  • Change the hostname to something somewhat unique so it is easy to identify in the GitHub self-hosted runner UI.
  • Add a root password.
  • Add a "runner" account and do not use a password or give it administrator permissions.

After adjusting all the settings, press "b" to begin the installation process. It will take some time. After it is finished, hit Enter to reboot the machine. After that, you will still be in the serial console, which I am sure you have noticed by now is harder to work with so we want to log into the virtual machine via SSH.

If you did not give the runner account a password, log into the root account in the serial console, adjust the PermitEmptyPasswords SSH option, and restart sshd.

# sed -i 's/^#PermitEmptyPasswords no/PermitEmptyPasswords yes/g' /etc/ssh/sshd_config
# systemctl restart sshd

If you want to administer the machine (such as taking updates) via the root account as opposed to logging into the runner account and running su, run the following command between the two above:

$ sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config

After that, hit Ctrl + ] to disconnect from the serial console. ci/install-vm.py will mark the newly created virtual machine for autostarting (so that you can reboot the host and the guest will start up automatically) and exit.

To get the IP address of the virtual machine, use virsh net-dhcp-leases default. Log into the runner account via SSH.

Once in the runner account, we need to install the self-hosted runner application. Navigate to the "Settings" tab of this repository, click on the "Actions" option in the sidebar, click on "Runner", then click on the green "New self-hosted runner" button. From there, click on "Linux" and either "x64" for an x86_64 machine or "ARM64" for an AArch64 machine. Follow all of the "Download" steps (I needed to change shasum -a 256 to sha256sum to avoid installing another package) and the first command of the "Configure" section (ci/configure-vm.sh will install and start a systemd service in lieu of the ./run.sh command).

Once the self-hosted runner application is set up, exit the current SSH session, copy ci/configure-vm.sh into the guest, log back in, and execute it with su and the root password:

host $ scp ci/configure-vm.sh runner@...:/tmp
host $ ssh runner@...
guest $ su -c "/tmp/configure-vm.sh $USER"

After that, you should see the newly created virtual machine added to the list of runners in the "Runners" section of the repository settings.

I uploaded a video going through this entire process for the more visually inclined:

YouTube video

If you need to uninstall the virtual machine for any reason (like starting over), run the following commands on the host (replace fedora if you used a different name during ci/install-vm.py).

$ virsh destroy fedora
$ virsh undefine fedora || virsh undefine --nvram fedora
$ virsh vol-delete --pool default fedora.qcow2

Make sure to remove the runner in the "Runners" section of the repository settings if it has been set up already (force removing is okay because there is no risk of leaking credentials, given the entire disk has been removed with the final command above).

Clone this wiki locally