initial
Some checks failed
CI / Type Check & Lint (push) Failing after 5s
CI / Build Test (Current Platform) (push) Failing after 5s
CI / Build All Platforms (push) Successful in 49s

This commit is contained in:
2026-01-30 03:16:57 +00:00
commit daaf6559e3
80 changed files with 14430 additions and 0 deletions

233
ts/hardware/system-info.ts Normal file
View File

@@ -0,0 +1,233 @@
/**
* System Info
*
* Gathers system information including CPU, RAM, OS, and Docker status.
*/
import { exec } from 'node:child_process';
import { promisify } from 'node:util';
import * as os from 'node:os';
import type { ISystemInfo } from '../interfaces/gpu.ts';
import { GpuDetector } from './gpu-detector.ts';
import { logger } from '../logger.ts';
const execAsync = promisify(exec);
/**
* System Info class for gathering system information
*/
export class SystemInfo {
private gpuDetector: GpuDetector;
constructor() {
this.gpuDetector = new GpuDetector();
}
/**
* Get complete system information
*/
public async getSystemInfo(): Promise<ISystemInfo> {
const [gpus, dockerVersion, nvidiaContainerVersion, kernelVersion] = await Promise.all([
this.gpuDetector.detectGpus(),
this.getDockerVersion(),
this.getNvidiaContainerVersion(),
this.getKernelVersion(),
]);
return {
hostname: os.hostname(),
cpuModel: this.getCpuModel(),
cpuCores: os.cpus().length,
ramTotal: Math.round(os.totalmem() / (1024 * 1024)),
ramAvailable: Math.round(os.freemem() / (1024 * 1024)),
os: this.getOsInfo(),
kernelVersion,
gpus,
dockerVersion,
nvidiaContainerVersion,
};
}
/**
* Get CPU model name
*/
private getCpuModel(): string {
const cpus = os.cpus();
if (cpus.length > 0) {
return cpus[0].model;
}
return 'Unknown CPU';
}
/**
* Get OS information string
*/
private getOsInfo(): string {
const platform = os.platform();
const release = os.release();
if (platform === 'linux') {
return `Linux ${release}`;
} else if (platform === 'darwin') {
return `macOS ${release}`;
}
return `${platform} ${release}`;
}
/**
* Get kernel version
*/
private async getKernelVersion(): Promise<string> {
try {
const { stdout } = await execAsync('uname -r', { timeout: 5000 });
return stdout.trim();
} catch {
return os.release();
}
}
/**
* Get Docker version
*/
private async getDockerVersion(): Promise<string | undefined> {
try {
const { stdout } = await execAsync('docker --version', { timeout: 5000 });
const match = stdout.match(/Docker version (\d+\.\d+\.\d+)/);
return match ? match[1] : stdout.trim();
} catch {
return undefined;
}
}
/**
* Get NVIDIA Container Toolkit version
*/
private async getNvidiaContainerVersion(): Promise<string | undefined> {
try {
const { stdout } = await execAsync('nvidia-container-cli --version 2>&1 | head -1', { timeout: 5000 });
const match = stdout.match(/version (\d+\.\d+\.\d+)/);
return match ? match[1] : undefined;
} catch {
return undefined;
}
}
/**
* Check if Docker is running
*/
public async isDockerRunning(): Promise<boolean> {
try {
await execAsync('docker info', { timeout: 5000 });
return true;
} catch {
return false;
}
}
/**
* Check if NVIDIA Docker runtime is available
*/
public async isNvidiaRuntimeAvailable(): Promise<boolean> {
try {
const { stdout } = await execAsync('docker info --format "{{.Runtimes}}"', { timeout: 5000 });
return stdout.includes('nvidia');
} catch {
return false;
}
}
/**
* Check if Podman is available
*/
public async isPodmanAvailable(): Promise<boolean> {
try {
await execAsync('podman --version', { timeout: 5000 });
return true;
} catch {
return false;
}
}
/**
* Get available disk space in the data directory
* @param path Directory to check
* @returns Available space in MB
*/
public async getAvailableDiskSpace(path: string = '/var/lib'): Promise<number> {
try {
const { stdout } = await execAsync(`df -m "${path}" | tail -1 | awk '{print $4}'`, { timeout: 5000 });
return parseInt(stdout.trim(), 10) || 0;
} catch {
return 0;
}
}
/**
* Get system memory usage
*/
public getMemoryUsage(): { total: number; used: number; available: number; percent: number } {
const total = Math.round(os.totalmem() / (1024 * 1024));
const available = Math.round(os.freemem() / (1024 * 1024));
const used = total - available;
const percent = Math.round((used / total) * 100);
return { total, used, available, percent };
}
/**
* Get system load average
*/
public getLoadAverage(): { load1: number; load5: number; load15: number } {
const [load1, load5, load15] = os.loadavg();
return {
load1: Math.round(load1 * 100) / 100,
load5: Math.round(load5 * 100) / 100,
load15: Math.round(load15 * 100) / 100,
};
}
/**
* Print system info summary to logger
*/
public async printSystemInfo(): Promise<void> {
const info = await this.getSystemInfo();
logger.logBoxTitle('System Information', 70, 'info');
logger.logBoxLine(`Hostname: ${info.hostname}`);
logger.logBoxLine(`OS: ${info.os}`);
logger.logBoxLine(`Kernel: ${info.kernelVersion}`);
logger.logBoxLine(`CPU: ${info.cpuModel} (${info.cpuCores} cores)`);
logger.logBoxLine(`RAM: ${Math.round(info.ramTotal / 1024)} GB total, ${Math.round(info.ramAvailable / 1024)} GB available`);
logger.logBoxLine('');
if (info.dockerVersion) {
logger.logBoxLine(`Docker: v${info.dockerVersion}`);
} else {
logger.logBoxLine('Docker: Not installed');
}
if (info.nvidiaContainerVersion) {
logger.logBoxLine(`NVIDIA Container Toolkit: v${info.nvidiaContainerVersion}`);
}
logger.logBoxLine('');
logger.logBoxLine(`GPUs Detected: ${info.gpus.length}`);
for (const gpu of info.gpus) {
const vramGb = Math.round(gpu.vram / 1024 * 10) / 10;
logger.logBoxLine(` ${gpu.id}: ${gpu.model} (${vramGb} GB)`);
if (gpu.driverVersion) {
logger.logBoxLine(` Driver: ${gpu.driverVersion}`);
}
if (gpu.cudaVersion) {
logger.logBoxLine(` CUDA: ${gpu.cudaVersion}`);
}
if (gpu.rocmVersion) {
logger.logBoxLine(` ROCm: ${gpu.rocmVersion}`);
}
}
logger.logBoxEnd();
}
}