Repository navigation
ci: preserve recovery routes and reconcile quota authority - #313
Merged
Merged
Conversation
Contributor
Author
|
APPROVE: see TC-959 |
Billing's storage-comp guard checks its TINYCLOUD_ADMIN_SECRET Worker secret, the node/billing shared admin value that PROD_TINYCLOUD_ADMIN_SECRET also holds. Map QUOTA_BILLING_ADMIN_SECRET from it and drop the unprovisioned PROD_TINYCLOUD_BILLING_ADMIN_SECRET. The recovery harness now models one shared value.
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope and merge order
Combined atomic merge vehicle for approved #310 plus its recovery delta. This branch is stacked directly on #310 head 87b2a38 (parent approval); recovery head 63d11dd. Target
mainintentionally includes the parent changes so there is no intermediate #310-only main state. Do not merge #310 alone. #309 remains separate for the later logging window. No merge or deployment authorization is requested here; review routing stays with Amos and the same Astra reviewer.Delta:
docker.yml, reviewed quota config, two offline rollback config artifacts, a CI-only quota helper, focused tests and release documentation. No app/Rust/root-compose edits. Amos explicitly approved the separate CI helper; onlydocker.ymlinvokes it operationally, using fixed arguments and runner env, never expression interpolation or credential argv.Deployment routing
All deploys require manual dispatch and
authorize_quota_values=true. Missing authorization, missing/unknown reviewed authority, missing runner billing/admin credentials or incompatible billing URL rejects before compose/CVM/whitelist mutation.rollback_pre_n0=true, exact captured source plus explicit approved privacy choice. No path override, symlink, edited source or forward-image substitution.Raw SHA256 identities:
28302d6761d841b7cc5c11314aed2d377735e6bbdcaf85972a752e03bc9fdc93(independently checked through read-only GitHub source API).ops/rollback/pre-n0-compose.yaml:df239749ca0a9c09893a855ae2a8abb94090b8556515ad002105c58ac91f4c91. Saved private file was stat/hash-only, not opened; the frozen public template with only the immutable node pin reproduces these exact bytes.315ceca54bf8bfefe2b395b4097fe38ed8ec847fa0688bc873220bd65efc99ec. Parsed configs prove only node and ingress logging policies change (json-file, 3×50 MB →none); other service configuration is identical.ca110b0bae6d5a06a1002fb80df3f71cffec11659c9f9dbfa5d72624735546f6, from Add a compose-only node log sidecar #309 exact reviewed head 44eeb20, review approval. Its separately approved hosted acceptance is run 38963872225.Rollback privacy defaults to unselected/refuse, not retention or deletion. Sam's card must explicitly choose
keep-json-fileorstop-future-local-logs, recorded in repository variableTC959_ROLLBACK_PRIVACY_MODE; the input must match. Only node/ingress Docker logging is changed in the latter mode. Host/SSH-gateway logging is not reconfigured. Stopping future logs does not purge old files; no truncation/deletion route exists here. Forward/current-compose promotion cannot select the rollback privacy switch.Immutable identity and preserved sealing
Node image:
ghcr.io/tinycloudlabs/tinycloud-node@sha256:4bdae4fc232d886bb56bfbce4ec62ed4b8fb4e1369a01f6afb73d06dd68c188fActual OCI version 1.20.6-dstack, revision e18578f. Dispatch
image_version=1.20.6; all deployment/ship/watch summaries use verified image identity, not the current crate version. Ingress remainssha256:63c1c44e2ded5b73a5f174807b91ca677826974df0f9ab3045f6ec87865a5744.Sealed-runtime preflight runs on every selected deploy path, including old recorded-image labels. Exact N0 digest-pinned compose and original
:dstackpath remain supported. Secret NAMEPROD_TINYCLOUD_BETTERSTACK_SOURCE_TOKENmaps only to sealedBETTERSTACK_SOURCE_TOKEN, source 2795437. Required secrets fail before deployment;.phala-prod.envstays mode 0600/umask 077, quiet compose validation, no echo/artifact, always cleanup.Complete known env values are required before any whitelist PATCH: an existing live name absent from the sealed file fails closed.
updateCvmEnvssends complete encrypted env plusenv_keys, never anallowed_envsPATCH input; no-op validates token-name presence. Async operation must have an observed transition before final running/whitelist/health gates; an unobserved fast/queued operation remains fail-closed, not assumed complete. Unexpected KMS preconditions fail closed. Existing private-logs/private-sysinfo flags remain unchanged, no tcbinfo change. Operator pre/post readback must preserve false/false/true.General quota authority, after the final restart
Reviewed
ops/quota-overrides.jsonexplicitly selectsnode-overridenow. Values authorization is per dispatch, not N0-specific. Helper preflight validates config, credentials and HTTPS same-origin/api/quotaURL shape without any service request; recovery does not require a warm/healthy node before restart.After final deploy/allowed-env operation and required version/ingress health, before ancillary Policy probes:
/admin/usagemust contain each exact configured full ID once, with positive known integer usage. Missing/duplicate/null/zero/wrong-owner fails before any node PUT./api/admin/storage-comp/:space_idfor BOTH targets before any node PUT. Innode-override, 404 or valid HTTP200active:falsepermits restore; active comp refuses with authority mismatch. Malformed/unknown bodies, other 4xx/auth, 5xx and bounded transport exhaustion fail closed. No HTTP-error retry or absent-comp fallback.override_bytesandeffective_limit_bytes. Unapplied/effective mismatch fails loudly.Later separately reviewed
authority=billingnever PUTs/DELETEs a node override. Active absolute per-spacestorage_limit_bytes, not incrementalcomp_bytes, must cover each reviewed floor; node GET must showoverride_bytes=null, otherwise stale legacy override fails. Cold cache is not failure:billing-authoritative; the node fetches on the next write (≤60 s TTL).Any attempted CVM mutation without verified reconciliation emits fatal OVERRIDES UNVERIFIED. Quota is in the SAME deploy job, independent of watch scheduling and before Policy probes. Partial deploy/sync/health/quota failures cannot silently skip verification. This addresses loss of in-memory node overrides on restart without shadowing active billing authority.
Runner-only production-environment secret NAME
PROD_TINYCLOUD_BILLING_ADMIN_SECRETis explicitly separate from node admin auth, never CVM env/allowed_envs, argv or logs. It is UNPROVISIONED: Sam's card must provision it; absence blocks before mutation. Node admin uses existing repository secret NAMEPROD_TINYCLOUD_ADMIN_SECRET. No credential values, full IDs, response bodies or raw SDK messages are logged. Only classifications and the two reviewed numbers appear in quota summaries.Exact operator commands — NOT executed
Canonical, tested one-copy-paste commands are in
docs/releasing.md; rollback has two explicit privacy variants, both requiring Sam's recorded selection.12c current-compose recovery:
TC-1302 captured rollback uses the same immutable tuple plus
rollback_pre_n0=trueand exactly one approvedrollback_privacy_mode=keep-json-file/stop-future-local-logs; full literal commands are in the linked runbook, not an implicit production default. Other feature/audit/non-descendant inputs retain their false defaults.No deployment on merge
A merge emits
push, notworkflow_dispatch.deploy-phalarequiresgithub.event_name == 'workflow_dispatch',inputs.deploy_phala, successful guards/build-or-recorded digest, and repeats main/ref validation beside production access. Version guard additionally rejects missing quota authorization before any deploy mutation. Digest promotions requirerefs/heads/main; explicit captured rollback requires the exact immutable tuple and approved privacy mode. Watch dispatch is downstream/manual-only and retains its ownactions:write; no permission is added to the deploy job. #306 release-only floating tags are unchanged. Existing CI build/publish can still occur on configured events; that is not a CVM deploy.Exercised evidence
Tests-first red/green: initial recovery matrix failed against the parent workflow; authority matrix failed against the old inline path. Added destination-symlink regression failed before the fixed-path guard; explicit privacy reporting failed before its implementation. Final local runs:
No local Docker, production/Phala/billing request, credential value read, workflow dispatch, merge or extra reviewer launch. Exact-head hosted CI and final API head/base are recorded below. Deployment stays HELD: combined review/landing, Sam's window/card/privacy decision, missing billing credential, operator pre/post privacy readback, and quota fallback ownership remain gates. Historical TC-780 commands remain explicitly retired and unchanged; operator packets must use the tested current runbook commands, not the removed N0-only authorization input.
Reviewed API contract and exact source
Billing API contract was inspected read-only at TinyCloudLabs/billing #48, head
26d9d0f7c0151c380affd4b6a621a6f16bb26c46. Itsstorage_limit_bytesis the absolute queried-space limit; the record'sspace_idcan name a sibling comp intent, so node inventory/readback—not that record field—provides exact target identity proof. The separately authenticated runner credential is not assumed equal to node admin auth.Exact source commands: 12c recovery and both explicit TC-1302 rollback privacy variants.
Final REST API: head
63d11dd67e07378acb9213ecd8e3b895c7be5931, basemainatf2792bb9f2f82691fcd777bfb0701e22bfc30eff; direct parent remains frozen approved #31087b2a38b2ad523bf6587e3c08ef1e072138b56e7. PR is open, unmerged.Terminal exact-head hosted CI
19/19 terminal: 10 success, 9 intentionally skipped, 0 pending, 0 failure. All three workflow runs report
completed/successfor this exact head.Skipped checks:
promote-watch,deploy-phala,announce,publish-homebrew-formula,host,build-global-artifacts,build-local-artifacts,build-dstack,rollback-audit. In particular, neither deploy nor watch ran. Ready for Amos to route the combined delta to the same Astra reviewer; no release/deploy GO.