@calltelemetry/cli 0.12.10 → 0.12.12
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/dist/commands/config.d.ts +25 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +42 -3
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/db.d.ts +24 -0
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +43 -4
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/go-parity.d.ts +32 -0
- package/dist/commands/go-parity.d.ts.map +1 -0
- package/dist/commands/go-parity.js +359 -0
- package/dist/commands/go-parity.js.map +1 -0
- package/dist/commands/jtapi.d.ts.map +1 -1
- package/dist/commands/jtapi.js +2 -0
- package/dist/commands/jtapi.js.map +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +2 -0
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/network.d.ts.map +1 -1
- package/dist/commands/network.js +63 -50
- package/dist/commands/network.js.map +1 -1
- package/dist/commands/offline.d.ts.map +1 -1
- package/dist/commands/offline.js +2 -0
- package/dist/commands/offline.js.map +1 -1
- package/dist/commands/seed.d.ts.map +1 -1
- package/dist/commands/seed.js +2 -0
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/ship-certs.d.ts +7 -0
- package/dist/commands/ship-certs.d.ts.map +1 -0
- package/dist/commands/ship-certs.js +105 -0
- package/dist/commands/ship-certs.js.map +1 -0
- package/dist/commands/ship-db.d.ts +8 -0
- package/dist/commands/ship-db.d.ts.map +1 -0
- package/dist/commands/ship-db.js +358 -0
- package/dist/commands/ship-db.js.map +1 -0
- package/dist/commands/ship-diag.d.ts +10 -0
- package/dist/commands/ship-diag.d.ts.map +1 -0
- package/dist/commands/ship-diag.js +73 -0
- package/dist/commands/ship-diag.js.map +1 -0
- package/dist/commands/ship-ipv6.d.ts +6 -0
- package/dist/commands/ship-ipv6.d.ts.map +1 -0
- package/dist/commands/ship-ipv6.js +59 -0
- package/dist/commands/ship-ipv6.js.map +1 -0
- package/dist/commands/ship-logging.d.ts +7 -0
- package/dist/commands/ship-logging.d.ts.map +1 -0
- package/dist/commands/ship-logging.js +71 -0
- package/dist/commands/ship-logging.js.map +1 -0
- package/dist/commands/ship-migrate.d.ts +6 -0
- package/dist/commands/ship-migrate.d.ts.map +1 -0
- package/dist/commands/ship-migrate.js +152 -0
- package/dist/commands/ship-migrate.js.map +1 -0
- package/dist/commands/ship-os-updates.d.ts +6 -0
- package/dist/commands/ship-os-updates.d.ts.map +1 -0
- package/dist/commands/ship-os-updates.js +116 -0
- package/dist/commands/ship-os-updates.js.map +1 -0
- package/dist/commands/ship-postgres.d.ts +6 -0
- package/dist/commands/ship-postgres.d.ts.map +1 -0
- package/dist/commands/ship-postgres.js +84 -0
- package/dist/commands/ship-postgres.js.map +1 -0
- package/dist/commands/ship-services.d.ts +7 -0
- package/dist/commands/ship-services.d.ts.map +1 -0
- package/dist/commands/ship-services.js +127 -0
- package/dist/commands/ship-services.js.map +1 -0
- package/dist/commands/ship-sql-monitor.d.ts +6 -0
- package/dist/commands/ship-sql-monitor.d.ts.map +1 -0
- package/dist/commands/ship-sql-monitor.js +89 -0
- package/dist/commands/ship-sql-monitor.js.map +1 -0
- package/dist/commands/ship-status.d.ts +6 -0
- package/dist/commands/ship-status.d.ts.map +1 -0
- package/dist/commands/ship-status.js +21 -0
- package/dist/commands/ship-status.js.map +1 -0
- package/dist/commands/ship-update.d.ts +31 -0
- package/dist/commands/ship-update.d.ts.map +1 -0
- package/dist/commands/ship-update.js +234 -0
- package/dist/commands/ship-update.js.map +1 -0
- package/dist/commands/ship-users.d.ts +7 -0
- package/dist/commands/ship-users.d.ts.map +1 -0
- package/dist/commands/ship-users.js +118 -0
- package/dist/commands/ship-users.js.map +1 -0
- package/dist/commands/syslog.d.ts.map +1 -1
- package/dist/commands/syslog.js +18 -2
- package/dist/commands/syslog.js.map +1 -1
- package/dist/commands/update.d.ts +45 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +74 -3
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/users.d.ts.map +1 -1
- package/dist/commands/users.js +51 -0
- package/dist/commands/users.js.map +1 -1
- package/dist/index.js +3 -72
- package/dist/index.js.map +1 -1
- package/dist/lib/network-apply.d.ts +102 -0
- package/dist/lib/network-apply.d.ts.map +1 -0
- package/dist/lib/network-apply.js +472 -0
- package/dist/lib/network-apply.js.map +1 -0
- package/dist/lib/ops-port.d.ts +205 -0
- package/dist/lib/ops-port.d.ts.map +1 -0
- package/dist/lib/ops-port.js +906 -0
- package/dist/lib/ops-port.js.map +1 -0
- package/dist/lib/public-doc.d.ts +37 -0
- package/dist/lib/public-doc.d.ts.map +1 -0
- package/dist/lib/public-doc.js +27 -0
- package/dist/lib/public-doc.js.map +1 -0
- package/dist/lib/ship-identity.d.ts +9 -0
- package/dist/lib/ship-identity.d.ts.map +1 -0
- package/dist/lib/ship-identity.js +12 -0
- package/dist/lib/ship-identity.js.map +1 -0
- package/dist/lib/ship-logo.d.ts +11 -0
- package/dist/lib/ship-logo.d.ts.map +1 -0
- package/dist/lib/ship-logo.js +17 -0
- package/dist/lib/ship-logo.js.map +1 -0
- package/dist/lib/ship-status.d.ts +21 -0
- package/dist/lib/ship-status.d.ts.map +1 -0
- package/dist/lib/ship-status.js +82 -0
- package/dist/lib/ship-status.js.map +1 -0
- package/dist/lib/syslog.d.ts +4 -0
- package/dist/lib/syslog.d.ts.map +1 -1
- package/dist/lib/syslog.js +28 -0
- package/dist/lib/syslog.js.map +1 -1
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/program.d.ts +22 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +124 -0
- package/dist/program.js.map +1 -0
- package/dist/shell/commands/diag.d.ts.map +1 -1
- package/dist/shell/commands/diag.js +47 -19
- package/dist/shell/commands/diag.js.map +1 -1
- package/dist/shell/commands/ops-mutates.d.ts +16 -0
- package/dist/shell/commands/ops-mutates.d.ts.map +1 -0
- package/dist/shell/commands/ops-mutates.js +62 -0
- package/dist/shell/commands/ops-mutates.js.map +1 -0
- package/dist/shell/commands/registry.d.ts.map +1 -1
- package/dist/shell/commands/registry.js +43 -0
- package/dist/shell/commands/registry.js.map +1 -1
- package/dist/shell/commands/show.d.ts +12 -0
- package/dist/shell/commands/show.d.ts.map +1 -1
- package/dist/shell/commands/show.js +190 -10
- package/dist/shell/commands/show.js.map +1 -1
- package/dist/shell/commands/telemetry.d.ts +11 -0
- package/dist/shell/commands/telemetry.d.ts.map +1 -0
- package/dist/shell/commands/telemetry.js +49 -0
- package/dist/shell/commands/telemetry.js.map +1 -0
- package/dist/shell/network-onboarding.d.ts +7 -4
- package/dist/shell/network-onboarding.d.ts.map +1 -1
- package/dist/shell/network-onboarding.js +22 -38
- package/dist/shell/network-onboarding.js.map +1 -1
- package/dist/ship-entry.d.ts +3 -0
- package/dist/ship-entry.d.ts.map +1 -0
- package/dist/ship-entry.js +121 -0
- package/dist/ship-entry.js.map +1 -0
- package/dist/ui/views/MainMenu.d.ts.map +1 -1
- package/dist/ui/views/MainMenu.js +3 -0
- package/dist/ui/views/MainMenu.js.map +1 -1
- package/dist/ui/views/SyslogView.d.ts +7 -0
- package/dist/ui/views/SyslogView.d.ts.map +1 -0
- package/dist/ui/views/SyslogView.js +53 -0
- package/dist/ui/views/SyslogView.js.map +1 -0
- package/package.json +9 -2
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reboot-safe NetworkManager apply path (parity with Go ct #923/#924).
|
|
3
|
+
*
|
|
4
|
+
* - Demote competing ethernet autoconnect profiles on the same iface
|
|
5
|
+
* - Create ct-network at autoconnect priority 200
|
|
6
|
+
* - On static: disable/mask cloud-init network rewrite
|
|
7
|
+
* - Verify ct-network is the active profile after up
|
|
8
|
+
* - Mid-sequence failure: best-effort restore demoted autoconnect + actionable recovery text
|
|
9
|
+
*/
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { exec } from './exec.js';
|
|
12
|
+
import { getPaths } from './paths.js';
|
|
13
|
+
import { updateEnvKeys } from './env.js';
|
|
14
|
+
export const CT_NETWORK_CONN = 'ct-network';
|
|
15
|
+
export const CT_NETWORK_AUTOCONNECT_PRIORITY = '200';
|
|
16
|
+
/** Human-facing recovery pointer used in fail-closed messages. */
|
|
17
|
+
export const NETWORK_FIX_HINT = 'Recovery: run `ct network fix` to demote competitors and re-activate ct-network, ' +
|
|
18
|
+
'or re-enable a prior profile: `nmcli connection modify <name|uuid> connection.autoconnect yes` ' +
|
|
19
|
+
'then `nmcli connection up <name|uuid>`.';
|
|
20
|
+
const defaultRun = async (cmd, args) => {
|
|
21
|
+
const r = await exec(cmd, args);
|
|
22
|
+
return { stdout: String(r.stdout ?? ''), stderr: String(r.stderr ?? '') };
|
|
23
|
+
};
|
|
24
|
+
async function runSoft(run, cmd, args) {
|
|
25
|
+
try {
|
|
26
|
+
const r = await run(cmd, args);
|
|
27
|
+
return String(r.stdout ?? '').trim();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return '';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Primary ethernet device name (nmcli DEVICE,TYPE). */
|
|
34
|
+
export async function detectPrimaryEthernet(run = defaultRun) {
|
|
35
|
+
const out = await runSoft(run, 'nmcli', ['-t', '-f', 'DEVICE,TYPE', 'device']);
|
|
36
|
+
const line = out.split('\n').find((l) => l.includes(':ethernet'));
|
|
37
|
+
const iface = line?.split(':')[0]?.trim();
|
|
38
|
+
if (!iface)
|
|
39
|
+
throw new Error('No ethernet interface detected.');
|
|
40
|
+
return iface;
|
|
41
|
+
}
|
|
42
|
+
/** Active connection name on iface, or empty. */
|
|
43
|
+
export async function activeConnectionOnIface(iface, run = defaultRun) {
|
|
44
|
+
const out = await runSoft(run, 'nmcli', ['-t', '-f', 'NAME,DEVICE', 'connection', 'show', '--active']);
|
|
45
|
+
const line = out.split('\n').find((l) => l.endsWith(`:${iface}`));
|
|
46
|
+
return line ? line.split(':')[0] : '';
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Disable autoconnect on competing ethernet profiles bound to iface
|
|
50
|
+
* (except ct-network). Matches Go disableCompetingNetworkProfiles.
|
|
51
|
+
* @returns UUIDs that were demoted (for mid-sequence recovery).
|
|
52
|
+
*/
|
|
53
|
+
export async function disableCompetingNetworkProfiles(iface, run = defaultRun) {
|
|
54
|
+
const demoted = [];
|
|
55
|
+
const productUUID = await runSoft(run, 'nmcli', [
|
|
56
|
+
'-g', 'connection.uuid', 'connection', 'show', CT_NETWORK_CONN,
|
|
57
|
+
]);
|
|
58
|
+
const raw = await runSoft(run, 'nmcli', ['-t', '-f', 'UUID,DEVICE,TYPE', 'connection', 'show']);
|
|
59
|
+
if (!raw)
|
|
60
|
+
return demoted;
|
|
61
|
+
for (const line of raw.split('\n')) {
|
|
62
|
+
const parts = line.trim().split(':');
|
|
63
|
+
if (parts.length < 3)
|
|
64
|
+
continue;
|
|
65
|
+
const [profileUUID, device, typ] = parts;
|
|
66
|
+
if (!profileUUID)
|
|
67
|
+
continue;
|
|
68
|
+
if (typ !== '802-3-ethernet' && typ !== 'ethernet')
|
|
69
|
+
continue;
|
|
70
|
+
if (productUUID && profileUUID === productUUID)
|
|
71
|
+
continue;
|
|
72
|
+
const profileIface = await runSoft(run, 'nmcli', [
|
|
73
|
+
'-g', 'connection.interface-name', 'connection', 'show', 'uuid', profileUUID,
|
|
74
|
+
]);
|
|
75
|
+
if (device !== iface && profileIface !== iface)
|
|
76
|
+
continue;
|
|
77
|
+
await run('nmcli', [
|
|
78
|
+
'connection', 'modify', 'uuid', profileUUID, 'connection.autoconnect', 'no',
|
|
79
|
+
]);
|
|
80
|
+
demoted.push(profileUUID);
|
|
81
|
+
}
|
|
82
|
+
return demoted;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Best-effort re-enable autoconnect on profiles demoted earlier in this apply.
|
|
86
|
+
* Used when create/up fails after demote/delete so the box is not left without
|
|
87
|
+
* an autoconnect path.
|
|
88
|
+
*/
|
|
89
|
+
export async function restoreDemotedProfiles(demotedUuids, run = defaultRun) {
|
|
90
|
+
const restored = [];
|
|
91
|
+
const failed = [];
|
|
92
|
+
for (const uuid of demotedUuids) {
|
|
93
|
+
try {
|
|
94
|
+
await run('nmcli', [
|
|
95
|
+
'connection', 'modify', 'uuid', uuid, 'connection.autoconnect', 'yes',
|
|
96
|
+
]);
|
|
97
|
+
restored.push(uuid);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
failed.push(uuid);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return { restored, failed };
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* After a mid-sequence failure: re-enable demoted profiles and try to bring
|
|
107
|
+
* back a prior active connection. Always returns ok:false with named step.
|
|
108
|
+
*/
|
|
109
|
+
export async function recoverAfterApplyFailure(opts) {
|
|
110
|
+
const { step, detail, iface, demotedUuids, previousActive, run } = opts;
|
|
111
|
+
const { restored, failed } = await restoreDemotedProfiles(demotedUuids, run);
|
|
112
|
+
let upTarget = '';
|
|
113
|
+
// Prefer prior active profile when it still exists and is not the product conn we may have deleted.
|
|
114
|
+
if (previousActive && previousActive !== CT_NETWORK_CONN) {
|
|
115
|
+
try {
|
|
116
|
+
await run('nmcli', ['connection', 'up', previousActive]);
|
|
117
|
+
upTarget = previousActive;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// fall through to uuid up
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (!upTarget && restored.length > 0) {
|
|
124
|
+
try {
|
|
125
|
+
await run('nmcli', ['connection', 'up', 'uuid', restored[0]]);
|
|
126
|
+
upTarget = `uuid ${restored[0]}`;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// best-effort only
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const recoveryLines = [];
|
|
133
|
+
if (demotedUuids.length > 0) {
|
|
134
|
+
recoveryLines.push(`Best-effort recovery: re-enabled autoconnect on ${restored.length}/${demotedUuids.length} demoted profile(s)` +
|
|
135
|
+
(failed.length ? ` (failed: ${failed.join(', ')})` : '') +
|
|
136
|
+
(upTarget ? `; brought up ${upTarget}` : '; no profile could be brought up'));
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
recoveryLines.push('Best-effort recovery: no demoted profiles to restore.');
|
|
140
|
+
}
|
|
141
|
+
recoveryLines.push(NETWORK_FIX_HINT);
|
|
142
|
+
return {
|
|
143
|
+
ok: false,
|
|
144
|
+
message: [
|
|
145
|
+
`Error: network apply failed at step "${step}" on ${iface}: ${detail}`,
|
|
146
|
+
...recoveryLines,
|
|
147
|
+
].join('\n'),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/** Best-effort cloud-init network disable + unit mask (static apply only). */
|
|
151
|
+
export async function disableCloudInitNetworking(run = defaultRun) {
|
|
152
|
+
await runSoft(run, 'sudo', ['mkdir', '-p', '/etc/cloud/cloud.cfg.d']);
|
|
153
|
+
await runSoft(run, 'sudo', [
|
|
154
|
+
'bash', '-c',
|
|
155
|
+
`printf '%s\\n' 'network: {config: disabled}' > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg`,
|
|
156
|
+
]);
|
|
157
|
+
await runSoft(run, 'sudo', [
|
|
158
|
+
'systemctl', 'disable', '--now',
|
|
159
|
+
'cloud-init.service', 'cloud-init-local.service', 'cloud-config.service', 'cloud-final.service',
|
|
160
|
+
]);
|
|
161
|
+
await runSoft(run, 'sudo', [
|
|
162
|
+
'systemctl', 'mask',
|
|
163
|
+
'cloud-init.service', 'cloud-init-local.service', 'cloud-config.service', 'cloud-final.service',
|
|
164
|
+
]);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Create/activate static ct-network (priority 200), demote competitors,
|
|
168
|
+
* disable cloud-init, verify active profile. On create/up failure after
|
|
169
|
+
* demote/delete, best-effort restore demoted autoconnect paths.
|
|
170
|
+
*/
|
|
171
|
+
export async function applyStaticAddress(opts) {
|
|
172
|
+
const run = opts.run ?? defaultRun;
|
|
173
|
+
const address = opts.address.trim();
|
|
174
|
+
const gateway = opts.gateway.trim();
|
|
175
|
+
if (!address || !gateway) {
|
|
176
|
+
return {
|
|
177
|
+
ok: false,
|
|
178
|
+
message: 'Error: IP address and gateway are required.\nUsage: ct network address <ip/prefix> <gateway>',
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
let iface;
|
|
182
|
+
try {
|
|
183
|
+
iface = opts.iface?.trim() || (await detectPrimaryEthernet(run));
|
|
184
|
+
}
|
|
185
|
+
catch (e) {
|
|
186
|
+
return { ok: false, message: e?.message ?? 'No ethernet interface detected.' };
|
|
187
|
+
}
|
|
188
|
+
const previousActive = await activeConnectionOnIface(iface, run);
|
|
189
|
+
let demotedUuids = [];
|
|
190
|
+
try {
|
|
191
|
+
demotedUuids = await disableCompetingNetworkProfiles(iface, run);
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
return {
|
|
195
|
+
ok: false,
|
|
196
|
+
message: `Error: failed to disable competing network profiles: ${e?.message ?? e}`,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
// Point of no return for "may leave no autoconnect" — delete old product profile.
|
|
200
|
+
await runSoft(run, 'nmcli', ['connection', 'delete', CT_NETWORK_CONN]);
|
|
201
|
+
try {
|
|
202
|
+
await run('nmcli', [
|
|
203
|
+
'connection', 'add', 'type', 'ethernet',
|
|
204
|
+
'con-name', CT_NETWORK_CONN, 'ifname', iface,
|
|
205
|
+
'ipv4.method', 'manual',
|
|
206
|
+
'ipv4.addresses', address,
|
|
207
|
+
'ipv4.gateway', gateway,
|
|
208
|
+
'connection.autoconnect', 'yes',
|
|
209
|
+
'connection.autoconnect-priority', CT_NETWORK_AUTOCONNECT_PRIORITY,
|
|
210
|
+
]);
|
|
211
|
+
}
|
|
212
|
+
catch (e) {
|
|
213
|
+
return recoverAfterApplyFailure({
|
|
214
|
+
step: 'create-static-profile',
|
|
215
|
+
detail: String(e?.message ?? e),
|
|
216
|
+
iface,
|
|
217
|
+
demotedUuids,
|
|
218
|
+
previousActive,
|
|
219
|
+
run,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (opts.dnsServers && opts.dnsServers.length > 0) {
|
|
223
|
+
try {
|
|
224
|
+
await run('nmcli', [
|
|
225
|
+
'connection', 'modify', CT_NETWORK_CONN,
|
|
226
|
+
'ipv4.dns', opts.dnsServers.join(','),
|
|
227
|
+
]);
|
|
228
|
+
}
|
|
229
|
+
catch (e) {
|
|
230
|
+
return recoverAfterApplyFailure({
|
|
231
|
+
step: 'set-dns',
|
|
232
|
+
detail: String(e?.message ?? e),
|
|
233
|
+
iface,
|
|
234
|
+
demotedUuids,
|
|
235
|
+
previousActive,
|
|
236
|
+
run,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
await disableCloudInitNetworking(run);
|
|
241
|
+
try {
|
|
242
|
+
await run('nmcli', ['connection', 'up', CT_NETWORK_CONN]);
|
|
243
|
+
}
|
|
244
|
+
catch (e) {
|
|
245
|
+
return recoverAfterApplyFailure({
|
|
246
|
+
step: 'activate-static-profile',
|
|
247
|
+
detail: String(e?.message ?? e),
|
|
248
|
+
iface,
|
|
249
|
+
demotedUuids,
|
|
250
|
+
previousActive,
|
|
251
|
+
run,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
const active = await activeConnectionOnIface(iface, run);
|
|
255
|
+
if (active !== CT_NETWORK_CONN) {
|
|
256
|
+
return recoverAfterApplyFailure({
|
|
257
|
+
step: 'verify-active-profile',
|
|
258
|
+
detail: `static network profile is not active on ${iface} (active profile: ${active || '(none)'})`,
|
|
259
|
+
iface,
|
|
260
|
+
demotedUuids,
|
|
261
|
+
previousActive,
|
|
262
|
+
run,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
ok: true,
|
|
267
|
+
mode: 'static',
|
|
268
|
+
iface,
|
|
269
|
+
message: `Static IP ${address} configured (gateway: ${gateway}). Will auto-connect on boot.\nNext: ct network dns-servers 8.8.8.8 4.4.4.4`,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/** Create/activate DHCP ct-network (priority 200); do not mask cloud-init. */
|
|
273
|
+
export async function applyDhcp(opts = {}) {
|
|
274
|
+
const run = opts.run ?? defaultRun;
|
|
275
|
+
let iface;
|
|
276
|
+
try {
|
|
277
|
+
iface = opts.iface?.trim() || (await detectPrimaryEthernet(run));
|
|
278
|
+
}
|
|
279
|
+
catch (e) {
|
|
280
|
+
return { ok: false, message: e?.message ?? 'No ethernet interface detected.' };
|
|
281
|
+
}
|
|
282
|
+
const previousActive = await activeConnectionOnIface(iface, run);
|
|
283
|
+
let demotedUuids = [];
|
|
284
|
+
try {
|
|
285
|
+
demotedUuids = await disableCompetingNetworkProfiles(iface, run);
|
|
286
|
+
}
|
|
287
|
+
catch (e) {
|
|
288
|
+
return {
|
|
289
|
+
ok: false,
|
|
290
|
+
message: `Error: failed to disable competing network profiles: ${e?.message ?? e}`,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
await runSoft(run, 'nmcli', ['connection', 'delete', CT_NETWORK_CONN]);
|
|
294
|
+
try {
|
|
295
|
+
await run('nmcli', [
|
|
296
|
+
'connection', 'add', 'type', 'ethernet',
|
|
297
|
+
'con-name', CT_NETWORK_CONN, 'ifname', iface,
|
|
298
|
+
'ipv4.method', 'auto',
|
|
299
|
+
'connection.autoconnect', 'yes',
|
|
300
|
+
'connection.autoconnect-priority', CT_NETWORK_AUTOCONNECT_PRIORITY,
|
|
301
|
+
]);
|
|
302
|
+
}
|
|
303
|
+
catch (e) {
|
|
304
|
+
return recoverAfterApplyFailure({
|
|
305
|
+
step: 'create-dhcp-profile',
|
|
306
|
+
detail: String(e?.message ?? e),
|
|
307
|
+
iface,
|
|
308
|
+
demotedUuids,
|
|
309
|
+
previousActive,
|
|
310
|
+
run,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
try {
|
|
314
|
+
await run('nmcli', ['connection', 'up', CT_NETWORK_CONN]);
|
|
315
|
+
}
|
|
316
|
+
catch (e) {
|
|
317
|
+
return recoverAfterApplyFailure({
|
|
318
|
+
step: 'activate-dhcp-profile',
|
|
319
|
+
detail: String(e?.message ?? e),
|
|
320
|
+
iface,
|
|
321
|
+
demotedUuids,
|
|
322
|
+
previousActive,
|
|
323
|
+
run,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
const active = await activeConnectionOnIface(iface, run);
|
|
327
|
+
if (active !== CT_NETWORK_CONN) {
|
|
328
|
+
return recoverAfterApplyFailure({
|
|
329
|
+
step: 'verify-active-profile',
|
|
330
|
+
detail: `DHCP network profile is not active on ${iface} (active profile: ${active || '(none)'})`,
|
|
331
|
+
iface,
|
|
332
|
+
demotedUuids,
|
|
333
|
+
previousActive,
|
|
334
|
+
run,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
ok: true,
|
|
339
|
+
mode: 'dhcp',
|
|
340
|
+
iface,
|
|
341
|
+
message: `DHCP configured on ${iface}. Will auto-connect on boot.`,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Repair NetworkManager: demote competitors and ensure ct-network autoconnects.
|
|
346
|
+
* Parity with Go `network fix`.
|
|
347
|
+
*/
|
|
348
|
+
export async function fixNetworkProfiles(iface, run = defaultRun) {
|
|
349
|
+
let resolved;
|
|
350
|
+
try {
|
|
351
|
+
resolved = iface?.trim() || (await detectPrimaryEthernet(run));
|
|
352
|
+
}
|
|
353
|
+
catch (e) {
|
|
354
|
+
return { ok: false, message: e?.message ?? 'No ethernet interface detected.' };
|
|
355
|
+
}
|
|
356
|
+
try {
|
|
357
|
+
await disableCompetingNetworkProfiles(resolved, run);
|
|
358
|
+
await run('nmcli', [
|
|
359
|
+
'connection', 'modify', CT_NETWORK_CONN,
|
|
360
|
+
'connection.autoconnect', 'yes',
|
|
361
|
+
'connection.autoconnect-priority', CT_NETWORK_AUTOCONNECT_PRIORITY,
|
|
362
|
+
]);
|
|
363
|
+
await run('nmcli', ['connection', 'up', CT_NETWORK_CONN]);
|
|
364
|
+
}
|
|
365
|
+
catch (e) {
|
|
366
|
+
return {
|
|
367
|
+
ok: false,
|
|
368
|
+
message: [
|
|
369
|
+
`Error: network fix failed: ${e?.message ?? e}`,
|
|
370
|
+
NETWORK_FIX_HINT,
|
|
371
|
+
].join('\n'),
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
const active = await activeConnectionOnIface(resolved, run);
|
|
375
|
+
if (active !== CT_NETWORK_CONN) {
|
|
376
|
+
return {
|
|
377
|
+
ok: false,
|
|
378
|
+
message: [
|
|
379
|
+
`Error: after fix, active profile on ${resolved} is ${active || '(none)'} (want ${CT_NETWORK_CONN}).`,
|
|
380
|
+
NETWORK_FIX_HINT,
|
|
381
|
+
].join('\n'),
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
ok: true,
|
|
386
|
+
mode: 'static',
|
|
387
|
+
iface: resolved,
|
|
388
|
+
message: `Network profiles repaired on ${resolved}: competitors demoted, ${CT_NETWORK_CONN} priority ${CT_NETWORK_AUTOCONNECT_PRIORITY}.`,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Persist EXTERNAL_IP-style callback address into appliance .env.
|
|
393
|
+
* Uses getPaths().installDir (via updateEnvKeys / getEnvFilePath) — never cwd-relative bare `.env`.
|
|
394
|
+
*/
|
|
395
|
+
export async function setExternalIp(ip, opts = {}) {
|
|
396
|
+
const value = ip.trim();
|
|
397
|
+
if (!value) {
|
|
398
|
+
return { ok: false, message: 'Error: IP required.\nUsage: ct network set-external-ip <ip|auto>' };
|
|
399
|
+
}
|
|
400
|
+
const resolvedEnvPath = opts.envPath ?? join(getPaths().installDir, '.env');
|
|
401
|
+
try {
|
|
402
|
+
if (opts.updateEnv) {
|
|
403
|
+
await opts.updateEnv({ EXTERNAL_IP: value });
|
|
404
|
+
}
|
|
405
|
+
else if (opts.envPath) {
|
|
406
|
+
// Explicit path (tests / rare overrides): update via Node fs helper path still under caller's control.
|
|
407
|
+
// Prefer updateEnvKeys when path matches installDir default; for custom paths write key with updateEnvKeys-style logic via env module is installDir-only, so use injectable updateEnv or write via updateEnvKeys after noting path.
|
|
408
|
+
// For custom envPath without updateEnv, call updateEnvKeys is wrong (wrong file). Use a small local rewrite via fs.
|
|
409
|
+
const { existsSync, readFileSync } = await import('node:fs');
|
|
410
|
+
const { writeFileSafe } = await import('./fs.js');
|
|
411
|
+
let raw = '';
|
|
412
|
+
try {
|
|
413
|
+
if (existsSync(opts.envPath))
|
|
414
|
+
raw = readFileSync(opts.envPath, 'utf-8');
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
raw = '';
|
|
418
|
+
}
|
|
419
|
+
const lines = raw.length > 0 ? raw.split('\n') : [];
|
|
420
|
+
if (lines.length > 0 && lines[lines.length - 1] === '')
|
|
421
|
+
lines.pop();
|
|
422
|
+
let found = false;
|
|
423
|
+
const out = [];
|
|
424
|
+
for (const line of lines) {
|
|
425
|
+
const trimmed = line.trim();
|
|
426
|
+
if (!trimmed || trimmed.startsWith('#')) {
|
|
427
|
+
out.push(line);
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
const stripped = trimmed.startsWith('export ') ? trimmed.slice(7) : trimmed;
|
|
431
|
+
const eq = stripped.indexOf('=');
|
|
432
|
+
if (eq === -1) {
|
|
433
|
+
out.push(line);
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
const key = stripped.slice(0, eq).trim();
|
|
437
|
+
if (key === 'EXTERNAL_IP' && !found) {
|
|
438
|
+
out.push(`EXTERNAL_IP=${value}`);
|
|
439
|
+
found = true;
|
|
440
|
+
}
|
|
441
|
+
else if (key === 'EXTERNAL_IP') {
|
|
442
|
+
// drop duplicates
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
out.push(line);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (!found)
|
|
449
|
+
out.push(`EXTERNAL_IP=${value}`);
|
|
450
|
+
await writeFileSafe(opts.envPath, out.length > 0 ? out.join('\n') + '\n' : `EXTERNAL_IP=${value}\n`, {
|
|
451
|
+
mode: 0o600,
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
// Default production path: getPaths().installDir/.env via env helper
|
|
456
|
+
await updateEnvKeys({ EXTERNAL_IP: value });
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
catch (e) {
|
|
460
|
+
return {
|
|
461
|
+
ok: false,
|
|
462
|
+
message: `Error: failed to set external IP at ${resolvedEnvPath}: ${e?.message ?? e}`,
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
return {
|
|
466
|
+
ok: true,
|
|
467
|
+
mode: 'static',
|
|
468
|
+
iface: '',
|
|
469
|
+
message: `Network environment external IP set to ${value} (${resolvedEnvPath}).`,
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
//# sourceMappingURL=network-apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-apply.js","sourceRoot":"","sources":["../../src/lib/network-apply.ts"],"names":[],"mappings":"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"}
|