Compare commits

...

10 Commits

10 changed files with 517 additions and 27 deletions

View File

@ -1,5 +1,38 @@
# Changelog # Changelog
## 2025-03-25 - 2.4.0 - feat(installer)
Add auto-yes flag to installer and update installation documentation
- Enhance install.sh to parse -y/--yes and -h/--help options, automating git installation when auto-yes is provided
- Improve user prompts for dependency installation and provide clearer instructions
- Update readme.md to document new installer options and enhanced file system and service changes details
## 2025-03-25 - 2.3.0 - feat(installer/cli)
Add OS detection and git auto-installation support to install.sh and improve service setup prompt in CLI
- Implemented helper functions in install.sh to detect OS type and automatically install git if missing
- Prompt user for git installation if not present before cloning the repository
- Enhanced CLI service setup flow to offer starting the NUPST service immediately after installation
## 2025-03-25 - 2.2.0 - feat(cli)
Add 'config' command to display current configuration and update CLI help
- Introduce new 'config' command to show SNMP settings, thresholds, and configuration file location
- Update help text to include details for 'nupst config' command
## 2025-03-25 - 2.1.0 - feat(cli)
Add uninstall command to CLI and update shutdown delay for graceful VM shutdown
- Implement uninstall command in ts/cli.ts that locates and executes uninstall.sh with user prompts
- Update uninstall.sh to support environment variables for configuration and repository removal
- Increase shutdown delay in ts/snmp/manager.ts from 1 minute to 5 minutes to allow VMs more time to shut down
## 2025-03-25 - 2.0.1 - fix(cli/systemd)
Fix status command to pass debug flag and improve systemd status logging output
- ts/cli.ts: Now extracts debug options from process arguments and passes debug mode to getStatus.
- ts/systemd.ts: Updated getStatus to accept a debugMode parameter, enabling detailed SNMP debug logging, explicitly reloading configuration, and printing connection details.
## 2025-03-25 - 2.0.0 - BREAKING CHANGE(snmp) ## 2025-03-25 - 2.0.0 - BREAKING CHANGE(snmp)
refactor: update SNMP type definitions and interface names for consistency refactor: update SNMP type definitions and interface names for consistency

View File

@ -2,7 +2,45 @@
# NUPST Installer Script # NUPST Installer Script
# Downloads and installs NUPST globally on the system # Downloads and installs NUPST globally on the system
# Can be used directly with curl: curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash # Can be used directly with curl:
# Without auto-installing dependencies:
# curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash
# With auto-installing dependencies:
# curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash -s -- -y
#
# Options:
# -y, --yes Automatically answer yes to all prompts
# -h, --help Show this help message
# Parse command line arguments
AUTO_YES=0
SHOW_HELP=0
for arg in "$@"; do
case $arg in
-y|--yes)
AUTO_YES=1
shift
;;
-h|--help)
SHOW_HELP=1
shift
;;
*)
# Unknown option
;;
esac
done
if [ $SHOW_HELP -eq 1 ]; then
echo "NUPST Installer Script"
echo "Usage: $0 [options]"
echo ""
echo "Options:"
echo " -y, --yes Automatically answer yes to all prompts"
echo " -h, --help Show this help message"
exit 0
fi
# Check if running as root # Check if running as root
if [ "$EUID" -ne 0 ]; then if [ "$EUID" -ne 0 ]; then
@ -17,6 +55,78 @@ if [ ! -t 0 ]; then
PIPED=1 PIPED=1
fi fi
# Helper function to detect OS type
detect_os() {
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
elif type lsb_release >/dev/null 2>&1; then
OS=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
elif [ -f /etc/lsb-release ]; then
. /etc/lsb-release
OS=$DISTRIB_ID
elif [ -f /etc/debian_version ]; then
OS="debian"
elif [ -f /etc/redhat-release ]; then
if grep -q "CentOS" /etc/redhat-release; then
OS="centos"
elif grep -q "Fedora" /etc/redhat-release; then
OS="fedora"
else
OS="rhel"
fi
else
OS=$(uname -s)
fi
echo $OS
}
# Helper function to install git
install_git() {
OS=$(detect_os)
echo "Detected OS: $OS"
case "$OS" in
ubuntu|debian|pop|mint|elementary|kali|zorin)
echo "Installing git using apt..."
apt-get update && apt-get install -y git
;;
fedora|rhel|centos|almalinux|rocky)
echo "Installing git using dnf/yum..."
if command -v dnf &> /dev/null; then
dnf install -y git
else
yum install -y git
fi
;;
arch|manjaro|endeavouros|garuda)
echo "Installing git using pacman..."
pacman -Sy --noconfirm git
;;
opensuse*|suse|sles)
echo "Installing git using zypper..."
zypper install -y git
;;
alpine)
echo "Installing git using apk..."
apk add git
;;
*)
echo "Unsupported OS: $OS"
echo "Please install git manually and run the installer again."
exit 1
;;
esac
# Check if git was installed successfully
if ! command -v git &> /dev/null; then
echo "Failed to install git. Please install git manually and run the installer again."
exit 1
fi
echo "Git installed successfully."
}
# Define installation directory # Define installation directory
INSTALL_DIR="/opt/nupst" INSTALL_DIR="/opt/nupst"
REPO_URL="https://code.foss.global/serve.zone/nupst.git" REPO_URL="https://code.foss.global/serve.zone/nupst.git"
@ -26,8 +136,23 @@ if [ $PIPED -eq 1 ]; then
# Check if git is installed # Check if git is installed
if ! command -v git &> /dev/null; then if ! command -v git &> /dev/null; then
echo "Git is required but not installed. Please install git first." echo "Git is required but not installed."
exit 1
if [ $AUTO_YES -eq 1 ]; then
echo "Auto-installing git (-y flag provided)..."
install_git
else
read -p "Would you like to install git now? (y/N): " install_git_prompt
if [[ "$install_git_prompt" =~ ^[Yy]$ ]]; then
install_git
else
echo "Git installation skipped. Please install git manually and run the installer again."
echo "Alternatively, you can run the installer with -y flag to automatically install git:"
echo " sudo bash install.sh -y"
exit 1
fi
fi
fi fi
# Check if installation directory exists # Check if installation directory exists

