CLI Reference — sre¶
sre --help groups subcommands into five buckets: dual (admins + GUI via sre-wrapper), admin-only, exam management, post-exam management, and internal (GUI-only).
Global options¶
sre [--user] [--debug] <subcommand> ...
Option |
Description |
|---|---|
|
Set by |
|
Verbose diagnostics to stderr. |
Access is restricted to root, the sre user (params.sre_uid = 1100), members of params.admin_uids, or members of any params.admin_gids group. Non-privileged users may only run cat, check-eval, re-eval, sheet, and outline.
Dual commands¶
sre start [-d data] [-p] [--flavor … | --flavor-json … | --set-flavor-name …] [--xauth-file <file>] [--instructor-mode] <lab> [data_version]¶
Starts a new lab instance, named {timestamp}@@@{lab_name}@@@{username}. Imports srelab.py, runs Data.generate(flavor) (or loads -d data.json), builds NetScheme, pulls images, deploys via Kathara, applies the initial state, and writes info.json. See Internals for file-transfer and progress mechanics.
Argument / Option |
Description |
|---|---|
|
Lab name (from |
|
Treat |
|
Reuse an existing |
|
Optional seed for |
|
Flavor field values (e.g. |
|
Flavor as JSON dict (used by the GUI). |
|
Use a named preset |
|
Read |
|
Start the project in instructor mode (privileged only). |
|
Start a debug project (see Lab Authoring; privileged only): |
|
The same debug project, |
sre stop <running_lab>¶
Undeploys containers and removes the project directory from /var/lib/sre/projects/. Kathara only undeploys the containers whose user label matches the caller, so stop first aligns SUDO_UID with the label used at deploy time (sre for non-privileged labs, the project owner for privileged ones; both are tried when the lab is not loaded, as in pre-start-exam).
The name may be a unique substring of the running lab name (every command taking a <running_lab> resolves it this way). In user mode only the caller’s own projects and those started by root or the sre user are candidates: another user’s project is refused by its exact name and never listed nor matched by a substring (params.check_project_owner).
sre stop-all¶
Stops every running project the caller may access, each one as sre stop does (with the lab_hash of its info.json: no lab module is loaded and both container labels are tried): all of them for a privileged caller, in user mode the caller’s own projects and those started by root or the sre user (every project when params.check_project_owner is off). The GUI’s File → Close All Projects runs it. Unlike sre wipe nothing else is touched: no Kathara wipe, the stray entries of the projects directory and the orphan user public directories stay, and a project without info.json (a start in progress or failed) is left alone. Refused in user mode during an exam, like stop.
sre save [-o <file>] [--full-images] <running_lab>¶
Saves a running project into a single save file (.sre): the filesystem of every container (captured by the patched Kathara save_lab, as a diff against the base image by default) plus the project files (data.json, answers/, .private/files, the user public dir with shared/ and the volume directories, .private/mnt). The lab must set allow_save_restore = True; the lab’s save state is applied first (see Lifecycle states). Only files are captured, not running processes.
Option |
Description |
|---|---|
|
Write the save file here instead of stdout (privileged only). |
|
Store full committed device images instead of filesystem diffs — self-contained but large (privileged only). |
In user mode (--user, i.e. from the GUI) the file is always written to stdout. When the lab defines save_key, the payload is encrypted. See Save file format.
sre restore [--instructor-mode] <save_file | ->¶
Restores a save file as a new running project (fresh timestamp, current user): loads the lab module named in the header (allow_save_restore required), recreates the project directories and copies the saved project files back, rebuilds the Kathara lab from the restored data.json (fresh host ports, X11 cookie, volumes, /shared), redeploys the containers from the saved filesystems (Kathara.restore_lab(…, lab=…), same pull/deploy progress events as start), refreshes exetests.py, applies the lab’s restore state and writes info.json. On failure everything created so far is rolled back.
- reads the save file from stdin — the only form accepted in user mode (the GUI opens the file as the student). Labs referenced by an absolute path (sre start -p) can only be restored by privileged users, unless the path lies inside the lab directory (/opt/sre/lab), in which case the save file is restored like any other lab of that directory. An encrypted file needs a lab with the same save_key; a cleartext file for a lab that defines save_key is refused in user mode (accepted with a warning otherwise).
--instructor-mode (privileged only) puts the new project in instructor mode. A save file never carries the mode: without the option the restored project is a normal one, whatever the saved project was.
sre wipe¶
Stops every running Kathara lab and removes everything under /var/lib/sre/projects/ and the user public directories. Privileged only: the user-mode form is sre stop-all.
sre connect [--shell <shell>] [--exec <argument…>] [--no-records] <running_lab> <device>¶
Opens a terminal session on a device: the shell of a machine, or the management console of a managed switch when <device> is a network declared with 'mode': 'managed' (prompt <network>$ , exit leaves). In user mode the console only accepts the commands of params.switch_user_commands, and it is refused when the lab sets 'allow_connection': False on the switch. The commands of the console are listed in Hubs, switches and VLANs.
Option |
Description |
|---|---|
|
Override the machine default shell (privileged only; not for a switch). |
|
Run one command via the shell and return (consumes rest of argv). On a switch: one console command, privileged only. |
|
Do not record the terminal session (privileged only). |
sre eval [-p path] [--auto-eval] <running_lab>¶
Evaluates a running lab. The atomic lock file .private/eval_in_progress prevents concurrent evals.
--auto-eval marks a user-triggered self-evaluation (sent by the GUI’s Start evaluation). With --user, it enables the delay_between_self_grade cooldown (outside exam mode), appends a line to .private/auto_eval.log, and prints the result JSON. Without --auto-eval, a --user invocation runs silently — no cooldown, no log, no stdout. The auto_eval_count (lines in .private/auto_eval.log before this run) is assigned to self.auto_eval_count and embedded in the archive’s answers. If the lab sets no_mark_on_self_grade, letter grades (OK/MEH/FAIL) replace numeric grades. Results are archived as .zst — see Archive format.
sre state <running_lab> <state_name>¶
Applies NetScheme.<state_name>() to a running lab. In user mode only the states declared @sre_state(user_allowed=True) of a lab setting allow_user_states = True are accepted, except on a debug project or a project in instructor mode, where every state is. File operations registered via file() / append_to_file() are injected via in-memory tar archives sent to container.put_archive("/").
Admin-only commands¶
sre exec [--shell <shell>] <running_lab> <device> <command…>¶
Runs shell -c <command> in a container and forwards stdout/stderr/exit code. Default shell is params.default_exec_shell.
When <device> is a managed switch (a network with 'mode': 'managed'), <command…> is one command of its management console, e.g. sre exec <running_lab> lan vlan/print or sre exec <running_lab> lan port/setvlan @pc1 10 (@machine: the port of that machine). The exit status is 0, or the error number given by the switch (17 when a VLAN already exists) with the message on stderr.
sre set-instructor-mode <running_lab> and sre remove-instructor-mode <running_lab>¶
Switch the instructor mode of a running project (sre start --instructor-mode and sre restore --instructor-mode set it from the beginning). The mode is meant for the instructor’s own project and has three effects:
the texts the lab wraps in
instructor()(see Lab Authoring) are kept ininfo.json; for any other project but a debug project (sre start --debug-project, which keeps them too) they are dropped before the file is written, so students cannot read them;every
sre stateappends what it executed to the project’soperations.log(evaluations are not logged, unlike in a debug project);every state can be applied, as to a debug project:
sre statein user mode (what the GUI runs) no longer requiresallow_user_statesnor@sre_state(user_allowed=True).
In the GUI all three show only while the Instructor mode button is on (see GUI). Nothing else changes: hidden machines and grades are those of a normal project.
Both commands write info.json again; the question hashes do not depend on the mode, so the answers already given stay attached. remove-instructor-mode also deletes operations.log, unless the project is a debug project (which also keeps its instructor texts).
sre eval-all [--display-grades / --no-display-grades]¶
Evaluates every running lab instance concurrently. --no-display-grades suppresses the per-lab grade summary.
sre check [-p] <lab> [<state>]¶
Validates a lab module without deploying: imports it, runs Data.generate(), checks that the Data instance survives the data.json round trip (to_json() / from_json(), pack() / unpack()), builds NetScheme, runs initial(), calls Grade.grade(). With state, also validates that state method. The networks that are not hubs are printed with their type and the VLANs of their ports, and the console commands a state sends to a managed switch are listed with its other operations (switch <network>: cmd …). The numbered sections of informations (info_subtitle() / @@sec@@ markers) are resolved as at sre start and printed as an outline (number, title, tag), and the @@ref@@ references of the question texts are checked: a marker outside a header, a level jump, a tag defined twice or unknown, or languages whose sections differ, is a FAIL.
sre watch [--timeout <sec>] [--interval <sec>] [-H <regexp>] [-S <time>] [-L] <dir…>¶
Live terminal dashboard scanning <dir…> for .zst archives. Default refresh: params.default_dashboard_refresh_interval_in_watch_command. --timeout is the inactivity-alert threshold (default 90 s). -H/--hostname-filter and -S/--starting-time preset the R and S keys.
One row per running project instance on a host: hostname + lab + the start timestamp of running_lab_name. A lab opened twice by the same student gives two rows with their own grades and alerts; a lab stopped then started again keeps its old row until it is dismissed (P), hidden (S) or collapsed. -L/--only-last-instances (the L key) collapses to one row per host and lab: the most recently started instance, whatever the age of its archives. Dismissals and S apply after the collapse, so they never reveal an older instance. Lab counts and statistics are per instance.
Columns (from each archive):
Column |
Source |
|---|---|
HOSTNAME / LOGIN |
|
LAB NAME |
Middle segment of |
STARTED |
First segment of |
GRADE |
|
ERR |
Length of |
LAST EVAL |
|
TIME REMAINING |
|
Keys:
Key |
Context |
Action |
|---|---|---|
|
Any |
Toggle focus between Projects and Alerts |
|
Projects / Alerts |
Move selection |
|
Projects |
On a project row: its grade elements; on a |
|
Projects |
Dismiss selected project instance (hostname + lab + start) |
|
Projects |
Dismiss all projects from the selected hostname |
|
Projects |
Set a hostname regexp filter (empty = show all; initial value: |
|
Projects |
Only show projects with an archive received after a time (empty = no limit; initial value: |
|
Projects |
Toggle “only last instances”: one row per host and lab, the most recently started (initial value: |
|
Either |
Un-dismiss all |
|
Alerts |
Dismiss selected alert |
|
Any |
Quit |
|
Any |
Toggle help |
Dismissals self-expire: inactivity alerts return on new archives, error alerts return when the count changes.
sre preload-images [--random-delay <sec>] [--progress] <file_or_dir…>¶
Scans lab .py files for image= / 'image': patterns and docker pulls each unique image. --random-delay <sec> waits 0–N seconds before pulling (smooths thundering-herd when invoked across many hosts). --progress also writes the steps as JSON lines on stderr ({"phase": "preload", "status": "start", "total": N}, then "status": "pull" with image / current / total before each pull and "status": "error" with image after a failed one); what is printed on stdout and the exit status are unchanged. It is what the agent of the web front-end runs when the portal gives its host a turn to preload (see Pre-loading the images in the pool section of the web front-end).
sre make-titles [-o <file> | -r] [-d] <directory>¶
Generates titles.json sidecars so the Open project dialog of the GUI and the Open page of the web front-end show friendly labels (e.g. static_routing.py → “Static routing”). Labs without a title attribute are skipped.
Option |
Description |
|---|---|
|
Write all titles to |
|
One |
|
Also list the sub-directories of each directory, with a |
Output keys match sre list: "<name>.py" for file labs, "<dirname>" for directory labs. A rerun merges into the existing file: its options and the order of its entries are kept (a manual order survives), the labs found now are updated, the entries naming nothing on disk any more are dropped, the new labs are appended by name; a fresh file lists the labs by name. The languages of a title are written sorted, the file atomically. Stale entries are also dropped at read time by sre list --with-titles.
Options and sub-directories (written by hand): every key starting with @ is an option, never an entry. "@sort" sets the order of the entries of the directory in the lab tree, the same in the GUI and on the web: "name" (the default: the file names, byte-wise), "title" (the labels in the language of the user, case and accents ignored, numbers compared as numbers so that “TP 2” comes before “TP 10”; a lab without title sorts by its file name) or "manual" (the order of the entries in the file, then the unlisted ones by name). In every mode the sub-directories come first, then the labs. A directory without the option takes the one of the nearest ancestor (so /opt/sre/lab/titles.json sets the whole tree); an unknown value is ignored and sre make-titles warns about it. A key may also name a sub-directory, with a title (shown instead of its name, in the language of the user) or null (shown by its name; listed for its position in the manual order only); sre make-titles keeps such entries as they are.
{
"@sort": "manual",
"s4": {"en": "Semester 4", "fr": "Semestre 4"},
"static_routing.py": {"en": "Static routing", "fr": "Routage statique"},
"tp_ssh": null
}
Sub-directory entries written by the command (-d): without the option the command never writes a sub-directory key, it only keeps those already there. With -d, the titles.json of a directory also lists its sub-directories, those of the lab tree (a lab lies somewhere below them; exam-only ones included, like the labs), each with null until a title is written by hand: the keys are there, only the titles are left to type. A sub-directory already listed keeps its entry and its place; the missing ones are added by name after the last sub-directory entry of the file, else before its first entry, so a fresh file lists the sub-directories then the labs, as the tree shows them, and the tree shown is the same before and after in every "@sort" mode. With -r -d every directory of the tree gets its file, including a level holding sub-directories only such as the lab root (/opt/sre/lab/titles.json), which -r alone never visits. The line reporting a written file names the sub-directories still without a title:
wrote 2 title(s) to /opt/sre/lab/titles.json (sub-directories without a title: s4, sre)
Typical usage: sudo /opt/sre/sbin/sre make-titles -r /opt/sre/lab, or with -d to also get the sub-directory entries to title.
sre update [--main | --ref <tag|branch|commit>] [--check | --force] [-y] [--venv]¶
Updates the installation (params.main_sre_dir, /opt/sre) from the GitHub repository sysreseval/sysreseval (params.update_github_repository). Privileged only, and root only: the tree is root-owned. By default the latest published release is installed. The installed version is the commit recorded by the previous update in <main_sre_dir>/.sre-update.json (or the checked-out commit of a git clone), so an unchanged repository means “already up to date”.
Option |
Description |
|---|---|
|
Follow the head of the |
|
Install this tag, branch or commit, e.g. the previous commit printed by the last update, to go back. |
|
Only report the installed and the available versions; nothing is changed. |
|
Install again even when the requested commit is already installed. |
|
No question: every customised parameter of |
|
Rebuild the Python virtual environment ( |
What an update does, in order:
Checks: no exam configured (
sre del-examfirst), a writable tree (on a read-only NFS mount, run it on the server), one update at a time.Downloads the source archive of the commit into a temporary directory of the tree and decides everything before touching anything: which files change, which are deleted, what
params.pybecomes, and that the new code compiles with the venv’s Python.Prints a summary and asks for a confirmation (unless
--yes).Runs
sre wipe: every running project is stopped and removed, since the new code may not handle projects started by the old one. Without a Docker daemon on the host (params.docker_socket_pathmissing, e.g. an NFS server), the wipe is skipped with a warning: runsre wipeon the client hosts.Replaces the files and reapplies the ownership and modes of
scripts/install.sh(root, world-readable; the entries oflab/andlib/to thesreuser, not world-readable), removes the stale__pycache__directories, then runsmake fonts sre-wrapperand makessbin/sreandbin/sysresevalexecutable again.
What is installed, kept and deleted:
lab/: onlylab/sre/(params.update_lab_subdirs) is refreshed, and reinstalled in full; every other entry oflab/is the site’s own and is left alone.lib/: the files of the repository are refreshed; the site’s extra files are kept.Files the repository dropped are deleted only when a previous update (or the git index of a cloned tree) installed them: the first update of a tree that was not cloned deletes nothing.
Never touched:
venv/,build/,graphics/fonts/,bin/sre-wrapper,.git/, theparams.pybackups.src/SRE/params.pyis merged, not copied. The installed file is backed up asparams.py.bak.<timestamp>first. A parameter the site never changed takes the new value; a parameter customised here that the new version does not change keeps its value; a parameter both customised here and changed upstream is asked about, the installed value being the default (kept with--yes).sre_versionanddefault_docker_image_versionalways take the new value; new parameters are added, dropped ones removed. The pristine upstream values come from the state file (orgit showon a cloned tree); without them, every difference is asked about. The merged file must compile and run before anything is replaced.
The state file .sre-update.json records the commit, the ref, the date, the previous commit, the manifest of the installed files and the pristine parameter values. Hints printed at the end: the command to go back (sre update --ref <previous commit>), make venv when the venv recipe of the Makefile changed, the scripts/etc/ templates that changed (system files to reinstall by hand), and the reminder that replicated hosts need their own sre update and NFS clients their own sre wipe.
Exam management¶
Exam state lives in /var/lib/sre/exam.json — see Exam Reference for the field schema. All field names are exposed as params.exam_* constants.
sre set-exam [options]¶
Creates or updates exam.json. Only provided options are updated; existing fields are preserved.
Option |
Description |
|---|---|
|
Authorised labs, optionally with a named flavor preset (e.g. |
|
Exam opens after this moment. ISO ( |
|
Exam closes before this moment. |
|
Max duration; ends at |
|
Period between automatic evals (default 60). |
|
Record terminal sessions ( |
sre del-exam¶
Removes exam.json and wipes all running projects.
sre save-records -d <dir> [--only-last-record]¶
Archives the records/ directories of running projects as .tar.gz files in <dir>. --only-last-record deletes prior archives for the same project so only the latest remains.
Post-exam management¶
Reads and transforms .zst evaluation archives — see Archive format for the schema.
sre cat [options] <file…>¶
Prints archive contents. Without a field option, all fields are shown.
Option |
Shows |
|---|---|
|
|
|
Raw test results per machine |
|
Evaluation errors |
|
Student answers |
|
Grade list, total grade, total max |
|
Files saved in the archive |
|
Extract saved files to the current directory |
|
Emit a single JSON dict per file on stdout |
sre check-eval [-s <srelab>] <file…>¶
Diffs stored grades against a re-grade (same logic as re-eval but without writing files). Prints per-element changes plus a summary count. -s selects an updated srelab.py or directory; if omitted, uses each archive’s .private/srelab symlink.
sre re-eval -s <srelab> -p <prefix> [-d <outdir>] [-r] [--update-web] <file_or_dir…>¶
Re-grades archives with an updated srelab.py. Useful for fixing a grading bug post-exam.
Option |
Description |
|---|---|
|
Updated |
|
Prepended to each output archive filename. |
|
Output directory (default: current). |
|
Recurse into subdirectories. |
|
Also replace the evaluations the web portal holds for these archives (see below). |
--update-web is for a site with the web front-end: the Archives page of the portal shows what it
collected when each evaluation ran, and a re-graded archive does not change it by itself. With the option, the new
results of every archive re-graded are queued on the host, in /var/lib/sre/web-updates/, under the name of the
archive they come from — the name the portal knows the evaluation by, whatever the prefix and the output directory —
and the web agent of the host hands them to the portal at its next collection (30 s by default), which replaces the
grades, marks, errors and elements of its row. See
Re-evaluated archives for what the row keeps.
Run it as root on a pool host (a host with
sre-agent): the queue belongs to thesreuser, and nothing reads it on a host without agent (a warning says so). Any other user gets an error before anything is re-graded.Give the archives under their original names (the files of
/var/lib/sre/archives, or copies of them): the output of an earlierre-eval(corrected2026…) and a renamed archive are re-graded but not queued, with anerror:line each.The portal only updates evaluations it holds. An update whose evaluation it has not collected yet waits on the host and is applied once it has; it is given up after a day.
The command ends with the number of evaluations queued; the portal’s log says when it replaced them.
sudo sre re-eval -s /opt/sre/lab/_EXAM_/ssh_corrected.py -p corrected -d /tmp/regraded \
--update-web /var/lib/sre/archives/*ssh*
sre sheet -o <output.ods> [-r] [-S <time>] [-F <time>] [--separate-instances] <file_or_dir…>¶
Exports archives to a LibreOffice ODS spreadsheet. Per distinct lab name, three sheets are produced:
Sheet |
Content |
|---|---|
|
One row per archive, sorted by |
|
Per-question: |
|
Per-student best score: |
fullname and email come from the archive’s answers (empty if absent).
sre outline [-o <summary.ods>] [-d <pdf_dir>] [-r] [-S <time>] [-F <time>] [--lang <lang>] [--no-timeline] [--remaining-time] [--separate-instances] [--users-file <file>] <file_or_dir…>¶
Generates per-student PDF reports plus a summary ODS — best-graded archive per student (login + hostname + lab). At least one of -o / -d is required.
When a student opened the same lab several times, the best grade is taken across every instance and the evaluation history shows one table per instance, each headed by its start time. --separate-instances produces one PDF and one ODS row per running project instance instead: the PDF name gains __<start timestamp>, its header a “Project started” line, and the ODS a project_start column.
The PDFs are named <login>__<lab>__<hostname>.pdf, <lab> being the file name of the lab. When two labs of one student would give the same name (a course copy and the shipped lab, s3/dns1.py and sre/dns1.py), the second one is named after its whole path (<login>__sre-dns1__<hostname>.pdf) instead of being written over the first.
The hostname is part of what a student is here (the workstation: the users of a shared account are told apart by it). The reports of the web front-end, built by sre report from the same code, leave it out: a project of the web runs on any host of the pool (see Web front-end).
Option |
Description |
|---|---|
|
Output |
|
Output dir for PDFs (omit to skip). |
|
Recurse into subdirectories. |
|
Force PDF language (e.g. |
|
Omit the evaluation-history table. |
|
Include the time-remaining column in the history. |
|
One report and one ODS row per running project instance instead of one per student. |
|
User list |
Name / email resolution: --users-file (if provided) → fullname / email from archive answers. Columns appear only when at least one student has a non-empty value.
Internal commands (GUI-only)¶
sre list [--with-titles] [--include-exam-only]¶
Prints a JSON array of lab names relative to /opt/sre/lab/ (s4/tp_ssh, s2/lab.py, …). Labs whose components match params.exam_only_affix (_EXAM_, _OLD_, _DRAFT_, _TESTS_) are hidden, unless --include-exam-only is given (privileged only: the web agent lists them to an instructor programming an exam; a student can still start such a lab by its exact name, which is how an exam project is created).
With --with-titles, output becomes the lab tree flattened in display order: [{"name": <path>, "title": <dict|string|null>, "kind": "dir"|"lab", "sort": <mode>}, …], a directory entry ("dir", listed when a lab lies below it) right before its content, the sub-directories of a directory before its labs (a directory lab is a "lab"), each group in the order of the effective "@sort" of the directory’s titles.json (see sre make-titles; sort is that mode, "name", "title" or "manual": the GUI and the browser keep this order and only sort the "title" mode themselves, since it depends on the language of the user). Titles come from per-directory titles.json; stale entries are dropped, and entries without a title get "title": null (the front-ends then fall back to the file name).
sre export <running_lab> [--sep <N>] [--curved] [--shapes] [--reverse] [--random-seed <N>]¶
Exports a running project as a Kathara zip archive, base64-encoded on stdout. The project name is resolved like the other commands (exact name or unique substring, the ownership check of user mode). Flags tune the embedded schema: --sep 0–9 (default 3), --curved for curved edges, --shapes for geometric nodes, --reverse to flip insertion order, --random-seed for node-order permutation. The lab.conf of the archive carries the type of the networks that are not hubs and the VLANs of the ports (CD_MODE[lan]="managed", pc1[0]="lan/vlan=10", r1[0]="lan/trunk=10,20"): this is the syntax of the Kathara fork SRE installs, not of the upstream Kathara.
sre report <sheet|outline|summary> [--lang <lang>] [--separate-instances] [--bonus-in-prefix] [--no-timeline] [--remaining-time] [--no-parts] [-o <file>]¶
What the web agent runs for the Reports of the Archives page of the portal: the spreadsheet of sre sheet (sheet: an ODS), the PDF reports of sre outline (outline: a zip holding one PDF per student, lab and host, and outline.ods, the summary) or that summary alone (summary: the ODS sre outline -o writes, one row per student, lab and host — per running instance with --separate-instances — with the best evaluation; the PDF flags --no-timeline, --remaining-time and --no-parts do not apply), built not from .zst files but from JSON archive records read on stdin ({"records": [...]}: the records of GET /v1/archives of the agent, what the portal keeps of every archive in its database and rebuilds for the evaluations an instructor selected), and written on stdout (-o <file>: a file instead). Each record becomes the pseudo archive the two commands read (archive_summary.raw_from_record: the student metadata, the time, the totals, the grade elements and parts, the number of errors; the tests and the answers were never in a record), so the files are those sre sheet / sre outline give on the same archives. The flags are those of the two commands (--lang applies to the PDFs; the headers of the spreadsheets follow the LANGUAGE of the environment). Privileged only (an admin may run it like sheet and outline); exit 1 with no records to process on an empty or unusable list, a record without running_lab_name is skipped with a warning on stderr.
sre pre-start-exam¶
Stops non-exam projects, then starts all exam labs so images are pre-pulled. Called by the GUI ~60 s before start_after. In user mode with params.check_project_owner on, the projects of the other users of the host are stopped too, whatever their lab (the GUI only counts the caller’s own tabs), and an exam lab is started unless the caller, or root, already runs one.
sre start-exam¶
Stamps started_at in exam.json. Called by the GUI once now ≥ start_after.
sre eval-exam¶
Evaluates every running exam project concurrently. Called by the GUI on a periodic timer (every eval_interval) and once at exam end.
sre end-exam¶
Stamps ended_at and runs a final concurrent eval on every running exam project. Called by the GUI when the exam ends.