feat(cli): Add uninstall command to CLI and update shutdown delay for graceful VM shutdown
This commit is contained in:
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/nupst',
|
||||
version: '2.0.1',
|
||||
version: '2.1.0',
|
||||
description: 'Node.js UPS Shutdown Tool for SNMP-enabled UPS devices'
|
||||
}
|
||||
|
103
ts/cli.ts
103
ts/cli.ts
@ -1,4 +1,7 @@
|
||||
import { execSync } from 'child_process';
|
||||
import { promises as fs } from 'fs';
|
||||
import { dirname, join } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { Nupst } from './nupst.js';
|
||||
|
||||
/**
|
||||
@ -94,6 +97,10 @@ export class NupstCli {
|
||||
case 'update':
|
||||
await this.update();
|
||||
break;
|
||||
|
||||
case 'uninstall':
|
||||
await this.uninstall();
|
||||
break;
|
||||
|
||||
case 'help':
|
||||
default:
|
||||
@ -366,6 +373,7 @@ Usage:
|
||||
nupst setup - Run the interactive setup to configure SNMP settings
|
||||
nupst test - Test the current configuration by connecting to the UPS
|
||||
nupst update - Update NUPST from repository and refresh systemd service (requires root)
|
||||
nupst uninstall - Completely uninstall NUPST from the system (requires root)
|
||||
nupst help - Show this help message
|
||||
|
||||
Options:
|
||||
@ -835,4 +843,99 @@ Options:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely uninstall NUPST from the system
|
||||
*/
|
||||
private async uninstall(): Promise<void> {
|
||||
// Check if running as root
|
||||
this.checkRootAccess('This command must be run as root.');
|
||||
|
||||
try {
|
||||
// Import readline module for user input
|
||||
const readline = await import('readline');
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
// Helper function to prompt for input
|
||||
const prompt = (question: string): Promise<string> => {
|
||||
return new Promise((resolve) => {
|
||||
rl.question(question, (answer: string) => {
|
||||
resolve(answer);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
console.log('\nNUPST Uninstaller');
|
||||
console.log('===============');
|
||||
console.log('This will completely remove NUPST from your system.\n');
|
||||
|
||||
// Ask about removing configuration
|
||||
const removeConfig = await prompt('Do you want to remove the NUPST configuration files? (y/N): ');
|
||||
|
||||
// Find the uninstall.sh script location
|
||||
let uninstallScriptPath: string;
|
||||
|
||||
// Try to determine script location based on executable path
|
||||
try {
|
||||
// For ESM, we can use import.meta.url, but since we might be in CJS
|
||||
// we'll use a more reliable approach based on process.argv[1]
|
||||
const binPath = process.argv[1];
|
||||
const modulePath = dirname(dirname(binPath));
|
||||
uninstallScriptPath = join(modulePath, 'uninstall.sh');
|
||||
|
||||
// Check if the script exists
|
||||
await fs.access(uninstallScriptPath);
|
||||
} catch (error) {
|
||||
// If we can't find it in the expected location, try common installation paths
|
||||
const commonPaths = [
|
||||
'/opt/nupst/uninstall.sh',
|
||||
join(process.cwd(), 'uninstall.sh')
|
||||
];
|
||||
|
||||
for (const path of commonPaths) {
|
||||
try {
|
||||
await fs.access(path);
|
||||
uninstallScriptPath = path;
|
||||
break;
|
||||
} catch {
|
||||
// Continue to next path
|
||||
}
|
||||
}
|
||||
|
||||
if (!uninstallScriptPath) {
|
||||
console.error('Could not locate uninstall.sh script. Aborting uninstall.');
|
||||
rl.close();
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Close readline before executing script
|
||||
rl.close();
|
||||
|
||||
// Execute uninstall.sh with the appropriate option
|
||||
console.log(`\nRunning uninstaller from ${uninstallScriptPath}...`);
|
||||
|
||||
// Pass the configuration removal option as an environment variable
|
||||
const env = {
|
||||
...process.env,
|
||||
REMOVE_CONFIG: removeConfig.toLowerCase() === 'y' ? 'yes' : 'no',
|
||||
REMOVE_REPO: 'yes', // Always remove repo as requested
|
||||
NUPST_CLI_CALL: 'true' // Flag to indicate this is being called from CLI
|
||||
};
|
||||
|
||||
// Run the uninstall script with sudo
|
||||
execSync(`sudo bash ${uninstallScriptPath}`, {
|
||||
env,
|
||||
stdio: 'inherit' // Show output in the terminal
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error(`Uninstall failed: ${error.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
@ -514,9 +514,10 @@ export class NupstSnmp {
|
||||
public async initiateShutdown(reason: string): Promise<void> {
|
||||
console.log(`Initiating system shutdown due to: ${reason}`);
|
||||
try {
|
||||
// Execute shutdown command
|
||||
const { stdout } = await execAsync('shutdown -h +1 "UPS battery critical, shutting down in 1 minute"');
|
||||
// Execute shutdown command with 5 minute delay to allow for VM graceful shutdown
|
||||
const { stdout } = await execAsync('shutdown -h +5 "UPS battery critical, shutting down in 5 minutes"');
|
||||
console.log('Shutdown initiated:', stdout);
|
||||
console.log('Allowing 5 minutes for VMs to shut down safely');
|
||||
} catch (error) {
|
||||
console.error('Failed to initiate shutdown:', error);
|
||||
// Try a different method if first one fails
|
||||
|
Reference in New Issue
Block a user