github actions is great, but it does not offer any arm hardware to run your tests on. So, I bought a Traverse Ten64 with the hope of using it as a github actions runner for the Solang Solidity Compiler.
In order to run the runner, you run some dotnet code called the GitHub Actions Runner. This software connects to github, and listens to instructions of what jobs to run. There are a few attack vectors here: someone could create a pull request with some malicious code in it (there is some mitigation against this), or github itself might be coerced into sending malicious commands to your runner.
The other consideration is that you would like each time that your runner executes some code, it has a clean environment with no residue from the last run. So, I think the best way to go about this is to run the runner in a VM, which then shuts itself down after each run, and then is restored from a VM snapshot.
First you want to set up your VM.
1 | qemu-img create /home/sean/runner-image/sean-ci-linux-arm64.qcow2 -f qcow2 200G |
I would create a user called runner, with no password and no root password either, so that sudo apt-get install foo...
works from github actions. You can remove a password with passwd -d
.
Now in your VM, download the github runner as instructed by github in your project settings, and configure it and register it using ./config.sh
. Do not install the service, we will be creating our own.
In the same directory as the runner, create a shell script called runshutdown.sh
with the following contents:
1 |
|
Also create a service in /etc/systemd/system/actions-runner.service
. Note this could probably be a user service.
1 | [Unit] |
Enable the service with:
1 | systemctl daemon-reload |
Now your VM should be ready for snapshotting, so shut it down with shutdown -h now
.
Once it is shutdown, create a snapshot using:
1 | qemu-img snapshot -c restore-me sean-ci-linux-arm64.qcow |
Now we’re going to create a script which restores the snapshot, starts the VM, and loops when the VM shuts down. I could not find a way of doing this in shell script, so this is done using the python libvirt api.
1 | #!/usr/bin/python3 -u |
Create a file ~/.config/systemd/user/action-runner-vm.service
:
1 | [Unit] |
Now start this service with:
1 | systemctl daemon-reload |
And you should be in business. You can always connect to the console of the actions runner with virsh console actions-runner
.