@glassmkr/crucible 0.13.5 → 0.13.7
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 +1 -1
- package/dist/alerts/state.d.ts +0 -1
- package/dist/alerts/state.js +0 -3
- package/dist/alerts/state.js.map +1 -1
- package/dist/collect/__tests__/cve.test.d.ts +1 -0
- package/dist/collect/__tests__/cve.test.js +29 -0
- package/dist/collect/__tests__/cve.test.js.map +1 -0
- package/dist/collect/__tests__/security.test.js +62 -0
- package/dist/collect/__tests__/security.test.js.map +1 -1
- package/dist/collect/cve.d.ts +9 -0
- package/dist/collect/cve.js +33 -23
- package/dist/collect/cve.js.map +1 -1
- package/dist/collect/dmesg-events.d.ts +6 -8
- package/dist/collect/dmesg-events.js +8 -26
- package/dist/collect/dmesg-events.js.map +1 -1
- package/dist/collect/dmi.js +7 -16
- package/dist/collect/dmi.js.map +1 -1
- package/dist/collect/edac.js +14 -43
- package/dist/collect/edac.js.map +1 -1
- package/dist/collect/fd.js +4 -12
- package/dist/collect/fd.js.map +1 -1
- package/dist/collect/gpu.d.ts +2 -3
- package/dist/collect/gpu.js +13 -19
- package/dist/collect/gpu.js.map +1 -1
- package/dist/collect/hardware-raid.js +5 -9
- package/dist/collect/hardware-raid.js.map +1 -1
- package/dist/collect/ntp.js +1 -6
- package/dist/collect/ntp.js.map +1 -1
- package/dist/collect/reboot-evidence.js +2 -7
- package/dist/collect/reboot-evidence.js.map +1 -1
- package/dist/collect/security.js +18 -4
- package/dist/collect/security.js.map +1 -1
- package/dist/collect/thermal.js +9 -14
- package/dist/collect/thermal.js.map +1 -1
- package/dist/collect/zfs.js +2 -3
- package/dist/collect/zfs.js.map +1 -1
- package/dist/lib/__tests__/dmesg.test.d.ts +1 -0
- package/dist/lib/__tests__/dmesg.test.js +87 -0
- package/dist/lib/__tests__/dmesg.test.js.map +1 -0
- package/dist/lib/__tests__/exec.test.js +16 -1
- package/dist/lib/__tests__/exec.test.js.map +1 -1
- package/dist/lib/__tests__/parse.test.js +50 -2
- package/dist/lib/__tests__/parse.test.js.map +1 -1
- package/dist/lib/dmesg.d.ts +29 -0
- package/dist/lib/dmesg.js +56 -0
- package/dist/lib/dmesg.js.map +1 -0
- package/dist/lib/exec.d.ts +2 -0
- package/dist/lib/exec.js +14 -0
- package/dist/lib/exec.js.map +1 -1
- package/dist/lib/parse.d.ts +3 -0
- package/dist/lib/parse.js +34 -1
- package/dist/lib/parse.js.map +1 -1
- package/dist/lib/version-check.d.ts +0 -6
- package/dist/lib/version-check.js +0 -11
- package/dist/lib/version-check.js.map +1 -1
- package/dist/metrics-server.js +0 -1
- package/dist/metrics-server.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Tests for the shared lib/dmesg read + timestamp parser.
|
|
2
|
+
//
|
|
3
|
+
// readDmesg is exercised with a mocked lib/exec `run` so we can assert
|
|
4
|
+
// the two-step argv (iso attempt, then plain fallback) and the
|
|
5
|
+
// fall-back-on-empty behaviour both collectors relied on.
|
|
6
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
7
|
+
const runMock = vi.fn();
|
|
8
|
+
vi.mock("../exec.js", () => ({
|
|
9
|
+
run: (...args) => runMock(...args),
|
|
10
|
+
}));
|
|
11
|
+
const { readDmesg, parseKernelLogTimestamp } = await import("../dmesg.js");
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
runMock.mockReset();
|
|
14
|
+
});
|
|
15
|
+
describe("readDmesg", () => {
|
|
16
|
+
it("returns the iso-attempt output when it succeeds (no fallback call)", async () => {
|
|
17
|
+
runMock.mockResolvedValueOnce("iso line\n");
|
|
18
|
+
const out = await readDmesg();
|
|
19
|
+
expect(out).toBe("iso line\n");
|
|
20
|
+
expect(runMock).toHaveBeenCalledTimes(1);
|
|
21
|
+
expect(runMock.mock.calls[0][0]).toBe("dmesg");
|
|
22
|
+
expect(runMock.mock.calls[0][1]).toEqual(["--time-format=iso", "--no-pager"]);
|
|
23
|
+
});
|
|
24
|
+
it("appends extraIsoArgs to the iso attempt only", async () => {
|
|
25
|
+
runMock.mockResolvedValueOnce("iso line\n");
|
|
26
|
+
await readDmesg({ extraIsoArgs: ["--ctime"] });
|
|
27
|
+
expect(runMock.mock.calls[0][1]).toEqual(["--time-format=iso", "--no-pager", "--ctime"]);
|
|
28
|
+
});
|
|
29
|
+
it("falls back to plain --no-pager when the iso attempt is null", async () => {
|
|
30
|
+
runMock.mockResolvedValueOnce(null);
|
|
31
|
+
runMock.mockResolvedValueOnce("plain line\n");
|
|
32
|
+
const out = await readDmesg();
|
|
33
|
+
expect(out).toBe("plain line\n");
|
|
34
|
+
expect(runMock).toHaveBeenCalledTimes(2);
|
|
35
|
+
expect(runMock.mock.calls[1][1]).toEqual(["--no-pager"]);
|
|
36
|
+
});
|
|
37
|
+
it("falls back when the iso attempt is an empty string", async () => {
|
|
38
|
+
runMock.mockResolvedValueOnce("");
|
|
39
|
+
runMock.mockResolvedValueOnce("plain line\n");
|
|
40
|
+
const out = await readDmesg();
|
|
41
|
+
expect(out).toBe("plain line\n");
|
|
42
|
+
expect(runMock).toHaveBeenCalledTimes(2);
|
|
43
|
+
});
|
|
44
|
+
it("returns null when both attempts produce nothing", async () => {
|
|
45
|
+
runMock.mockResolvedValueOnce(null);
|
|
46
|
+
runMock.mockResolvedValueOnce(null);
|
|
47
|
+
expect(await readDmesg()).toBeNull();
|
|
48
|
+
});
|
|
49
|
+
it("threads timeoutMs through to both run calls", async () => {
|
|
50
|
+
runMock.mockResolvedValueOnce(null);
|
|
51
|
+
runMock.mockResolvedValueOnce(null);
|
|
52
|
+
await readDmesg({ timeoutMs: 5000 });
|
|
53
|
+
expect(runMock.mock.calls[0][2]).toBe(5000);
|
|
54
|
+
expect(runMock.mock.calls[1][2]).toBe(5000);
|
|
55
|
+
});
|
|
56
|
+
it("omits the timeout arg entirely when timeoutMs is unset (run's default applies)", async () => {
|
|
57
|
+
runMock.mockResolvedValueOnce("x\n");
|
|
58
|
+
await readDmesg();
|
|
59
|
+
// run was called with exactly (cmd, args) — no third positional.
|
|
60
|
+
expect(runMock.mock.calls[0].length).toBe(2);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe("parseKernelLogTimestamp", () => {
|
|
64
|
+
it("parses ISO format with comma fractional seconds and timezone", () => {
|
|
65
|
+
const ts = parseKernelLogTimestamp("2026-05-19T12:34:56,789012+00:00 some message");
|
|
66
|
+
expect(ts).not.toBeNull();
|
|
67
|
+
expect(typeof ts).toBe("number");
|
|
68
|
+
// comma-normalised-to-dot must parse to the same instant as the dot form
|
|
69
|
+
expect(ts).toBe(Date.parse("2026-05-19T12:34:56.789012+00:00"));
|
|
70
|
+
});
|
|
71
|
+
it("parses ISO format with Z suffix", () => {
|
|
72
|
+
const ts = parseKernelLogTimestamp("2026-05-19T12:34:56Z kernel: hi");
|
|
73
|
+
expect(ts).toBe(Date.parse("2026-05-19T12:34:56Z"));
|
|
74
|
+
});
|
|
75
|
+
it("parses ctime format from --ctime", () => {
|
|
76
|
+
const ts = parseKernelLogTimestamp("[Mon May 19 12:34:56 2026] some message");
|
|
77
|
+
expect(ts).not.toBeNull();
|
|
78
|
+
expect(ts).toBe(Date.parse("Mon May 19 12:34:56 2026"));
|
|
79
|
+
});
|
|
80
|
+
it("returns null for relative-time format", () => {
|
|
81
|
+
expect(parseKernelLogTimestamp("[12345.678] some message")).toBeNull();
|
|
82
|
+
});
|
|
83
|
+
it("returns null for a line with no leading timestamp", () => {
|
|
84
|
+
expect(parseKernelLogTimestamp("no timestamp here")).toBeNull();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=dmesg.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dmesg.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/dmesg.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { run, runDetailed, looksLikeFieldRenameError } from "../exec.js";
|
|
2
|
+
import { run, runDetailed, looksLikeFieldRenameError, which, isUnitActive } from "../exec.js";
|
|
3
3
|
describe("looksLikeFieldRenameError", () => {
|
|
4
4
|
// Real-world fixtures from the two Crucible bugs that motivated this
|
|
5
5
|
// defense. If the heuristic stops recognising these strings, the next
|
|
@@ -70,4 +70,19 @@ describe("run (backwards-compat shim)", () => {
|
|
|
70
70
|
expect(out?.trim()).toBe("hi");
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
|
+
describe("which", () => {
|
|
74
|
+
it("returns true for a binary on PATH", async () => {
|
|
75
|
+
expect(await which("sh")).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
it("returns false for a binary not on PATH", async () => {
|
|
78
|
+
expect(await which("definitely-not-a-real-binary-9j43k")).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe("isUnitActive", () => {
|
|
82
|
+
// A unit that is not active (or a host without systemd, where the
|
|
83
|
+
// systemctl ENOENT path resolves to "not active") returns false.
|
|
84
|
+
it("returns false for a non-active / missing unit", async () => {
|
|
85
|
+
expect(await isUnitActive("crucible-nonexistent-9j43k.service")).toBe(false);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
73
88
|
//# sourceMappingURL=exec.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/exec.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"exec.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/exec.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
1
|
+
import { afterAll, beforeAll, describe, it, expect } from "vitest";
|
|
2
|
+
import { mkdtempSync, rmSync, writeFileSync } from "fs";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { parseKeyValue, parseKb, readDirSafe, readFileInt, readFileTrim } from "../parse.js";
|
|
3
6
|
describe("parseKeyValue", () => {
|
|
4
7
|
it("parses colon-delimited key/value lines", () => {
|
|
5
8
|
const out = parseKeyValue("Name: foo\nVersion: 1.2.3\n");
|
|
@@ -24,4 +27,49 @@ describe("parseKb", () => {
|
|
|
24
27
|
expect(parseKb("not a number")).toBe(0);
|
|
25
28
|
});
|
|
26
29
|
});
|
|
30
|
+
describe("file-read helpers", () => {
|
|
31
|
+
let dir;
|
|
32
|
+
beforeAll(() => {
|
|
33
|
+
dir = mkdtempSync(join(tmpdir(), "crucible-parse-"));
|
|
34
|
+
writeFileSync(join(dir, "value"), " 42\n");
|
|
35
|
+
writeFileSync(join(dir, "text"), " hello world \n");
|
|
36
|
+
writeFileSync(join(dir, "empty"), " \n");
|
|
37
|
+
writeFileSync(join(dir, "notint"), "12x\n");
|
|
38
|
+
});
|
|
39
|
+
afterAll(() => {
|
|
40
|
+
rmSync(dir, { recursive: true, force: true });
|
|
41
|
+
});
|
|
42
|
+
describe("readFileTrim", () => {
|
|
43
|
+
it("returns trimmed contents", () => {
|
|
44
|
+
expect(readFileTrim(join(dir, "text"))).toBe("hello world");
|
|
45
|
+
});
|
|
46
|
+
it("returns empty string (not null) for whitespace-only files", () => {
|
|
47
|
+
expect(readFileTrim(join(dir, "empty"))).toBe("");
|
|
48
|
+
});
|
|
49
|
+
it("returns null when the file does not exist", () => {
|
|
50
|
+
expect(readFileTrim(join(dir, "nope"))).toBeNull();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe("readFileInt", () => {
|
|
54
|
+
it("parses a non-negative integer", () => {
|
|
55
|
+
expect(readFileInt(join(dir, "value"))).toBe(42);
|
|
56
|
+
});
|
|
57
|
+
it("returns null for non-integer contents", () => {
|
|
58
|
+
expect(readFileInt(join(dir, "notint"))).toBeNull();
|
|
59
|
+
expect(readFileInt(join(dir, "text"))).toBeNull();
|
|
60
|
+
expect(readFileInt(join(dir, "empty"))).toBeNull();
|
|
61
|
+
});
|
|
62
|
+
it("returns null when the file does not exist", () => {
|
|
63
|
+
expect(readFileInt(join(dir, "nope"))).toBeNull();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe("readDirSafe", () => {
|
|
67
|
+
it("lists directory entries", () => {
|
|
68
|
+
expect(readDirSafe(dir).sort()).toEqual(["empty", "notint", "text", "value"]);
|
|
69
|
+
});
|
|
70
|
+
it("returns [] for a missing directory", () => {
|
|
71
|
+
expect(readDirSafe(join(dir, "nope"))).toEqual([]);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
27
75
|
//# sourceMappingURL=parse.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/parse.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/parse.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ReadDmesgOptions {
|
|
2
|
+
/** Per-call timeout passed to `run`. dmesg-events uses run's default
|
|
3
|
+
* (10s); the gpu collector uses its 5s nvidia-smi budget. */
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
/** Extra args appended to the FIRST (iso) attempt only. dmesg-events
|
|
6
|
+
* passes `--ctime`; the gpu collector passes nothing. Kept verbatim
|
|
7
|
+
* so each call site's argv is preserved exactly. */
|
|
8
|
+
extraIsoArgs?: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Read the kernel ring buffer. Returns the raw dmesg text, or null when
|
|
12
|
+
* dmesg is missing / not readable (CAP_SYSLOG absent or
|
|
13
|
+
* kernel.dmesg_restrict=1).
|
|
14
|
+
*
|
|
15
|
+
* Two-step, preserving the historical behavior of both callers:
|
|
16
|
+
* 1. `dmesg --time-format=iso --no-pager [extraIsoArgs...]`
|
|
17
|
+
* 2. on a null/empty result, `dmesg --no-pager`
|
|
18
|
+
*/
|
|
19
|
+
export declare function readDmesg(opts?: ReadDmesgOptions): Promise<string | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Extract a unix-ms timestamp from a dmesg line. Two absolute shapes:
|
|
22
|
+
* ISO: "2026-05-19T12:34:56,789012+00:00 ..." (--time-format=iso)
|
|
23
|
+
* ctime: "[Mon May 19 12:34:56 2026] ..." (--ctime)
|
|
24
|
+
*
|
|
25
|
+
* Relative-time format ("[12345.678]") returns null (no absolute anchor
|
|
26
|
+
* available without uptime). The comma fractional separator that iso
|
|
27
|
+
* format emits is normalised to a dot before Date.parse.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseKernelLogTimestamp(line: string): number | null;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Shared dmesg read + kernel-log timestamp parsing.
|
|
2
|
+
//
|
|
3
|
+
// Both the dmesg-events collector (C18) and the gpu collector's XID
|
|
4
|
+
// scan read the kernel ring buffer the same way: try `--time-format=iso`
|
|
5
|
+
// (kernel 5.10+) first, fall back to plain `--no-pager` when that call
|
|
6
|
+
// produces nothing (older kernels ignore the flag; missing privileges
|
|
7
|
+
// is the more common cause). They also parse the leading timestamp the
|
|
8
|
+
// same way. This module hosts the shared read + parse so the two
|
|
9
|
+
// collectors don't drift.
|
|
10
|
+
import { run } from "./exec.js";
|
|
11
|
+
/**
|
|
12
|
+
* Read the kernel ring buffer. Returns the raw dmesg text, or null when
|
|
13
|
+
* dmesg is missing / not readable (CAP_SYSLOG absent or
|
|
14
|
+
* kernel.dmesg_restrict=1).
|
|
15
|
+
*
|
|
16
|
+
* Two-step, preserving the historical behavior of both callers:
|
|
17
|
+
* 1. `dmesg --time-format=iso --no-pager [extraIsoArgs...]`
|
|
18
|
+
* 2. on a null/empty result, `dmesg --no-pager`
|
|
19
|
+
*/
|
|
20
|
+
export async function readDmesg(opts = {}) {
|
|
21
|
+
const { timeoutMs, extraIsoArgs = [] } = opts;
|
|
22
|
+
const isoArgs = ["--time-format=iso", "--no-pager", ...extraIsoArgs];
|
|
23
|
+
const first = timeoutMs === undefined
|
|
24
|
+
? await run("dmesg", isoArgs)
|
|
25
|
+
: await run("dmesg", isoArgs, timeoutMs);
|
|
26
|
+
if (first)
|
|
27
|
+
return first;
|
|
28
|
+
return timeoutMs === undefined
|
|
29
|
+
? await run("dmesg", ["--no-pager"])
|
|
30
|
+
: await run("dmesg", ["--no-pager"], timeoutMs);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Extract a unix-ms timestamp from a dmesg line. Two absolute shapes:
|
|
34
|
+
* ISO: "2026-05-19T12:34:56,789012+00:00 ..." (--time-format=iso)
|
|
35
|
+
* ctime: "[Mon May 19 12:34:56 2026] ..." (--ctime)
|
|
36
|
+
*
|
|
37
|
+
* Relative-time format ("[12345.678]") returns null (no absolute anchor
|
|
38
|
+
* available without uptime). The comma fractional separator that iso
|
|
39
|
+
* format emits is normalised to a dot before Date.parse.
|
|
40
|
+
*/
|
|
41
|
+
export function parseKernelLogTimestamp(line) {
|
|
42
|
+
const isoMatch = line.match(/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[,.]\d+)?(?:[+-]\d{2}:?\d{2}|Z)?)/);
|
|
43
|
+
if (isoMatch) {
|
|
44
|
+
// Normalise the comma fractional separator to dot.
|
|
45
|
+
const iso = isoMatch[1].replace(",", ".");
|
|
46
|
+
const t = Date.parse(iso);
|
|
47
|
+
return Number.isFinite(t) ? t : null;
|
|
48
|
+
}
|
|
49
|
+
const ctimeMatch = line.match(/^\[([A-Z][a-z]{2}\s+[A-Z][a-z]{2}\s+\d+\s+\d{2}:\d{2}:\d{2}\s+\d{4})\]/);
|
|
50
|
+
if (ctimeMatch) {
|
|
51
|
+
const t = Date.parse(ctimeMatch[1]);
|
|
52
|
+
return Number.isFinite(t) ? t : null;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=dmesg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dmesg.js","sourceRoot":"","sources":["../../src/lib/dmesg.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,EAAE;AACF,oEAAoE;AACpE,yEAAyE;AACzE,uEAAuE;AACvE,sEAAsE;AACtE,uEAAuE;AACvE,iEAAiE;AACjE,0BAA0B;AAE1B,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAYhC;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAyB,EAAE;IACzD,MAAM,EAAE,SAAS,EAAE,YAAY,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;IAC9C,MAAM,OAAO,GAAG,CAAC,mBAAmB,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,CAAC;IACrE,MAAM,KAAK,GACT,SAAS,KAAK,SAAS;QACrB,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;QAC7B,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC7C,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,SAAS,KAAK,SAAS;QAC5B,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,2EAA2E,CAC5E,CAAC;IACF,IAAI,QAAQ,EAAE,CAAC;QACb,mDAAmD;QACnD,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvC,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAC3B,wEAAwE,CACzE,CAAC;IACF,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/lib/exec.d.ts
CHANGED
|
@@ -7,4 +7,6 @@ export interface RunDetailedResult {
|
|
|
7
7
|
timedOut: boolean;
|
|
8
8
|
}
|
|
9
9
|
export declare function runDetailed(cmd: string, args: string[], timeoutMs?: number): Promise<RunDetailedResult>;
|
|
10
|
+
export declare function which(name: string, timeoutMs?: number): Promise<boolean>;
|
|
11
|
+
export declare function isUnitActive(unit: string, timeoutMs?: number): Promise<boolean>;
|
|
10
12
|
export declare function looksLikeFieldRenameError(stderr: string): boolean;
|
package/dist/lib/exec.js
CHANGED
|
@@ -34,6 +34,20 @@ export async function runDetailed(cmd, args, timeoutMs = 10000) {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
// Is `name` on PATH? Uses `which` (returns a path on stdout and exit 0
|
|
38
|
+
// when found, exit 1 / nothing when not). Shared by the hardware-raid and
|
|
39
|
+
// zfs collectors, which both gated CLI parsing on a `which` probe.
|
|
40
|
+
export async function which(name, timeoutMs = 2000) {
|
|
41
|
+
const out = await run("which", [name], timeoutMs);
|
|
42
|
+
return !!(out && out.trim());
|
|
43
|
+
}
|
|
44
|
+
// Is a systemd unit active? `systemctl is-active <unit>` prints "active"
|
|
45
|
+
// (and exits 0) when up, and a non-active state word otherwise. Shared by
|
|
46
|
+
// the ntp daemon detector and the gpu DCGM probe.
|
|
47
|
+
export async function isUnitActive(unit, timeoutMs = 3000) {
|
|
48
|
+
const out = await run("systemctl", ["is-active", unit], timeoutMs);
|
|
49
|
+
return out?.trim() === "active";
|
|
50
|
+
}
|
|
37
51
|
// Heuristic: does this stderr look like the "field/tag name not found"
|
|
38
52
|
// pattern that nvidia-smi (and others) emit when a query field has
|
|
39
53
|
// been renamed by a tool upgrade? Used by the gpu.ts collector's
|
package/dist/lib/exec.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/lib/exec.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/lib/exec.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/parse.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export declare function readProcFile(path: string): string | null;
|
|
2
|
+
export declare function readFileTrim(path: string): string | null;
|
|
3
|
+
export declare function readFileInt(path: string): number | null;
|
|
4
|
+
export declare function readDirSafe(path: string): string[];
|
|
2
5
|
export declare function parseKeyValue(raw: string): Record<string, string>;
|
|
3
6
|
export declare function parseKb(val: string | undefined): number;
|
|
4
7
|
export declare function sleep(ms: number): Promise<void>;
|
package/dist/lib/parse.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync } from "fs";
|
|
1
|
+
import { readFileSync, readdirSync } from "fs";
|
|
2
2
|
export function readProcFile(path) {
|
|
3
3
|
try {
|
|
4
4
|
return readFileSync(path, "utf-8");
|
|
@@ -7,6 +7,39 @@ export function readProcFile(path) {
|
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
+
// Read a file and return its trimmed contents, or null if it can't be
|
|
11
|
+
// read. Empty/whitespace-only files yield "" (not null); callers that
|
|
12
|
+
// treat empty as absent append `|| null`. Shared by the dmi/thermal/edac
|
|
13
|
+
// collectors and the per-process fd scan, which all had byte-equivalent
|
|
14
|
+
// private copies of this read.
|
|
15
|
+
export function readFileTrim(path) {
|
|
16
|
+
try {
|
|
17
|
+
return readFileSync(path, "utf-8").trim();
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Read a file expected to hold a single non-negative integer (the common
|
|
24
|
+
// /sys counter shape). Returns null on read failure or when the trimmed
|
|
25
|
+
// contents are not all digits. Mirrors edac.ts's former readUint.
|
|
26
|
+
export function readFileInt(path) {
|
|
27
|
+
const s = readFileTrim(path);
|
|
28
|
+
if (s === null || !/^\d+$/.test(s))
|
|
29
|
+
return null;
|
|
30
|
+
return parseInt(s, 10);
|
|
31
|
+
}
|
|
32
|
+
// List a directory, returning [] on any error (missing dir, EACCES, etc.).
|
|
33
|
+
// Callers that need to distinguish "looked but empty" from "couldn't look"
|
|
34
|
+
// must keep their own try/catch instead.
|
|
35
|
+
export function readDirSafe(path) {
|
|
36
|
+
try {
|
|
37
|
+
return readdirSync(path);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
10
43
|
export function parseKeyValue(raw) {
|
|
11
44
|
const result = {};
|
|
12
45
|
for (const line of raw.split("\n")) {
|
package/dist/lib/parse.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/lib/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/lib/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AAE/C,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,sEAAsE;AACtE,sEAAsE;AACtE,yEAAyE;AACzE,wEAAwE;AACxE,+BAA+B;AAC/B,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,wEAAwE;AACxE,kEAAkE;AAClE,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,OAAO,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC;AAED,2EAA2E;AAC3E,2EAA2E;AAC3E,yCAAyC;AACzC,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,SAAS;QACzB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACjE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAuB;IAC7C,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,CAAC;IACnB,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { CRUCIBLE_VERSION as CURRENT_VERSION } from "./version.js";
|
|
2
2
|
let lastCheckTime = 0;
|
|
3
|
-
let lastResult = null;
|
|
4
3
|
const CHECK_INTERVAL = 6 * 60 * 60 * 1000; // check every 6 hours
|
|
5
|
-
export function getCurrentVersion() {
|
|
6
|
-
return CURRENT_VERSION;
|
|
7
|
-
}
|
|
8
4
|
export async function checkForUpdates(dashboardUrl) {
|
|
9
5
|
const now = Date.now();
|
|
10
6
|
if (now - lastCheckTime < CHECK_INTERVAL)
|
|
@@ -23,17 +19,10 @@ export async function checkForUpdates(dashboardUrl) {
|
|
|
23
19
|
console.log(`[update] New Crucible version available: ${latest} (current: ${CURRENT_VERSION})`);
|
|
24
20
|
console.log(`[update] Changelog: ${data.crucible?.changelog_url || "https://github.com/glassmkr/crucible/releases"}`);
|
|
25
21
|
console.log(`[update] Run: npm update -g @glassmkr/crucible && sudo systemctl restart glassmkr-crucible`);
|
|
26
|
-
lastResult = { updateAvailable: true, latest, changelog: data.crucible?.changelog_url || "" };
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
lastResult = { updateAvailable: false, latest, changelog: "" };
|
|
30
22
|
}
|
|
31
23
|
}
|
|
32
24
|
catch {
|
|
33
25
|
// Version check is non-critical, fail silently
|
|
34
26
|
}
|
|
35
27
|
}
|
|
36
|
-
export function getUpdateStatus() {
|
|
37
|
-
return lastResult;
|
|
38
|
-
}
|
|
39
28
|
//# sourceMappingURL=version-check.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-check.js","sourceRoot":"","sources":["../../src/lib/version-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAEnE,IAAI,aAAa,GAAG,CAAC,CAAC;AACtB,
|
|
1
|
+
{"version":3,"file":"version-check.js","sourceRoot":"","sources":["../../src/lib/version-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAEnE,IAAI,aAAa,GAAG,CAAC,CAAC;AACtB,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,sBAAsB;AAEjE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,YAAqB;IACzD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,GAAG,GAAG,aAAa,GAAG,cAAc;QAAE,OAAO;IACjD,aAAa,GAAG,GAAG,CAAC;IAEpB,MAAM,GAAG,GAAG,YAAY,IAAI,0BAA0B,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,iBAAiB,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO;QACpB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAwF,CAAC;QACpH,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,4CAA4C,MAAM,cAAc,eAAe,GAAG,CAAC,CAAC;YAChG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,QAAQ,EAAE,aAAa,IAAI,+CAA+C,EAAE,CAAC,CAAC;YACtH,OAAO,CAAC,GAAG,CAAC,4FAA4F,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;AACH,CAAC"}
|
package/dist/metrics-server.js
CHANGED
|
@@ -80,7 +80,6 @@ function formatPrometheus(snap) {
|
|
|
80
80
|
if (snap.ipmi?.available) {
|
|
81
81
|
for (const sensor of snap.ipmi.sensors) {
|
|
82
82
|
if (typeof sensor.value === "number") {
|
|
83
|
-
const sensorName = sensor.name.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase();
|
|
84
83
|
lines.push(`glassmkr_ipmi_sensor{sensor="${sensor.name}",unit="${sensor.unit}"} ${sensor.value}`);
|
|
85
84
|
}
|
|
86
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics-server.js","sourceRoot":"","sources":["../src/metrics-server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"metrics-server.js","sourceRoot":"","sources":["../src/metrics-server.ts"],"names":[],"mappings":"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"}
|