Commit 00a19f9
feat(app): wire in-place updates in members (MIG) mode
The 0.3.0-beta.1 guardrail that refused app-level mutable-field updates
in members mode is gone. phala_app.Update now propagates every common
edit across all slots while preserving slot identity (vm_uuid and name
are unchanged across the update).
Two complementary execution paths, picked by what changed:
1. Compose-body changes (docker_compose, pre_launch_script, public_*,
gateway_enabled, secure_time, env-key list) use the cloud's
app-revision endpoint:
a. provisionAndApplyComposeFileUpdate on the bootstrap CVM. This
provisions the new compose hash AND applies it to the bootstrap,
creating the revision row in the app's history.
b. Wait for the bootstrap to settle on the new compose_hash.
c. Read the new compose_hash back from the bootstrap row.
d. findRevisionIDByComposeHash against /apps/{id}/revisions.
e. redeployRevisionAcrossCVMs to every other slot via
POST /apps/{id}/revisions/{rev}/redeploy with vm_uuids=[others].
f. waitForCVMsOnComposeHash until every CVM lands on the new hash.
We split the bootstrap apply from the slot redeploy because
/cvms/{id}/compose_file/provision only caches a compose_hash — it
does NOT create a revision row. The PATCH /compose_file (or the
POST equivalent) is what materializes the revision in the app's
history, and the redeploy endpoint requires the revision to already
exist in ClickHouse. Reading the new compose_hash off the bootstrap
CVM after it settles is the cheapest way to resolve the
revision_id without a separate "list revisions and pick the
newest" heuristic.
2. Per-CVM mutable fields the cloud doesn't expose at the app level —
env values via PATCH /cvms/{uuid}/envs, image via /os-image,
size/disk via /resources — get a sequential fan-out over the known
vm_uuids list. The app-rooted KMS public key is shared across all
CVMs in one app, so we encrypt env once against the bootstrap's
pubkey and the same bytes are accepted by every slot. Fail-fast on
the first error so partial-apply recovery in Terraform has a clear
stop position.
ModifyPlan now does only the one structural check: refuse the
"removing members from a previously-members-mode app" transition,
because that would orphan phala_app_instance slots. All the
mutable-field plan-time blocks are gone — those fields work now.
Single-CVM apps (no `members`) still use the existing direct-PATCH
path against the bootstrap CVM with zero fan-out machinery. Update was
restructured into applyMembersModeUpdate vs applySingleCVMUpdate so
the two paths are clearly separated without code duplication.
Live verification on real Phala Cloud (h4xuser, US-WEST-1) on a 2-slot
MIG (`upd-a` bootstrap + `upd-b` instance):
- Initial apply: both CVMs come up running with compose_hash
2608b800ef995746dc46ce0418752779e947278aa158eed28709accdeff9a912.
- Compose update (docker_compose marker INITIAL → UPDATED):
apply succeeded in 2m16s, both vm_uuids preserved
(4e0fd1e7-d4b0-4d68-98f3-37f3a011c8a3 and
3307fe7d-f4e3-48db-91ad-891c6783ca53), both CVMs report the new
compose_hash 39ef1e5ed81d70c61fc822dfacd7d19b084f3bea103d45306a7f626bdd0125c9,
and `docker-compose.yml` on each CVM now serves `MARKER=UPDATED`.
- Env-only update (TEST_KEY v1 → v2-updated, no compose change):
apply succeeded in 1m10s, both vm_uuids preserved, both CVMs still
on the same compose_hash 39ef1e5e... — env path correctly did not
trigger a new revision.
- Subsequent `terraform plan` against the updated stack: "No changes."
- Destroy clean; baseline CVM count restored.
Unit tests added in resource_app_members_update_test.go cover:
- provision → list-revisions → redeploy chain ordering with both
a single-page and a 2-page revision list.
- redeploy body shape (vm_uuids array passed through).
- 465 on-chain KMS rejection surfaced as "kms = phala only" error.
- per-CVM env fan-out sequencing and fail-fast.
- waitForCVMsOnComposeHash transitioning across polls.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent e6000ba commit 00a19f9
8 files changed
Lines changed: 951 additions & 389 deletions
File tree
- docs/resources
- internal/provider
- templates/resources
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
7 | 28 | | |
8 | 29 | | |
9 | 30 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
59 | | - | |
| 59 | + | |
60 | 60 | | |
61 | | - | |
| 61 | + | |
62 | 62 | | |
63 | | - | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
64 | 66 | | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
| 67 | + | |
70 | 68 | | |
71 | 69 | | |
72 | 70 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
49 | 56 | | |
50 | 57 | | |
51 | 58 | | |
| |||
0 commit comments