Installation and Setup¶
Prerequisites¶
A Linux host.
scripts/install.shknows how toapt-get installmissing packages on Debian and Ubuntu; on anything else you must install the prerequisites yourself.Root access. The installer refuses to start unless
EUID == 0(run withsudo).The Docker daemon running, with
/var/run/docker.sockpresent. The installer reads the socket’s GID and grants thesreuser access to it; if the socket is missing it aborts with a hint to start the daemon.Python 3.13. On Ubuntu < 24.04 you may need the
deadsnakesPPA; on Debian < 13 you need to upgrade or build it from source. The installer will offer toapt-get install python3.13on Debian-likes.
These tools must already be on PATH (always present on a POSIX system): sed grep stat getent useradd groupadd usermod install.
These tools are auto-installed via apt-get on Debian-likes if missing:
docker(any variety)asciinemamake gccgraphvizpython3.13
On other distributions install them with your package manager before running the installer.
Deployment layout¶
SRE’s runtime root defaults to /opt/sre, but the installer makes it configurable. Clone the repo (git clone https://github.com/sysreseval/sysreseval /opt/sre) or untar the release into /opt/sre — or into any other location you prefer.
scripts/install.sh detects where it is being run from and offers that path as the default — /opt/sre when run from /opt/sre/scripts/,
otherwise the parent of the script directory. The chosen value is patched into src/SRE/params.py (main_sre_dir) and substituted for /opt/sre in the sudoers rule,
the .desktop file, and the sre-preload-images.service unit at install time.
The installer is interactive — it asks roughly ten configuration questions, then creates the sre user, installs a sudoers file, and runs the build — and is meant to be run once per build, not once per student workstation. The trick to scaling from a single interactive run to a classroom of student machines is to share the resulting runtime tree (and replay a small per-host setup on each workstation). The rest of this document uses /opt/sre as the canonical example path; substitute your main_sre_dir wherever it appears if you chose something else.
Two common topologies:
Single read-only NFS export (recommended for classrooms). Clone the repo on a build server inside the directory you intend to export, run sudo ./scripts/install.sh
there once, then export the directory read-only and mount it as /opt/sre on every student workstation. Updates take effect everywhere as soon as the export is refreshed,
and students cannot tamper with the binaries or with the project files. The shell wrappers in sbin/ and bin/ don’t write to their own tree,
and all runtime state lives elsewhere — /var/lib/sre (sre_pub_dir) and /home/sre (sre_user_public_dir) stay on the local workstation — so a read-only mount works.
Build once, replicate per workstation. Run the installer once on a reference machine cloned at /opt/sre, then rsync (or image-clone) the resulting /opt/sre tree to every workstation. Running install.sh interactively on each machine is impractical for more than a handful of hosts.
Either way, each student workstation still needs a few per-host bits that aren’t part of the /opt/sre tree:
the
sresystem user/group, with the UID/GID baked intoparams.pyat build time/etc/sudoers.d/sremembership of
srein the localdockergroupa copy of
scripts/etc/sre_bash_completioninto/etc/bash_completion.d/srea copy of
scripts/etc/sysreseval.desktopinto/usr/share/applications/raised inotify limits and other post-install steps (see Post-install steps)
for the NFS topology, the mount itself
Script these from the relevant sections of scripts/install.sh if you have many machines.
The /opt/sre tree must contain lab/, lib/, graphics/, translations/, locale/, bin/, sbin/, src/, venv/. Lab authors also browse src/ while writing srelab.py files. See Runtime & Internals for the expected layout.
If you’d rather build in a separate working checkout (CI runner, personal dev tree) and move the result over afterwards, rsync or bind-mount the built tree into /opt/sre once make install has finished, then continue with the Post-install steps.
Running the installer¶
sudo ./scripts/install.sh
The script is interactive. It asks, in order:
Prompt |
Default |
Purpose |
|---|---|---|
|
|
Runtime root for SRE binaries, libs, labs, graphics, translations, locale. Substituted for |
|
|
UID of the system user that owns running labs. |
|
|
GID of the matching group. |
|
|
Public state: running projects, archives, |
|
|
Per-lab shared |
|
|
Whether |
|
|
|
extra authorized src dirs |
|
Extra directories (beyond |
Admin UIDs / GIDs |
(none) |
Extra UIDs/GIDs that SRE treats as administrators. |
The Docker socket GID is detected automatically (no prompt).
After you confirm the summary, the installer:
Saves a backup of
params.pytoparams.py.bak.<YYYYmmdd-HHMMSS>.Patches the answers into
src/SRE/params.py(single-linekey = valuesubstitutions, each verified after the edit).Runs
make remove-debug-modeifdebug_mode = Trueis currently set —make installrefuses to build while debug mode is on.Creates the
sresystem group and user (nologinshell, home/home/sre) if they don’t already exist. If a user/group with the requested name exists with a different UID/GID, it is kept as-is rather than overwritten — the installer warns and continues.Adds
sreto the Docker group resolved from the socket GID.Installs
/etc/sudoers.d/sre(required — thesysresevalGUI shells out tosudo /opt/sre/sbin/sre --userviasre-wrapper, so labs cannot start without this rule), validated byvisudo -cbefore being kept. The rule it installs is:Defaults!/opt/sre/sbin/sre env_keep += "USER_USERNAME SRE_XAUTH_COOKIE" ALL ALL= NOPASSWD: /opt/sre/sbin/sre --user *
The rule grants passwordless access to every user on the host, not a specific group —
sre-wrapperis the only entry point and it always passes--userwith the caller’s real login, so widening the sudoers scope doesn’t lower the security envelope. Restrict it to a specific group (e.g.%etudiant) if your site policy requires it.Optionally installs
scripts/etc/sysreseval.desktopto/usr/share/applications/so the GUI appears in the desktop application menu.Optionally installs
scripts/etc/sre_bash_completionto/etc/bash_completion.d/sreso thesreCLI gets bash completion system-wide.Optionally installs the
sre-preload-images.servicesystemd unit (oneshot, requiresopt-sre.mount; not enabled by default — enable withsystemctl enable --now sre-preload-images.serviceonce/opt/sreis mounted).Runs
make venvthenmake install(which ischeck-debug-mode+sre-wrapper+wrappers).Optionally creates symlinks in
/usr/local/bin/and/usr/local/sbin/pointing to each executable undermain_sre_dir/bin/andmain_sre_dir/sbin/, sosre,sysreseval, andsre-wrappercan be launched without their full path. Existing non-symlink files at the same paths are left untouched (with a warning).
Install manually¶
If you prefer to skip scripts/install.sh (e.g. on a non-Debian distribution, or to integrate with your own configuration management), perform the same steps by hand from a checkout of the repo:
Create the
sresystem group and user. Pick a UID/GID (the installer defaults to1100). The user needs a real home for shared/home/sre/{running_lab}mounts but no shell login:groupadd --system --gid 1100 sre useradd --system --uid 1100 --gid 1100 --home-dir /home/sre --shell /usr/sbin/nologin sre install -d -o sre -g sre -m 0755 /home/sre
Add
sreto the Docker group so it can talk to/var/run/docker.sock:usermod -aG "$(stat -c %G /var/run/docker.sock)" sre
Edit
src/SRE/params.pyto match your site. At minimum review:main_sre_dir— runtime root for SRE binaries, libs, labs, graphics, translations, locale (default/opt/sre). If you change this, also rewrite the literal/opt/srein the sudoers rule,.desktopfile, andsre-preload-images.servicesnippets below.sre_uid,sre_gid— must match the user/group created above.docker_gid— GID of the group owning/var/run/docker.sock.sre_pub_dir— public state directory (default/var/lib/sre).sre_user_public_dir— per-lab shared directory (default/home/sre).allow_privileged_machines— whethersrelab.pyfiles may declare privileged containers.execute_commands_on_host—'shell','split', orFalse.authorized_src_dir— list of directories from whichsrelab.pyfiles may be loaded. Must includemain_sre_dir + '/lab'; defaults to also including/home.admin_uids,admin_gids— extra UIDs/GIDs treated as administrators.terminal_cmd_prefix,terminal_title_opt— the external terminal emulator the GUI launches to open machine connections (defaultmate-terminal). Check which terminals are installed and uncomment the matching pair shown inparams.py:command -v mate-terminal gnome-terminal xfce4-terminal xterm terminator
debug_mode— must beFalsebefore building (make wrappersrefuses otherwise). Usemake remove-debug-modeif needed.
Install the sudoers rule — required for
sysresevalto start labs (the GUI invokessudo /opt/sre/sbin/sre --userthroughsre-wrapper). The rule allows every user on the host to invoke the wrapper without a password; restrict the first column to a specific group (e.g.%etudiant) if your site policy requires it. Then validate before keeping the file:Defaults!/opt/sre/sbin/sre env_keep += "USER_USERNAME SRE_XAUTH_COOKIE" ALL ALL= NOPASSWD: /opt/sre/sbin/sre --user *
visudo -cf /etc/sudoers.d/sre && chmod 0440 /etc/sudoers.d/sre
(Optional) Install the desktop entry so the GUI appears in the desktop application menu:
install -m 0644 -o root -g root scripts/etc/sysreseval.desktop /usr/share/applications/sysreseval.desktop
(Optional) Install the image pre-pull systemd unit from
scripts/etc/sre-preload-images.serviceinto/etc/systemd/system/. It requiresopt-sre.mountand is not enabled by default — see Pre-loading Docker images below.(Optional) Install bash completion for the
sreCLI. The script underscripts/etc/sre_bash_completioncompletes subcommands, running lab names (read from/var/lib/sre/projects/), available labs (viasre list), and option arguments. Install it system-wide:cp scripts/etc/sre_bash_completion /etc/bash_completion.d/sre
Or source it per-user from
~/.bashrc:. /path/to/sre_bash_completionBuild the venv and the binaries:
make venv # creates venv/ with Python 3.13 deps — see Dependencies below make install # check-debug-mode + sre-wrapper + wrappers
You can also run the CLI and GUI directly from source against the venv:
source venv/bin/activate
python3 -W ignore src/sre.py <command> # CLI
python3 src/sysreseval.py # GUI
Most sre subcommands need root and a working Docker setup, but the pure-Python paths (e.g. sre cat, sre sheet, sre outline) work from a venv as a regular user against pre-existing archive files.
Post-install steps¶
Once the installer has built the binaries, finish the deployment:
1. Deploy and verify¶
Make sure the built tree is reachable at
/opt/sreon every workstation that will run labs. If you ran the installer from/opt/sredirectly (per Deployment layout) this is already done; otherwise copy/bind-mount the built tree into place, or expose it via the read-only NFS export and mount it as/opt/sreon each workstation.Verify Docker access for the
sreuser:sudo -u sre docker ps
The Docker images SRE needs are pulled from Docker Hub on first lab start; no local image build is required.
Make sure
/opt/sre/binand/opt/sre/sbinare reachable onPATHso thatsysreseval,sre-wrapper, andsrecan be launched without their full path. The installer offers to create the symlinks under/usr/local/binand/usr/local/sbinfor you; if you skipped that prompt (or installed by hand), either add the two directories to the system-widePATH(e.g. via/etc/profile.d/sre.sh), or create the symlinks manually:ln -s /opt/sre/bin/* /usr/local/bin/ ln -s /opt/sre/sbin/* /usr/local/sbin/
2. Raise inotify limits¶
Privileged labs run /sbin/init (systemd PID 1) inside each container, and systemd reserves inotify watches per cgroup. Debian defaults (max_user_instances = 128) are quickly exhausted once two privileged labs run side by side, after which systemd in any new container exits at startup with Failed to create control group inotify object: Too many open files. Drop in the file shipped under scripts/etc/:
cp scripts/etc/sre-inotify.conf /etc/sysctl.d/60-sre-inotify.conf
sysctl --system
(Optional) Tune src/SRE/params.py further — see Runtime & Internals.
3. Enable X11 access for lab virtual machines¶
Labs run graphical (X11) applications inside their containers and those apps display on the host’s X server
(if the parameter x11_host is set to True in a virtual machine configuration).
For this to work the host’s X server must accept TCP connections on port 6000 (display :0). Modern X servers start with -nolisten tcp, so TCP is disabled by default and must be turned on explicitly. Access to individual labs is then authorized per project via an xauth cookie (SRE_XAUTH_COOKIE / sre start --xauth-file), so no xhost tweaks are needed — only the TCP listener.
How to enable TCP listening depends on your display manager. Two common cases:
GDM — in
/etc/gdm3/custom.conf:[security] DisallowTCP=false
LightDM — in
/etc/lightdm/lightdm.confunder[Seat:*]:xserver-allow-tcp=true
Restart the display manager (or log out and back in) for the change to take effect, then verify:
ss -ltn | grep 6000
You should see the X server listening on 0.0.0.0:6000 (and/or [::]:6000). scripts/install.sh runs this same check at the end and warns if no X server is listening on port 6000.
4. Restricting student access to Docker¶
For an exam to be meaningful, students must not be able to talk to Docker directly — otherwise a docker exec -it ... from a regular shell would let them connect to a forbidden container and bypass the lab’s restrictions.
The recommended setup:
Remove students from the
dockergroup entirely. Onlysre(and any administrator account) should be a member.Create a separate
docker-accessgroup and add the student accounts to it.Toggle that group’s access to
/var/run/docker.sockwith the two helpers shipped underscripts/:scripts/docker-allowedgrantsrwon the socket todocker-access(run before non-exam sessions).scripts/docker-forbiddenrevokes it (run before an exam).
Both helpers use setfacl on the Docker socket, so the change is immediate and survives until the next call.
6. Pre-loading Docker images¶
When an exam starts, every workstation pulls the same images at the same time — without precaution this can saturate the network and cause a meltdown. The fix is to pre-pull the images on each host ahead of time.
The unit scripts/etc/sre-preload-images.service (offered for installation by scripts/install.sh) runs once at boot and shells out to:
/opt/sre/sbin/sre preload-images --random-delay 120 /opt/sre/lab/
The --random-delay spreads the pulls over a 120-second window so workstations don’t hit Docker Hub simultaneously. The unit requires opt-sre.mount (i.e. /opt/sre mounted as a systemd mount unit) and is not enabled by default:
systemctl enable --now sre-preload-images.service
Reference¶
Build targets¶
Target |
Output |
|---|---|
|
Marks |
|
|
|
|
|
Compile Qt |
|
API docs (pdoc) + main docs (Sphinx) → |
|
Flip |
debug_mode must be False for make wrappers and make install, but must be True to run exam-mode integration tests — the GUI then emits the JSON event stream those tests assert on.
Tests¶
make tests # unit tests (excludes test_exam_mode.py)
make test FILE=test_net_config.py # single file
make functional-tests # functional tests (test_functional.py)
make exam-tests # exam-mode integration tests (requires debug_mode=True)
make all-tests # tests + functional-tests + exam-tests
Unit tests don’t need Docker or Kathara — they cover serialization, topology, grading logic, and pure-Python helpers. Functional and exam-mode tests stand up more of the system: see tests/conftest.py for the shared fixtures (mock_sre_args, tmp_lab_dir, tmp_pub_dir).
Pytest runs with -p no:cacheprovider so the production install (/opt/sre/, read-only) doesn’t try to write a cache.
Building the documentation¶
make docs # api_doc + main_doc_pdf + main_doc_html
make main_doc_html # Sphinx HTML only → docs/html/main/
make main_doc_pdf # Sphinx LaTeX → docs/documentation.pdf
make api_doc # pdoc API → docs/html/api/
The Sphinx targets pip-install sphinx myst-parser furo into the existing venv on demand; api_doc does the same for pdoc.
Dependencies¶
Installed by make venv:
Package |
Purpose |
|---|---|
|
Docker lab orchestration |
|
Qt6 GUI |
|
Efficient binary serialization |
|
Archive compression |
|
Network topology diagrams |
|
LibreOffice ODS spreadsheet export |
|
PDF report generation |
|
Lab description rendering |
|
MAC address handling |
|
Test runner |
Documentation builds also fetch sphinx, myst-parser, furo, and pdoc on demand.