@caelo-cms/provisioning 0.10.48 → 0.10.49
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.
- package/caddy/Caddyfile.production +1 -1
- package/caddy/Caddyfile.staging +1 -1
- package/dist/agent-db.js +98 -58
- package/dist/release-manifest.d.ts +2 -41
- package/dist/release-manifest.d.ts.map +1 -1
- package/dist/release-manifest.js +18 -121
- package/dist/release-manifest.js.map +1 -1
- package/dist/upgrade/release-images.d.ts +14 -2
- package/dist/upgrade/release-images.d.ts.map +1 -1
- package/dist/upgrade/release-images.js +4 -2
- package/dist/upgrade/release-images.js.map +1 -1
- package/dist/upgrader-assess.d.ts +4 -1
- package/dist/upgrader-assess.d.ts.map +1 -1
- package/dist/upgrader-assess.js +6 -0
- package/dist/upgrader-assess.js.map +1 -1
- package/dist/upgrader-job.d.ts +3 -1
- package/dist/upgrader-job.d.ts.map +1 -1
- package/dist/upgrader-job.js.map +1 -1
- package/package.json +2 -2
- package/src/agent/run.test.ts +55 -0
- package/src/release-manifest.test.ts +8 -1
- package/src/release-manifest.ts +37 -157
- package/src/upgrade/release-images.ts +4 -2
- package/src/upgrader-assess.test.ts +42 -1
- package/src/upgrader-assess.ts +18 -1
- package/src/upgrader-job.test.ts +3 -0
- package/src/upgrader-job.ts +3 -0
|
@@ -35,9 +35,12 @@ const POLICY: StoredUpdatePolicy = {
|
|
|
35
35
|
windowEnd: null,
|
|
36
36
|
windowTimezone: "UTC",
|
|
37
37
|
soakHours: 24,
|
|
38
|
+
securitySoakHours: 2,
|
|
38
39
|
paused: false,
|
|
39
40
|
pausedReason: null,
|
|
40
41
|
pausedAt: null,
|
|
42
|
+
pausedUntil: null,
|
|
43
|
+
pausedByOwner: false,
|
|
41
44
|
updatedAt: "2026-10-13T00:00:00Z",
|
|
42
45
|
};
|
|
43
46
|
|
|
@@ -57,6 +60,7 @@ interface Row {
|
|
|
57
60
|
readonly manifest?: ReleaseManifestResult;
|
|
58
61
|
readonly installed?: InstalledState;
|
|
59
62
|
readonly trigger?: "manual" | "auto";
|
|
63
|
+
readonly autoBasis?: "security" | "patch" | "minor";
|
|
60
64
|
readonly policy?: StoredUpdatePolicy;
|
|
61
65
|
readonly target?: string;
|
|
62
66
|
/** "proceed" or `<status>/<code>`. */
|
|
@@ -157,6 +161,39 @@ const ROWS: readonly Row[] = [
|
|
|
157
161
|
manifest: verified({ security: true, advisories: ["GHSA-abcd-efgh-ijkm"] }),
|
|
158
162
|
expect: "proceed",
|
|
159
163
|
},
|
|
164
|
+
{
|
|
165
|
+
name: "automatic 'security' flag without a published advisory",
|
|
166
|
+
trigger: "auto",
|
|
167
|
+
policy: { ...POLICY, autoMinor: false, autoPatch: false },
|
|
168
|
+
manifest: verified({ security: true, advisories: [] }),
|
|
169
|
+
expect: "refused/policy",
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: "queued as a security fix, signed manifest says it is not one",
|
|
173
|
+
trigger: "auto",
|
|
174
|
+
autoBasis: "security",
|
|
175
|
+
expect: "refused/policy",
|
|
176
|
+
reasonContains: "names no published security advisory",
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: "queued as a security fix, signed manifest agrees",
|
|
180
|
+
trigger: "auto",
|
|
181
|
+
autoBasis: "security",
|
|
182
|
+
manifest: verified({ security: true, advisories: ["GHSA-abcd-efgh-ijkm"] }),
|
|
183
|
+
expect: "proceed",
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: "automatic, Owner pause already over",
|
|
187
|
+
trigger: "auto",
|
|
188
|
+
policy: {
|
|
189
|
+
...POLICY,
|
|
190
|
+
paused: true,
|
|
191
|
+
pausedByOwner: true,
|
|
192
|
+
pausedAt: "2026-10-12T00:00:00Z",
|
|
193
|
+
pausedUntil: "2026-10-13T00:00:00Z",
|
|
194
|
+
},
|
|
195
|
+
expect: "proceed",
|
|
196
|
+
},
|
|
160
197
|
{
|
|
161
198
|
name: "automatic, outside the window",
|
|
162
199
|
trigger: "auto",
|
|
@@ -175,7 +212,11 @@ const ROWS: readonly Row[] = [
|
|
|
175
212
|
describe("assessUpgradeRequest — refusal matrix", () => {
|
|
176
213
|
it.each(ROWS.map((r) => [r.name, r] as const))("%s", (_name, row) => {
|
|
177
214
|
const d = assessUpgradeRequest({
|
|
178
|
-
request: {
|
|
215
|
+
request: {
|
|
216
|
+
targetVersion: row.target ?? "0.11.0",
|
|
217
|
+
trigger: row.trigger ?? "manual",
|
|
218
|
+
autoBasis: row.autoBasis ?? null,
|
|
219
|
+
},
|
|
179
220
|
manifest: row.manifest ?? verified(),
|
|
180
221
|
installed: row.installed ?? INSTALLED,
|
|
181
222
|
policy: row.policy ?? POLICY,
|
package/src/upgrader-assess.ts
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
* | contract (destructive) migrations, automatic run | refused |
|
|
31
31
|
* | contract migrations, Owner's click | proceed + warning |
|
|
32
32
|
* | automatic run the update policy does not allow | refused |
|
|
33
|
+
* | automatic "security" run, signed manifest disagrees | refused |
|
|
33
34
|
*
|
|
34
35
|
* Self-hosted installs (the host agent, #696 Phase 4c) have no separately
|
|
35
36
|
* converged infrastructure: their Compose file, roles and bootstrap script
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
*/
|
|
41
42
|
|
|
42
43
|
import {
|
|
44
|
+
type AutoUpdateBasis,
|
|
43
45
|
autoInstallRefusal,
|
|
44
46
|
type PlatformUpdateTrigger,
|
|
45
47
|
type StoredUpdatePolicy,
|
|
@@ -119,7 +121,12 @@ const stop = (
|
|
|
119
121
|
|
|
120
122
|
/** Decide what the job does with a request. See the file comment for the matrix. */
|
|
121
123
|
export function assessUpgradeRequest(input: {
|
|
122
|
-
readonly request: {
|
|
124
|
+
readonly request: {
|
|
125
|
+
readonly targetVersion: string;
|
|
126
|
+
readonly trigger: PlatformUpdateTrigger;
|
|
127
|
+
/** Why the admin's scheduler queued an automatic request (Phase 5). */
|
|
128
|
+
readonly autoBasis?: AutoUpdateBasis | null;
|
|
129
|
+
};
|
|
123
130
|
readonly manifest: ReleaseManifestResult;
|
|
124
131
|
readonly installed: InstalledState;
|
|
125
132
|
readonly policy: StoredUpdatePolicy;
|
|
@@ -228,6 +235,16 @@ export function assessUpgradeRequest(input: {
|
|
|
228
235
|
if (refusal) {
|
|
229
236
|
return stop("refused", "policy", `Not installed automatically: ${refusal}.`, manifest);
|
|
230
237
|
}
|
|
238
|
+
// The scheduler read the manifest unverified; it may only have used the
|
|
239
|
+
// security fix's shorter soak period if the SIGNED manifest backs it.
|
|
240
|
+
if (request.autoBasis === "security" && assessment.kind !== "security") {
|
|
241
|
+
return stop(
|
|
242
|
+
"refused",
|
|
243
|
+
"policy",
|
|
244
|
+
`Not installed automatically: v${target} was queued as a security fix, but its signed release information names no published security advisory. Install it from Settings → Updates.`,
|
|
245
|
+
manifest,
|
|
246
|
+
);
|
|
247
|
+
}
|
|
231
248
|
}
|
|
232
249
|
return { kind: "proceed", manifest, warnings };
|
|
233
250
|
}
|
package/src/upgrader-job.test.ts
CHANGED
|
@@ -53,9 +53,12 @@ const POLICY: StoredUpdatePolicy = {
|
|
|
53
53
|
windowEnd: null,
|
|
54
54
|
windowTimezone: "UTC",
|
|
55
55
|
soakHours: 24,
|
|
56
|
+
securitySoakHours: 2,
|
|
56
57
|
paused: false,
|
|
57
58
|
pausedReason: null,
|
|
58
59
|
pausedAt: null,
|
|
60
|
+
pausedUntil: null,
|
|
61
|
+
pausedByOwner: false,
|
|
59
62
|
updatedAt: "2026-10-13T00:00:00Z",
|
|
60
63
|
};
|
|
61
64
|
|
package/src/upgrader-job.ts
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
35
|
import type {
|
|
36
|
+
AutoUpdateBasis,
|
|
36
37
|
PlatformUpdateEventLevel,
|
|
37
38
|
PlatformUpdatePhase,
|
|
38
39
|
PlatformUpdateTrigger,
|
|
@@ -61,6 +62,8 @@ export interface ClaimedUpdate {
|
|
|
61
62
|
readonly id: string;
|
|
62
63
|
readonly targetVersion: string;
|
|
63
64
|
readonly trigger: PlatformUpdateTrigger;
|
|
65
|
+
/** Why the admin's scheduler queued an automatic request; null for the Owner's. */
|
|
66
|
+
readonly autoBasis?: AutoUpdateBasis | null;
|
|
64
67
|
readonly policy: StoredUpdatePolicy;
|
|
65
68
|
}
|
|
66
69
|
|