Files
pikasTech-HWLAB/docs/reference/deployment-publish.md
T
2026-05-23 10:22:57 +00:00

341 lines
17 KiB
Markdown

# HWLAB Deployment And Publish Reference
This reference records the stable DEV publish and rollout rules. It does not
authorize PROD, service restarts outside the documented DEV path, secret reads,
or direct pushes to `main`.
It is also the long-term reference for
[pikasTech/HWLAB#116](https://github.com/pikasTech/HWLAB/issues/116): service
deployment regularization must progress from stable docs, to controlled
CLI/script entrypoints, to UniDesk CI/CD plus imageized delivery.
## Workspaces
| Purpose | Path |
| --- | --- |
| Runner and commander worktree | `/workspace/hwlab` |
| D601 publish/build worktree | `/home/ubuntu/workspace/hwlab` |
Use `/home/ubuntu/workspace/hwlab` for D601 build and rollout operations.
Do not treat `/home/ubuntu/hwlab` or other runner worktrees as the publishing
truth.
## Regularization Stages
| Stage | Current HWLAB state | Required next behavior |
| --- | --- | --- |
| 1. Long-term reference | This file records DEV deployment, Cloud Web publish, API/edge/health, frp, D601 registry, k3s rollout, rollback, and verification rules. `AGENTS.md` indexes it. | Keep process issues as sources only; update this reference when a deployment rule changes. |
| 2. CLI or controlled scripts | `scripts/dev-cd-apply.mjs` is the only formal DEV CD side-effect entrypoint for publish, desired-state refresh, apply, and live verify. Other controlled scripts still cover contract planning, dry-run planning, preflight, single-step internals, k3s read-only visibility, and Cloud Web checks. Rollback is documented as commands/report hints but is not yet one unified CLI command. | Converge check, plan, rollback, status, and verify into HWLAB CLI while preserving the single transaction lock for side effects backed by `deploy/deploy.json`. |
| 3. UniDesk CI/CD plus images | DEV services are imageized and published to the D601 registry. D601 rollout still includes manual bridge steps for Cloud Web and frp/k3s execution. | Move build, publish, desired-state refresh, rollout, post-deploy validation, and report upload into standard UniDesk CI/CD jobs without replacing HWLAB runtime. |
## DEV CD Transaction
The stable DEV CD side-effect command is:
```sh
node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report
```
This command is the only formal path that may publish DEV artifacts, refresh
desired-state from the publish report, apply to `hwlab-dev`, and verify public
`16666/16667` in one run. It reads `deploy/deploy.json` at transaction start,
records the manifest hash and target commit, acquires
`Lease/hwlab-dev/hwlab-dev-cd-lock`, runs the internal steps serially, writes
`reports/dev-gate/dev-cd-apply.json`, and releases the Lease.
The Lease is a deployment-plane mutex, not a desired-state source. Its
annotations record at least `promotionCommit`, `deployJsonHash`,
`ownerTaskId`, `transactionId`, `phase`, `startedAt`, `updatedAt`,
`ttlSeconds`, `liveBefore`, and `targetNamespace`. `deploy/deploy.json`,
`deploy/artifact-catalog.dev.json`, and `deploy/k8s/base/workloads.yaml`
remain the only authoritative deploy inputs.
If another transaction holds the Lease, the command must stop before publish or
apply with structured `deploy-lock-held` output that includes holder,
promotion commit, phase, target namespace, and retry seconds. Expired locks are
not silently overwritten; taking over a stale lock requires both
`--break-stale-lock` and `--confirm-dev`, and the previous holder is retained
in audit annotations/report fields.
`scripts/dev-cd-apply.mjs` also owns the read-only status surface. Running it
without arguments, with `--status`, or with `--dry-run` must return compact JSON
for the target ref, `deploy/deploy.json`, current Lease, and public
`16666/16667` live health. These modes must not acquire the Lease, publish
artifacts, apply Kubernetes workloads, or write reports. Normal `--apply`
stdout is also compact by default; the complete transaction record is preserved
through `--write-report`, or printed only when `--full-output` is explicit.
When the current DEV apply must be stopped, the operator may use
`--force-interrupt-lock` together with `--apply --confirm-dev
--confirmed-non-production`. This is a DEV-only takeover path: it first tries
to send `TERM` to local `scripts/dev-cd-apply.mjs --apply` processes, then
replaces the Lease holder and records the interrupted holder and interrupt
attempt in Lease annotations and the transaction report. Do not use this flag
for ordinary contention; prefer waiting for the holder or breaking only a
confirmed stale lock.
The old side-effect commands are now internal transaction steps. Direct manual
use of `scripts/dev-artifact-publish.mjs --publish` or
`scripts/dev-deploy-apply.mjs --apply` without `HWLAB_CD_TRANSACTION_ID` is
rejected with `cd-transaction-required`; preflight, build, dry-run, check, and
read-only modes remain available.
## Artifact Publish
DEV artifacts publish to the D601 local/internal registry:
```text
127.0.0.1:5000/hwlab/*
```
The single-step publish command is a transaction-internal side-effect step:
```sh
node scripts/dev-artifact-publish.mjs --publish
```
It only runs in side-effect mode when `HWLAB_CD_TRANSACTION_ID` is set by
`scripts/dev-cd-apply.mjs`. Use `node scripts/dev-cd-apply.mjs --apply
--confirm-dev --confirmed-non-production --write-report` for normal DEV CD.
For Cloud Web source freshness before the transaction:
```sh
node web/hwlab-cloud-web/scripts/check.mjs
node web/hwlab-cloud-web/scripts/build.mjs
node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report
```
Cloud Web must build `web/hwlab-cloud-web/dist` before publish because the
runtime wrapper serves `dist` before source files. A correct source commit with
stale `dist` can still publish an old UI. The build/check pair is part of the
publish contract, but with separate responsibilities: `check.mjs` validates
source and does not require ignored `dist/` in a clean checkout. `build.mjs`
regenerates `dist` and verifies every runtime file and route alias matches
source. `scripts/dev-artifact-publish.mjs` runs that build/freshness gate and
records the `distFreshness` result before it builds the image.
After a successful multi-service publish, refresh the artifact catalog from the
publish report:
```sh
node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json
node scripts/deploy-desired-state-plan.mjs --target-ref origin/main --check
```
If publish is blocked, keep the report blocked rather than inventing digests:
```sh
node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --blocked
node scripts/deploy-desired-state-plan.mjs --target-ref origin/main --check
```
The desired-state files are a single deployment truth: `deploy/deploy.json`,
`deploy/artifact-catalog.dev.json`, and `deploy/k8s/base/workloads.yaml` must
carry the same promotion commit and immutable image tag before they are used as
apply input. A `--target-ref` desired-state plan may report a uniform older
state as `promotion_pending`; PR review and CI/CD promotion gates must use
`--target-ref origin/main --check` or `--promotion-commit <sha> --check` so
stale or partially refreshed commit, image, workload, and mirror-env fields are
blocked before any DEV apply.
Reports under `reports/` are evidence snapshots only and cannot override this
desired-state contract.
## Latest-Main Artifact/Runtime Guard
Before any controlled DEV apply for latest `origin/main`, run the read-only
artifact/runtime guard:
```sh
node scripts/artifact-runtime-readiness-guard.mjs --target-ref origin/main --check --no-report
```
When current readiness is expected to be blocked, use:
```sh
node scripts/artifact-runtime-readiness-guard.mjs --target-ref origin/main --check --no-report --expect-blocked
```
The guard compares target main, `reports/dev-gate/dev-artifacts.json`,
`deploy/artifact-catalog.dev.json`, the desired-state planner, Cloud API
`/health/live`, and Cloud Web `:16666/health/live`. It is report-only and must
not be used as an apply command. A local source check, static workbench smoke,
or stale report snapshot cannot claim latest-main deployment unless the guard's
runtime and artifact identity checks also pass.
## API, Edge, Health, And FRP
The public route is fixed:
| Surface | Current entry |
| --- | --- |
| Cloud Web | `http://74.48.78.17:16666/` |
| Cloud Web live health | `http://74.48.78.17:16666/health/live` |
| API/edge health | `http://74.48.78.17:16667/health` |
| API/live health | `http://74.48.78.17:16667/health/live` |
FRP maps master public `16666/16667` to D601 `hwlab-dev` services. Use
`deploy/deploy.json` as the source for endpoint and FRP drift checks:
```sh
node scripts/deploy-contract-plan.mjs --check
```
Do not reintroduce public `6666/6667` as active DEV endpoints. Internal k3s
services may still use internal `6667`.
## Cloud Web Manual DEV Rollout
This section is retained as historical operational baseline for what the
transaction reproduces. New DEV side effects should use
`scripts/dev-cd-apply.mjs`; do not bypass the Lease with ad hoc publish,
`kubectl set image`, or restart commands.
The DEV CD transaction owns the durable runtime support sequence before final
live postflight:
```sh
node scripts/dev-runtime-provisioning.mjs --apply --confirm-dev --confirmed-non-production --write-report
node scripts/dev-runtime-migration.mjs --apply --confirm-dev --confirmed-non-production --write-report
node scripts/dev-runtime-postflight.mjs --live --confirm-dev --confirmed-non-production --target api --write-report
```
These commands are called by `scripts/dev-cd-apply.mjs` under the transaction
Lease. Runners without explicit rollout authorization may run the source-only
`--check` variants and prepare PRs/artifacts, but must leave DEV apply,
rollout, live verification, and lock ownership to the host commander.
The previous verified manual path for `hwlab-cloud-web` was:
```sh
cd /home/ubuntu/workspace/hwlab
git pull --ff-only origin main
node web/hwlab-cloud-web/scripts/build.mjs
node scripts/dev-artifact-publish.mjs --publish --services hwlab-cloud-web
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev set image deployment/hwlab-cloud-web hwlab-cloud-web=127.0.0.1:5000/hwlab/hwlab-cloud-web:<tag>
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev rollout status deployment/hwlab-cloud-web --timeout=180s
```
That historical sequence is no longer the normal side-effect path; direct
`--publish` is rejected unless it is called by the transaction.
The rollout must use D601 native k3s:
```sh
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev get deploy hwlab-cloud-web -o wide
```
The rollout report must tie the live deployment back to artifact identity:
source commit, image tag, image reference, registry digest or `not_published`,
and Kubernetes rollout revision. `scripts/dev-deploy-apply.mjs` reports this
under `devDeployApply.cloudWebRollout` when read-only Deployment access exists;
without that access, it reports the blocker and the exact read/rollout commands
instead of claiming a live rollout.
Public verification must check the browser entry on `16666`, not legacy
ports:
```sh
curl -fsS http://74.48.78.17:16666/health/live
curl -fsS http://74.48.78.17:16666/ | sed -n '1,80p'
curl -fsS http://74.48.78.17:16666/styles.css | rg 'overflow: hidden|100dvh'
curl -fsS http://74.48.78.17:16666/help.md | sed -n '1,40p'
curl -fsS http://74.48.78.17:16667/health/live
```
Cloud Workbench acceptance also expects Chinese default UI, no outer page
scroll, and an internal Markdown help surface. The frontend contract is
[cloud-workbench.md](cloud-workbench.md).
## Apply Boundary
`scripts/dev-deploy-apply.mjs` is the DEV-only apply/report backend. A real
apply requires the transaction environment created by `scripts/dev-cd-apply.mjs`
plus explicit non-production flags:
```sh
node scripts/dev-deploy-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report
```
Direct manual `--apply` calls without `HWLAB_CD_TRANSACTION_ID` return
`cd-transaction-required`. The apply path must stop before mutation when
artifact evidence, registry digests, kube access, DEV health, or required
runtime readiness are missing. It must not read secret values or target PROD.
Suspended template Jobs are immutable in `spec.template`. Only the explicit
DEV allowlist may be replaced by the apply script:
- `hwlab-agent-worker-template`
- `hwlab-cli-template`
## Rollback Boundary
Rollback remains DEV-only and must be explicit. Capture current image state
before changing a workload:
```sh
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev get deploy hwlab-cloud-web -o wide
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev rollout history deployment/hwlab-cloud-web
```
For a Deployment rolled by `set image`, use Kubernetes rollout undo only for
the same DEV Deployment:
```sh
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev rollout undo deployment/hwlab-cloud-web
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev rollout status deployment/hwlab-cloud-web --timeout=180s
```
After rollback, repeat public verification on `16666` and `16667`. Do not use
rollback to change PROD, read secrets, restart unrelated services, or conceal
an artifact/report mismatch.
## Controlled Entrypoint Design
The #116 target is a single controlled deployment surface. Until that lands,
use the repo-owned scripts below instead of ad hoc shell fragments.
| Action | Current controlled entrypoint | Gap to close |
| --- | --- | --- |
| Check deployment contract and FRP/endpoint drift | `node scripts/deploy-contract-plan.mjs --check` | Fold into `hwlab deploy check --env dev`. |
| Plan desired image/workload state | `node scripts/deploy-desired-state-plan.mjs --plan --pretty` and `node scripts/deploy-desired-state-plan.mjs --promotion-commit <sha> --check` | Fold into `hwlab deploy plan --env dev --file deploy/deploy.json` with a promotion commit gate. |
| Preflight artifact publish | `node scripts/dev-artifact-publish.mjs --preflight` | Keep as backend for `hwlab artifact publish --preflight`. |
| Publish/apply/verify DEV | `node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report` | Keep as the single side-effect transaction and run from repo-owned DEV CI/CD. |
| Publish DEV images | `node scripts/dev-artifact-publish.mjs --publish` inside `HWLAB_CD_TRANSACTION_ID` | Internal step only; direct side-effect calls are rejected. |
| Refresh catalog/desired state | `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json` | Internal transaction step after publish; read/write desired-state only from repo files. |
| Apply DEV rollout | `node scripts/dev-deploy-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report` inside `HWLAB_CD_TRANSACTION_ID` | Internal transaction step; direct side-effect calls are rejected. |
| Roll back DEV Deployment | `kubectl -n hwlab-dev rollout undo deployment/<name>` with explicit D601 kubeconfig | Add `hwlab deploy rollback --env dev --service <id> --to-revision <n>`. |
| Verify status | `curl` checks plus `node scripts/d601-k3s-readonly-observability.mjs` | Add `hwlab deploy verify --env dev --write-report`. |
## Automation Direction
The stable direction from
[pikasTech/HWLAB#61](https://github.com/pikasTech/HWLAB/issues/61) and
[pikasTech/HWLAB#116](https://github.com/pikasTech/HWLAB/issues/116) is to
converge manual operations into CLI plus `deploy/deploy.json`, then run that
surface from UniDesk CI/CD:
- render and verify frps/frpc from the deploy manifest;
- publish images and write digest reports;
- refresh catalog/workload desired state from the publish report;
- apply DEV with immutable Job replacement policy;
- verify `16666` Cloud Web and `16667/health/live` API;
- invalidate or regenerate active reports after endpoint or artifact changes.
UniDesk CI/CD is infrastructure only. It may schedule build/publish/deploy
jobs and store artifacts, but it must not replace `hwlab-cloud-api`,
`hwlab-cloud-web`, `hwlab-router`, `hwlab-patch-panel`, simulators, gateways,
or agent services as the runtime being validated.
## Stable Sources
- [docs/dev-artifact-publish.md](../dev-artifact-publish.md): artifact publish
command and report contract.
- [docs/dev-deploy-apply.md](../dev-deploy-apply.md): apply/report and Cloud
Web manual rollout details.
- [web/hwlab-cloud-web/scripts/dist-contract.mjs](../../web/hwlab-cloud-web/scripts/dist-contract.mjs): Cloud Web `dist` freshness contract used by build/check/publish.
- [pikasTech/HWLAB#61](https://github.com/pikasTech/HWLAB/issues/61): manual
rollout review and automation target.
- [pikasTech/HWLAB#116](https://github.com/pikasTech/HWLAB/issues/116):
deployment regularization stages and acceptance.