Files
KF-OnlineJudge/deploy/release/README.md
T

135 lines
6.6 KiB
Markdown

# Single-node delivery
The single-node profile packages the application, four judging runtimes and the
installation tools for offline use. `contract.v1.json` defines the installation
interface. Judging v1/v2 reports keep their existing formats.
Full installation and recovery acceptance is in progress. Validate a release on
an independent test node before using it for production.
## Requirements
| Item | Required profile |
| --- | --- |
| OS | Arch/CachyOS, Linux x86_64-v3, glibc 2.44, systemd 262, cgroup v2 |
| Memory | At least 4 GiB, with enough free capacity for the configured services and tasks |
| Storage | At least 12 GiB filesystem capacity; preflight calculates the required free space |
| Concurrency | One judging job and one problem import |
| Dependencies | PostgreSQL 18.6 and the fixed broker runtime, prepared from verified offline materials |
Other distributions need a separately verified profile. Preflight checks the
effective kernel limits and available capacity as well as nominal RAM and disk
size. Its free-space calculation includes the application, protected runtime
images, the separate GNU legacy image and 4 GiB for mutable data and operations.
## Verify a bundle
Use a separately trusted checker and the manifest digest supplied with the release:
```sh
python3.13 -m scripts.release contract deploy/release/contract.v1.json
python3.13 -m scripts.release verify /path/to/bundle --manifest-sha256 SHA256_FROM_RECEIPT
```
A bundle contains at most 50,000 single-link regular files, 256 MiB per file,
4 GiB in total and 8 MiB of metadata. Verification rejects links, extra members,
private paths and changed bytes. Keep bundles and real configuration outside Git.
Verification is read-only. Installation, running services and execution isolation
each need their own acceptance evidence.
## Directories and authority
| Location | Contents |
| --- | --- |
| `/opt/kf-onlinejudge/releases` | Installed application versions |
| `current` | Explicitly selected application version |
| `/etc/kf-onlinejudge` and `/etc/kf-judge` | Private operator and service configuration |
| `/var/lib/kf-onlinejudge` | Mutable application data |
| `/var/lib/kf-judge` | Protected Sandbox state and runtime images |
Backend Alembic is the only schema migration entry point. Database identities are
separate for migration, API/outbox, Coordinator, problem import and local account
operations. Rust Worker has no database identity; the Root factory has no
database, MQ, platform, SSH or GitHub credentials. Sandbox owns privileged
execution. Public and admin pages share the HTTPS origin; control interfaces stay
internal.
Application services and the task subtree share `kfonlinejudge.slice`, capped at
3840 MiB, zero swap, 384 processes/threads and two CPU equivalents. The remaining
physical memory is reserved for the kernel and minimal OS. Tasks use
`/sys/fs/cgroup/kfonlinejudge.slice/kf-judge-tasks`, separate from the Root
supervisor's cgroup. Read back service and task limits on the target node.
## Prepare configuration
Supply two 0600 single-link JSON files to `generate-configuration`:
| Input | Fields |
| --- | --- |
| Node | `schema_version: 1`, `origin`, `worker_id`, `measurement_nonce` |
| Endpoints | `schema_version: 1`, `database`, `amqp` |
`origin` is one HTTPS origin. `worker_id` is a canonical nonzero UUID.
`measurement_nonce` is null or a fresh operator-generated SHA-256-sized nonce.
The database object has `api`, `coordinator`, `import`, `migration` and `identity`
keys; the broker object has `outbox` and `worker` keys. Supply a different private
credential for every endpoint. Import uses `/run/postgresql`; other control
connections use numeric loopback. The tool checks login names and locations.
The generated admission profile binds C17/C++20, CPython 3.13.16 and OpenJDK
21.0.12.1+1-LTS to verified catalogs and the existing per-language budgets. The
GNU legacy image retains its v1 header and verified executable/library bytes in
a separate directory. Worker, task identities and execution/prefetch/import
slots remain one. Historical reports and runtime identities remain unchanged.
## Select a version
Configuration batches have content-bound `cfg-...` identities. Preparation keeps
earlier batches and does not select a new one. `activate` requires an explicit
`--configuration-id`, a fully validated batch, inactive application units,
stopped control ports and no retained task resources.
Selection writes the code pointer and `/etc/kf-onlinejudge/active.json`. A crash
between those atomic writes can leave a mismatch; stop and inspect it before
starting services. `check-active` rejects inconsistent pointers, changed bytes
and stale hardware bindings. Root journals and earlier batches remain intact.
A stopped stale batch can be retired without accepting it under a changed kernel.
## Performance comparability
Comparability defaults to unavailable (`measurement_epoch=null`). Use
`--attest-measurement` after verifying the node's limits and execution environment.
It binds a fresh nonce, worker, source, images, budgets, CPU/microcode, kernel and
node scheduling snapshot. `check-configuration` rejects a changed binding.
After an environment change, drain execution, install a complete batch with a new
nonce and revalidate before resuming. Earlier reports retain their original
measurements. Configuration validation alone does not prove comparable performance
or execution isolation.
## Installation order
Use `python3.13 -m scripts.release
--help` for the command interface. Prepare the OS dependencies and dedicated data
volumes, then follow this order:
1. Verify the bundle and run preflight.
2. Install files and runtime images.
3. Generate and install a private configuration batch.
4. Activate that batch while services and tasks are stopped.
5. Install the journal profile and selected dependency snapshots.
6. Initialize PostgreSQL, provision DB identities, run Backend Alembic and create
application accounts; stop the initialization database before installing units.
7. Install ordinary units, the Root factory and the HTTPS snapshot/TLS material.
8. Start the bounded service lifecycle and verify readiness and actual execution.
The tools use offline materials and do not contact a package index.
See the [operator command reference](../../scripts/release/README.md) for service,
HTTPS, backup and recovery operations. Upgrades and restores must preserve
immutable problem versions, submitted source, audit and original judging reports.
A confirmed consistent backup cut has a zero data-loss target. Recovery from
prepared release and backup materials has a 30-minute target, including health
and four-language verification. Both targets require measured acceptance results.