@caelo-cms/provisioning 0.10.53 → 0.10.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/dist/agent-db.js +272 -128
  2. package/dist/audit-job-setup.d.ts +69 -0
  3. package/dist/audit-job-setup.d.ts.map +1 -0
  4. package/dist/audit-job-setup.js +317 -0
  5. package/dist/audit-job-setup.js.map +1 -0
  6. package/dist/caddy.d.ts +9 -0
  7. package/dist/caddy.d.ts.map +1 -1
  8. package/dist/caddy.js +38 -0
  9. package/dist/caddy.js.map +1 -1
  10. package/dist/cli-routing.js +1 -1
  11. package/dist/cli-routing.js.map +1 -1
  12. package/dist/cli.js +36 -9
  13. package/dist/cli.js.map +1 -1
  14. package/dist/compose.js +5 -0
  15. package/dist/compose.js.map +1 -1
  16. package/dist/converge-checkpoint.d.ts +66 -0
  17. package/dist/converge-checkpoint.d.ts.map +1 -0
  18. package/dist/converge-checkpoint.js +61 -0
  19. package/dist/converge-checkpoint.js.map +1 -0
  20. package/dist/converge-job-gcp.d.ts +46 -0
  21. package/dist/converge-job-gcp.d.ts.map +1 -0
  22. package/dist/converge-job-gcp.js +368 -0
  23. package/dist/converge-job-gcp.js.map +1 -0
  24. package/dist/converge-job-setup.d.ts +62 -0
  25. package/dist/converge-job-setup.d.ts.map +1 -0
  26. package/dist/converge-job-setup.js +228 -0
  27. package/dist/converge-job-setup.js.map +1 -0
  28. package/dist/converge-job.d.ts +141 -0
  29. package/dist/converge-job.d.ts.map +1 -0
  30. package/dist/converge-job.js +325 -0
  31. package/dist/converge-job.js.map +1 -0
  32. package/dist/gcp-names.d.ts +25 -1
  33. package/dist/gcp-names.d.ts.map +1 -1
  34. package/dist/gcp-names.js +36 -0
  35. package/dist/gcp-names.js.map +1 -1
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +2 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/infra-contract.d.ts +1 -1
  41. package/dist/infra-contract.d.ts.map +1 -1
  42. package/dist/infra-contract.js +28 -1
  43. package/dist/infra-contract.js.map +1 -1
  44. package/dist/install-job.d.ts +11 -3
  45. package/dist/install-job.d.ts.map +1 -1
  46. package/dist/install-job.js +22 -12
  47. package/dist/install-job.js.map +1 -1
  48. package/dist/lifecycle.d.ts +13 -1
  49. package/dist/lifecycle.d.ts.map +1 -1
  50. package/dist/lifecycle.js +115 -58
  51. package/dist/lifecycle.js.map +1 -1
  52. package/dist/operator-access.d.ts.map +1 -1
  53. package/dist/operator-access.js +13 -3
  54. package/dist/operator-access.js.map +1 -1
  55. package/dist/private-file.d.ts +26 -0
  56. package/dist/private-file.d.ts.map +1 -0
  57. package/dist/private-file.js +49 -0
  58. package/dist/private-file.js.map +1 -0
  59. package/dist/release-contract.d.ts +3 -2
  60. package/dist/release-contract.d.ts.map +1 -1
  61. package/dist/release-contract.js +8 -2
  62. package/dist/release-contract.js.map +1 -1
  63. package/dist/release-manifest.d.ts +2 -0
  64. package/dist/release-manifest.d.ts.map +1 -1
  65. package/dist/release-manifest.js.map +1 -1
  66. package/dist/remote-mcp-edge.d.ts +114 -0
  67. package/dist/remote-mcp-edge.d.ts.map +1 -0
  68. package/dist/remote-mcp-edge.js +116 -0
  69. package/dist/remote-mcp-edge.js.map +1 -0
  70. package/dist/remote-mcp.d.ts +117 -0
  71. package/dist/remote-mcp.d.ts.map +1 -0
  72. package/dist/remote-mcp.js +379 -0
  73. package/dist/remote-mcp.js.map +1 -0
  74. package/dist/runtime-secrets.d.ts +12 -0
  75. package/dist/runtime-secrets.d.ts.map +1 -1
  76. package/dist/runtime-secrets.js +32 -4
  77. package/dist/runtime-secrets.js.map +1 -1
  78. package/dist/seal-key-rotation.d.ts +38 -0
  79. package/dist/seal-key-rotation.d.ts.map +1 -0
  80. package/dist/seal-key-rotation.js +206 -0
  81. package/dist/seal-key-rotation.js.map +1 -0
  82. package/dist/stack-contract.d.ts +175 -3
  83. package/dist/stack-contract.d.ts.map +1 -1
  84. package/dist/stack-contract.js +183 -3
  85. package/dist/stack-contract.js.map +1 -1
  86. package/dist/stack-converge.d.ts +38 -1
  87. package/dist/stack-converge.d.ts.map +1 -1
  88. package/dist/stack-converge.js +74 -4
  89. package/dist/stack-converge.js.map +1 -1
  90. package/dist/state-lock-lease.d.ts +142 -0
  91. package/dist/state-lock-lease.d.ts.map +1 -0
  92. package/dist/state-lock-lease.js +347 -0
  93. package/dist/state-lock-lease.js.map +1 -0
  94. package/dist/state-store.d.ts +66 -9
  95. package/dist/state-store.d.ts.map +1 -1
  96. package/dist/state-store.js +249 -30
  97. package/dist/state-store.js.map +1 -1
  98. package/dist/tar-entries.d.ts.map +1 -1
  99. package/dist/tar-entries.js +84 -9
  100. package/dist/tar-entries.js.map +1 -1
  101. package/dist/upgrade/app-roll.d.ts +36 -7
  102. package/dist/upgrade/app-roll.d.ts.map +1 -1
  103. package/dist/upgrade/app-roll.js +88 -19
  104. package/dist/upgrade/app-roll.js.map +1 -1
  105. package/dist/upgrade/audit-job-roll.d.ts +38 -0
  106. package/dist/upgrade/audit-job-roll.d.ts.map +1 -0
  107. package/dist/upgrade/audit-job-roll.js +43 -0
  108. package/dist/upgrade/audit-job-roll.js.map +1 -0
  109. package/dist/upgrade/converge.d.ts.map +1 -1
  110. package/dist/upgrade/converge.js +141 -8
  111. package/dist/upgrade/converge.js.map +1 -1
  112. package/dist/upgrade/gcp-lookup.d.ts +27 -10
  113. package/dist/upgrade/gcp-lookup.d.ts.map +1 -1
  114. package/dist/upgrade/gcp-lookup.js +46 -7
  115. package/dist/upgrade/gcp-lookup.js.map +1 -1
  116. package/dist/upgrade/record-rolled.d.ts +40 -0
  117. package/dist/upgrade/record-rolled.d.ts.map +1 -0
  118. package/dist/upgrade/record-rolled.js +46 -0
  119. package/dist/upgrade/record-rolled.js.map +1 -0
  120. package/dist/upgrade/upgrade.d.ts +45 -1
  121. package/dist/upgrade/upgrade.d.ts.map +1 -1
  122. package/dist/upgrade/upgrade.js +60 -17
  123. package/dist/upgrade/upgrade.js.map +1 -1
  124. package/dist/upgrader-assess.d.ts +15 -1
  125. package/dist/upgrader-assess.d.ts.map +1 -1
  126. package/dist/upgrader-assess.js +36 -6
  127. package/dist/upgrader-assess.js.map +1 -1
  128. package/dist/upgrader-gcp.d.ts +15 -0
  129. package/dist/upgrader-gcp.d.ts.map +1 -1
  130. package/dist/upgrader-gcp.js +42 -7
  131. package/dist/upgrader-gcp.js.map +1 -1
  132. package/dist/upgrader-iam-preflight.d.ts +123 -0
  133. package/dist/upgrader-iam-preflight.d.ts.map +1 -0
  134. package/dist/upgrader-iam-preflight.js +414 -0
  135. package/dist/upgrader-iam-preflight.js.map +1 -0
  136. package/dist/upgrader-job.d.ts +33 -9
  137. package/dist/upgrader-job.d.ts.map +1 -1
  138. package/dist/upgrader-job.js +169 -27
  139. package/dist/upgrader-job.js.map +1 -1
  140. package/dist/upgrader-records.d.ts +58 -0
  141. package/dist/upgrader-records.d.ts.map +1 -0
  142. package/dist/upgrader-records.js +87 -0
  143. package/dist/upgrader-records.js.map +1 -0
  144. package/dist/upgrader-reporter.d.ts +3 -2
  145. package/dist/upgrader-reporter.d.ts.map +1 -1
  146. package/dist/upgrader-reporter.js +10 -2
  147. package/dist/upgrader-reporter.js.map +1 -1
  148. package/dist/upgrader-setup.d.ts +25 -3
  149. package/dist/upgrader-setup.d.ts.map +1 -1
  150. package/dist/upgrader-setup.js +132 -14
  151. package/dist/upgrader-setup.js.map +1 -1
  152. package/dist/wizards/gcp-cost.d.ts.map +1 -1
  153. package/dist/wizards/gcp-cost.js +14 -6
  154. package/dist/wizards/gcp-cost.js.map +1 -1
  155. package/dist/wizards/gcp-pulumi.d.ts +6 -0
  156. package/dist/wizards/gcp-pulumi.d.ts.map +1 -1
  157. package/dist/wizards/gcp-pulumi.js +7 -0
  158. package/dist/wizards/gcp-pulumi.js.map +1 -1
  159. package/dist/wizards/gcp.d.ts.map +1 -1
  160. package/dist/wizards/gcp.js +130 -4
  161. package/dist/wizards/gcp.js.map +1 -1
  162. package/package.json +4 -4
  163. package/src/agent/run.test.ts +15 -1
  164. package/src/audit-job-setup.test.ts +234 -0
  165. package/src/audit-job-setup.ts +360 -0
  166. package/src/caddy-redirects.docker.test.ts +19 -6
  167. package/src/caddy.test.ts +30 -0
  168. package/src/caddy.ts +43 -0
  169. package/src/cli-init-validation.test.ts +44 -0
  170. package/src/cli-routing.ts +1 -1
  171. package/src/cli.ts +40 -8
  172. package/src/compose.ts +5 -0
  173. package/src/converge-checkpoint.ts +75 -0
  174. package/src/converge-entrypoint.test.ts +213 -0
  175. package/src/converge-job-gcp.test.ts +222 -0
  176. package/src/converge-job-gcp.ts +443 -0
  177. package/src/converge-job-setup.test.ts +152 -0
  178. package/src/converge-job-setup.ts +268 -0
  179. package/src/converge-job.test.ts +486 -0
  180. package/src/converge-job.ts +542 -0
  181. package/src/gateway-env-isolation.test.ts +8 -1
  182. package/src/gcp-names.ts +43 -1
  183. package/src/gcp-url-map.test.ts +9 -1
  184. package/src/index.ts +8 -0
  185. package/src/infra-contract.test.ts +7 -4
  186. package/src/infra-contract.ts +28 -1
  187. package/src/install-job.test.ts +3 -1
  188. package/src/install-job.ts +31 -14
  189. package/src/lifecycle.ts +137 -71
  190. package/src/operator-access.test.ts +14 -0
  191. package/src/operator-access.ts +13 -3
  192. package/src/private-file.test.ts +80 -0
  193. package/src/private-file.ts +50 -0
  194. package/src/release-contract.ts +8 -2
  195. package/src/release-manifest.test.ts +42 -0
  196. package/src/release-manifest.ts +2 -0
  197. package/src/remote-mcp-edge.ts +137 -0
  198. package/src/remote-mcp.test.ts +517 -0
  199. package/src/remote-mcp.ts +460 -0
  200. package/src/runtime-secrets.test.ts +31 -6
  201. package/src/runtime-secrets.ts +41 -3
  202. package/src/seal-key-rotation.test.ts +131 -0
  203. package/src/seal-key-rotation.ts +258 -0
  204. package/src/stack-contract-parity.test.ts +20 -3
  205. package/src/stack-contract.test.ts +34 -2
  206. package/src/stack-contract.ts +305 -3
  207. package/src/stack-converge-secrets.test.ts +3 -0
  208. package/src/stack-converge.test.ts +21 -5
  209. package/src/stack-converge.ts +101 -7
  210. package/src/state-attach.test.ts +7 -1
  211. package/src/state-lock-lease.test.ts +302 -0
  212. package/src/state-lock-lease.ts +423 -0
  213. package/src/state-lock.test.ts +568 -0
  214. package/src/state-store.ts +347 -27
  215. package/src/tar-entries.test.ts +149 -7
  216. package/src/tar-entries.ts +90 -9
  217. package/src/upgrade/app-roll.ts +135 -21
  218. package/src/upgrade/audit-job-roll.ts +68 -0
  219. package/src/upgrade/converge.ts +170 -7
  220. package/src/upgrade/gcp-lookup.test.ts +80 -0
  221. package/src/upgrade/gcp-lookup.ts +65 -8
  222. package/src/upgrade/record-rolled.test.ts +105 -0
  223. package/src/upgrade/record-rolled.ts +91 -0
  224. package/src/upgrade/upgrade.test.ts +279 -5
  225. package/src/upgrade/upgrade.ts +120 -24
  226. package/src/upgrader-assess.test.ts +93 -3
  227. package/src/upgrader-assess.ts +58 -9
  228. package/src/upgrader-gcp.ts +47 -8
  229. package/src/upgrader-iam-preflight.test.ts +393 -0
  230. package/src/upgrader-iam-preflight.ts +510 -0
  231. package/src/upgrader-job.test.ts +587 -15
  232. package/src/upgrader-job.ts +237 -53
  233. package/src/upgrader-records.ts +151 -0
  234. package/src/upgrader-reporter.test.ts +6 -0
  235. package/src/upgrader-reporter.ts +7 -2
  236. package/src/upgrader-setup.test.ts +4 -3
  237. package/src/upgrader-setup.ts +137 -13
  238. package/src/wizards/gcp-cost.ts +15 -6
  239. package/src/wizards/gcp-pulumi.ts +7 -0
  240. package/src/wizards/gcp.ts +162 -4
  241. package/stacks/aws/index.ts +18 -0
  242. package/stacks/azure/index.ts +18 -0
  243. package/stacks/gcp/index.ts +59 -7
  244. package/stacks/gcp-firebase/index.ts +50 -6
