]> Monitor and control your Unraid system via REST API, WebSocket, MCP, Prometheus, and MQTT. Supports Docker/VM control, real-time metrics, Home Assistant integration, and AI agent tooling. See CHANGELOG.md for full release notes and change history: https://github.com/tinkerologie/unraid-management-agent/blob/main/CHANGELOG.md &bundleURL; &md5; &sha256; /dev/null | sort -V | tail -n 1) if [ -z "$BUNDLE" ]; then echo "✗ Error: No plugin bundle found in ${CONFIG_DIR}" exit 1 fi # Extract version from bundle filename (e.g., unraid-management-agent-2025.11.2.tgz -> 2025.11.2) VERSION=$(basename "$BUNDLE" .tgz | sed "s/${PLUGIN_NAME}-//") echo "" echo "=========================================" echo " Installing ${PLUGIN_NAME}" echo " Version: ${VERSION}" echo "=========================================" echo "" # Check if service is running running=$(pidof ${PLUGIN_NAME} | wc -w) # Stop service if running if [ $running -ge 1 ]; then echo "Stopping existing service..." killall ${PLUGIN_NAME} 2>/dev/null sleep 2 fi # Remove old plugin files echo "Removing old plugin files..." rm -rf ${INSTALL_DIR}/* 2>/dev/null mkdir -p ${INSTALL_DIR} # Remove old bundle files (keep current version) echo "Cleaning up old bundles..." rm -f $(ls ${CONFIG_DIR}/${PLUGIN_NAME}*.tgz 2>/dev/null | grep -v "${VERSION}.tgz") # Extract the bundle echo "Extracting plugin bundle..." if [ -f "${BUNDLE}" ]; then # Never take owners from the archive or rewrite existing system directories (#242) tar --no-same-owner --no-overwrite-dir -xzf "${BUNDLE}" -C / 2>&1 TAR_EXIT=$? if [ $TAR_EXIT -eq 0 ]; then echo "✓ Bundle extracted successfully" else echo "✗ Failed to extract bundle (exit code: $TAR_EXIT)" exit 1 fi else echo "✗ Bundle not found: ${BUNDLE}" exit 1 fi # Restore root ownership that earlier bundles set on shared directories (#242) for DIR in /usr /usr/local /usr/local/emhttp /usr/local/emhttp/plugins "${INSTALL_DIR}"; do if [ -d "$DIR" ] && [ "$(stat -c '%u:%g' "$DIR")" != "0:0" ]; then if chown root:root "$DIR"; then echo "✓ Restored root ownership of ${DIR}" else echo "⚠ Could not restore root ownership of ${DIR}" fi fi done # Set executable permissions echo "Setting permissions..." chmod +x ${INSTALL_DIR}/${PLUGIN_NAME} 2>/dev/null chmod +x ${INSTALL_DIR}/scripts/* 2>/dev/null chmod +x ${INSTALL_DIR}/event/* 2>/dev/null # Verify installation if [ -f "${INSTALL_DIR}/${PLUGIN_NAME}" ]; then echo "✓ Binary installed" else echo "✗ Binary not found after installation" exit 1 fi # Keep network write access for existing installs without an API token (#245). # A failure leaves the install on the secure default, so it does not abort. # The marker is set only when the migration succeeds (it exits 0 for fresh # installs too), so a failed migration is retried on the next upgrade. if "${INSTALL_DIR}/scripts/migrate-secure-defaults"; then touch "${CONFIG_DIR}/.secure-defaults-migrated" else echo "⚠ Secure-defaults migration failed; set an API token to re-enable control actions" fi # Switch hardware-dependent collectors left on a shipped default to "auto" (#261). # The marker is set only on success, so a failed migration is retried. if "${INSTALL_DIR}/scripts/migrate-auto-intervals"; then touch "${CONFIG_DIR}/.auto-intervals-migrated" else echo "⚠ Auto-interval migration failed; hardware collectors keep their saved intervals" fi # Move existing installs whose intervals are all shipped defaults to dynamic # collection; tuned installs stay on manual (#280). Runs after the auto-interval # migration so its "auto" values count as defaults. The marker is set only on # success (the script exits 0 for fresh installs too), so a failure is retried. if "${INSTALL_DIR}/scripts/migrate-collection-mode"; then touch "${CONFIG_DIR}/.collection-mode-migrated" else echo "⚠ Collection-mode migration failed; the agent keeps using the manual intervals" fi # Start service if it was running before, or if this is a fresh install if [ $running -ge 1 ] || [ ! -f "${CONFIG_DIR}/.installed" ]; then echo "Starting service..." ${INSTALL_DIR}/scripts/start sleep 2 # Verify service started if pidof ${PLUGIN_NAME} > /dev/null; then echo "✓ Service started successfully" else echo "⚠ Service may not have started. Check logs: /var/log/${PLUGIN_NAME}.log" fi fi # Mark as installed touch ${CONFIG_DIR}/.installed echo "" echo "=========================================" echo " ${PLUGIN_NAME} v${VERSION}" echo " Installation Complete!" echo "=========================================" echo "" echo "API Server: http://localhost:8043" echo "Configuration: ${CONFIG_DIR}/config.cfg" echo "Logs: /var/log/${PLUGIN_NAME}.log" echo "" echo "For documentation and support:" echo " https://github.com/tinkerologie/unraid-management-agent" echo "" ]]> /dev/null | sort -V | tail -n 1) if [ -n "$BUNDLE" ]; then VERSION=$(basename "$BUNDLE" .tgz | sed "s/${PLUGIN_NAME}-//") else VERSION="unknown" fi echo "" echo "=========================================" echo " Removing ${PLUGIN_NAME}" echo " Version: ${VERSION}" echo "=========================================" echo "" # Stop the service echo "Stopping service..." if [ -f "${INSTALL_DIR}/scripts/stop" ]; then ${INSTALL_DIR}/scripts/stop else killall ${PLUGIN_NAME} 2>/dev/null fi sleep 2 # Verify service stopped if pidof ${PLUGIN_NAME} > /dev/null; then echo "Force stopping service..." killall -9 ${PLUGIN_NAME} 2>/dev/null sleep 1 fi # Final verification if pidof ${PLUGIN_NAME} > /dev/null; then echo "✗ Warning: Service may still be running" else echo "✓ Service stopped" fi echo "" echo "Removing all plugin files and data..." echo "" # Remove plugin installation directory if [ -d "${INSTALL_DIR}" ]; then rm -rf ${INSTALL_DIR} if [ $? -eq 0 ]; then echo "✓ Removed plugin directory: ${INSTALL_DIR}" else echo "✗ Failed to remove: ${INSTALL_DIR}" fi else echo " Plugin directory not found (already removed)" fi # Remove configuration directory if [ -d "${CONFIG_DIR}" ]; then rm -rf ${CONFIG_DIR} if [ $? -eq 0 ]; then echo "✓ Removed configuration directory: ${CONFIG_DIR}" else echo "✗ Failed to remove: ${CONFIG_DIR}" fi else echo " Configuration directory not found (already removed)" fi # Remove log file if [ -f "${LOG_FILE}" ]; then rm -f ${LOG_FILE} if [ $? -eq 0 ]; then echo "✓ Removed log file: ${LOG_FILE}" else echo "✗ Failed to remove: ${LOG_FILE}" fi else echo " Log file not found (already removed)" fi echo "" echo "=========================================" echo " Complete Removal Successful" echo "=========================================" echo "" echo "All plugin files and data have been removed from the system." echo "" ]]>