107 lines
4.8 KiB
Markdown
107 lines
4.8 KiB
Markdown
# Deployment preflight tests
|
|
|
|
Run the deployment preflight on every new node after its qBittorrent and
|
|
Syncthing stacks are running, but before starting the Archive Control daemon
|
|
for normal operation or creating any routes/jobs. It is read-only: it does not
|
|
contact the control daemon, alter Syncthing/qBittorrent state, or print secret
|
|
contents.
|
|
|
|
The script is [`scripts/preflight-deployment.py`](../scripts/preflight-deployment.py).
|
|
It deliberately takes paths and container names as arguments rather than
|
|
assuming hostnames, compose project names, mount paths, credentials, or roles.
|
|
It can therefore be used unchanged on cache and archive nodes.
|
|
|
|
## Requirements
|
|
|
|
- Run it on the Docker host being checked.
|
|
- Use Python 3.11 or newer (the script uses the standard-library `tomllib`).
|
|
- Have Docker CLI access to the daemon.
|
|
- Have the checkout containing the script available on that host, or copy only
|
|
this script into the node's compose directory.
|
|
- Bring up qBittorrent and Syncthing first. Do not start the normal Archive
|
|
Control daemon yet.
|
|
|
|
The disposable client container below uses the exact `archive-client` service
|
|
image, mounts, environment, and network specified by that node's compose file.
|
|
Consequently its qB/Syncthing API probes validate the same runtime environment
|
|
the daemon will use, not the host shell's network namespace.
|
|
|
|
## New-node procedure
|
|
|
|
The example uses generic names. Replace paths, compose project directories,
|
|
service names, and real container names for the node being deployed.
|
|
|
|
```sh
|
|
# 1. Bring up only the local dependencies.
|
|
cd /srv/compose/syncthing-node && docker compose up -d
|
|
cd /srv/compose/qbittorrent-node && docker compose up -d
|
|
|
|
# 2. Create a temporary client from the exact production image/config, without
|
|
# running the daemon or registering it with control.
|
|
cd /srv/compose/ArchiveControl-archive
|
|
docker compose run -d --no-deps --name archive-control-preflight \
|
|
--entrypoint sleep archive-client infinity
|
|
|
|
# 3. Discover the real dependency container names if needed.
|
|
docker ps --format '{{.Names}}'
|
|
|
|
# 4. Run the read-only checks.
|
|
python3 /path/to/archive-clients/scripts/preflight-deployment.py \
|
|
--client-config /srv/compose/ArchiveControl-archive/client.toml \
|
|
--client-container archive-control-preflight \
|
|
--syncthing-container syncthing-node-syncthing-1 \
|
|
--qbittorrent-container qbittorrent-node-qbittorrent-1
|
|
|
|
# 5. Remove the temporary container, then start the real daemon only after a
|
|
# successful result.
|
|
docker rm -f archive-control-preflight
|
|
docker compose up -d archive-client
|
|
```
|
|
|
|
If the real client configuration is mounted somewhere other than the standard
|
|
`/etc/archive-control/client.toml`, pass that in-container location explicitly:
|
|
|
|
```sh
|
|
python3 scripts/preflight-deployment.py ... \
|
|
--container-config /custom/path/client.toml
|
|
```
|
|
|
|
## Required arguments
|
|
|
|
| Argument | Meaning |
|
|
| --- | --- |
|
|
| `--client-config` | Host path to the exact `client.toml` that will be mounted into the daemon. |
|
|
| `--client-container` | Running disposable or already-running client container to inspect and probe. |
|
|
| `--syncthing-container` | Running Syncthing container for this node. |
|
|
| `--qbittorrent-container` | Running qBittorrent container for this node. |
|
|
| `--container-config` | Optional `client.toml` path inside the client container; defaults to `/etc/archive-control/client.toml`. |
|
|
|
|
## What it checks
|
|
|
|
- Each configured qBittorrent and Syncthing API root resolves through Docker
|
|
mounts to the same host path as the matching client local root.
|
|
- The client uses one bind mount for its qBittorrent and Syncthing roots, so
|
|
hard-link staging remains possible rather than silently falling back to a
|
|
space-consuming copy.
|
|
- The token, qB password, and Syncthing API-key files are non-empty regular
|
|
files with no group/world permissions.
|
|
- The client image can read its configuration and reports usable permissions,
|
|
sparse-file support, and filesystem capabilities for both roots.
|
|
- qBittorrent authentication/version compatibility and Syncthing
|
|
authentication/device identity are healthy from the client container.
|
|
|
|
In particular, `syncthing.api_root` must refer to the Syncthing **shared-data
|
|
mount**, not its configuration volume. For example, if Syncthing mounts its
|
|
config at `/var/syncthing` and data at `/var/syncthing/Sync`, use
|
|
`api_root = "/var/syncthing/Sync"` when `local_root` maps that data directory.
|
|
This prevents a route folder being created in the config volume while the
|
|
client writes nonce files into the data volume.
|
|
|
|
## Failure handling
|
|
|
|
Treat a nonzero exit status as a deployment blocker. Correct the compose
|
|
mounts, `client.toml`, secret permissions, service credentials, or service
|
|
image/version that the message identifies, then rerun the same command. Do not
|
|
work around a mapping failure by creating route folders manually: the route
|
|
provisioner relies on those API/local path mappings being exact.
|