@@ -0,0 +1,142 @@
1
+ import { z } from "zod";
2
+ import type { GcloudResult } from "./gcloud.js";
3
+ /** A Cloud Run job execution, fully addressed. */
4
+ export interface CloudRunExecutionRef {
5
+ readonly projectId: string;
6
+ readonly region: string;
7
+ /** The execution's short name (`CLOUD_RUN_EXECUTION`). */
8
+ readonly name: string;
9
+ }
10
+ /**
11
+ * A lock holder that Cloud Run can vouch for: the execution and the
12
+ * longest it can run (its task timeout).
13
+ */
14
+ export interface ExecutionLockHolder {
15
+ readonly execution: CloudRunExecutionRef;
16
+ readonly maxRuntimeMs: number;
17
+ }
18
+ /**
19
+ * A lock holder outside Cloud Run (a CLI process): its lease is short and
20
+ * renewed by a heartbeat while it runs, so a holder that dies stops
21
+ * renewing and its lock expires on its own (#815).
22
+ */
23
+ export interface ProcessLockHolder {
24
+ readonly leaseMs: number;
25
+ }
26
+ /** Who takes a lock: a Cloud Run execution, or a renewing process. */
27
+ export type LockHolder = ExecutionLockHolder | ProcessLockHolder;
28
+ /** The lease of a CLI process's lock; renewed every third of it. */
29
+ export declare const PROCESS_LEASE_MS: number;
30
+ /**
31
+ * Margin added to a lease for clock skew between the holder and the run
32
+ * judging it (both read their own clock; Cloud Run's are NTP-synced, a
33
+ * developer laptop's may not be).
34
+ */
35
+ export declare const LEASE_SKEW_MS: number;
36
+ /** The lock object's body. `execution` + `leaseUntil` appear together (#815). */
37
+ declare const lockBodySchema: z.ZodObject<{
38
+ purpose: z.ZodString;
39
+ id: z.ZodOptional<z.ZodString>;
40
+ host: z.ZodOptional<z.ZodString>;
41
+ machine: z.ZodOptional<z.ZodNullable<z.ZodString>>;
42
+ pid: z.ZodOptional<z.ZodNumber>;
43
+ startedAt: z.ZodOptional<z.ZodString>;
44
+ execution: z.ZodOptional<z.ZodObject<{
45
+ projectId: z.ZodString;
46
+ region: z.ZodString;
47
+ name: z.ZodString;
48
+ }, z.core.$strip>>;
49
+ leaseUntil: z.ZodOptional<z.ZodString>;
50
+ }, z.core.$strip>;
51
+ /** The lock body as written by {@link lockBody}. */
52
+ export type LockBody = z.infer<typeof lockBodySchema>;
53
+ /**
54
+ * The body a new lock is written with.
55
+ *
56
+ * @param holder a Cloud Run execution (lease: `now + maxRuntimeMs +
57
+ * LEASE_SKEW_MS`) or a renewing process (lease: `now + leaseMs +
58
+ * LEASE_SKEW_MS`); none only for the machine-local lock file, which is
59
+ * judged by its pid alone
60
+ * @param id the acquisition's id; a fresh one when omitted
61
+ */
62
+ export declare function lockBody(purpose: string, now: Date, holder?: LockHolder, id?: string): string;
63
+ /**
64
+ * The same lock body with its lease moved to `now + leaseMs + skew` — the
65
+ * heartbeat of a process holder. Everything else (id, start) is kept.
66
+ */
67
+ export declare function renewedLockBody(body: LockBody, now: Date, leaseMs: number): string;
68
+ /** Whether process `pid` exists on this host (signal 0 checks without signalling). */
69
+ export declare function processAlive(pid: number): boolean;
70
+ /**
71
+ * An id for this machine AND pid namespace, so a pid is only ever checked
72
+ * where it was taken: the host name, the network cards' MAC addresses and
73
+ * (on Linux) the pid namespace. Null inside Cloud Run, where every
74
+ * container is called `localhost`, has its own pid space and no stable
75
+ * hardware to tell it apart — a lock from there is judged by its lease
76
+ * alone. Null too when the machine shows no network card. An id that
77
+ * changes while a lock is held (a new network card) only makes a later
78
+ * judge wait for the lease: a mismatch is always the safe direction.
79
+ */
80
+ export declare function machineId(env?: NodeJS.ProcessEnv): string | null;
81
+ /** The judging run's own host and how it checks a local pid. */
82
+ export interface LocalHost {
83
+ readonly host: string;
84
+ /**
85
+ * {@link machineId}; a lock that names another (or none) is never judged
86
+ * by its pid. Left out only by a lock from before the machine id, which
87
+ * falls back to comparing host names (state-lock-lease tests).
88
+ */
89
+ readonly machine?: string | null;
90
+ readonly alive: (pid: number) => boolean;
91
+ }
92
+ /** Parse a lock body; null when it is not one this code wrote. */
93
+ export declare function parseLockBody(text: string): LockBody | null;
94
+ /** What Cloud Run says about the holder's execution. */
95
+ export type ExecutionState = {
96
+ readonly kind: "running";
97
+ } | {
98
+ readonly kind: "finished";
99
+ readonly how: string;
100
+ } | {
101
+ readonly kind: "not-found";
102
+ }
103
+ /** Cloud Run could not be asked; `error` says why. */
104
+ | {
105
+ readonly kind: "unknown";
106
+ readonly error: string;
107
+ };
108
+ /**
109
+ * Read an execution's state from `gcloud run jobs executions describe
110
+ * --format=json`. An execution has finished once Cloud Run stamped its
111
+ * completion time or decided its `Completed` condition (True: succeeded;
112
+ * False: failed or cancelled). Anything else is still running — including
113
+ * an execution Cloud Run has not started yet.
114
+ */
115
+ export declare function parseExecutionState(result: GcloudResult): ExecutionState;
116
+ /** `gcloud run jobs executions describe`, for {@link judgeHeldLock}. */
117
+ export declare function describeExecutionArgs(ref: CloudRunExecutionRef): string[];
118
+ /** Whether a held lock may be broken, and the words for either outcome. */
119
+ export type LockVerdict = {
120
+ readonly kind: "break";
121
+ readonly why: string;
122
+ } | {
123
+ readonly kind: "held";
124
+ readonly why: string;
125
+ readonly manualRemoval: boolean;
126
+ }
127
+ /** The holder could not be checked; never treated as "dead". */
128
+ | {
129
+ readonly kind: "unknown";
130
+ readonly why: string;
131
+ };
132
+ /**
133
+ * Decide whether the lock with body `text` may be broken.
134
+ *
135
+ * @param describe looks the holder's execution up in Cloud Run; called only
136
+ * when the body names one
137
+ * @param now the judging run's clock, compared against the lease
138
+ * @param here this host's name and pid check, for a process holder's lock
139
+ */
140
+ export declare function judgeHeldLock(text: string, describe: (ref: CloudRunExecutionRef) => ExecutionState, now: Date, here?: LocalHost): LockVerdict;
141
+ export {};
142
+ //# sourceMappingURL=state-lock-lease.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-lock-lease.d.ts","sourceRoot":"","sources":["../src/state-lock-lease.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,347 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * The lease on the install's bucket state lock (#815): who holds it, and
4
+ * whether a later run may break it.
5
+ *
6
+ * A lock written by a Cloud Run job execution (the upgrader job, later the
7
+ * converge job #819) names that execution and a lease: the execution's
8
+ * start plus its task timeout, after which Cloud Run has killed it for
9
+ * sure. A run that finds the lock held asks Cloud Run about the holder:
10
+ *
11
+ * - the execution has finished (succeeded, failed, cancelled): it can no
12
+ * longer write, so its lock is dead and may be broken;
13
+ * - it is still running: the lock is live and is NEVER broken — not even
14
+ * past its lease (a lease is our estimate; Cloud Run's state is fact);
15
+ * - Cloud Run does not know it (deleted, or a name we cannot resolve):
16
+ * broken only once the lease has expired, when no execution of that
17
+ * job can still be alive;
18
+ * - Cloud Run cannot be asked (no access, gcloud error): not decided
19
+ * here — the caller reports the error; guessing "dead" could let two
20
+ * runs write the same state.
21
+ *
22
+ * A lock taken by a process outside Cloud Run (a CLI run on someone's
23
+ * machine or in Cloud Shell) names its host and pid and carries a short
24
+ * lease that the holder renews while it runs (the heartbeat in
25
+ * state-store.ts). Such a lock is broken when:
26
+ *
27
+ * - it was taken on THIS machine and its pid is no longer alive (a
28
+ * killed CLI on the same machine — no need to wait for the lease). The
29
+ * machine is told apart by {@link machineId}, not by its host name
30
+ * alone: every Cloud Run container calls itself the same, and two
31
+ * laptops may too, so a pid that is dead HERE says nothing about a
32
+ * process THERE. Inside Cloud Run there is no machine id at all, so a
33
+ * lock from there is only ever judged by its lease; or
34
+ * - its lease has expired: the holder stopped renewing it (killed, or a
35
+ * closed Cloud Shell), so it can no longer be writing.
36
+ *
37
+ * Only a lock written before #815 (no lease, no execution) is never broken
38
+ * automatically; its holder message names the command to remove it.
39
+ *
40
+ * Everything here is pure except {@link describeExecution}, which takes a
41
+ * {@link SyncGcloud}; the lock itself (create, generation-matched break,
42
+ * release) lives in state-store.ts.
43
+ */
44
+ import { createHash, randomUUID } from "node:crypto";
45
+ import { readlinkSync } from "node:fs";
46
+ import { hostname, networkInterfaces } from "node:os";
47
+ import { z } from "zod";
48
+ /** The lease of a CLI process's lock; renewed every third of it. */
49
+ export const PROCESS_LEASE_MS = 10 * 60_000;
50
+ /**
51
+ * Margin added to a lease for clock skew between the holder and the run
52
+ * judging it (both read their own clock; Cloud Run's are NTP-synced, a
53
+ * developer laptop's may not be).
54
+ */
55
+ export const LEASE_SKEW_MS = 5 * 60_000;
56
+ const executionRefSchema = z.object({
57
+ projectId: z.string().min(1),
58
+ region: z.string().min(1),
59
+ name: z.string().min(1),
60
+ });
61
+ /** The lock object's body. `execution` + `leaseUntil` appear together (#815). */
62
+ const lockBodySchema = z.object({
63
+ purpose: z.string(),
64
+ /** Unique per acquisition: proves a lock is still the one this run took. */
65
+ id: z.string().optional(),
66
+ host: z.string().optional(),
67
+ /** {@link machineId} of the writer; null when it has none (Cloud Run). */
68
+ machine: z.string().nullable().optional(),
69
+ pid: z.number().optional(),
70
+ startedAt: z.string().optional(),
71
+ execution: executionRefSchema.optional(),
72
+ leaseUntil: z.string().optional(),
73
+ });
74
+ /**
75
+ * The body a new lock is written with.
76
+ *
77
+ * @param holder a Cloud Run execution (lease: `now + maxRuntimeMs +
78
+ * LEASE_SKEW_MS`) or a renewing process (lease: `now + leaseMs +
79
+ * LEASE_SKEW_MS`); none only for the machine-local lock file, which is
80
+ * judged by its pid alone
81
+ * @param id the acquisition's id; a fresh one when omitted
82
+ */
83
+ export function lockBody(purpose, now, holder, id = randomUUID()) {
84
+ const leaseMs = holder ? ("execution" in holder ? holder.maxRuntimeMs : holder.leaseMs) : null;
85
+ const body = {
86
+ purpose,
87
+ id,
88
+ host: THIS_HOST.host,
89
+ machine: THIS_HOST.machine ?? null,
90
+ pid: process.pid,
91
+ startedAt: now.toISOString(),
92
+ ...(holder && "execution" in holder ? { execution: { ...holder.execution } } : {}),
93
+ ...(leaseMs !== null
94
+ ? { leaseUntil: new Date(now.getTime() + leaseMs + LEASE_SKEW_MS).toISOString() }
95
+ : {}),
96
+ };
97
+ return JSON.stringify(body);
98
+ }
99
+ /**
100
+ * The same lock body with its lease moved to `now + leaseMs + skew` — the
101
+ * heartbeat of a process holder. Everything else (id, start) is kept.
102
+ */
103
+ export function renewedLockBody(body, now, leaseMs) {
104
+ return JSON.stringify({
105
+ ...body,
106
+ leaseUntil: new Date(now.getTime() + leaseMs + LEASE_SKEW_MS).toISOString(),
107
+ });
108
+ }
109
+ /** Whether process `pid` exists on this host (signal 0 checks without signalling). */
110
+ export function processAlive(pid) {
111
+ try {
112
+ process.kill(pid, 0);
113
+ return true;
114
+ }
115
+ catch (e) {
116
+ // EPERM: it exists, it is just someone else's.
117
+ return e.code === "EPERM";
118
+ }
119
+ }
120
+ /**
121
+ * An id for this machine AND pid namespace, so a pid is only ever checked
122
+ * where it was taken: the host name, the network cards' MAC addresses and
123
+ * (on Linux) the pid namespace. Null inside Cloud Run, where every
124
+ * container is called `localhost`, has its own pid space and no stable
125
+ * hardware to tell it apart — a lock from there is judged by its lease
126
+ * alone. Null too when the machine shows no network card. An id that
127
+ * changes while a lock is held (a new network card) only makes a later
128
+ * judge wait for the lease: a mismatch is always the safe direction.
129
+ */
130
+ export function machineId(env = process.env) {
131
+ if (env.CLOUD_RUN_EXECUTION || env.K_SERVICE)
132
+ return null;
133
+ const macs = new Set();
134
+ for (const cards of Object.values(networkInterfaces())) {
135
+ for (const card of cards ?? []) {
136
+ if (!card.internal && card.mac && card.mac !== "00:00:00:00:00:00")
137
+ macs.add(card.mac);
138
+ }
139
+ }
140
+ if (macs.size === 0)
141
+ return null;
142
+ let pidSpace = "";
143
+ try {
144
+ pidSpace = readlinkSync("/proc/self/ns/pid");
145
+ }
146
+ catch {
147
+ // Not Linux: the machine has one pid space, which the MACs already name.
148
+ }
149
+ return createHash("sha256")
150
+ .update([hostname(), pidSpace, ...[...macs].sort()].join("\n"))
151
+ .digest("hex")
152
+ .slice(0, 32);
153
+ }
154
+ const THIS_HOST = { host: hostname(), machine: machineId(), alive: processAlive };
155
+ /** Parse a lock body; null when it is not one this code wrote. */
156
+ export function parseLockBody(text) {
157
+ let raw;
158
+ try {
159
+ raw = JSON.parse(text);
160
+ }
161
+ catch {
162
+ return null;
163
+ }
164
+ const parsed = lockBodySchema.safeParse(raw);
165
+ return parsed.success ? parsed.data : null;
166
+ }
167
+ const NOT_FOUND = /NOT_FOUND|not found|could not be found|does not exist/i;
168
+ const executionStatusSchema = z.object({
169
+ status: z
170
+ .object({
171
+ completionTime: z.string().optional(),
172
+ conditions: z
173
+ .array(z.object({
174
+ type: z.string(),
175
+ status: z.string(),
176
+ reason: z.string().optional(),
177
+ }))
178
+ .optional(),
179
+ })
180
+ .optional(),
181
+ });
182
+ /**
183
+ * Read an execution's state from `gcloud run jobs executions describe
184
+ * --format=json`. An execution has finished once Cloud Run stamped its
185
+ * completion time or decided its `Completed` condition (True: succeeded;
186
+ * False: failed or cancelled). Anything else is still running — including
187
+ * an execution Cloud Run has not started yet.
188
+ */
189
+ export function parseExecutionState(result) {
190
+ if (!result.ok) {
191
+ if (NOT_FOUND.test(result.stderr))
192
+ return { kind: "not-found" };
193
+ return {
194
+ kind: "unknown",
195
+ error: result.stderr.trim() || `gcloud exited ${result.exitCode}`,
196
+ };
197
+ }
198
+ let raw;
199
+ try {
200
+ raw = JSON.parse(result.stdout);
201
+ }
202
+ catch {
203
+ return { kind: "unknown", error: "gcloud returned no JSON for the execution" };
204
+ }
205
+ const parsed = executionStatusSchema.safeParse(raw);
206
+ if (!parsed.success) {
207
+ return { kind: "unknown", error: "gcloud returned an execution without a readable status" };
208
+ }
209
+ const status = parsed.data.status;
210
+ const completed = status?.conditions?.find((c) => c.type === "Completed");
211
+ if (completed && (completed.status === "True" || completed.status === "False")) {
212
+ const how = completed.status === "True" ? "succeeded" : (completed.reason ?? "failed").toLowerCase();
213
+ return { kind: "finished", how };
214
+ }
215
+ if (status?.completionTime)
216
+ return { kind: "finished", how: "completed" };
217
+ return { kind: "running" };
218
+ }
219
+ /** `gcloud run jobs executions describe`, for {@link judgeHeldLock}. */
220
+ export function describeExecutionArgs(ref) {
221
+ return [
222
+ "run",
223
+ "jobs",
224
+ "executions",
225
+ "describe",
226
+ ref.name,
227
+ `--region=${ref.region}`,
228
+ `--project=${ref.projectId}`,
229
+ "--format=json",
230
+ ];
231
+ }
232
+ /**
233
+ * Decide whether the lock with body `text` may be broken.
234
+ *
235
+ * @param describe looks the holder's execution up in Cloud Run; called only
236
+ * when the body names one
237
+ * @param now the judging run's clock, compared against the lease
238
+ * @param here this host's name and pid check, for a process holder's lock
239
+ */
240
+ export function judgeHeldLock(text, describe, now, here = THIS_HOST) {
241
+ const body = parseLockBody(text);
242
+ if (!body) {
243
+ return {
244
+ kind: "held",
245
+ why: `the lock's holder is not readable (${text.trim().slice(0, 200) || "empty"})`,
246
+ manualRemoval: true,
247
+ };
248
+ }
249
+ const who = holderText(body);
250
+ if (!body.execution)
251
+ return judgeProcessLock(body, who, now, here);
252
+ const leaseUntil = body.leaseUntil ? Date.parse(body.leaseUntil) : Number.NaN;
253
+ const state = describe(body.execution);
254
+ switch (state.kind) {
255
+ case "finished":
256
+ return {
257
+ kind: "break",
258
+ why: `${who} has ${state.how}, but its lock was left behind`,
259
+ };
260
+ case "running":
261
+ return { kind: "held", why: `${who} is still running`, manualRemoval: false };
262
+ case "not-found":
263
+ if (Number.isNaN(leaseUntil)) {
264
+ return {
265
+ kind: "held",
266
+ why: `${who} is unknown to Cloud Run and its lock carries no readable lease`,
267
+ manualRemoval: true,
268
+ };
269
+ }
270
+ if (now.getTime() > leaseUntil) {
271
+ return {
272
+ kind: "break",
273
+ why: `${who} is unknown to Cloud Run and its lease ended at ${body.leaseUntil}`,
274
+ };
275
+ }
276
+ return {
277
+ kind: "held",
278
+ why: `${who} is unknown to Cloud Run, but its lease runs until ${body.leaseUntil}`,
279
+ manualRemoval: false,
280
+ };
281
+ case "unknown":
282
+ return {
283
+ kind: "unknown",
284
+ why: `could not check whether ${who} is still running: ${state.error}`,
285
+ };
286
+ }
287
+ }
288
+ /**
289
+ * A process holder's lock (a CLI run): broken when its pid is dead on this
290
+ * very host, or once its lease — renewed while the holder runs — expired.
291
+ */
292
+ function judgeProcessLock(body, who, now, here) {
293
+ if (body.pid !== undefined && sameMachine(body, here) && !here.alive(body.pid)) {
294
+ return { kind: "break", why: `${who} has ended (its process is gone on this machine)` };
295
+ }
296
+ if (body.leaseUntil === undefined) {
297
+ // Written before #815: no lease to wait out, and its host may be
298
+ // another machine — only a person may remove it.
299
+ return { kind: "held", why: `held by ${who}`, manualRemoval: true };
300
+ }
301
+ const leaseUntil = Date.parse(body.leaseUntil);
302
+ if (Number.isNaN(leaseUntil)) {
303
+ return {
304
+ kind: "held",
305
+ why: `held by ${who}, whose lock carries no readable lease`,
306
+ manualRemoval: true,
307
+ };
308
+ }
309
+ if (now.getTime() > leaseUntil) {
310
+ return {
311
+ kind: "break",
312
+ why: `${who} stopped renewing its lock; its lease ended at ${body.leaseUntil}`,
313
+ };
314
+ }
315
+ return {
316
+ kind: "held",
317
+ why: `held by ${who}; its lease runs until ${body.leaseUntil} unless renewed`,
318
+ manualRemoval: false,
319
+ };
320
+ }
321
+ /**
322
+ * Whether the lock was taken where `here` can check its pid. A lock naming
323
+ * a machine id needs this run's to match; one naming none (Cloud Run)
324
+ * never matches; a lock from before machine ids compares host names.
325
+ */
326
+ function sameMachine(body, here) {
327
+ if (body.host !== here.host)
328
+ return false;
329
+ // A judge in Cloud Run shares its host name with every other container.
330
+ if (here.machine === null)
331
+ return false;
332
+ if (body.machine === undefined)
333
+ return true;
334
+ return body.machine !== null && here.machine != null && body.machine === here.machine;
335
+ }
336
+ /** "caelo upgrader job (run X, started T)" — for messages. */
337
+ function holderText(body) {
338
+ const parts = [];
339
+ if (body.execution)
340
+ parts.push(`run ${body.execution.name}`);
341
+ else if (body.host)
342
+ parts.push(`on ${body.host}${body.pid ? `, pid ${body.pid}` : ""}`);
343
+ if (body.startedAt)
344
+ parts.push(`started ${body.startedAt}`);
345
+ return parts.length > 0 ? `${body.purpose} (${parts.join(", ")})` : body.purpose;
346
+ }
347
+ //# sourceMappingURL=state-lock-lease.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-lock-lease.js","sourceRoot":"","sources":["../src/state-lock-lease.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type GcloudResult } from "./gcloud.js";
2
+ import { type ExecutionLockHolder, type LocalHost } from "./state-lock-lease.js";
2
3
  /** The two documents a store holds. */
3
4
  export type StateFile = "install.json" | "progress.json";
4
5
  /** Reads and writes an install's metadata documents. */
@@ -62,29 +63,85 @@ export declare class StateLockHeldError extends Error {
62
63
  }
63
64
  /** `gs://<bucket>/install/state.lock` — see {@link acquireBucketStateLock}. */
64
65
  export declare function bucketStateLockUrl(bucket: string): string;
66
+ /** How a bucket lock is taken: who holds it, and the clock to judge leases by. */
67
+ export interface BucketLockOptions {
68
+ /**
69
+ * The Cloud Run execution taking the lock (#815): the lock's lease is the
70
+ * execution's task timeout, and a later run may break it once Cloud Run
71
+ * says this execution has finished. Without it the holder is this
72
+ * process (a CLI run): the lock names host + pid, carries a lease of
73
+ * {@link PROCESS_LEASE_MS} and is renewed by a heartbeat until released.
74
+ */
75
+ readonly holder?: ExecutionLockHolder;
76
+ /** Told when a dead holder's lock was broken, with why. */
77
+ readonly onBreak?: (message: string) => void;
78
+ /**
79
+ * Told when the heartbeat found the lock no longer this run's (another
80
+ * run broke it after the lease ran out, e.g. while this machine slept).
81
+ */
82
+ readonly onLost?: (message: string) => void;
83
+ readonly now?: () => Date;
84
+ /** Starts the heartbeat; returns its stop. Defaults to an unref'd setInterval. */
85
+ readonly schedule?: (tick: () => void, everyMs: number) => () => void;
86
+ /** This host and its pid check (state-lock-lease.ts LocalHost); tests pass a fake. */
87
+ readonly here?: LocalHost;
88
+ }
65
89
  /**
66
90
  * The install's state lock in its ops bucket, created only if absent
67
91
  * (`--if-generation-match=0`). Held by every writer of a bucket-backed
68
- * install's state — an installer run's `pulumi up`, `state migrate` — so
69
- * none writes a backend another is switching away from. A lock left by a
70
- * crashed run is reported with the command to remove it, never broken
71
- * automatically.
92
+ * install's state — an installer run's `pulumi up`, `state migrate`, the
93
+ * CLI `upgrade`, the upgrader job — so none writes a backend another is
94
+ * switching away from.
72
95
  *
73
- * @returns the release function
96
+ * A lock that is held is judged (state-lock-lease.ts): one whose Cloud Run
97
+ * execution has finished, whose execution is gone after its lease, whose
98
+ * CLI process is gone on this host, or whose CLI lease ran out unrenewed,
99
+ * is broken with a generation-matched delete and taken once more. The
100
+ * generation is read BEFORE the body, so the delete can only remove the
101
+ * lock that was judged: if another run replaced it in between, the
102
+ * delete's precondition fails and nothing is removed. Two runs breaking the
103
+ * same dead lock cannot both win either — the slower one's create fails
104
+ * its own precondition and reports the lock as held.
105
+ *
106
+ * A CLI holder renews its lease every third of {@link PROCESS_LEASE_MS}
107
+ * with a generation-matched rewrite, so a run that is alive keeps its lock
108
+ * however long it takes, and a killed one loses it within one lease.
109
+ *
110
+ * @returns the release function; it stops the heartbeat and deletes only
111
+ * this lock's generation
112
+ * @throws StateLockHeldError when another run holds the lock
113
+ * @throws Error when the lock or its holder cannot be read (no access)
74
114
  */
75
- export declare function acquireBucketStateLock(bucket: string, purpose: string, run?: SyncGcloud): () => void;
115
+ export declare function acquireBucketStateLock(bucket: string, purpose: string, run?: SyncGcloud, opts?: BucketLockOptions): () => void;
76
116
  /**
77
117
  * The same lock for an install whose state is on this machine:
78
- * `~/.caelo-<id>/state.lock`, created exclusively.
118
+ * `~/.caelo-<id>/state.lock`, created exclusively. A lock left by a
119
+ * process that is gone on this machine is taken over (#815).
79
120
  *
121
+ * @param here this host and its pid check; tests pass a fake
80
122
  * @returns the release function
81
123
  */
82
- export declare function acquireLocalStateLock(root: string, purpose: string): () => void;
124
+ export declare function acquireLocalStateLock(root: string, purpose: string, here?: LocalHost): () => void;
83
125
  /** The state lock for whichever backend `bucket` (gcs) or `root` (local) names. */
84
126
  export declare function acquireStateLock(backend: {
85
127
  readonly kind: "local";
86
128
  } | {
87
129
  readonly kind: "gcs";
88
130
  readonly bucket: string;
89
- }, root: string, purpose: string, run?: SyncGcloud): () => void;
131
+ }, root: string, purpose: string, run?: SyncGcloud, opts?: BucketLockOptions): () => void;
132
+ /** The part of `process` {@link releaseOnSignal} needs; tests pass a fake. */
133
+ export interface SignalTarget {
134
+ once(signal: "SIGINT" | "SIGTERM", listener: () => void): unknown;
135
+ removeListener(signal: "SIGINT" | "SIGTERM", listener: () => void): unknown;
136
+ exit(code: number): never;
137
+ }
138
+ /**
139
+ * Give the state lock back when the CLI is stopped (Ctrl-C, a closed Cloud
140
+ * Shell tab's SIGTERM), then exit with the signal's conventional code
141
+ * (#815). Without this a stopped run leaves its lock until its lease ends.
142
+ *
143
+ * @param report told what happened to the lock
144
+ * @returns removes the handlers; call it once the run released the lock itself
145
+ */
146
+ export declare function releaseOnSignal(release: () => void, report: (message: string) => void, proc?: SignalTarget): () => void;
90
147
  //# sourceMappingURL=state-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../src/state-store.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,KAAK,YAAY,EAAa,MAAM,aAAa,CAAC;AAG3D,uCAAuC;AACvC,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,eAAe,CAAC;AAEzD,wDAAwD;AACxD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IAC/B,2DAA2D;IAC3D,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACrC,qDAAqD;IACrD,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9C;AAED,mFAAmF;AACnF,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC;AAE1E,mEAAmE;AACnE,eAAO,MAAM,cAAc,EAAE,UAc5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAIxE;AAcD,wDAAwD;AACxD,qBAAa,eAAgB,YAAW,UAAU;IAEpC,OAAO,CAAC,QAAQ,CAAC,IAAI;IADjC,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;gBACJ,IAAI,EAAE,MAAM;IAEzC,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI;IAKpC,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;CAG7C;AAKD;;;;;;GAMG;AACH,qBAAa,aAAc,YAAW,UAAU;IAK5C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;gBAG1C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,UAA2B;IAGnD,sCAAsC;IACtC,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM;IAIlC;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI;IASpC,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI;IAQpC,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;CAc7C;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,SAAkB,IAAI,wBAAwB;CAC/C;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzD;AAYD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,UAA2B,GAC/B,MAAM,IAAI,CAgBZ;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,IAAI,CAa/E;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACvF,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,UAA2B,GAC/B,MAAM,IAAI,CAIZ"}
1
+ {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../src/state-store.ts"],"names":[],"mappings":"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"}