From 1395130d6d82e43d34f1b5523ec843f369c6005f Mon Sep 17 00:00:00 2001 From: Logan Cusano Date: Sun, 3 Mar 2024 19:41:06 -0500 Subject: [PATCH] Starting to work on instal and update function #10 - Added a new self updater module that will update the git repo and restart the node service - Added a setup script that will install and setup both OP25 and the DRB node - Updated service names --- client/modules/selfUpdater.mjs | 39 ++++++ client/op25Handler/op25Handler.mjs | 6 +- client/serviceStart.sh | 1 + client/setup.sh | 198 +++++++++++++++++++++++++++++ 4 files changed, 241 insertions(+), 3 deletions(-) create mode 100644 client/modules/selfUpdater.mjs create mode 100644 client/serviceStart.sh create mode 100644 client/setup.sh diff --git a/client/modules/selfUpdater.mjs b/client/modules/selfUpdater.mjs new file mode 100644 index 0000000..7a84963 --- /dev/null +++ b/client/modules/selfUpdater.mjs @@ -0,0 +1,39 @@ +import simpleGit from 'simple-git'; +import { restartService } from './serviceHandler.mjs' + +const git = simpleGit(); + +// Function to check for updates +export const checkForUpdates = async () => { + try { + // Fetch remote changes + await git.fetch(); + + // Get the latest commit hash + const latestCommitHash = await git.revparse(['@{u}']); + + // Compare with the local commit hash + const localCommitHash = await git.revparse(['HEAD']); + + if (latestCommitHash !== localCommitHash) { + console.log('An update is available. Updating...'); + + // Pull the latest changes from the remote repository + await git.pull(); + + console.log('Update completed successfully. Restarting the application...'); + // Restart the application to apply the updates + restartApplication(); + } else { + console.log('The application is up to date.'); + } + } catch (error) { + console.error('Error checking for updates:', error); + } +} + +// Function to restart the application +const restartApplication = () => { + console.log('Restarting the application...'); + restartService('discord-radio-bot'); +} \ No newline at end of file diff --git a/client/op25Handler/op25Handler.mjs b/client/op25Handler/op25Handler.mjs index 07f51d9..f4c2e8b 100644 --- a/client/op25Handler/op25Handler.mjs +++ b/client/op25Handler/op25Handler.mjs @@ -40,8 +40,8 @@ const createConfigAndRestartService = async (systemName, preset) => { await generator.exportToFile(op25ConfigPath); // Restart the service - await stopService('op25'); - await startService('op25'); + await stopService('op25-multi_rx'); + await startService('op25-multi_rx'); }; /** @@ -72,7 +72,7 @@ export const openOP25 = async (systemName) => { */ export const closeOP25 = async () => { currentSystem = undefined; - await stopService('op25'); + await stopService('op25-multi_rx'); }; /** diff --git a/client/serviceStart.sh b/client/serviceStart.sh new file mode 100644 index 0000000..bf38fc4 --- /dev/null +++ b/client/serviceStart.sh @@ -0,0 +1 @@ +node . 2> stderr.2 \ No newline at end of file diff --git a/client/setup.sh b/client/setup.sh new file mode 100644 index 0000000..f1756fc --- /dev/null +++ b/client/setup.sh @@ -0,0 +1,198 @@ +#!/bin/bash + +####------------------- Pre-Flight Checks +# Exit on error +set -e + +# Check if the script is run as root +if [[ $(id -u) -ne 0 ]]; then + echo "Please run this script as root." + exit 1 +fi + +# Check if the working directory is 'client' and contains package.json +if [[ ! -f "$(pwd)/package.json" ]]; then + echo "Error: Please make sure the working directory is 'client' and contains package.json." + exit 1 +fi + +####------------------- Functions +# Function to prompt user for input with a specific message and store the result in a variable +prompt_user() { + read -p "$1: " input + echo "$input" +} + +# Function to prompt user for capabilities options and store the result in a variable +prompt_capabilities() { + options=("radio" "placeholder1" "placeholder2") # Add more options as needed + echo "Select the capabilities of this node (comma-separated):" + select option in "${options[@]}"; do + if [[ "$option" ]]; then + capabilities="$option" + break + else + echo "Invalid selection. Please try again." + fi + done + echo "$capabilities" +} + +# Function to prompt user for nearby systems details +prompt_nearby_system() { + local system_name="" + local frequencies="" + local mode="" + local trunk_file="" + local whitelist_file="" + + read -p "Enter system name: " system_name + read -p "Enter frequencies (comma-separated): " frequencies + read -p "Enter mode (p25/nbfm): " mode + + if [[ "$mode" == "p25" ]]; then + read -p "Enter trunk file: " trunk_file + read -p "Enter whitelist file: " whitelist_file + fi + + echo "\"$system_name\": { + \"frequencies\": [$(echo "$frequencies" | sed 's/,/","/g')], + \"mode\": \"$mode\", + \"trunkFile\": \"$trunk_file\", + \"whitelistFile\": \"$whitelist_file\" +}," +} + +####------------------- Initial Prereqs and init steps +# Update the system +echo "Updating system..." +apt update && apt upgrade -y + +# Install required dependencies: nodejs, ffmpeg +echo "Installing dependencies..." +apt install -y nodejs ffmpeg git + + +####------------------- Install and setup node +# Run npm install to install dependencies listed in package.json +echo "Installing npm dependencies..." +npm install + +# Generate .env file +echo "# Client Config" > .env +echo "CLIENT_NUID=0" >> .env +client_name=$(prompt_user "Enter the name for this node") +echo "CLIENT_NAME=$client_name" >> .env +client_location=$(prompt_user "Enter the location of this node") +echo "CLIENT_LOCATION=$client_location" >> .env +client_capabilities=$(prompt_capabilities) +echo "CLIENT_CAPABILITIES=$client_capabilities" >> .env + +# Server configuration (preset values) +echo "" >> .env +echo "# Configuration for the connection to the server" >> .env +echo "SERVER_IP=vpn.cusano.net" >> .env +echo "SERVER_PORT=3000" >> .env + +# OP25 configuration (preset values) +echo "" >> .env +echo "# Configuration for OP25" >> .env +op25_full_path="$(pwd)/op25/op25/gr-op25_repeater/apps" # Update this with the actual path +echo "OP25_FULL_PATH=$op25_full_path" >> .env + +# Core configuration (preset value) +echo "" >> .env +echo "# Core config, DO NOT TOUCH UNLESS YOU KNOW WHAT YOU ARE DOING" >> .env +echo "CONFIG_PATH=./config/radioPresets.json" >> .env + +echo ".env file generated successfully." + +# Create a JSON object to store nearby systems +systems_json="{" +while true; do + systems_json+="$(prompt_nearby_system)" + read -p "Do you want to add another system? (yes/no): " choice + if [[ "$choice" != "yes" ]]; then + break + fi +done +systems_json="${systems_json%,}" # Remove trailing comma +systems_json+="}" + +# Append the created systems to the presets file +echo "$systems_json" >> "./config/radioPresets.json" + +echo "Systems added to radioPresets.json." + +# Create a systemd service file +echo "Adding DRB Node service..." +service_content="[Unit] +Description=Discord-Radio-Bot_v3 +After=syslog.target network.target nss-lookup.target network-online.target +Requires=network-online.target + +[Service] +User=1000 +Group=1000 +WorkingDirectory=$(pwd) +ExecStart=/bin/bash -- serviceStart.sh +RestartSec=5 +Restart=on-failure + +[Install] +WantedBy=multi-user.target" + +# Write the systemd service file +echo "$service_content" > /etc/systemd/system/discord-radio-bot.service + +# Reload systemd daemon +systemctl daemon-reload +systemctl stop discord-radio-bot.service + +echo "Discord Client Node install completed!" + +####------------------- OP25 Installation +# Clone OP25 from the git repository +echo "Cloning OP25 from the git repository..." +git clone https://github.com/boatbod/op25.git + +# Navigate to the OP25 directory +cd op25 + +# Edit the startup script to use the active.cfg.json config file generated by the app +echo "Editing startup script..." +sed -i 's/p25_rtl_example.json/active.cfg.json/g' op25-multi_rx.sh + +# Move the startup script to the apps dir +mv op25-multi_rx.sh op25/gr-op25_repeater/apps/ + +# Install the OP25 service +echo "Adding OP25 service..." +service_content="[Unit] +Description=op25-multi_rx +After=syslog.target network.target nss-lookup.target network-online.target +Requires=network-online.target + +[Service] +User=1000 +Group=1000 +WorkingDirectory=$(pwd)/op25/gr-op25_repeater/apps +ExecStart=/bin/bash -- op25-multi_rx.sh +RestartSec=5 +Restart=on-failure + +[Install] +WantedBy=multi-user.target" + +# Write the systemd service file +echo "$service_content" > /etc/systemd/system/op25-multi_rx.service + +# Reload systemd daemon +systemctl daemon-reload +systemctl stop op25-multi_rx.service + +# Install OP25 using the provided installation script +echo "Installing OP25..." +./install.sh + +echo "OP25 installation completed!" \ No newline at end of file