@glassmkr/crucible 0.10.1 → 0.10.2
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
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@glassmkr/crucible)
|
|
5
5
|
|
|
6
6
|
<!-- Canonical rule count: see RULES_COUNT.md in the Glassmkr monorepo. -->
|
|
7
|
-
Lightweight bare metal server monitoring agent. Collects hardware and OS health every 5 minutes and pushes snapshots to
|
|
7
|
+
Lightweight bare metal server monitoring agent. Collects hardware and OS health every 5 minutes and pushes snapshots to the [Glassmkr Dashboard](https://app.glassmkr.com), which evaluates 38 alert rules and sends notifications.
|
|
8
8
|
|
|
9
|
-
Open source. MIT licensed. Built by [Glassmkr](https://glassmkr.com). See also [Bench](https://
|
|
9
|
+
Open source. MIT licensed. Built by [Glassmkr](https://glassmkr.com). See also the [Bench MCP packages](https://glassmkr.com/docs/mcp) (`@glassmkr/bench-*` on npm) for AI-tool access to your Glassmkr fleet.
|
|
10
10
|
|
|
11
11
|
**Resource usage:** ~90MB RSS memory (varies by hardware: servers with more IPMI sensors use more), <0.1% CPU at 5-minute collection interval. Collects IPMI, SMART, ZFS, network bonds, security posture, conntrack, systemd, NTP, and file descriptors.
|
|
12
12
|
|
|
@@ -31,7 +31,7 @@ agent, and runs `glassmkr-crucible init` to validate your key, write
|
|
|
31
31
|
service.
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
curl -sf https://
|
|
34
|
+
curl -sf https://glassmkr.com/install.sh | bash -s -- --api-key gmk_cru_live_<your-key>
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
Or run the steps yourself:
|
|
@@ -62,7 +62,7 @@ collection:
|
|
|
62
62
|
dashboard:
|
|
63
63
|
enabled: true
|
|
64
64
|
url: "https://app.glassmkr.com"
|
|
65
|
-
api_key: "
|
|
65
|
+
api_key: "gmk_cru_live_YOUR_KEY_HERE"
|
|
66
66
|
EOF
|
|
67
67
|
|
|
68
68
|
# Run with docker compose
|
|
@@ -77,7 +77,7 @@ Images are published to [ghcr.io/glassmkr/crucible](https://github.com/glassmkr/
|
|
|
77
77
|
|
|
78
78
|
## Quick Start
|
|
79
79
|
|
|
80
|
-
1. Create an API key in the Dashboard
|
|
80
|
+
1. Create an API key in the Glassmkr Dashboard (Servers → Add server).
|
|
81
81
|
2. Run `init`:
|
|
82
82
|
|
|
83
83
|
```bash
|
|
@@ -90,7 +90,7 @@ Images are published to [ghcr.io/glassmkr/crucible](https://github.com/glassmkr/
|
|
|
90
90
|
you want to inspect the unit before enabling it. Pass `--api-key -`
|
|
91
91
|
to read the key from stdin (handy for password-manager pipes).
|
|
92
92
|
|
|
93
|
-
Snapshots appear in the Dashboard
|
|
93
|
+
Snapshots appear in the Glassmkr Dashboard within seconds of the first
|
|
94
94
|
push.
|
|
95
95
|
|
|
96
96
|
If you can't or won't run `init` (config-management is doing it for
|
|
@@ -132,14 +132,36 @@ dashboard:
|
|
|
132
132
|
Hand-edit any time. The agent re-reads on restart. Run
|
|
133
133
|
`glassmkr-crucible init --help` for the full flag list.
|
|
134
134
|
|
|
135
|
-
### Migrating from
|
|
135
|
+
### Migrating from 0.9.x to 0.10.x
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
**Breaking change in 0.10.0**: the top-level config block was renamed
|
|
138
|
+
from `forge:` to `dashboard:`, and the default endpoint changed from
|
|
139
|
+
`forge.glassmkr.com` to `app.glassmkr.com`. Edit your existing
|
|
140
|
+
`/etc/glassmkr/collector.yaml`:
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
```yaml
|
|
143
|
+
# OLD (0.9.x):
|
|
144
|
+
forge:
|
|
145
|
+
enabled: true
|
|
146
|
+
url: "https://forge.glassmkr.com"
|
|
147
|
+
api_key: "gmk_cru_live_..."
|
|
148
|
+
|
|
149
|
+
# NEW (0.10+):
|
|
150
|
+
dashboard:
|
|
151
|
+
enabled: true
|
|
152
|
+
url: "https://app.glassmkr.com"
|
|
153
|
+
api_key: "gmk_cru_live_..."
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The `api_key` value itself is unchanged — only the parent key
|
|
157
|
+
(`forge:` → `dashboard:`) and the endpoint hostname need updating.
|
|
158
|
+
After the edit, restart the service:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
sudo systemctl restart glassmkr-crucible
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For a clean reinstall from scratch, prefer `init --force`:
|
|
143
165
|
|
|
144
166
|
```bash
|
|
145
167
|
sudo systemctl stop glassmkr-crucible
|
|
@@ -216,7 +238,7 @@ sudo systemctl status glassmkr-crucible
|
|
|
216
238
|
|
|
217
239
|
If you ever upgrade `@glassmkr/crucible` and the binary moves (rare, but
|
|
218
240
|
possible on a distro change), re-run the `command -v` step and update the
|
|
219
|
-
unit file. The bootstrap script at `https://
|
|
241
|
+
unit file. The bootstrap script at `https://glassmkr.com/install.sh` does
|
|
220
242
|
this detection automatically; the manual flow above is just the equivalent.
|
|
221
243
|
|
|
222
244
|
## What It Collects
|
|
@@ -5,11 +5,20 @@ describe("readOsReleaseField", () => {
|
|
|
5
5
|
const s = 'NAME="Ubuntu"\nID=ubuntu\nID_LIKE=debian\nVERSION_ID="24.04"';
|
|
6
6
|
expect(readOsReleaseField(s, "ID")).toBe("ubuntu");
|
|
7
7
|
expect(readOsReleaseField(s, "ID_LIKE")).toBe("debian");
|
|
8
|
+
expect(readOsReleaseField(s, "VERSION_ID")).toBe("24.04");
|
|
8
9
|
});
|
|
9
10
|
it("parses quoted RHEL-family values", () => {
|
|
10
|
-
const s = 'NAME="Rocky Linux"\nID="rocky"\nID_LIKE="rhel centos fedora"';
|
|
11
|
+
const s = 'NAME="Rocky Linux"\nID="rocky"\nID_LIKE="rhel centos fedora"\nVERSION_ID="9.6"';
|
|
11
12
|
expect(readOsReleaseField(s, "ID")).toBe("rocky");
|
|
12
13
|
expect(readOsReleaseField(s, "ID_LIKE")).toBe("rhel centos fedora");
|
|
14
|
+
expect(readOsReleaseField(s, "VERSION_ID")).toBe("9.6");
|
|
15
|
+
});
|
|
16
|
+
it("parses Debian's bare numeric VERSION_ID", () => {
|
|
17
|
+
// Debian trixie /etc/os-release: VERSION_ID="13" (with quotes).
|
|
18
|
+
// Earlier Debian releases sometimes wrote VERSION_ID=13 unquoted;
|
|
19
|
+
// both shapes must parse to the same value.
|
|
20
|
+
expect(readOsReleaseField('VERSION_ID="13"', "VERSION_ID")).toBe("13");
|
|
21
|
+
expect(readOsReleaseField("VERSION_ID=13", "VERSION_ID")).toBe("13");
|
|
13
22
|
});
|
|
14
23
|
it("lowercases the result (some distros uppercase their ID)", () => {
|
|
15
24
|
expect(readOsReleaseField("ID=Alpine", "ID")).toBe("alpine");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.test.js","sourceRoot":"","sources":["../../../src/collect/__tests__/system.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,GAAG,8DAA8D,CAAC;QACzE,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"system.test.js","sourceRoot":"","sources":["../../../src/collect/__tests__/system.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,GAAG,8DAA8D,CAAC;QACzE,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,GAAG,gFAAgF,CAAC;QAC3F,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACpE,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,gEAAgE;QAChE,kEAAkE;QAClE,4CAA4C;QAC5C,MAAM,CAAC,kBAAkB,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvE,MAAM,CAAC,kBAAkB,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,GAAG,+BAA+B,CAAC;QAC1C,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/collect/system.js
CHANGED
|
@@ -12,6 +12,14 @@ export async function collectSystem() {
|
|
|
12
12
|
const osName = osRelease.match(/PRETTY_NAME="(.+?)"/)?.[1] || "Unknown";
|
|
13
13
|
const os_id = readOsReleaseField(osRelease, "ID");
|
|
14
14
|
const os_id_like = readOsReleaseField(osRelease, "ID_LIKE");
|
|
15
|
+
// VERSION_ID added 2026-05-18: Dashboard's FIX-workflow variant
|
|
16
|
+
// selector keys distro_match patterns on `<os_id>-<os_version_id>`
|
|
17
|
+
// (e.g. "debian-13", "ubuntu-24.04"). Without this field, every
|
|
18
|
+
// variant with a `["debian-*", ...]` pattern falls through to the
|
|
19
|
+
// wildcard `["*"]` fallback in Dashboard, so customers running the
|
|
20
|
+
// 0.10.1-or-older agent see the generic "distro/vendor unknown"
|
|
21
|
+
// FIX block on alert detail pages.
|
|
22
|
+
const os_version_id = readOsReleaseField(osRelease, "VERSION_ID");
|
|
15
23
|
const kernel = (await run("uname", ["-r"]))?.trim() || "unknown";
|
|
16
24
|
const uptimeRaw = readProcFile("/proc/uptime") || "0";
|
|
17
25
|
const uptimeSeconds = Math.floor(parseFloat(uptimeRaw.split(" ")[0]));
|
|
@@ -22,6 +30,7 @@ export async function collectSystem() {
|
|
|
22
30
|
os: osName,
|
|
23
31
|
...(os_id ? { os_id } : {}),
|
|
24
32
|
...(os_id_like ? { os_id_like } : {}),
|
|
33
|
+
...(os_version_id ? { os_version_id } : {}),
|
|
25
34
|
kernel,
|
|
26
35
|
uptime_seconds: uptimeSeconds,
|
|
27
36
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/collect/system.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAGrC,0EAA0E;AAC1E,yDAAyD;AACzD,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,GAAW;IAC/D,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,SAAS,GAAG,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACxD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IACxE,MAAM,KAAK,GAAG,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACjE,MAAM,SAAS,GAAG,YAAY,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC;IACtD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IAE9E,OAAO;QACL,QAAQ,EAAE,QAAQ,EAAE;QACpB,EAAE;QACF,EAAE,EAAE,MAAM;QACV,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,MAAM;QACN,cAAc,EAAE,aAAa;KAC9B,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/collect/system.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAGrC,0EAA0E;AAC1E,yDAAyD;AACzD,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,GAAW;IAC/D,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,SAAS,GAAG,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACxD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IACxE,MAAM,KAAK,GAAG,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC5D,gEAAgE;IAChE,mEAAmE;IACnE,gEAAgE;IAChE,kEAAkE;IAClE,mEAAmE;IACnE,gEAAgE;IAChE,mCAAmC;IACnC,MAAM,aAAa,GAAG,kBAAkB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACjE,MAAM,SAAS,GAAG,YAAY,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC;IACtD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IAE9E,OAAO;QACL,QAAQ,EAAE,QAAQ,EAAE;QACpB,EAAE;QACF,EAAE,EAAE,MAAM;QACV,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,MAAM;QACN,cAAc,EAAE,aAAa;KAC9B,CAAC;AACJ,CAAC"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -112,6 +112,11 @@ export interface SystemInfo {
|
|
|
112
112
|
* to pick distro-family-specific fix command variants. e.g. on Rocky this
|
|
113
113
|
* is "rhel centos fedora"; on Ubuntu it is "debian". */
|
|
114
114
|
os_id_like?: string;
|
|
115
|
+
/** `VERSION_ID=` from /etc/os-release, lowercased. e.g. "13" on Debian
|
|
116
|
+
* trixie, "24.04" on Ubuntu, "9.6" on Rocky. Combined with `os_id` by
|
|
117
|
+
* Dashboard to form the distro token (`debian-13` etc.) that
|
|
118
|
+
* FIX-workflow variant patterns key on. Added 2026-05-18. */
|
|
119
|
+
os_version_id?: string;
|
|
115
120
|
kernel: string;
|
|
116
121
|
uptime_seconds: number;
|
|
117
122
|
}
|