Updating a lab¶
Runtime computers never run from a git checkout. They install a versioned, hash-checked bundle built on the development PC. Each computer keeps its settings in one file that updates never touch. You start each process by hand in its own window, in the order listed in starting the lab by hand:
| Computer | Settings file | Start command |
|---|---|---|
| Central | C:\ProgramData\LabNet\central.env |
central-venv\Scripts\labnet-central --env-file …\central.env |
| Central (web interface) | C:\ProgramData\LabNet\control-center.env |
control-center-venv\Scripts\labnet-control-center --env-file …\control-center.env |
| Lab PC | C:\ProgramData\LabNet\lab-pc.env |
lab-pc-venv\Scripts\labnet-lab-pc --env-file …\lab-pc.env |
| Client | C:\ProgramData\LabNet\client.env |
set LABNET_ENV_FILE to it, then run scripts |
First-time setup of a computer is in Deploying a lab. After that, every update follows these steps:
1. Build the bundle (development PC)¶
# bump version = "x.y.z" in every packages/*/pyproject.toml, then:
pytest && labnet driver build --core --check
git commit -am "Release x.y.z"
labnet bundle --site sites/pqt # add --driver <package> for each driver the lab uses
labnet bundle refuses to overwrite an existing bundle, or to pack a site
folder holding anything that looks like a secret (*.env, keys, logins). It
makes (in dist/, git-ignored):
dist/labnet-x.y.z-pqt/
MANIFEST.json version, site, git revision, which wheel each role installs, SHA-256 of every file
wheels/*.whl LabNet, the Control Center, the drivers, and every dependency (for Windows, Python 3.11)
site-pqt.zip sites/pqt/: env templates, the Caddyfile template, every Lab PC inventory
--no-dependencies leaves out the dependencies, for computers that can
reach PyPI; --python and --platform choose another target. Copy the
folder to the release share (for example
\\192.168.50.40\LabNet-Releases\x.y.z).
2. Install it on each computer, in dependency order¶
Stop processes in reverse order (clients, then Lab PCs, then the Control Center, Caddy, and Central). Then update and start them in this order: Central → Control Center → each Lab PC → clients. On each computer, in PowerShell:
$install = '\\192.168.50.40\LabNet-Releases\x.y.z\install.ps1' # or a local copy of the bundle
powershell -ExecutionPolicy Bypass -File $install -Role central # on central_server_pc
powershell -ExecutionPolicy Bypass -File $install -Role control-center # on central_server_pc too
powershell -ExecutionPolicy Bypass -File $install -Role lab-pc # on each Lab PC
powershell -ExecutionPolicy Bypass -File $install -Role client # on each client
install.ps1 checks the bundle, installs labnet from it into a temporary
environment, and runs labnet update from there, so the update never runs
from the environment it replaces. It needs only Python 3.11 and its py
launcher (-Python <python.exe> picks another). -ExecutionPolicy Bypass
applies to that one run: Windows otherwise refuses unsigned scripts from a
share. Where labnet is already installed, labnet update --from <bundle>
--role <role> does the same.
labnet update handles the steps that are easy to get wrong:
| Step | What it does |
|---|---|
| Verify | Compares every file's SHA-256 with MANIFEST.json; stops on any mismatch |
| Safety | Refuses to run while that role still answers on its loopback health port (for the Control Center, the watchdog's too) |
| Install | Builds a new environment, C:\ProgramData\LabNet\venvs\<role>-x.y.z-<time>, from the bundle's wheels; the current one is untouched |
| Central | Backs up the SQLite file named in central.env (labnet.db.before-x.y.z.<time>), then applies migrations |
| Lab PC | Installs the site as C:\ProgramData\LabNet\site\, then loads lab-pc.env and builds its inventory's devices (without connecting), so a missing driver shows now rather than at startup |
| Control Center | Loads control-center.env with the new code |
| Switch | Points C:\ProgramData\LabNet\<role>-venv (a junction) at the new environment, and records the bundle in <role>-RELEASE.json |
If any check fails, the new environment is deleted and nothing else has
changed. Start the role again and check its /health/ready. Then run the
deployment verification checklist.
Rollback: each role keeps its last three environments in
C:\ProgramData\LabNet\venvs\, and <role>-RELEASE.json names the
previous one. Point the junction back with
cmd /c rmdir C:\ProgramData\LabNet\central-venv then
cmd /c mklink /J C:\ProgramData\LabNet\central-venv <previous environment>.
The previous site is kept as site.previous. Reinstalling old code does not
undo a schema migration: restore the labnet.db.before-* backup if you need to.
Operations and upgrades¶
Start components in this order: Central (after any migration) and Caddy, then Lab PCs, then clients. For an upgrade:
- test, then build a new bundle (
labnet bundle --site sites/pqt); - keep the previously approved bundle;
- stop the affected processes in reverse order;
- run
labnet update --from <bundle> --role <role>on each computer (Installing from the bundle), which installs side by side and, on Central, backs up SQLite and migrates; - restart in dependency order; and
- repeat the deployment verification checks.
Roll back code by stopping the process and pointing <role>-venv back at
the previous environment, which <role>-RELEASE.json names
(cmd /c rmdir C:\ProgramData\LabNet\<role>-venv, then
cmd /c mklink /J C:\ProgramData\LabNet\<role>-venv <previous>); each role
keeps its last three in C:\ProgramData\LabNet\venvs\. Reinstalling old
code does not reverse a schema migration; restore the
labnet.db.before-<version>.<time> backup for that.