21
license Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Task Venture Capital GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,6 +1,6 @@
{ {
"name": "@serve.zone/nupst", "name": "@serve.zone/nupst",
"version": "2.0.0", "version": "2.4.0",
"description": "Node.js UPS Shutdown Tool for SNMP-enabled UPS devices", "description": "Node.js UPS Shutdown Tool for SNMP-enabled UPS devices",
"main": "dist/index.js", "main": "dist/index.js",
"bin": { "bin": {

View File

@ -21,6 +21,9 @@ NUPST is a command-line tool that monitors SNMP-enabled UPS devices and initiate
```bash ```bash
# Install directly without cloning the repository (requires root privileges) # Install directly without cloning the repository (requires root privileges)
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash
# Install with auto-yes for dependencies (will install git automatically if needed)
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash -s -- -y
``` ```
### Direct from Git ### Direct from Git
@ -33,20 +36,58 @@ cd nupst
# Option 1: Quick install (requires root privileges) # Option 1: Quick install (requires root privileges)
sudo ./install.sh sudo ./install.sh
# Option 1a: Quick install with auto-yes for dependencies
sudo ./install.sh -y
# Option 2: Manual setup # Option 2: Manual setup
./setup.sh ./setup.sh
sudo ln -s $(pwd)/bin/nupst /usr/local/bin/nupst sudo ln -s $(pwd)/bin/nupst /usr/local/bin/nupst
``` ```
### Installation Options
The installer script (`install.sh`) supports the following options:
```
-y, --yes Automatically answer yes to all prompts (like installing git)
-h, --help Show the help message
```
### From NPM ### From NPM
```bash ```bash
npm install -g @serve.zone/nupst npm install -g @serve.zone/nupst
``` ```
## System Changes
When installed, NUPST makes the following changes to your system:
### File System Changes
| Path | Description |
|------|-------------|
| `/opt/nupst/` | Main installation directory containing the NUPST files |
| `/etc/nupst/config.json` | Configuration file |
| `/usr/local/bin/nupst` | Symlink to the NUPST executable |
| `/etc/systemd/system/nupst.service` | Systemd service file (when enabled) |
### Service Changes
- Creates and enables a systemd service called `nupst.service` (when enabled with `nupst enable`)
- The service runs with root permissions to allow system shutdown capabilities
### Network Access
- NUPST only communicates with your UPS device via SNMP (default port 161)
- Brief connections to npmjs.org to check for updates
## Uninstallation ## Uninstallation
```bash ```bash
# Using the CLI tool:
sudo nupst uninstall
# If installed from git repository: # If installed from git repository:
cd /path/to/nupst cd /path/to/nupst
sudo ./uninstall.sh sudo ./uninstall.sh
@ -57,9 +98,10 @@ npm uninstall -g @serve.zone/nupst
The uninstaller will: The uninstaller will:
- Stop and disable the systemd service (if installed) - Stop and disable the systemd service (if installed)
- Remove the systemd service file - Remove the systemd service file from `/etc/systemd/system/nupst.service`
- Remove the symlink from /usr/local/bin - Remove the symlink from `/usr/local/bin/nupst`
- Optionally remove configuration files from /etc/nupst - Optionally remove configuration files from `/etc/nupst/`
- Remove the repository directory from `/opt/nupst/` (when using `nupst uninstall`)
## Usage ## Usage
@ -76,7 +118,9 @@ Usage:
nupst status - Show status of the systemd service and UPS status nupst status - Show status of the systemd service and UPS status
nupst setup - Run the interactive setup to configure SNMP settings nupst setup - Run the interactive setup to configure SNMP settings
nupst test - Test the current configuration by connecting to the UPS nupst test - Test the current configuration by connecting to the UPS
nupst config - Display the current configuration
nupst update - Update NUPST from repository and refresh systemd service (requires root) 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 nupst help - Show this help message
Options: Options:

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@serve.zone/nupst', name: '@serve.zone/nupst',
version: '2.0.0', version: '2.4.0',
description: 'Node.js UPS Shutdown Tool for SNMP-enabled UPS devices' description: 'Node.js UPS Shutdown Tool for SNMP-enabled UPS devices'
} }

217
ts/cli.ts
View File

@ -1,4 +1,7 @@
import { execSync } from 'child_process'; 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'; import { Nupst } from './nupst.js';
/** /**
@ -94,6 +97,14 @@ export class NupstCli {
case 'update': case 'update':
await this.update(); await this.update();
break; break;
case 'uninstall':
await this.uninstall();
break;
case 'config':
await this.showConfig();
break;
case 'help': case 'help':
default: default:
@ -182,7 +193,9 @@ export class NupstCli {
* Show status of the systemd service and UPS * Show status of the systemd service and UPS
*/ */
private async status(): Promise<void> { private async status(): Promise<void> {
await this.nupst.getSystemd().getStatus(); // Extract debug options from args array
const debugOptions = this.extractDebugOptions(process.argv);
await this.nupst.getSystemd().getStatus(debugOptions.debugMode);
} }
/** /**
@ -363,7 +376,9 @@ Usage:
nupst status - Show status of the systemd service and UPS status nupst status - Show status of the systemd service and UPS status
nupst setup - Run the interactive setup to configure SNMP settings nupst setup - Run the interactive setup to configure SNMP settings
nupst test - Test the current configuration by connecting to the UPS nupst test - Test the current configuration by connecting to the UPS
nupst config - Display the current configuration
nupst update - Update NUPST from repository and refresh systemd service (requires root) 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 nupst help - Show this help message
Options: Options:
@ -819,7 +834,7 @@ Options:
} }
/** /**
* Optionally enable systemd service * Optionally enable and start systemd service
* @param prompt Function to prompt for user input * @param prompt Function to prompt for user input
*/ */
private async optionallyEnableService(prompt: (question: string) => Promise<string>): Promise<void> { private async optionallyEnableService(prompt: (question: string) => Promise<string>): Promise<void> {
@ -828,9 +843,203 @@ Options:
} else { } else {
const setupService = await prompt('Would you like to enable NUPST as a system service? (y/N): '); const setupService = await prompt('Would you like to enable NUPST as a system service? (y/N): ');
if (setupService.toLowerCase() === 'y') { if (setupService.toLowerCase() === 'y') {
await this.nupst.getSystemd().install(); try {
console.log('Service installed. Use "nupst start" to start the service.'); await this.nupst.getSystemd().install();
console.log('Service installed and enabled to start on boot.');
// Ask if the user wants to start the service now
const startService = await prompt('Would you like to start the NUPST service now? (Y/n): ');
if (startService.toLowerCase() !== 'n') {
await this.nupst.getSystemd().start();
console.log('NUPST service started successfully.');
} else {
console.log('Service not started. Use "nupst start" to start the service manually.');
}
} catch (error) {
console.error(`Failed to setup service: ${error.message}`);
}
} }
} }
} }
/**
* Display the current configuration
*/
private async showConfig(): Promise<void> {
try {
// Try to load configuration
try {
await this.nupst.getDaemon().loadConfig();
} catch (error) {
console.error('┌─ Configuration Error ─────────────────────┐');
console.error('│ No configuration found.');
console.error('│ Please run \'nupst setup\' first to create a configuration.');
console.error('└──────────────────────────────────────────┘');
return;
}
// Get current configuration
const config = this.nupst.getDaemon().getConfig();
console.log('┌─ NUPST Configuration ──────────────────────┐');
// SNMP Settings
console.log('│ SNMP Settings:');
console.log(`│ Host: ${config.snmp.host}`);
console.log(`│ Port: ${config.snmp.port}`);
console.log(`│ Version: ${config.snmp.version}`);
console.log(`│ UPS Model: ${config.snmp.upsModel || 'cyberpower'}`);
if (config.snmp.version === 1 || config.snmp.version === 2) {
console.log(`│ Community: ${config.snmp.community}`);
} else if (config.snmp.version === 3) {
console.log(`│ Security Level: ${config.snmp.securityLevel}`);
console.log(`│ Username: ${config.snmp.username}`);
// Show auth and privacy details based on security level
if (config.snmp.securityLevel === 'authNoPriv' || config.snmp.securityLevel === 'authPriv') {
console.log(`│ Auth Protocol: ${config.snmp.authProtocol || 'None'}`);
}
if (config.snmp.securityLevel === 'authPriv') {
console.log(`│ Privacy Protocol: ${config.snmp.privProtocol || 'None'}`);
}
// Show timeout value
console.log(`│ Timeout: ${config.snmp.timeout / 1000} seconds`);
}
// Show OIDs if custom model is selected
if (config.snmp.upsModel === 'custom' && config.snmp.customOIDs) {
console.log('│ Custom OIDs:');
console.log(`│ Power Status: ${config.snmp.customOIDs.POWER_STATUS || 'Not set'}`);
console.log(`│ Battery Capacity: ${config.snmp.customOIDs.BATTERY_CAPACITY || 'Not set'}`);
console.log(`│ Battery Runtime: ${config.snmp.customOIDs.BATTERY_RUNTIME || 'Not set'}`);
}
// Thresholds
console.log('│ Thresholds:');
console.log(`│ Battery: ${config.thresholds.battery}%`);
console.log(`│ Runtime: ${config.thresholds.runtime} minutes`);
console.log(`│ Check Interval: ${config.checkInterval / 1000} seconds`);
// Configuration file location
console.log('│');
console.log('│ Configuration File Location:');
console.log('│ /etc/nupst/config.json');
console.log('└──────────────────────────────────────────┘');
// Show service status
try {
const isActive = execSync('systemctl is-active nupst.service || true').toString().trim() === 'active';
const isEnabled = execSync('systemctl is-enabled nupst.service || true').toString().trim() === 'enabled';
console.log('┌─ Service Status ─────────────────────────┐');
console.log(`│ Service Active: ${isActive ? 'Yes' : 'No'}`);
console.log(`│ Service Enabled: ${isEnabled ? 'Yes' : 'No'}`);
console.log('└──────────────────────────────────────────┘');
} catch (error) {
// Ignore errors checking service status
}
} catch (error) {
console.error(`Failed to display configuration: ${error.message}`);
}
}
/**
* 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);
}
}
} }

View File

@ -514,9 +514,10 @@ export class NupstSnmp {
public async initiateShutdown(reason: string): Promise<void> { public async initiateShutdown(reason: string): Promise<void> {
console.log(`Initiating system shutdown due to: ${reason}`); console.log(`Initiating system shutdown due to: ${reason}`);
try { try {
// Execute shutdown command // Execute shutdown command with 5 minute delay to allow for VM graceful shutdown
const { stdout } = await execAsync('shutdown -h +1 "UPS battery critical, shutting down in 1 minute"'); const { stdout } = await execAsync('shutdown -h +5 "UPS battery critical, shutting down in 5 minutes"');
console.log('Shutdown initiated:', stdout); console.log('Shutdown initiated:', stdout);
console.log('Allowing 5 minutes for VMs to shut down safely');
} catch (error) { } catch (error) {
console.error('Failed to initiate shutdown:', error); console.error('Failed to initiate shutdown:', error);
// Try a different method if first one fails // Try a different method if first one fails

View File

@ -126,9 +126,18 @@ WantedBy=multi-user.target
/** /**
* Get status of the systemd service and UPS * Get status of the systemd service and UPS
* @param debugMode Whether to enable debug mode for SNMP
*/ */
public async getStatus(): Promise<void> { public async getStatus(debugMode: boolean = false): Promise<void> {
try { try {
// Enable debug mode if requested
if (debugMode) {
console.log('┌─ Debug Mode ─────────────────────────────┐');
console.log('│ SNMP debugging enabled - detailed logs will be shown');
console.log('└──────────────────────────────────────────┘');
this.daemon.getNupstSnmp().enableDebug();
}
// Display version information // Display version information
this.daemon.getNupstSnmp().getNupst().logVersionInfo(); this.daemon.getNupstSnmp().getNupst().logVersionInfo();
@ -170,6 +179,8 @@ WantedBy=multi-user.target
*/ */
private async displayUpsStatus(): Promise<void> { private async displayUpsStatus(): Promise<void> {
try { try {
// Explicitly load the configuration first to ensure it's up-to-date
await this.daemon.loadConfig();
const config = this.daemon.getConfig(); const config = this.daemon.getConfig();
const snmp = this.daemon.getNupstSnmp(); const snmp = this.daemon.getNupstSnmp();
@ -179,6 +190,11 @@ WantedBy=multi-user.target
timeout: Math.min(config.snmp.timeout, 10000) // Use at most 10 seconds for status check timeout: Math.min(config.snmp.timeout, 10000) // Use at most 10 seconds for status check
}; };
console.log('┌─ Connecting to UPS... ────────────────────┐');
console.log(`│ Host: ${config.snmp.host}:${config.snmp.port}`);
console.log(`│ UPS Model: ${config.snmp.upsModel || 'cyberpower'}`);
console.log('└──────────────────────────────────────────┘');
const status = await snmp.getUpsStatus(snmpConfig); const status = await snmp.getUpsStatus(snmpConfig);
console.log('┌─ UPS Status ───────────────────────────────┐'); console.log('┌─ UPS Status ───────────────────────────────┐');

View File

@ -5,13 +5,22 @@
# Check if running as root # Check if running as root
if [ "$EUID" -ne 0 ]; then if [ "$EUID" -ne 0 ]; then
echo "Please run as root (sudo ./uninstall.sh)" echo "Please run as root (sudo nupst uninstall or sudo ./uninstall.sh)"
exit 1 exit 1
fi fi
# This script can be called directly or through the CLI
# When called through the CLI, environment variables are set
# REMOVE_CONFIG=yes|no - whether to remove configuration files
# REMOVE_REPO=yes|no - whether to remove the repository
# If not set through CLI, use defaults
REMOVE_CONFIG=${REMOVE_CONFIG:-"no"}
REMOVE_REPO=${REMOVE_REPO:-"no"}
echo "NUPST Uninstaller" echo "NUPST Uninstaller"
echo "=================" echo "================="
echo "This script will completely remove NUPST from your system." echo "This will completely remove NUPST from your system."
# Find the directory where this script is located # Find the directory where this script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
@ -37,20 +46,52 @@ if [ -L "/usr/local/bin/nupst" ]; then
rm -f /usr/local/bin/nupst rm -f /usr/local/bin/nupst
fi fi
# Step 3: Ask about removing configuration # Step 3: Remove configuration if requested
read -p "Do you want to remove the NUPST configuration files? (y/N) " -n 1 -r if [ "$REMOVE_CONFIG" = "yes" ]; then
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Removing configuration files..." echo "Removing configuration files..."
rm -rf /etc/nupst rm -rf /etc/nupst
else
# If not called through CLI, ask user
if [ -z "$NUPST_CLI_CALL" ]; then
read -p "Do you want to remove the NUPST configuration files? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Removing configuration files..."
rm -rf /etc/nupst
fi
fi
fi fi
# Step 4: Check if this was a git installation # Step 4: Remove repository if requested
if [ -d "$SCRIPT_DIR/.git" ]; then if [ "$REMOVE_REPO" = "yes" ]; then
echo if [ -d "$SCRIPT_DIR/.git" ]; then
echo "This appears to be a git installation. The local repository will remain intact." echo "Removing NUPST repository directory..."
echo "If you wish to completely remove it, you can delete the directory:"
echo " rm -rf $SCRIPT_DIR" # Get parent directory to remove it after the script exits
PARENT_DIR=$(dirname "$SCRIPT_DIR")
REPO_NAME=$(basename "$SCRIPT_DIR")
# Create a temporary cleanup script
CLEANUP_SCRIPT=$(mktemp)
echo "#!/bin/bash" > "$CLEANUP_SCRIPT"
echo "sleep 1" >> "$CLEANUP_SCRIPT"
echo "rm -rf \"$SCRIPT_DIR\"" >> "$CLEANUP_SCRIPT"
echo "echo \"NUPST repository has been removed.\"" >> "$CLEANUP_SCRIPT"
chmod +x "$CLEANUP_SCRIPT"
# Run the cleanup script in the background
nohup "$CLEANUP_SCRIPT" > /dev/null 2>&1 &
echo "NUPST repository will be removed after uninstaller exits."
else
echo "No git repository found."
fi
else
# If not requested, just display info
if [ -d "$SCRIPT_DIR/.git" ]; then
echo
echo "NUPST repository at $SCRIPT_DIR will remain intact."
fi
fi fi
# Check for npm global installation # Check for npm global installation