This repository contains the configuration for setting up computers for participants, either for contests or for training.
The installation is done with FAI (Fully Automatic Installation), read the [FAI guide] to learn about it.
[FAI guide]: https://fai-project.org/fai-guide/
The way it works is that you have a FAI server, which is just a computer running a lot of different servers.
The computers to be installed are then network booted, and the installation happens automatically, which takes about 10 minutes.
Finally, the computers can be rebooted into the installed operating system.
When the installed computers are running, you can edit the configuration and perform a soft update.
This applies the entire configuration without reinstalling the machines, and it only takes a few seconds.
Here is what each server on the FAI server does:
- DHCP: This assigns IP addresses to machines, and also the TFTP server and filename for network booting.
- TFTP: This serves the bootloader and kernel which runs during the installation.
It also has a config file for each machine, which tells it what to do after network booting.
- NFS: Short for Network File System. It is read-only for clients, and contains two things:
- The NFS root. This is the root file system of the OS which runs during the installation.
- The config space. This is stored in this repository, and it defines how the machines are configured.
- SSH: When the installation is complete, the installer uploads log files via ssh, and also disables installation for the just installed machine.
- NTP: This serves the time, important for contests.
- apt-cacher-ng: This is a proxy for APT, which caches all downloaded packages. That way, the machines don't need to be connected to the internet for the installation, and you only download everything once.
- FAI monitor: This is a nice GUI which shows you the installation progress of all machines. It is optional.
## Setting up the FAI server
This part is unfortunately not automatic, but here is how to do it.
I don't think it's a good idea to install this on your personal laptop, so instead I made a fresh install of Ubuntu on an external SSD and installed FAI server there.
You could consider using Debian instead of Ubuntu, since Ubuntu needs a few extra steps.
When installing the system, set the hostname to `contestserver`.
Don't use `fai` as your username, because that is reserved for the log upload.
### Installing Ubuntu on an external disk
This works almost like a normal install: Download the Ubuntu installer ISO, flash it to a USB drive, and boot from it.
However, there is one issue, which is that the EFI bootloader needs to be installed in a different way on external disks, and the Ubuntu installer does not support that.
Here are some guides:
- https://wiki.ubuntuusers.de/EFI_Externer-Datentr%C3%A4ger/ (it seems this doesn't work, but it explains some things)
Note: Some extensions (e.g. cpptools and python) may have pre-release versions, which should be avoided. But the marketplace website does not show which versions are pre-release, and if you just click "Download Extension", you will get a pre-release if there is one. To see which version is the most recent non-prerelease, open the extension in the marketplace in VS Code and look for the version tag. Then download this version in the "Version History" tab on the marketplace website.
Download the [SOI Code::Blocks template] for Ubuntu and put it in `/srv/soifai/config/downloads`.
(Comment: Wifi devices are turned on by default, and if you turn it off (through the UI, or with nmcli or rfkill), systemd-rfkill will create a file called e.g. `/var/lib/systemd/rfkill/pci-0000\:02\:00.0-bcma-1\:wlan` with content 1, to remember that *this* device should be turned off. I have not found a way to have *all* wifi devices turned off by default.)
Test time sync:
```
parallel-ssh -h hostlist -i date
```
### Performing a soft update
Do this to apply configuration after you have changed it.
Open FAI monitor to see progress:
```
fai-monitor | fai-monitor-gui -
```
Then:
```
parallel-ssh -h hostlist -o output --timeout 0 fai -v softupdate
```
The output of each machine is stored in the folder `output`.
While working on the config and testing on a single machine, you can also run a single script, which is faster:
```
mount -t nfs 10.0.0.9:/srv/soifai/config /var/lib/fai/config
We used the laptops owned by SOI for the replacement exams.
For this, we manually set a static IP address (same as the DHCP assigned one) in the settings on each laptop (it will prompt you for the root password).
That way, it works without the FAI server.
All the commands in the section "Starting the contest" can then be run from the grader.
You just need to install: `sudo apt install ntp pssh`
## Contest setup at Uni Bern
At Uni Bern, we don't set up the machines from scratch.
Most of the software is already installed for us.
Copy this repository to the server, and run admin commands from there.
**Problems with RTL8153-based USB Ethernet adapters.**
I suspect that problems are caused by faulty firmware in the adapters.
We had a strange problem where network booting failed when the laptops were connected to a Netgear GS316P switch, but worked when connected to a Netgear GS108 switch.
The adapters have issues when connected over USB 3, but work fine over USB 2.
You can force USB 2 by connecting adapters via an USB 2 extension cable.
Half-inserting the USB connector also works in a pinch.
**Installation of packages fails.**
Check that the date is set correctly in the system settings.
If you get a HTTP 503 error, try restarting `apt-cacher-ng`.
Fixed by adding the gnome shell version from `gnome-shell --version` to the list of supported versions: `shell-version` in `simplefiles/CONTESTANT/usr/share/gnome-shell/extensions/user-indicator@soi.ch/metadata.json`.
The config space defines how the machines are setup.
It is mounted with nfs on the target machine.
FAI has the concept of *classes*.
Classes are defined by a list of strings.
Order matters, classes are applied in the order in which they are defined.
We have defined these classes:
-`PARTICIPANT`: This sets up things that are used for both contest and training.
- various code editors and other tools
- VS Code extensions
- soi header
- Code::Blocks template
- wallpaper
- default favorite apps
- default list of keyboard layouts
- only allow ssh login as root, and disable password auth
-`CONTESTANT`:
- firewall (configured in `simplefiles/CONTESTANT/etc/nftables.conf`)
- disable bluetooth
- disable sleep
- disable lock on blank screen
- disable software update notifications
- disable some panels in gnome-control-center
- add polkit rules which block changing network settings and mounting storage devices (it prompts for the root password)
- configure NTP server
- set `authorized_keys` for root
- enable automatic login
- set browser homepage and bookmarks to https://finals.soi.ch
- add a gnome shell extension which displays the user name in the top bar
- add contest lock gnome shell extension
- add some management scripts to be run via ssh
- add some packages
-`TRAINING`:
- add admin user with sudo rights
- remove APT proxy after packages are installed
Here is an overview of the file structure:
-`class`:
First, all scripts in this folder which start with two digits are run.
Of these files, the ones which do not have a `.sh` suffix define the classes.
FAI then goes through the list of classes and reads variables from the `$class.var` file (if it exists).
-`script`:
This contains a folder of scripts for each class.
In these scripts, we can use these variables:
-`$FAI`: Path to the config space.
-`$target`: The root of the system being installed.
For soft update, this is `/`.
-`$ROOTCMD`: `chroot $target` during install.
For soft update, this is empty.
-`simplefiles`:
This contains a bunch of files for each class that are copied over the root of the target.
(The FAI example config only has `files`, but that is annoying because classes are at the end of the path.)
-`package_config`:
This defines which packages are installed.
During the warmup, some participants requested additional VS code extensions.
Because we didn't want them to be enabled for everyone, we put the .vsix files into `simplefiles/CONTESTANT/opt/` and did a soft update, so that they could manually install it from `/opt`.
Whenever you add a new script, don't forget to make it executable with `chmod +x script.sh`, otherwise it will silently not be executed.
Third-party apt repos are already setup. This is how it was done:
The contest lock screen is a gnome extension which can lock the screen and show a countdown until the contest starts.
The screen is unlocked when the contest starts.
The lock screen also displays the user name and a title.
It is configured in the file `/etc/contest-lock.json`.
It watches this file, and when it changes the new configuration is instantly applied.
If there is an error in the config file, it will continue to use the old config and print a message.
To see the logs, run this on a contestant machine:
```
journalctl -f -o cat /usr/bin/gnome-shell
```
An additional text can be shown with the `message` field. It can contain newlines (`\n`).
In case there is a problem with the contest lock screen and you can't fix it, the backup solution is to turn off `AutomaticLoginEnable` and set a password instead, that you announce when the contest starts: