@celilo/cli 0.17.0 → 0.19.0
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/CELILO_CORE_MODULES.md +1 -1
- package/CELILO_SUBSYSTEMS.md +38 -9
- package/drizzle/0019_backup_pid.sql +18 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +5 -5
- package/schemas/system_config.json +1 -1
- package/src/api/remote-client.test.ts +62 -0
- package/src/api/serve.ts +14 -6
- package/src/cli/command-tree-parser.ts +0 -1
- package/src/cli/commands/apt-upgrade.test.ts +20 -1
- package/src/cli/commands/apt-upgrade.ts +12 -2
- package/src/cli/commands/backup-sweep.ts +62 -0
- package/src/cli/commands/events.ts +90 -0
- package/src/cli/commands/module-operations.test.ts +45 -1
- package/src/cli/commands/module-operations.ts +35 -12
- package/src/cli/commands/module-show.ts +1 -0
- package/src/cli/commands/module-update.test.ts +72 -1
- package/src/cli/commands/module-update.ts +45 -22
- package/src/cli/commands/system-audit.ts +2 -0
- package/src/cli/commands/system-migrate.test.ts +56 -0
- package/src/cli/commands/system-migrate.ts +92 -4
- package/src/cli/commands/system-update.ts +5 -0
- package/src/cli/completion.ts +19 -0
- package/src/cli/fuel-gauge.ts +0 -1
- package/src/cli/generate-zsh-completion.ts +1 -1
- package/src/cli/index.ts +5 -1
- package/src/cli/tui/audit-state.ts +4 -0
- package/src/cli/tui/audit-tui.test.tsx +0 -1
- package/src/db/migration-status.test.ts +114 -0
- package/src/db/migration-status.ts +78 -0
- package/src/db/schema-introspection.ts +8 -1
- package/src/db/schema.ts +53 -9
- package/src/hooks/capability-loader.ts +30 -1
- package/src/ipam/allocator.ts +13 -3
- package/src/services/alerting/builtin-monitors.test.ts +42 -0
- package/src/services/alerting/builtin-monitors.ts +2 -0
- package/src/services/alerting/builtin-source.ts +15 -0
- package/src/services/audit/abandoned-operations.test.ts +73 -0
- package/src/services/audit/abandoned-operations.ts +0 -0
- package/src/services/audit/disk-space.test.ts +111 -0
- package/src/services/audit/disk-space.ts +114 -0
- package/src/services/audit/index.test.ts +1 -0
- package/src/services/audit/index.ts +9 -0
- package/src/services/audit/types.ts +2 -0
- package/src/services/backup-create.ts +4 -4
- package/src/services/backup-in-flight-refusal.test.ts +2 -0
- package/src/services/backup-metadata.ts +4 -0
- package/src/services/backup-staging.test.ts +134 -0
- package/src/services/backup-staging.ts +192 -0
- package/src/services/backup-sweep.test.ts +68 -0
- package/src/services/backup-sweep.ts +62 -0
- package/src/services/bus-interview.ts +11 -5
- package/src/services/config-interview.ts +1 -1
- package/src/services/deploy-ansible.ts +0 -1
- package/src/services/disk-probe.test.ts +74 -0
- package/src/services/disk-probe.ts +145 -0
- package/src/services/events-daemon.test.ts +244 -0
- package/src/services/events-daemon.ts +295 -8
- package/src/services/fleet-checks.test.ts +75 -4
- package/src/services/fleet-checks.ts +97 -12
- package/src/services/interview-errors.ts +20 -0
- package/src/services/module-operations.test.ts +22 -0
- package/src/services/module-operations.ts +48 -1
- package/src/services/module-subscriptions.test.ts +39 -6
- package/src/services/module-subscriptions.ts +6 -4
- package/src/services/module-types-generator.test.ts +6 -3
- package/src/services/module-types-generator.ts +12 -7
- package/src/services/remote-responder.test.ts +70 -0
- package/src/services/remote-responder.ts +27 -10
- package/src/services/responder-probe.ts +3 -1
- package/src/services/update/orchestrator.test.ts +1 -0
- package/src/variables/context.ts +6 -1
|
@@ -20,6 +20,9 @@ const NO_SCHEMAS = defineEvents({});
|
|
|
20
20
|
/** The normalized question handed to the wire (mirrors InterviewMessage). */
|
|
21
21
|
export interface WireInterview {
|
|
22
22
|
id: string;
|
|
23
|
+
/** The question's stable identity, so a client can pre-stage `<scope>.<key>`. */
|
|
24
|
+
scope: string;
|
|
25
|
+
key: string;
|
|
23
26
|
kind: InterviewRequiredPayload['kind'];
|
|
24
27
|
message: string;
|
|
25
28
|
description?: string;
|
|
@@ -54,16 +57,30 @@ export function startRemoteResponder(opts: RemoteResponderOptions): RemoteRespon
|
|
|
54
57
|
return;
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
let value: unknown;
|
|
61
|
+
try {
|
|
62
|
+
value = await opts.ask({
|
|
63
|
+
id: String(event.id),
|
|
64
|
+
scope: payload.scope,
|
|
65
|
+
key: payload.key,
|
|
66
|
+
kind: payload.kind,
|
|
67
|
+
message: payload.message,
|
|
68
|
+
description: payload.description,
|
|
69
|
+
defaultValue: payload.defaultValue,
|
|
70
|
+
placeholder: payload.placeholder,
|
|
71
|
+
options: payload.options,
|
|
72
|
+
required: payload.required,
|
|
73
|
+
});
|
|
74
|
+
} catch (err) {
|
|
75
|
+
// The client had no way to answer. Reply with the reason so the waiting
|
|
76
|
+
// command fails loudly — never let the question decay to its default.
|
|
77
|
+
bus.emitRaw(
|
|
78
|
+
`${event.type}.reply`,
|
|
79
|
+
{ error: err instanceof Error ? err.message : String(err) },
|
|
80
|
+
{ replyFor: event.id, emittedBy: me },
|
|
81
|
+
);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
67
84
|
|
|
68
85
|
bus.emitRaw(`${event.type}.reply`, { value }, { replyFor: event.id, emittedBy: me });
|
|
69
86
|
});
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { defineEvents, openBus } from '@celilo/event-bus';
|
|
16
16
|
import { getEventBusPath } from '../config/paths';
|
|
17
|
+
import { InterviewUnansweredError } from './interview-errors';
|
|
17
18
|
|
|
18
19
|
const NO_SCHEMAS = defineEvents({});
|
|
19
20
|
|
|
@@ -63,7 +64,8 @@ export async function ensureResponderForInterview(queryType: string): Promise<vo
|
|
|
63
64
|
if (process.stdin.isTTY) return;
|
|
64
65
|
const available = await probeForResponder(getEventBusPath());
|
|
65
66
|
if (available) return;
|
|
66
|
-
throw new
|
|
67
|
+
throw new InterviewUnansweredError(
|
|
68
|
+
queryType,
|
|
67
69
|
`No responder is listening and stdin isn't a TTY, so this interview prompt can't be answered (${queryType}).
|
|
68
70
|
|
|
69
71
|
Either:
|
|
@@ -76,6 +76,7 @@ const cleanAudit: AuditDeps = {
|
|
|
76
76
|
moduleConfigs: { modules: [] },
|
|
77
77
|
health: { results: [] },
|
|
78
78
|
backups: { modules: [] },
|
|
79
|
+
abandonedOperations: { records: [] },
|
|
79
80
|
undeployedModules: { modules: [] },
|
|
80
81
|
unconfiguredModules: { modules: [] },
|
|
81
82
|
servicesCredentials: { results: [] },
|
package/src/variables/context.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { DbClient } from '../db/client';
|
|
|
5
5
|
import {
|
|
6
6
|
capabilities,
|
|
7
7
|
containerServices,
|
|
8
|
+
isAllocatableZone,
|
|
8
9
|
machines,
|
|
9
10
|
moduleConfigs,
|
|
10
11
|
moduleInfrastructure,
|
|
@@ -391,7 +392,11 @@ export async function buildResolutionContext(
|
|
|
391
392
|
.get();
|
|
392
393
|
isProxmox = svc?.providerName === 'proxmox';
|
|
393
394
|
}
|
|
394
|
-
|
|
395
|
+
// `isAllocatableZone`, not `zone !== 'external'`: that check was written
|
|
396
|
+
// when `external` was the only zone celilo does not address, and it
|
|
397
|
+
// silently became wrong the moment `vpn` joined it — a VPN client subnet
|
|
398
|
+
// is assigned by the tunnel module, so allocating into it would collide.
|
|
399
|
+
if (isProxmox && isAllocatableZone(zone)) {
|
|
395
400
|
await db.transaction(async (tx) => {
|
|
396
401
|
const existing = await getAllocation(moduleId, tx);
|
|
397
402
|
const allocation = existing ?? (await allocateResources(moduleId, zone, tx));
|