feat(cli): Add initial MOXYTOOL implementation, packaging, install/uninstall scripts, CI and release workflows

This commit is contained in:
2025-10-27 11:27:44 +00:00
commit 71e283bcd5
23 changed files with 1932 additions and 0 deletions

8
ts/00_commitinfo_data.ts Normal file
View File

@@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@serve.zone/moxytool',
version: '1.1.0',
description: 'Proxmox administration tool for vGPU setup, VM management, and cluster configuration'
}

28
ts/index.ts Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env node
/**
* MOXYTOOL - Proxmox Administration Tool
* Node.js entry point for library usage
*/
import * as cli from './moxytool.cli.ts';
import { logger } from './moxytool.logging.ts';
import process from 'node:process';
/**
* Main entry point for MOXYTOOL
* Initializes the CLI and executes the given command
*/
async function main() {
await cli.runCli();
}
// Run the main function and handle any errors
main().catch((error) => {
logger.error(`Error: ${error}`);
process.exit(1);
});
// Export for library usage
export { logger };
export * from './moxytool.cli.ts';

112
ts/moxytool.cli.ts Normal file
View File

@@ -0,0 +1,112 @@
import * as plugins from './moxytool.plugins.ts';
import * as paths from './moxytool.paths.ts';
import { logger } from './moxytool.logging.ts';
export const runCli = async () => {
const smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash',
});
const smartcliInstance = new plugins.smartcli.Smartcli();
// Standard command (no arguments)
smartcliInstance.standardCommand().subscribe(async () => {
logger.log('info', 'MOXYTOOL - Proxmox Administration Tool');
logger.log('info', '');
logger.log('info', 'Available commands:');
logger.log('info', '* vgpu-setup - Install and configure Proxmox vGPU support');
logger.log('info', '');
logger.log('info', 'Usage: moxytool <command> [options]');
});
// vGPU setup command
smartcliInstance.addCommand('vgpu-setup').subscribe(async (argvArg) => {
logger.log('ok', 'Starting Proxmox vGPU setup process');
logger.log('info', 'This will install vGPU support for NVIDIA GPUs on Proxmox');
logger.log('info', '');
// Check for arguments
const step = argvArg.step;
const url = argvArg.url;
const file = argvArg.file;
const debug = argvArg.debug;
// Check if running on Proxmox
try {
const result = await smartshellInstance.exec('which pveversion');
if (result.exitCode !== 0) {
logger.log('error', 'This system does not appear to be running Proxmox');
logger.log('error', 'Please run this command on a Proxmox host');
Deno.exit(1);
}
} catch (e) {
logger.log('error', 'Failed to verify Proxmox installation');
logger.log('error', 'Please ensure you are running this on a Proxmox host');
Deno.exit(1);
}
// Create temporary directory
const tmpDir = '/tmp/moxytool-vgpu-setup';
await smartshellInstance.exec(`mkdir -p ${tmpDir}`);
try {
// Step 1: Clone and run the installer script
logger.log('info', 'Step 1: Downloading Proxmox vGPU installer (supports v9)...');
const cloneResult = await smartshellInstance.exec(
`cd ${tmpDir} && git clone https://github.com/anomixer/proxmox-vgpu-installer.git`,
);
if (cloneResult.exitCode !== 0) {
logger.log('error', 'Failed to clone the installer repository');
logger.log('error', cloneResult.stderr || 'Unknown error');
Deno.exit(1);
}
logger.log('ok', 'Installer downloaded successfully');
logger.log('info', '');
// Build command with arguments
let command = 'bash proxmox-installer.sh';
if (step) {
command += ` --step ${step}`;
}
if (url) {
command += ` --url ${url}`;
}
if (file) {
command += ` --file ${file}`;
}
if (debug) {
command += ' --debug';
}
logger.log('info', 'Running installer script...');
logger.log('info', 'Please follow the interactive prompts');
logger.log('info', '');
// Run the installer script interactively
const installResult = await smartshellInstance.exec(
`cd ${tmpDir}/proxmox-vgpu-installer && ${command}`,
);
if (installResult.exitCode !== 0) {
logger.log('error', 'Installer script failed');
logger.log('error', installResult.stderr || 'Unknown error');
Deno.exit(1);
}
logger.log('ok', 'vGPU setup process completed');
logger.log('info', '');
logger.log('info', 'Next steps:');
logger.log('info', '1. If prompted, reboot your system');
logger.log('info', '2. After reboot, run this command again to continue setup');
logger.log('info', '3. Verify installation with: mdevctl types');
logger.log('info', '4. Configure your VMs with vGPU in the Proxmox web UI');
} catch (error) {
logger.log('error', `Setup failed: ${error instanceof Error ? error.message : String(error)}`);
Deno.exit(1);
}
});
smartcliInstance.startParse();
};

57
ts/moxytool.logging.ts Normal file
View File

@@ -0,0 +1,57 @@
import * as plugins from './moxytool.plugins.ts';
/**
* A simple logger class for MOXYTOOL
*/
class Logger {
private static instance: Logger;
public static getInstance(): Logger {
if (!Logger.instance) {
Logger.instance = new Logger();
}
return Logger.instance;
}
public log(level: string, message: string): void {
const timestamp = new Date().toISOString();
switch (level) {
case 'error':
console.error(`[${timestamp}] [ERROR] ${message}`);
break;
case 'warn':
console.warn(`[${timestamp}] [WARN] ${message}`);
break;
case 'ok':
case 'success':
console.log(`[${timestamp}] [OK] ${message}`);
break;
case 'info':
default:
console.log(`[${timestamp}] [INFO] ${message}`);
break;
}
}
public error(message: string): void {
this.log('error', message);
}
public warn(message: string): void {
this.log('warn', message);
}
public info(message: string): void {
this.log('info', message);
}
public success(message: string): void {
this.log('success', message);
}
}
/**
* Logger instance for MOXYTOOL
*/
export const logger = Logger.getInstance();

21
ts/moxytool.paths.ts Normal file
View File

@@ -0,0 +1,21 @@
import * as plugins from './moxytool.plugins.ts';
/**
* Package directory path
*/
export const packageDir = plugins.path.dirname(plugins.path.dirname(import.meta.url));
/**
* Data directory for moxytool configurations
*/
export const dataDir = '/etc/moxytool';
/**
* Log directory
*/
export const logDir = plugins.path.join(dataDir, 'logs');
/**
* Temporary working directory
*/
export const tmpDir = plugins.path.join(dataDir, 'tmp');

29
ts/moxytool.plugins.ts Normal file
View File

@@ -0,0 +1,29 @@
// std library scope
import * as path from '@std/path';
export { path };
// @pushrocks scope
import * as npmextra from '@push.rocks/npmextra';
import * as projectinfo from '@push.rocks/projectinfo';
import * as smartcli from '@push.rocks/smartcli';
import * as smartdelay from '@push.rocks/smartdelay';
import * as smartfile from '@push.rocks/smartfile';
import * as smartjson from '@push.rocks/smartjson';
import * as smartlog from '@push.rocks/smartlog';
import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local';
import * as smartpath from '@push.rocks/smartpath';
import * as smartshell from '@push.rocks/smartshell';
export {
npmextra,
projectinfo,
smartcli,
smartdelay,
smartfile,
smartjson,
smartlog,
smartlogDestinationLocal,
smartpath,
smartshell,
};