aiservermanager 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 +31 -0
- package/backend/dist/di/container.js +80 -0
- package/backend/dist/di/container.js.map +1 -0
- package/backend/dist/di/types.js +18 -0
- package/backend/dist/di/types.js.map +1 -0
- package/backend/dist/files/validatePassword.ps1 +10 -0
- package/backend/dist/files/wmiGpuQuery.ps1 +15 -0
- package/backend/dist/helpers/ExecTools.js +101 -0
- package/backend/dist/helpers/ExecTools.js.map +1 -0
- package/backend/dist/index.js +51 -0
- package/backend/dist/index.js.map +1 -0
- package/backend/dist/middleware/authMiddleware.js +32 -0
- package/backend/dist/middleware/authMiddleware.js.map +1 -0
- package/backend/dist/models/GpuInfo.js +3 -0
- package/backend/dist/models/GpuInfo.js.map +1 -0
- package/backend/dist/models/ServiceConfig.js +46 -0
- package/backend/dist/models/ServiceConfig.js.map +1 -0
- package/backend/dist/models/ServiceStatus.js +3 -0
- package/backend/dist/models/ServiceStatus.js.map +1 -0
- package/backend/dist/routes/authRoutes.js +46 -0
- package/backend/dist/routes/authRoutes.js.map +1 -0
- package/backend/dist/routes/gpuRoutes.js +35 -0
- package/backend/dist/routes/gpuRoutes.js.map +1 -0
- package/backend/dist/routes/serviceRoutes.js +206 -0
- package/backend/dist/routes/serviceRoutes.js.map +1 -0
- package/backend/dist/routes/systemRoutes.js +64 -0
- package/backend/dist/routes/systemRoutes.js.map +1 -0
- package/backend/dist/services/auth/linuxPasswordVerifier.js +74 -0
- package/backend/dist/services/auth/linuxPasswordVerifier.js.map +1 -0
- package/backend/dist/services/auth/passwordVerifier.js +3 -0
- package/backend/dist/services/auth/passwordVerifier.js.map +1 -0
- package/backend/dist/services/auth/windowsPasswordVerifier.js +73 -0
- package/backend/dist/services/auth/windowsPasswordVerifier.js.map +1 -0
- package/backend/dist/services/authService.js +240 -0
- package/backend/dist/services/authService.js.map +1 -0
- package/backend/dist/services/configManager.js +96 -0
- package/backend/dist/services/configManager.js.map +1 -0
- package/backend/dist/services/controllers/systemctlController.js +287 -0
- package/backend/dist/services/controllers/systemctlController.js.map +1 -0
- package/backend/dist/services/controllers/windowsServiceController.js +201 -0
- package/backend/dist/services/controllers/windowsServiceController.js.map +1 -0
- package/backend/dist/services/detectors/amdLinuxDetector.js +127 -0
- package/backend/dist/services/detectors/amdLinuxDetector.js.map +1 -0
- package/backend/dist/services/detectors/gpuDetector.js +3 -0
- package/backend/dist/services/detectors/gpuDetector.js.map +1 -0
- package/backend/dist/services/detectors/nvidiaSmiDetector.js +67 -0
- package/backend/dist/services/detectors/nvidiaSmiDetector.js.map +1 -0
- package/backend/dist/services/detectors/wmiDetector.js +125 -0
- package/backend/dist/services/detectors/wmiDetector.js.map +1 -0
- package/backend/dist/services/enrichers/gpuEnricher.js +3 -0
- package/backend/dist/services/enrichers/gpuEnricher.js.map +1 -0
- package/backend/dist/services/enrichers/lspciEnricher.js +92 -0
- package/backend/dist/services/enrichers/lspciEnricher.js.map +1 -0
- package/backend/dist/services/enrichers/vulkanEnricher.js +57 -0
- package/backend/dist/services/enrichers/vulkanEnricher.js.map +1 -0
- package/backend/dist/services/gpuService.js +108 -0
- package/backend/dist/services/gpuService.js.map +1 -0
- package/backend/dist/services/helpers/gpuDedup.js +46 -0
- package/backend/dist/services/helpers/gpuDedup.js.map +1 -0
- package/backend/dist/services/helpers/gpuEngineNames.js +22 -0
- package/backend/dist/services/helpers/gpuEngineNames.js.map +1 -0
- package/backend/dist/services/llamaAutocompleteService.js +277 -0
- package/backend/dist/services/llamaAutocompleteService.js.map +1 -0
- package/backend/dist/services/managedServicesController.js +72 -0
- package/backend/dist/services/managedServicesController.js.map +1 -0
- package/backend/dist/services/managedServicesManager.js +91 -0
- package/backend/dist/services/managedServicesManager.js.map +1 -0
- package/backend/dist/services/probes/amdLinuxUsageProbe.js +109 -0
- package/backend/dist/services/probes/amdLinuxUsageProbe.js.map +1 -0
- package/backend/dist/services/probes/gpuUsageProbe.js +3 -0
- package/backend/dist/services/probes/gpuUsageProbe.js.map +1 -0
- package/backend/dist/services/probes/nvidiaSmiUsageProbe.js +67 -0
- package/backend/dist/services/probes/nvidiaSmiUsageProbe.js.map +1 -0
- package/backend/dist/services/providers/systemInfoLinuxProvider.js +188 -0
- package/backend/dist/services/providers/systemInfoLinuxProvider.js.map +1 -0
- package/backend/dist/services/providers/systemInfoWindowsProvider.js +101 -0
- package/backend/dist/services/providers/systemInfoWindowsProvider.js.map +1 -0
- package/backend/dist/services/serviceConfigController.js +116 -0
- package/backend/dist/services/serviceConfigController.js.map +1 -0
- package/backend/dist/services/serviceController.js +3 -0
- package/backend/dist/services/serviceController.js.map +1 -0
- package/backend/dist/services/serviceManager.js +157 -0
- package/backend/dist/services/serviceManager.js.map +1 -0
- package/backend/dist/services/systemInfoProvider.js +3 -0
- package/backend/dist/services/systemInfoProvider.js.map +1 -0
- package/backend/dist/services/systemService.js +42 -0
- package/backend/dist/services/systemService.js.map +1 -0
- package/backend/public/browser/chunk-34LU6STA.js +1 -0
- package/backend/public/browser/chunk-JGNPKRLU.js +4 -0
- package/backend/public/browser/favicon.svg +11 -0
- package/backend/public/browser/index.html +15 -0
- package/backend/public/browser/main-MUMQYBNS.js +5579 -0
- package/backend/public/browser/polyfills-5CFQRCPP.js +2 -0
- package/backend/public/browser/styles-QBUDNRKH.css +1 -0
- package/bin/aiservermanager.js +2 -0
- package/package.json +45 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ManagedServicesController = void 0;
|
|
16
|
+
const inversify_1 = require("inversify");
|
|
17
|
+
const managedServicesManager_1 = require("./managedServicesManager");
|
|
18
|
+
const configManager_1 = require("./configManager");
|
|
19
|
+
/**
|
|
20
|
+
* API layer for discovering available system services and managing the user's selection.
|
|
21
|
+
* Excludes custom services (those with a config) from the available list.
|
|
22
|
+
*/
|
|
23
|
+
let ManagedServicesController = class ManagedServicesController {
|
|
24
|
+
controllers;
|
|
25
|
+
manager = new managedServicesManager_1.ManagedServicesManager();
|
|
26
|
+
configManager = new configManager_1.ConfigManager();
|
|
27
|
+
constructor(controllers) {
|
|
28
|
+
this.controllers = controllers;
|
|
29
|
+
}
|
|
30
|
+
async getActiveController() {
|
|
31
|
+
for (const c of this.controllers) {
|
|
32
|
+
if (await c.isAvailable())
|
|
33
|
+
return c;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
/** List all installed services on the system (excludes custom). */
|
|
38
|
+
async listAvailable() {
|
|
39
|
+
const controller = await this.getActiveController();
|
|
40
|
+
if (!controller)
|
|
41
|
+
return [];
|
|
42
|
+
return controller.listAvailable();
|
|
43
|
+
}
|
|
44
|
+
/** List the user-selected managed service names. */
|
|
45
|
+
listManaged() {
|
|
46
|
+
return this.manager.list();
|
|
47
|
+
}
|
|
48
|
+
/** Add a service name to the managed list. */
|
|
49
|
+
addManaged(name) {
|
|
50
|
+
// Reject custom — those are managed via configs
|
|
51
|
+
if (this.configManager.get(name) !== null) {
|
|
52
|
+
return { ok: false, error: `"${name}" is a custom service — manage it via the service config dialog` };
|
|
53
|
+
}
|
|
54
|
+
const added = this.manager.add(name);
|
|
55
|
+
if (!added)
|
|
56
|
+
return { ok: false, error: `"${name}" is already in the managed list` };
|
|
57
|
+
return { ok: true };
|
|
58
|
+
}
|
|
59
|
+
/** Remove a service name from the managed list. */
|
|
60
|
+
removeManaged(name) {
|
|
61
|
+
const removed = this.manager.remove(name);
|
|
62
|
+
if (!removed)
|
|
63
|
+
return { ok: false, error: `"${name}" is not in the managed list` };
|
|
64
|
+
return { ok: true };
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.ManagedServicesController = ManagedServicesController;
|
|
68
|
+
exports.ManagedServicesController = ManagedServicesController = __decorate([
|
|
69
|
+
__param(0, (0, inversify_1.multiInject)("SERVICE_CONTROLLER")),
|
|
70
|
+
__metadata("design:paramtypes", [Array])
|
|
71
|
+
], ManagedServicesController);
|
|
72
|
+
//# sourceMappingURL=managedServicesController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"managedServicesController.js","sourceRoot":"","sources":["../../src/services/managedServicesController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,yCAAwC;AAExC,qEAAkE;AAClE,mDAAgD;AAEhD;;;GAGG;AACH,IAAa,yBAAyB,GAAtC,MAAa,yBAAyB;IAMjB;IALF,OAAO,GAAG,IAAI,+CAAsB,EAAE,CAAC;IACvC,aAAa,GAAG,IAAI,6BAAa,EAAE,CAAC;IAErD,YAEmB,WAAgC;QAAhC,gBAAW,GAAX,WAAW,CAAqB;IAChD,CAAC;IAEI,KAAK,CAAC,mBAAmB;QAC/B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE;gBAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mEAAmE;IACnE,KAAK,CAAC,aAAa;QACjB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACpD,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAC3B,OAAO,UAAU,CAAC,aAAa,EAAE,CAAC;IACpC,CAAC;IAED,oDAAoD;IACpD,WAAW;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,8CAA8C;IAC9C,UAAU,CAAC,IAAY;QACrB,gDAAgD;QAChD,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,IAAI,iEAAiE,EAAE,CAAC;QACzG,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,IAAI,kCAAkC,EAAE,CAAC;QACpF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,mDAAmD;IACnD,aAAa,CAAC,IAAY;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,IAAI,8BAA8B,EAAE,CAAC;QAClF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;CACF,CAAA;AA7CY,8DAAyB;oCAAzB,yBAAyB;IAKjC,WAAA,IAAA,uBAAW,EAAC,oBAAoB,CAAC,CAAA;;GALzB,yBAAyB,CA6CrC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ManagedServicesManager = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const CONFIG_DIR = path.join(process.env.HOME ?? "", ".config", "aiservermanager");
|
|
40
|
+
const MANAGED_FILE = path.join(CONFIG_DIR, "managed-services.json");
|
|
41
|
+
/**
|
|
42
|
+
* Persists the user-selected list of managed service names.
|
|
43
|
+
* Stored in ~/.config/aiservermanager/managed-services.json as a JSON array of strings.
|
|
44
|
+
*/
|
|
45
|
+
class ManagedServicesManager {
|
|
46
|
+
ensureDir() {
|
|
47
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
48
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Load the managed service names from disk. Returns [] if the file doesn't exist. */
|
|
52
|
+
list() {
|
|
53
|
+
if (!fs.existsSync(MANAGED_FILE))
|
|
54
|
+
return [];
|
|
55
|
+
try {
|
|
56
|
+
const raw = fs.readFileSync(MANAGED_FILE, "utf-8");
|
|
57
|
+
const parsed = JSON.parse(raw);
|
|
58
|
+
if (!Array.isArray(parsed))
|
|
59
|
+
return [];
|
|
60
|
+
return parsed.filter((s) => typeof s === "string" && s.trim() !== "");
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Save the managed service names to disk. Deduplicates and sorts. */
|
|
67
|
+
save(names) {
|
|
68
|
+
this.ensureDir();
|
|
69
|
+
const deduped = [...new Set(names)].sort();
|
|
70
|
+
fs.writeFileSync(MANAGED_FILE, JSON.stringify(deduped, null, 2) + "\n", "utf-8");
|
|
71
|
+
}
|
|
72
|
+
/** Add a service name to the managed list. Returns true if it was newly added. */
|
|
73
|
+
add(name) {
|
|
74
|
+
const current = this.list();
|
|
75
|
+
if (current.includes(name))
|
|
76
|
+
return false;
|
|
77
|
+
this.save([...current, name]);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
/** Remove a service name from the managed list. Returns true if it was present. */
|
|
81
|
+
remove(name) {
|
|
82
|
+
const current = this.list();
|
|
83
|
+
const filtered = current.filter((s) => s !== name);
|
|
84
|
+
if (filtered.length === current.length)
|
|
85
|
+
return false;
|
|
86
|
+
this.save(filtered);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.ManagedServicesManager = ManagedServicesManager;
|
|
91
|
+
//# sourceMappingURL=managedServicesManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"managedServicesManager.js","sourceRoot":"","sources":["../../src/services/managedServicesManager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;AACnF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAa,sBAAsB;IACzB,SAAS;QACf,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,sFAAsF;IACtF,IAAI;QACF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,OAAO,EAAE,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,OAAO,EAAE,CAAC;YACtC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAU,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9F,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,IAAI,CAAC,KAAe;QAClB,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACnF,CAAC;IAED,kFAAkF;IAClF,GAAG,CAAC,IAAY;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mFAAmF;IACnF,MAAM,CAAC,IAAY;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACnD,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA5CD,wDA4CC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.AmdLinuxUsageProbe = void 0;
|
|
13
|
+
const inversify_1 = require("inversify");
|
|
14
|
+
const ExecTools_1 = require("../../helpers/ExecTools");
|
|
15
|
+
/**
|
|
16
|
+
* Lightweight usage probe for AMD GPUs on Linux via `rocm-smi`.
|
|
17
|
+
* Queries only temperature, usage%, and VRAM — skips product name and bus info.
|
|
18
|
+
*/
|
|
19
|
+
let AmdLinuxUsageProbe = class AmdLinuxUsageProbe {
|
|
20
|
+
availableCache = null;
|
|
21
|
+
constructor() {
|
|
22
|
+
if (process.platform !== "linux") {
|
|
23
|
+
this.availableCache = false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async isAvailable() {
|
|
27
|
+
if (this.availableCache !== null)
|
|
28
|
+
return this.availableCache;
|
|
29
|
+
const result = await ExecTools_1.ExecTools.safeExec("rocm-smi --showproductname --json", { timeout: 5000 });
|
|
30
|
+
const available = result.stdout.trim().length > 0;
|
|
31
|
+
if (available) {
|
|
32
|
+
this.availableCache = true;
|
|
33
|
+
}
|
|
34
|
+
return available;
|
|
35
|
+
}
|
|
36
|
+
async probe(gpus) {
|
|
37
|
+
const results = await Promise.all([
|
|
38
|
+
ExecTools_1.ExecTools.safeExec("rocm-smi -t --json", { timeout: 10000 }),
|
|
39
|
+
ExecTools_1.ExecTools.safeExec("rocm-smi -u --json", { timeout: 10000 }),
|
|
40
|
+
ExecTools_1.ExecTools.safeExec("rocm-smi --showmeminfo vram --json", { timeout: 10000 }),
|
|
41
|
+
]);
|
|
42
|
+
const tempData = this.parseJson(results[0].stdout);
|
|
43
|
+
const usageData = this.parseJson(results[1].stdout);
|
|
44
|
+
const memData = this.parseJson(results[2].stdout);
|
|
45
|
+
// Build card→key mapping from static GPU info
|
|
46
|
+
const keyMap = this.buildKeyMap(gpus);
|
|
47
|
+
const usages = [];
|
|
48
|
+
for (const [cardKey, matchKey] of keyMap) {
|
|
49
|
+
usages.push(this.extractUsage(cardKey, matchKey, tempData, usageData, memData));
|
|
50
|
+
}
|
|
51
|
+
return usages;
|
|
52
|
+
}
|
|
53
|
+
parseJson(raw) {
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(raw.trim());
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Build cardKey → matchKey mapping.
|
|
63
|
+
* matchKey is the pciBusId from static info (or "AMD:index" fallback).
|
|
64
|
+
*/
|
|
65
|
+
buildKeyMap(gpus) {
|
|
66
|
+
const map = new Map();
|
|
67
|
+
const cardKeys = [];
|
|
68
|
+
for (let i = 0; i < gpus.length; i++) {
|
|
69
|
+
const cardKey = `card${i}`;
|
|
70
|
+
const gpu = gpus[i];
|
|
71
|
+
const matchKey = gpu.pciBusId || `AMD:${i}`;
|
|
72
|
+
map.set(cardKey, matchKey);
|
|
73
|
+
cardKeys.push(cardKey);
|
|
74
|
+
}
|
|
75
|
+
return map;
|
|
76
|
+
}
|
|
77
|
+
extractUsage(cardKey, matchKey, tempData, usageData, memData) {
|
|
78
|
+
const entry = { key: matchKey, usage: 0, temperature: 0, vramUsed: 0 };
|
|
79
|
+
// Temperature
|
|
80
|
+
if (tempData) {
|
|
81
|
+
const card = tempData[cardKey];
|
|
82
|
+
const val = card?.["Temperature (Sensor edge) (C)"];
|
|
83
|
+
if (val !== undefined)
|
|
84
|
+
entry.temperature = parseFloat(String(val)) || 0;
|
|
85
|
+
}
|
|
86
|
+
// Usage %
|
|
87
|
+
if (usageData) {
|
|
88
|
+
const card = usageData[cardKey];
|
|
89
|
+
const val = card?.["GPU use (%)"];
|
|
90
|
+
if (val !== undefined)
|
|
91
|
+
entry.usage = parseFloat(String(val)) || 0;
|
|
92
|
+
}
|
|
93
|
+
// VRAM used (bytes → GB)
|
|
94
|
+
if (memData) {
|
|
95
|
+
const card = memData[cardKey];
|
|
96
|
+
const usedBytes = card?.["VRAM Total Used Memory (B)"];
|
|
97
|
+
if (usedBytes !== undefined) {
|
|
98
|
+
entry.vramUsed = parseFloat(String(usedBytes)) / 1024 ** 3;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return entry;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
exports.AmdLinuxUsageProbe = AmdLinuxUsageProbe;
|
|
105
|
+
exports.AmdLinuxUsageProbe = AmdLinuxUsageProbe = __decorate([
|
|
106
|
+
(0, inversify_1.injectable)(),
|
|
107
|
+
__metadata("design:paramtypes", [])
|
|
108
|
+
], AmdLinuxUsageProbe);
|
|
109
|
+
//# sourceMappingURL=amdLinuxUsageProbe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amdLinuxUsageProbe.js","sourceRoot":"","sources":["../../../src/services/probes/amdLinuxUsageProbe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpuUsageProbe.js","sourceRoot":"","sources":["../../../src/services/probes/gpuUsageProbe.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.NvidiaSmiUsageProbe = void 0;
|
|
10
|
+
const inversify_1 = require("inversify");
|
|
11
|
+
const ExecTools_1 = require("../../helpers/ExecTools");
|
|
12
|
+
/**
|
|
13
|
+
* Lightweight usage probe for NVIDIA GPUs.
|
|
14
|
+
* Queries only utilization.gpu, temperature.gpu, memory.used — no name/brand/PCI.
|
|
15
|
+
*/
|
|
16
|
+
let NvidiaSmiUsageProbe = class NvidiaSmiUsageProbe {
|
|
17
|
+
availableCache = null;
|
|
18
|
+
async isAvailable() {
|
|
19
|
+
if (this.availableCache !== null)
|
|
20
|
+
return this.availableCache;
|
|
21
|
+
const result = await ExecTools_1.ExecTools.safeExec("nvidia-smi --query-gpu=index --format=csv,noheader,nounits", {
|
|
22
|
+
timeout: 5000,
|
|
23
|
+
});
|
|
24
|
+
const available = result.stdout.trim().length > 0;
|
|
25
|
+
if (available) {
|
|
26
|
+
this.availableCache = true;
|
|
27
|
+
}
|
|
28
|
+
return available;
|
|
29
|
+
}
|
|
30
|
+
async probe(_gpus) {
|
|
31
|
+
const result = await ExecTools_1.ExecTools.safeExec("nvidia-smi --query-gpu=index,utilization.gpu,temperature.gpu,memory.used,pci.bus_id --format=csv,noheader,nounits", { timeout: 10000 });
|
|
32
|
+
if (!result.stdout.trim())
|
|
33
|
+
return [];
|
|
34
|
+
return this.parseCsv(result.stdout);
|
|
35
|
+
}
|
|
36
|
+
parseCsv(raw) {
|
|
37
|
+
const usages = [];
|
|
38
|
+
for (const line of raw.trim().split("\n")) {
|
|
39
|
+
const parts = line.split(",").map((s) => s.trim());
|
|
40
|
+
if (parts.length < 5)
|
|
41
|
+
continue;
|
|
42
|
+
const index = parseInt(parts[0], 10);
|
|
43
|
+
const usage = parseFloat(parts[1]);
|
|
44
|
+
const temperature = parseFloat(parts[2]);
|
|
45
|
+
const vramUsedMiB = parseFloat(parts[3]);
|
|
46
|
+
let busId = parts[4];
|
|
47
|
+
// Normalize to lspci format: strip "0000:" domain prefix (Linux)
|
|
48
|
+
if (busId.startsWith("0000:")) {
|
|
49
|
+
busId = busId.slice(5);
|
|
50
|
+
}
|
|
51
|
+
// Key: prefer pciBusId, fallback to index
|
|
52
|
+
const key = busId || `NVIDIA:${index}`;
|
|
53
|
+
usages.push({
|
|
54
|
+
key,
|
|
55
|
+
usage: Number.isNaN(usage) ? 0 : usage,
|
|
56
|
+
temperature: Number.isNaN(temperature) ? 0 : temperature,
|
|
57
|
+
vramUsed: Math.round(vramUsedMiB / 1024),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return usages;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
exports.NvidiaSmiUsageProbe = NvidiaSmiUsageProbe;
|
|
64
|
+
exports.NvidiaSmiUsageProbe = NvidiaSmiUsageProbe = __decorate([
|
|
65
|
+
(0, inversify_1.injectable)()
|
|
66
|
+
], NvidiaSmiUsageProbe);
|
|
67
|
+
//# sourceMappingURL=nvidiaSmiUsageProbe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nvidiaSmiUsageProbe.js","sourceRoot":"","sources":["../../../src/services/probes/nvidiaSmiUsageProbe.ts"],"names":[],"mappings":";;;;;;;;;AAAA,yCAAuC;AAEvC,uDAAoD;AAGpD;;;GAGG;AAEI,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IACtB,cAAc,GAAmB,IAAI,CAAC;IAE9C,KAAK,CAAC,WAAW;QACf,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,cAAc,CAAC;QAE7D,MAAM,MAAM,GAAG,MAAM,qBAAS,CAAC,QAAQ,CAAC,4DAA4D,EAAE;YACpG,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;QAClD,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAgB;QAC1B,MAAM,MAAM,GAAG,MAAM,qBAAS,CAAC,QAAQ,CACrC,mHAAmH,EACnH,EAAE,OAAO,EAAE,KAAK,EAAE,CACnB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;QAErC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAEO,QAAQ,CAAC,GAAW;QAC1B,MAAM,MAAM,GAAe,EAAE,CAAC;QAE9B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAE/B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACrC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,IAAI,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAErB,iEAAiE;YACjE,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9B,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC;YAED,0CAA0C;YAC1C,MAAM,GAAG,GAAG,KAAK,IAAI,UAAU,KAAK,EAAE,CAAC;YAEvC,MAAM,CAAC,IAAI,CAAC;gBACV,GAAG;gBACH,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;gBACtC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW;gBACxD,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;aACzC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAA;AA1DY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,sBAAU,GAAE;GACA,mBAAmB,CA0D/B"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SystemInfoLinuxProvider = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const ExecTools_1 = require("../../helpers/ExecTools");
|
|
6
|
+
/** Gather system info on Linux via standard CLI tools. */
|
|
7
|
+
class SystemInfoLinuxProvider {
|
|
8
|
+
async isAvailable() {
|
|
9
|
+
return process.platform === "linux";
|
|
10
|
+
}
|
|
11
|
+
async getSystemInfo() {
|
|
12
|
+
return {
|
|
13
|
+
os: await this.getOsRelease(),
|
|
14
|
+
hostname: await this.getHostname(),
|
|
15
|
+
kernel: await execStr("uname -r"),
|
|
16
|
+
uptime: await execStr("uptime -p"),
|
|
17
|
+
disks: await this.getDiskInfo(),
|
|
18
|
+
logs: await this.getLogSizes(),
|
|
19
|
+
timeshift: (await this.getTimeshiftInfo()) ?? undefined,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
async getHostname() {
|
|
23
|
+
// 1. Read /etc/hostname directly (most reliable, no dependency on PATH)
|
|
24
|
+
try {
|
|
25
|
+
return (0, fs_1.readFileSync)("/etc/hostname", "utf8").trim();
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// file doesn't exist or can't be read
|
|
29
|
+
}
|
|
30
|
+
// 2. Fallback to hostnamectl --static (systemd)
|
|
31
|
+
const { stdout } = await ExecTools_1.ExecTools.safeExec("hostnamectl --static");
|
|
32
|
+
if (stdout.trim())
|
|
33
|
+
return stdout.trim();
|
|
34
|
+
// 3. Last resort: hostname command
|
|
35
|
+
return execStr("hostname");
|
|
36
|
+
}
|
|
37
|
+
async getOsRelease() {
|
|
38
|
+
const { stdout } = await ExecTools_1.ExecTools.safeExec("cat /etc/os-release");
|
|
39
|
+
const parse = (line) => {
|
|
40
|
+
const out = {};
|
|
41
|
+
for (const m of line.matchAll(/^(PRETTY_NAME|NAME|VERSION|ID)=\"([^\"]*)\"|^(PRETTY_NAME|NAME|VERSION|ID)=(\S+)/gm)) {
|
|
42
|
+
const key = (m[1] ?? m[3]).toUpperCase();
|
|
43
|
+
const value = m[2] ?? m[4];
|
|
44
|
+
out[key] = value;
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
};
|
|
48
|
+
const r = parse(stdout);
|
|
49
|
+
return {
|
|
50
|
+
name: r.PRETTY_NAME ?? r.NAME ?? "Unknown",
|
|
51
|
+
version: r.VERSION ?? "",
|
|
52
|
+
id: r.ID ?? "unknown",
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
async getDiskInfo() {
|
|
56
|
+
const { stdout } = await ExecTools_1.ExecTools.safeExec("df -BG --local -x tmpfs -x devtmpfs -x overlay -x efivarfs -x squashfs");
|
|
57
|
+
const disks = [];
|
|
58
|
+
const lines = stdout.trim().split("\n").slice(1);
|
|
59
|
+
const skipPrefixes = ["/boot", "/efi", "/var", "/tmp", "/snap", "/private", "/System"];
|
|
60
|
+
for (const line of lines) {
|
|
61
|
+
const parts = line.split(/\s+/);
|
|
62
|
+
if (parts.length >= 6) {
|
|
63
|
+
const mountPoint = parts[5];
|
|
64
|
+
if (skipPrefixes.some((prefix) => mountPoint === prefix || mountPoint.startsWith(prefix + "/")))
|
|
65
|
+
continue;
|
|
66
|
+
const total = parseInt(parts[1], 10);
|
|
67
|
+
const used = parseInt(parts[2], 10);
|
|
68
|
+
const available = parseInt(parts[3], 10);
|
|
69
|
+
const pct = parseInt(parts[4].replace("%", ""), 10);
|
|
70
|
+
disks.push({
|
|
71
|
+
device: parts[0],
|
|
72
|
+
mountPoint,
|
|
73
|
+
total: isNaN(total) ? 0 : total * 1024 * 1024 * 1024,
|
|
74
|
+
used: isNaN(used) ? 0 : used * 1024 * 1024 * 1024,
|
|
75
|
+
available: isNaN(available) ? 0 : available * 1024 * 1024 * 1024,
|
|
76
|
+
usePercent: isNaN(pct) ? 0 : pct,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return disks;
|
|
81
|
+
}
|
|
82
|
+
async getLogSizes() {
|
|
83
|
+
const paths = ["/var/log/kern.log", "/var/log/syslog"];
|
|
84
|
+
const results = [];
|
|
85
|
+
for (const p of paths) {
|
|
86
|
+
try {
|
|
87
|
+
const { stdout } = await ExecTools_1.ExecTools.safeExec(`stat --format="%s" "${p}" 2>/dev/null`);
|
|
88
|
+
const size = parseInt(stdout.trim(), 10);
|
|
89
|
+
results.push({ path: p, size: isNaN(size) ? 0 : size, exists: true });
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
results.push({ path: p, size: 0, exists: false });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return results;
|
|
96
|
+
}
|
|
97
|
+
async getTimeshiftInfo() {
|
|
98
|
+
// Check if timeshift is installed
|
|
99
|
+
const { stdout: whichOut } = await ExecTools_1.ExecTools.safeExec("which timeshift");
|
|
100
|
+
if (!whichOut.trim())
|
|
101
|
+
return null;
|
|
102
|
+
// Check sudo access
|
|
103
|
+
const hasSudoResult = await ExecTools_1.ExecTools.safeExecWithCode("sudo -n true");
|
|
104
|
+
if (hasSudoResult.exitCode !== 0)
|
|
105
|
+
return null;
|
|
106
|
+
// Read config
|
|
107
|
+
let config = {};
|
|
108
|
+
try {
|
|
109
|
+
const raw = (0, fs_1.readFileSync)("/etc/timeshift/timeshift.json", "utf8");
|
|
110
|
+
config = JSON.parse(raw);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
// Parse output of `sudo timeshift --list`
|
|
116
|
+
const { stdout } = await ExecTools_1.ExecTools.safeExec("sudo timeshift --list");
|
|
117
|
+
const lines = stdout.split("\n");
|
|
118
|
+
// Use /^\s*\w+\s*:/ pattern to find "Key : Value" lines (not "Mounted")
|
|
119
|
+
const findField = (name) => {
|
|
120
|
+
for (const line of lines) {
|
|
121
|
+
if (new RegExp(`^\\s*${name}\\s*:`, "i").test(line)) {
|
|
122
|
+
return line.split(":")[1].trim();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
};
|
|
127
|
+
const device = findField("Device") ?? "";
|
|
128
|
+
const mode = (findField("Mode") ?? "RSYNC");
|
|
129
|
+
// Parse free space: "3 snapshots, 2.8 TB free"
|
|
130
|
+
const freeMatch = stdout.match(/(\d+(?:\.\d+)?)\s+(TB|GB|MB)\s+free/);
|
|
131
|
+
const freeSpace = freeMatch ? this.parseSize(parseFloat(freeMatch[1]), freeMatch[2]) : 0;
|
|
132
|
+
// Parse snapshots
|
|
133
|
+
const snapshotMatch = stdout.match(/(\d+)\s+snapshots?/);
|
|
134
|
+
const snapshots = snapshotMatch ? parseInt(snapshotMatch[1], 10) : 0;
|
|
135
|
+
// Parse last snapshot name
|
|
136
|
+
const lastSnapshot = this.parseLastSnapshot(lines);
|
|
137
|
+
// Get total disk size from the backup device via df
|
|
138
|
+
const totalSpace = await this.getDiskTotalSpace(device);
|
|
139
|
+
// Parse schedules from config
|
|
140
|
+
const schedules = [];
|
|
141
|
+
if (config["schedule_weekly"] === "true")
|
|
142
|
+
schedules.push("weekly");
|
|
143
|
+
if (config["schedule_daily"] === "true")
|
|
144
|
+
schedules.push("daily");
|
|
145
|
+
if (config["schedule_monthly"] === "true")
|
|
146
|
+
schedules.push("monthly");
|
|
147
|
+
if (config["schedule_hourly"] === "true")
|
|
148
|
+
schedules.push("hourly");
|
|
149
|
+
if (config["schedule_boot"] === "true")
|
|
150
|
+
schedules.push("boot");
|
|
151
|
+
return { mode, device, snapshots, lastSnapshot, totalSpace, freeSpace, schedules };
|
|
152
|
+
}
|
|
153
|
+
async getDiskTotalSpace(device) {
|
|
154
|
+
if (!device)
|
|
155
|
+
return 0;
|
|
156
|
+
// blockdev works on unmounted devices (df does not)
|
|
157
|
+
const { stdout } = await ExecTools_1.ExecTools.safeExec(`sudo blockdev --getsize64 "${device}" 2>/dev/null`);
|
|
158
|
+
const bytes = parseInt(stdout.trim(), 10);
|
|
159
|
+
return isNaN(bytes) ? 0 : bytes;
|
|
160
|
+
}
|
|
161
|
+
parseSize(value, unit) {
|
|
162
|
+
switch (unit) {
|
|
163
|
+
case "TB":
|
|
164
|
+
return value * 1024 * 1024 * 1024 * 1024;
|
|
165
|
+
case "GB":
|
|
166
|
+
return value * 1024 * 1024 * 1024;
|
|
167
|
+
case "MB":
|
|
168
|
+
return value * 1024 * 1024;
|
|
169
|
+
default:
|
|
170
|
+
return value * 1024;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
parseLastSnapshot(lines) {
|
|
174
|
+
const snapshotLines = lines.filter((line) => /\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}/.test(line));
|
|
175
|
+
if (snapshotLines.length === 0)
|
|
176
|
+
return "";
|
|
177
|
+
const last = snapshotLines[snapshotLines.length - 1].trim();
|
|
178
|
+
const dateMatch = last.match(/(\d{4}-\d{2}-\d{2})_(\d{2})-(\d{2})-(\d{2})/);
|
|
179
|
+
// Convert "2026-08-09_12-00-02" → "2026-08-09T12:00:02" (ISO for Angular date pipe)
|
|
180
|
+
return dateMatch ? `${dateMatch[1]}T${dateMatch[2]}:${dateMatch[3]}:${dateMatch[4]}` : "";
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.SystemInfoLinuxProvider = SystemInfoLinuxProvider;
|
|
184
|
+
async function execStr(cmd) {
|
|
185
|
+
const { stdout } = await ExecTools_1.ExecTools.safeExec(cmd);
|
|
186
|
+
return stdout.trim();
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=systemInfoLinuxProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemInfoLinuxProvider.js","sourceRoot":"","sources":["../../../src/services/providers/systemInfoLinuxProvider.ts"],"names":[],"mappings":"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"}
|