influx-local-cli 0.1.0 → 0.1.1
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/README.md +21 -9
- package/package.json +2 -2
- package/src/manager.js +65 -8
package/README.md
CHANGED
|
@@ -208,11 +208,18 @@ declares a generic `http:` tool with the versioned URL, e.g.:
|
|
|
208
208
|
|
|
209
209
|
`setup`/`install` run `mise install` against that file and resolve the resulting
|
|
210
210
|
binaries through `mise where`, so several versions can be installed side by side.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
The first install downloads the official tarball (≈52 MB for 1.x, ≈60 MB for 2.x,
|
|
212
|
+
≈100 MB for 3.x); progress is streamed to your terminal.
|
|
213
|
+
|
|
214
|
+
Every mise call is made with `MISE_CEILING_PATHS` set to the instance's **parent**
|
|
215
|
+
directory and `MISE_TRUSTED_CONFIG_PATHS` to the instance directory. The ceiling
|
|
216
|
+
stops mise's upward config search, so an unrelated (and untrusted) `.mise.toml`
|
|
217
|
+
in `$HOME`, `/tmp` or any project above the data dir can neither abort the call
|
|
218
|
+
with `Config files ... are not trusted` nor inject a foreign toolchain.
|
|
219
|
+
Note the ceiling path itself is excluded from the search, which is why it must
|
|
220
|
+
be the parent and not the instance directory: using the instance dir as ceiling
|
|
221
|
+
makes mise ignore the instance's own `.mise.toml`, and `mise install` then exits
|
|
222
|
+
successfully without installing anything (`test/toolchain.test.js` guards this).
|
|
216
223
|
|
|
217
224
|
### Per-line provisioning
|
|
218
225
|
|
|
@@ -226,7 +233,11 @@ that has nothing to do with this instance.
|
|
|
226
233
|
re-issued (and stale ones deleted) on every `setup`.
|
|
227
234
|
- **3.x** — a single binary (`influxdb3 serve`). The admin token is minted once
|
|
228
235
|
by the server, so it is written to `creds.env` and reused; the database and
|
|
229
|
-
the initial table are created afterwards.
|
|
236
|
+
the initial table are created afterwards. Note that 3 Core's SQL endpoint is
|
|
237
|
+
read/DDL only: writing points goes through line protocol
|
|
238
|
+
(`influxdb3 write --database <db> '<lp>'`, or `POST /api/v3/write_lp?db=<db>`
|
|
239
|
+
with the admin token) — `query` relays the server's
|
|
240
|
+
`DML not supported: Insert Into` error if you try an `INSERT`.
|
|
230
241
|
|
|
231
242
|
## Known limitations
|
|
232
243
|
|
|
@@ -253,9 +264,10 @@ npm test
|
|
|
253
264
|
```
|
|
254
265
|
|
|
255
266
|
The unit tests cover the version catalog (URL/bin-path per line, catalog
|
|
256
|
-
integrity)
|
|
257
|
-
|
|
258
|
-
|
|
267
|
+
integrity), the credential schema and the mise invocation environment
|
|
268
|
+
(the regression guard for the install path); they need no network and no
|
|
269
|
+
InfluxDB install. For an end-to-end check, create an instance and run `setup` —
|
|
270
|
+
that is the path CI cannot cover without downloading InfluxDB.
|
|
259
271
|
|
|
260
272
|
## License
|
|
261
273
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "influx-local-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Create, start and manage local InfluxDB instances (1.x / 2.x / 3.x) without Docker/Podman. CLI + Web dashboard, powered by mise.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"influxdb",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"LICENSE"
|
|
30
30
|
],
|
|
31
31
|
"scripts": {
|
|
32
|
-
"test": "node --test test/catalog.test.js test/creds.test.js",
|
|
32
|
+
"test": "node --test test/catalog.test.js test/creds.test.js test/toolchain.test.js",
|
|
33
33
|
"start": "node bin/influx-local.js web"
|
|
34
34
|
},
|
|
35
35
|
"engines": {
|
package/src/manager.js
CHANGED
|
@@ -51,6 +51,40 @@ function errText(msg, res) {
|
|
|
51
51
|
return detail ? `${msg}: ${detail}` : msg;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
// Like spawnOut, but forwards the child's output to our stderr as it arrives.
|
|
55
|
+
// `mise install` downloads a ~50-150 MB tarball per InfluxDB version and prints
|
|
56
|
+
// progress on stderr; capturing it silently makes the tool look hung, which
|
|
57
|
+
// invites a Ctrl-C halfway through the install.
|
|
58
|
+
function spawnStream(cmd, args, opts = {}) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
let child;
|
|
61
|
+
try {
|
|
62
|
+
child = spawn(cmd, args, {
|
|
63
|
+
env: { ...baseEnv(), ...(opts.env || {}) },
|
|
64
|
+
cwd: opts.cwd,
|
|
65
|
+
windowsHide: true,
|
|
66
|
+
});
|
|
67
|
+
} catch (err) {
|
|
68
|
+
reject(err);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const out = [];
|
|
72
|
+
const errOut = [];
|
|
73
|
+
child.stdout.on('data', (d) => {
|
|
74
|
+
out.push(d);
|
|
75
|
+
if (opts.forward !== false) process.stderr.write(d);
|
|
76
|
+
});
|
|
77
|
+
child.stderr.on('data', (d) => {
|
|
78
|
+
errOut.push(d);
|
|
79
|
+
if (opts.forward !== false) process.stderr.write(d);
|
|
80
|
+
});
|
|
81
|
+
child.on('error', reject);
|
|
82
|
+
child.on('close', (code) =>
|
|
83
|
+
resolve({ code, stdout: Buffer.concat(out).toString('utf8'), stderr: Buffer.concat(errOut).toString('utf8') }),
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
54
88
|
// Environment for every child process: the user's own InfluxDB variables are
|
|
55
89
|
// stripped so an exported INFLUXDB_HTTP_BIND_ADDRESS / INFLUX_TOKEN cannot leak
|
|
56
90
|
// into an instance we manage.
|
|
@@ -185,14 +219,19 @@ function clearBinCache(cfg) {
|
|
|
185
219
|
}
|
|
186
220
|
|
|
187
221
|
// Environment for every mise invocation. Two things matter:
|
|
188
|
-
// MISE_CEILING_PATHS stops the config search
|
|
189
|
-
// unrelated (and untrusted)
|
|
190
|
-
//
|
|
191
|
-
// "Config files ... are not trusted".
|
|
222
|
+
// MISE_CEILING_PATHS stops the config search immediately above the
|
|
223
|
+
// instance dir, so an unrelated (and untrusted)
|
|
224
|
+
// .mise.toml in $HOME or /tmp cannot abort the call
|
|
225
|
+
// with "Config files ... are not trusted".
|
|
226
|
+
// The ceiling path itself is EXCLUDED from the search
|
|
227
|
+
// (verified against mise 2026.8.11), so it must be the
|
|
228
|
+
// PARENT: using the instance dir as the ceiling makes
|
|
229
|
+
// mise ignore the instance's own .mise.toml, and then
|
|
230
|
+
// `mise install` exits 0 without installing anything.
|
|
192
231
|
// MISE_TRUSTED_CONFIG_PATHS trusts the .mise.toml we generate per instance.
|
|
193
232
|
function miseEnv(cfg) {
|
|
194
233
|
return {
|
|
195
|
-
MISE_CEILING_PATHS: cfg.instanceDir,
|
|
234
|
+
MISE_CEILING_PATHS: path.dirname(cfg.instanceDir),
|
|
196
235
|
MISE_TRUSTED_CONFIG_PATHS: cfg.instanceDir,
|
|
197
236
|
};
|
|
198
237
|
}
|
|
@@ -266,14 +305,31 @@ async function findExecutable(root, name, maxDepth = 5) {
|
|
|
266
305
|
|
|
267
306
|
// Install (idempotent) the instance's pinned version through mise.
|
|
268
307
|
async function installTools(cfg, log = noopLog) {
|
|
308
|
+
const artifacts = artifactsFor(cfg.version);
|
|
269
309
|
log(`installing InfluxDB ${cfg.version} (${cfg.flavorLabel}) via ${miseBin()}…`);
|
|
310
|
+
log(` (the first run downloads the official tarball: ${artifacts.map((a) => a.url).join(' ')})`);
|
|
270
311
|
await saveMiseToml(cfg.name, cfg.version);
|
|
271
|
-
const res = await
|
|
312
|
+
const res = await spawnStream(miseBin(), ['install', '-C', cfg.instanceDir], { env: miseEnv(cfg) });
|
|
272
313
|
if (res.code !== 0) {
|
|
273
|
-
throw new Error(
|
|
314
|
+
throw new Error(
|
|
315
|
+
errText(
|
|
316
|
+
`failed to install InfluxDB ${cfg.version} (download interrupted or unavailable?)`,
|
|
317
|
+
res,
|
|
318
|
+
) +
|
|
319
|
+
`\n artifact: ${artifacts.map((a) => a.url).join('\n ')}` +
|
|
320
|
+
`\n retry with: influx-local install ${cfg.name}`,
|
|
321
|
+
);
|
|
274
322
|
}
|
|
275
323
|
clearBinCache(cfg);
|
|
276
|
-
|
|
324
|
+
let bins;
|
|
325
|
+
try {
|
|
326
|
+
bins = await resolveBins(cfg);
|
|
327
|
+
} catch (err) {
|
|
328
|
+
throw new Error(
|
|
329
|
+
`mise reported a successful install but InfluxDB ${cfg.version} is still not resolvable.\n` +
|
|
330
|
+
` That means mise never read ${cfg.miseTomlPath} — check for MISE_* overrides in your environment.\n ${err.message}`,
|
|
331
|
+
);
|
|
332
|
+
}
|
|
277
333
|
const list = Object.entries(bins).map(([exe, p]) => `${exe} → ${p}`).join(', ');
|
|
278
334
|
log(`toolchain ready: ${list}`);
|
|
279
335
|
return bins;
|
|
@@ -1786,6 +1842,7 @@ module.exports = {
|
|
|
1786
1842
|
shellInstance,
|
|
1787
1843
|
queryInstance,
|
|
1788
1844
|
resolveBins,
|
|
1845
|
+
miseEnv,
|
|
1789
1846
|
verifyAdmin,
|
|
1790
1847
|
instanceHasData,
|
|
1791
1848
|
httpBase,
|