vpsgui 1.2.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/LICENSE +21 -0
- package/README.md +130 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +564 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +199 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +315 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +61 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +164 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +391 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const readline = __importStar(require("readline"));
|
|
38
|
+
const stream_1 = require("stream");
|
|
39
|
+
const client_1 = require("./client");
|
|
40
|
+
const config_1 = require("./config");
|
|
41
|
+
/**
|
|
42
|
+
* The `vpsgui` command.
|
|
43
|
+
*
|
|
44
|
+
* A deliberately small surface: sign in once, then run the handful of things an
|
|
45
|
+
* operator wants from a terminal without opening the dashboard. Anything richer
|
|
46
|
+
* belongs in a script against the SDK, which is what this shares its config
|
|
47
|
+
* with.
|
|
48
|
+
*/
|
|
49
|
+
const VERSION = '1.2.0';
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Output
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Respect NO_COLOR, and never emit escapes when piped - `vpsgui ps | grep` and
|
|
54
|
+
// `vpsgui status > log` should produce plain text.
|
|
55
|
+
const useColor = process.stdout.isTTY === true && !process.env.NO_COLOR;
|
|
56
|
+
const ESC = String.fromCharCode(27);
|
|
57
|
+
const paint = (code) => (s) => (useColor ? ESC + '[' + code + 'm' + s + ESC + '[0m' : s);
|
|
58
|
+
const bold = paint('1');
|
|
59
|
+
const dim = paint('2');
|
|
60
|
+
const red = paint('31');
|
|
61
|
+
const green = paint('32');
|
|
62
|
+
const yellow = paint('33');
|
|
63
|
+
const cyan = paint('36');
|
|
64
|
+
function out(line = '') {
|
|
65
|
+
process.stdout.write(line + '\n');
|
|
66
|
+
}
|
|
67
|
+
/** Errors go to stderr so they survive a pipe and do not corrupt parsed output. */
|
|
68
|
+
function fail(message, hint) {
|
|
69
|
+
process.stderr.write(`${red('error')} ${message}\n`);
|
|
70
|
+
if (hint)
|
|
71
|
+
process.stderr.write(`${dim(hint)}\n`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
function table(rows) {
|
|
75
|
+
if (rows.length === 0)
|
|
76
|
+
return;
|
|
77
|
+
const widths = rows[0].map((_, i) => Math.max(...rows.map((r) => (r[i] || '').length)));
|
|
78
|
+
rows.forEach((row, rowIndex) => {
|
|
79
|
+
const line = row
|
|
80
|
+
.map((cell, i) => (i === row.length - 1 ? cell : (cell || '').padEnd(widths[i])))
|
|
81
|
+
.join(' ');
|
|
82
|
+
out(rowIndex === 0 ? bold(line) : line);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// Input
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
function prompt(question) {
|
|
89
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
90
|
+
return new Promise((resolve) => {
|
|
91
|
+
rl.question(question, (answer) => {
|
|
92
|
+
rl.close();
|
|
93
|
+
resolve(answer.trim());
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Read a secret without echoing it.
|
|
99
|
+
*
|
|
100
|
+
* A muted writable swallows the keystrokes readline would otherwise echo, so
|
|
101
|
+
* the token never lands in a screen recording or a shoulder-surfer's view. It
|
|
102
|
+
* cannot reach the shell history either, which is the main reason this is a
|
|
103
|
+
* prompt rather than an argument.
|
|
104
|
+
*/
|
|
105
|
+
function promptSecret(question) {
|
|
106
|
+
if (!process.stdin.isTTY) {
|
|
107
|
+
// Piped input (`echo $TOKEN | vpsgui login`) has nothing to echo anyway.
|
|
108
|
+
return prompt('');
|
|
109
|
+
}
|
|
110
|
+
const muted = new stream_1.Writable({
|
|
111
|
+
write(chunk, encoding, callback) {
|
|
112
|
+
// Let the question itself through; suppress everything typed after it.
|
|
113
|
+
if (!muted.muting)
|
|
114
|
+
process.stdout.write(chunk, encoding);
|
|
115
|
+
callback();
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
const rl = readline.createInterface({ input: process.stdin, output: muted, terminal: true });
|
|
119
|
+
return new Promise((resolve) => {
|
|
120
|
+
rl.question(question, (answer) => {
|
|
121
|
+
rl.close();
|
|
122
|
+
process.stdout.write('\n');
|
|
123
|
+
resolve(answer.trim());
|
|
124
|
+
});
|
|
125
|
+
muted.muting = true;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
function parseArgs(argv) {
|
|
129
|
+
const positional = [];
|
|
130
|
+
const flags = {};
|
|
131
|
+
for (let i = 0; i < argv.length; i++) {
|
|
132
|
+
const arg = argv[i];
|
|
133
|
+
if (!arg.startsWith('--')) {
|
|
134
|
+
positional.push(arg);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const body = arg.slice(2);
|
|
138
|
+
const eq = body.indexOf('=');
|
|
139
|
+
if (eq !== -1) {
|
|
140
|
+
flags[body.slice(0, eq)] = body.slice(eq + 1);
|
|
141
|
+
}
|
|
142
|
+
else if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {
|
|
143
|
+
flags[body] = argv[++i];
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
flags[body] = true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { command: positional.shift() || 'help', positional, flags };
|
|
150
|
+
}
|
|
151
|
+
function flagString(args, name) {
|
|
152
|
+
const value = args.flags[name];
|
|
153
|
+
return typeof value === 'string' ? value : undefined;
|
|
154
|
+
}
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// Client
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
async function connect(args) {
|
|
159
|
+
const creds = await (0, config_1.loadCredentials)(flagString(args, 'profile'));
|
|
160
|
+
if (!creds) {
|
|
161
|
+
fail('Not signed in.', 'Run: vpsgui login');
|
|
162
|
+
}
|
|
163
|
+
return new client_1.VpsguiClient({ baseUrl: creds.url, token: creds.token });
|
|
164
|
+
}
|
|
165
|
+
/** Translate agent failures into something an operator can act on. */
|
|
166
|
+
function describe(e) {
|
|
167
|
+
if (e instanceof client_1.VpsguiError) {
|
|
168
|
+
if (e.status === 401) {
|
|
169
|
+
return { message: 'The agent rejected the token (401).', hint: 'Run: vpsgui login' };
|
|
170
|
+
}
|
|
171
|
+
// 403 means two unrelated things. Path confinement is by far the more common
|
|
172
|
+
// one, and telling someone to sign in again when the real problem is that
|
|
173
|
+
// /etc is not a configured root sends them down the wrong path entirely.
|
|
174
|
+
if (e.status === 403) {
|
|
175
|
+
if (/root/i.test(e.message)) {
|
|
176
|
+
return {
|
|
177
|
+
message: e.message,
|
|
178
|
+
hint: 'Run `vpsgui whoami` to see which paths this agent allows.',
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return { message: `${e.message} (403)`, hint: 'If this is unexpected, run: vpsgui login' };
|
|
182
|
+
}
|
|
183
|
+
if (e.status === 429) {
|
|
184
|
+
return { message: 'Locked out after repeated failed attempts. Wait a few minutes.' };
|
|
185
|
+
}
|
|
186
|
+
if (e.status === 404) {
|
|
187
|
+
return {
|
|
188
|
+
message: `${e.endpoint} does not exist on this agent (404).`,
|
|
189
|
+
hint: 'The agent is probably older than this CLI. Re-run the installer on the host: sudo ./run.sh',
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (e.status === 0) {
|
|
193
|
+
return {
|
|
194
|
+
message: `Could not reach the agent: ${e.message}`,
|
|
195
|
+
hint: 'Check the URL, that the agent is running, and that the port is open.',
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return { message: `${e.message} (${e.status})` };
|
|
199
|
+
}
|
|
200
|
+
return { message: e instanceof Error ? e.message : String(e) };
|
|
201
|
+
}
|
|
202
|
+
// ---------------------------------------------------------------------------
|
|
203
|
+
// Commands
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
/**
|
|
206
|
+
* Save credentials for a host, after proving they work.
|
|
207
|
+
*
|
|
208
|
+
* Verifying before writing matters: a saved-but-wrong token turns every later
|
|
209
|
+
* command into a 401 that looks like the agent is broken, and the operator has
|
|
210
|
+
* no way to tell which of the two values they got wrong.
|
|
211
|
+
*/
|
|
212
|
+
async function cmdLogin(args) {
|
|
213
|
+
const profileName = flagString(args, 'profile') || 'default';
|
|
214
|
+
const rawUrl = args.positional[0] || flagString(args, 'url') || (await prompt('Agent URL: '));
|
|
215
|
+
let url;
|
|
216
|
+
try {
|
|
217
|
+
url = (0, config_1.normaliseUrl)(rawUrl);
|
|
218
|
+
}
|
|
219
|
+
catch (e) {
|
|
220
|
+
fail(e instanceof Error ? e.message : String(e));
|
|
221
|
+
}
|
|
222
|
+
// --token exists for automation, but it lands in shell history, so the
|
|
223
|
+
// interactive path stays the default and the docs only show that one.
|
|
224
|
+
let token = flagString(args, 'token') || process.env.VPSGUI_AGENT_TOKEN || '';
|
|
225
|
+
if (!token) {
|
|
226
|
+
out(dim('The agent token is under Settings in the dashboard. It grants root-equivalent control.'));
|
|
227
|
+
token = await promptSecret('Agent token: ');
|
|
228
|
+
}
|
|
229
|
+
if (!token)
|
|
230
|
+
fail('No token entered.');
|
|
231
|
+
out(dim(`Verifying ${url}...`));
|
|
232
|
+
const client = new client_1.VpsguiClient({ baseUrl: url, token });
|
|
233
|
+
let info;
|
|
234
|
+
try {
|
|
235
|
+
info = await client.info();
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
238
|
+
const { message, hint } = describe(e);
|
|
239
|
+
fail(message, hint);
|
|
240
|
+
}
|
|
241
|
+
// Nice-to-have; a host that answers /agent/info but not /node is still usable.
|
|
242
|
+
let hostname;
|
|
243
|
+
try {
|
|
244
|
+
hostname = (await client.nodes.get()).name;
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
hostname = undefined;
|
|
248
|
+
}
|
|
249
|
+
const config = await (0, config_1.readConfig)();
|
|
250
|
+
config.profiles[profileName] = {
|
|
251
|
+
url,
|
|
252
|
+
token,
|
|
253
|
+
hostname,
|
|
254
|
+
agentVersion: info.version,
|
|
255
|
+
savedAt: new Date().toISOString(),
|
|
256
|
+
};
|
|
257
|
+
config.current = profileName;
|
|
258
|
+
await (0, config_1.writeConfig)(config);
|
|
259
|
+
out();
|
|
260
|
+
out(`${green('Signed in')} to ${bold(hostname || url)}`);
|
|
261
|
+
out(`${dim('agent')} ${info.version} on ${info.platform}`);
|
|
262
|
+
out(`${dim('profile')} ${profileName}`);
|
|
263
|
+
// NTFS ignores POSIX modes, so only claim the file is locked down where
|
|
264
|
+
// that is actually true.
|
|
265
|
+
const modeNote = process.platform === 'win32' ? '' : dim(' (mode 0600)');
|
|
266
|
+
out(`${dim('saved')} ${(0, config_1.configPath)()}${modeNote}`);
|
|
267
|
+
if (!info.shellEnabled) {
|
|
268
|
+
out(dim('Shell execution is disabled on this agent, so `vpsgui exec` will not work.'));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
async function cmdLogout(args) {
|
|
272
|
+
const config = await (0, config_1.readConfig)();
|
|
273
|
+
const name = (0, config_1.resolveProfileName)(config, flagString(args, 'profile'));
|
|
274
|
+
if (args.flags.all) {
|
|
275
|
+
const count = Object.keys(config.profiles).length;
|
|
276
|
+
config.profiles = {};
|
|
277
|
+
config.current = 'default';
|
|
278
|
+
await (0, config_1.writeConfig)(config);
|
|
279
|
+
out(`Removed ${count} profile${count === 1 ? '' : 's'}.`);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (!config.profiles[name]) {
|
|
283
|
+
out(`No profile named "${name}".`);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
delete config.profiles[name];
|
|
287
|
+
if (config.current === name) {
|
|
288
|
+
config.current = Object.keys(config.profiles)[0] || 'default';
|
|
289
|
+
}
|
|
290
|
+
await (0, config_1.writeConfig)(config);
|
|
291
|
+
out(`Removed profile "${name}".`);
|
|
292
|
+
out(dim('The token is gone from this machine. It is still valid on the host - rotate it there if it leaked.'));
|
|
293
|
+
}
|
|
294
|
+
async function cmdWhoami(args) {
|
|
295
|
+
const creds = await (0, config_1.loadCredentials)(flagString(args, 'profile'));
|
|
296
|
+
if (!creds) {
|
|
297
|
+
out('Not signed in.');
|
|
298
|
+
out(dim('Run: vpsgui login'));
|
|
299
|
+
process.exitCode = 1;
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
out(`${dim('url')} ${creds.url}`);
|
|
303
|
+
out(`${dim('source')} ${creds.source}`);
|
|
304
|
+
const client = new client_1.VpsguiClient({ baseUrl: creds.url, token: creds.token });
|
|
305
|
+
try {
|
|
306
|
+
const [info, node] = await Promise.all([client.info(), client.nodes.get()]);
|
|
307
|
+
out(`${dim('host')} ${node.name}`);
|
|
308
|
+
out(`${dim('agent')} ${info.version} on ${info.platform}`);
|
|
309
|
+
out(`${dim('roots')} ${info.fileRoots.join(', ')}`);
|
|
310
|
+
out(green('Token accepted.'));
|
|
311
|
+
}
|
|
312
|
+
catch (e) {
|
|
313
|
+
const { message, hint } = describe(e);
|
|
314
|
+
out(`${yellow('Saved, but not working:')} ${message}`);
|
|
315
|
+
if (hint)
|
|
316
|
+
out(dim(hint));
|
|
317
|
+
process.exitCode = 1;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
async function cmdProfiles() {
|
|
321
|
+
const config = await (0, config_1.readConfig)();
|
|
322
|
+
const names = Object.keys(config.profiles);
|
|
323
|
+
if (names.length === 0) {
|
|
324
|
+
out('No profiles. Run: vpsgui login');
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const rows = [['', 'PROFILE', 'HOST', 'URL', 'AGENT']];
|
|
328
|
+
for (const name of names) {
|
|
329
|
+
const p = config.profiles[name];
|
|
330
|
+
rows.push([
|
|
331
|
+
name === config.current ? '*' : ' ',
|
|
332
|
+
name,
|
|
333
|
+
p.hostname || '-',
|
|
334
|
+
p.url,
|
|
335
|
+
p.agentVersion || '-',
|
|
336
|
+
]);
|
|
337
|
+
}
|
|
338
|
+
table(rows);
|
|
339
|
+
}
|
|
340
|
+
async function cmdUse(args) {
|
|
341
|
+
const name = args.positional[0];
|
|
342
|
+
if (!name)
|
|
343
|
+
fail('Which profile?', 'Usage: vpsgui use <profile>');
|
|
344
|
+
const config = await (0, config_1.readConfig)();
|
|
345
|
+
if (!config.profiles[name]) {
|
|
346
|
+
fail(`No profile named "${name}".`, `Known: ${Object.keys(config.profiles).join(', ') || 'none'}`);
|
|
347
|
+
}
|
|
348
|
+
config.current = name;
|
|
349
|
+
await (0, config_1.writeConfig)(config);
|
|
350
|
+
out(`Now using "${name}" (${config.profiles[name].hostname || config.profiles[name].url}).`);
|
|
351
|
+
}
|
|
352
|
+
function bar(percent) {
|
|
353
|
+
const width = 20;
|
|
354
|
+
const filled = Math.max(0, Math.min(width, Math.round((percent / 100) * width)));
|
|
355
|
+
const glyph = '#'.repeat(filled) + '-'.repeat(width - filled);
|
|
356
|
+
const colour = percent >= 90 ? red : percent >= 70 ? yellow : green;
|
|
357
|
+
return colour(glyph);
|
|
358
|
+
}
|
|
359
|
+
async function cmdStatus(args) {
|
|
360
|
+
const client = await connect(args);
|
|
361
|
+
try {
|
|
362
|
+
const [node, telemetry, health] = await Promise.all([
|
|
363
|
+
client.nodes.get(),
|
|
364
|
+
client.system.telemetry(),
|
|
365
|
+
client.nodes.health(),
|
|
366
|
+
]);
|
|
367
|
+
const uptimeHours = Math.floor(node.os.uptimeSeconds / 3600);
|
|
368
|
+
const uptime = uptimeHours >= 24
|
|
369
|
+
? `${Math.floor(uptimeHours / 24)}d ${uptimeHours % 24}h`
|
|
370
|
+
: `${uptimeHours}h`;
|
|
371
|
+
out(bold(node.name));
|
|
372
|
+
out(dim(`${node.os.name} ${node.os.version} - kernel ${node.os.kernel} - up ${uptime}`));
|
|
373
|
+
out();
|
|
374
|
+
out(`cpu ${bar(telemetry.cpuPercent)} ${String(telemetry.cpuPercent).padStart(3)}% ${dim(`${node.hardware.cpuCores} cores`)}`);
|
|
375
|
+
out(`mem ${bar(telemetry.ramPercent)} ${String(telemetry.ramPercent).padStart(3)}% ${dim(`${node.hardware.ramGb} GB`)}`);
|
|
376
|
+
out(`disk ${bar(telemetry.diskPercent)} ${String(telemetry.diskPercent).padStart(3)}% ${dim(`${node.hardware.diskGb} GB`)}`);
|
|
377
|
+
const failing = health.filter((h) => h.status !== 'green');
|
|
378
|
+
if (failing.length > 0) {
|
|
379
|
+
out();
|
|
380
|
+
out(bold('Checks needing attention'));
|
|
381
|
+
for (const check of failing) {
|
|
382
|
+
const mark = check.status === 'red' ? red('x') : yellow('!');
|
|
383
|
+
out(` ${mark} ${check.name}${check.message ? dim(` - ${check.message}`) : ''}`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
catch (e) {
|
|
388
|
+
const { message, hint } = describe(e);
|
|
389
|
+
fail(message, hint);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
async function cmdPs(args) {
|
|
393
|
+
const client = await connect(args);
|
|
394
|
+
try {
|
|
395
|
+
const containers = await client.docker.listContainers();
|
|
396
|
+
if (containers.length === 0) {
|
|
397
|
+
out('No containers.');
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
const rows = [['NAME', 'IMAGE', 'STATUS', 'CPU', 'MEM']];
|
|
401
|
+
for (const c of containers) {
|
|
402
|
+
rows.push([
|
|
403
|
+
c.name,
|
|
404
|
+
c.image,
|
|
405
|
+
c.status,
|
|
406
|
+
c.cpuPercent == null ? '-' : `${c.cpuPercent}%`,
|
|
407
|
+
c.memoryUsageMb ? `${c.memoryUsageMb} MB` : '-',
|
|
408
|
+
]);
|
|
409
|
+
}
|
|
410
|
+
table(rows);
|
|
411
|
+
}
|
|
412
|
+
catch (e) {
|
|
413
|
+
const { message, hint } = describe(e);
|
|
414
|
+
fail(message, hint);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
async function cmdExec(args) {
|
|
418
|
+
const command = args.positional.join(' ');
|
|
419
|
+
if (!command)
|
|
420
|
+
fail('Nothing to run.', 'Usage: vpsgui exec "systemctl status nginx"');
|
|
421
|
+
const client = await connect(args);
|
|
422
|
+
try {
|
|
423
|
+
const result = await client.terminal.exec(command);
|
|
424
|
+
if (result.output)
|
|
425
|
+
process.stdout.write(result.output.endsWith('\n') ? result.output : result.output + '\n');
|
|
426
|
+
// Mirror the remote command's disposition, so `vpsgui exec ... && next`
|
|
427
|
+
// behaves the way it would over ssh.
|
|
428
|
+
if (!result.success)
|
|
429
|
+
process.exitCode = 1;
|
|
430
|
+
}
|
|
431
|
+
catch (e) {
|
|
432
|
+
const { message, hint } = describe(e);
|
|
433
|
+
fail(message, hint);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
async function cmdLs(args) {
|
|
437
|
+
const target = args.positional[0] || '/';
|
|
438
|
+
const client = await connect(args);
|
|
439
|
+
try {
|
|
440
|
+
const items = await client.files.list(target);
|
|
441
|
+
if (items.length === 0) {
|
|
442
|
+
out(dim('(empty)'));
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
const rows = [['TYPE', 'SIZE', 'MODIFIED', 'NAME']];
|
|
446
|
+
for (const item of items) {
|
|
447
|
+
rows.push([
|
|
448
|
+
item.type === 'directory' ? 'dir' : 'file',
|
|
449
|
+
item.type === 'directory' ? '-' : String(item.size ?? '-'),
|
|
450
|
+
item.modifiedAt
|
|
451
|
+
? new Date(item.modifiedAt).toISOString().slice(0, 16).replace('T', ' ')
|
|
452
|
+
: '-',
|
|
453
|
+
item.type === 'directory' ? cyan(item.name) : item.name,
|
|
454
|
+
]);
|
|
455
|
+
}
|
|
456
|
+
table(rows);
|
|
457
|
+
}
|
|
458
|
+
catch (e) {
|
|
459
|
+
const { message, hint } = describe(e);
|
|
460
|
+
fail(message, hint);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
async function cmdHealth(args) {
|
|
464
|
+
const client = await connect(args);
|
|
465
|
+
try {
|
|
466
|
+
const checks = await client.nodes.health();
|
|
467
|
+
const rows = [['', 'CHECK', 'DETAIL']];
|
|
468
|
+
for (const check of checks) {
|
|
469
|
+
const mark = check.status === 'green' ? green('ok') : check.status === 'red' ? red('fail') : yellow('warn');
|
|
470
|
+
rows.push([mark, check.name, check.message || '']);
|
|
471
|
+
}
|
|
472
|
+
table(rows);
|
|
473
|
+
// A red check is a real problem on the host, so exit non-zero and let a
|
|
474
|
+
// monitoring cron treat `vpsgui health` as a probe.
|
|
475
|
+
if (checks.some((c) => c.status === 'red'))
|
|
476
|
+
process.exitCode = 1;
|
|
477
|
+
}
|
|
478
|
+
catch (e) {
|
|
479
|
+
const { message, hint } = describe(e);
|
|
480
|
+
fail(message, hint);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
function cmdHelp() {
|
|
484
|
+
out(`${bold('vpsgui')} ${dim(VERSION)} - control a VPSGUI agent from the terminal`);
|
|
485
|
+
out();
|
|
486
|
+
out(bold('Usage'));
|
|
487
|
+
out(' vpsgui <command> [options]');
|
|
488
|
+
out();
|
|
489
|
+
out(bold('Getting started'));
|
|
490
|
+
out(` login [url] Save credentials for a host, after checking they work`);
|
|
491
|
+
out(` logout Forget this machine's copy of the token`);
|
|
492
|
+
out(` whoami Show the active profile and confirm the agent accepts it`);
|
|
493
|
+
out();
|
|
494
|
+
out(bold('Hosts'));
|
|
495
|
+
out(` profiles List saved hosts`);
|
|
496
|
+
out(` use <profile> Switch the default host`);
|
|
497
|
+
out();
|
|
498
|
+
out(bold('Operations'));
|
|
499
|
+
out(` status CPU, memory, disk, and any failing checks`);
|
|
500
|
+
out(` health Every health check, one per line`);
|
|
501
|
+
out(` ps Docker containers`);
|
|
502
|
+
out(` ls [path] List a directory on the host`);
|
|
503
|
+
out(` exec <command> Run a shell command on the host`);
|
|
504
|
+
out();
|
|
505
|
+
out(bold('Options'));
|
|
506
|
+
out(` --profile <name> Act on a specific saved host`);
|
|
507
|
+
out(` --url <url> Agent URL, for login`);
|
|
508
|
+
out(` --token <token> Agent token, for login ${dim('(ends up in shell history)')}`);
|
|
509
|
+
out(` --version Print the version`);
|
|
510
|
+
out();
|
|
511
|
+
out(bold('Environment'));
|
|
512
|
+
out(` VPSGUI_API_URL, VPSGUI_AGENT_TOKEN Use instead of a saved profile`);
|
|
513
|
+
out(` VPSGUI_PROFILE Default profile name`);
|
|
514
|
+
out(` VPSGUI_CONFIG_DIR Override ~/.vpsgui`);
|
|
515
|
+
out(` NO_COLOR Disable colour`);
|
|
516
|
+
}
|
|
517
|
+
// ---------------------------------------------------------------------------
|
|
518
|
+
async function main() {
|
|
519
|
+
const args = parseArgs(process.argv.slice(2));
|
|
520
|
+
if (args.flags.version || args.command === 'version') {
|
|
521
|
+
out(VERSION);
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
if (args.flags.help) {
|
|
525
|
+
cmdHelp();
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
switch (args.command) {
|
|
529
|
+
case 'login':
|
|
530
|
+
return cmdLogin(args);
|
|
531
|
+
case 'logout':
|
|
532
|
+
return cmdLogout(args);
|
|
533
|
+
case 'whoami':
|
|
534
|
+
case 'me':
|
|
535
|
+
return cmdWhoami(args);
|
|
536
|
+
case 'profiles':
|
|
537
|
+
return cmdProfiles();
|
|
538
|
+
case 'use':
|
|
539
|
+
return cmdUse(args);
|
|
540
|
+
case 'status':
|
|
541
|
+
return cmdStatus(args);
|
|
542
|
+
case 'health':
|
|
543
|
+
return cmdHealth(args);
|
|
544
|
+
case 'ps':
|
|
545
|
+
return cmdPs(args);
|
|
546
|
+
case 'ls':
|
|
547
|
+
return cmdLs(args);
|
|
548
|
+
case 'exec':
|
|
549
|
+
case 'run':
|
|
550
|
+
return cmdExec(args);
|
|
551
|
+
case 'help':
|
|
552
|
+
cmdHelp();
|
|
553
|
+
return;
|
|
554
|
+
default:
|
|
555
|
+
process.stderr.write(`${red('error')} Unknown command "${args.command}".\n`);
|
|
556
|
+
process.stderr.write(dim('Run: vpsgui help\n'));
|
|
557
|
+
process.exit(1);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
main().catch((e) => {
|
|
561
|
+
const { message, hint } = describe(e);
|
|
562
|
+
fail(message, hint);
|
|
563
|
+
});
|
|
564
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|