mirror of
https://github.com/unraid/api.git
synced 2026-05-12 10:40:09 -05:00
chore: require connect plugin to enable flash backup (#1419)
## Summary by CodeRabbit - **New Features** - Added a check to ensure the "unraid-api-plugin-connect" plugin is enabled before allowing flash backup functionality. - Introduced a utility to directly verify if specific API plugins are enabled. - **Refactor** - Updated internal logic to use a centralized class and script-based checks for plugin status and version instead of manual config parsing. - Improved script command-line interface for easier plugin status and version checks. - **Bug Fixes** - Flash Backup feature and service now only activate when the required API plugin is enabled, preventing unintended usage. - Flash Backup UI is conditionally displayed based on the presence of the API plugin. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1209357561531351 - https://app.asana.com/0/0/1210541992642236
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
# This file is /etc/rc.d/rc.flash_backup
|
||||
# use at queue "f" for flash backup
|
||||
scripts_dir="/usr/local/share/dynamix.unraid.net/scripts"
|
||||
QUEUE=" -q f "
|
||||
TASKNAME="/etc/rc.d/rc.flash_backup watch"
|
||||
TASKACTION="/usr/local/emhttp/plugins/dynamix.my.servers/scripts/UpdateFlashBackup update"
|
||||
@@ -153,7 +154,10 @@ _enabled() {
|
||||
local output
|
||||
output=$(git -C /boot config --get remote.origin.url 2>&1)
|
||||
if [[ "${output}" == *"backup.unraid.net"* ]]; then
|
||||
return 0
|
||||
# Also check if the connect API plugin is enabled
|
||||
if "$scripts_dir/api_utils.sh" is_api_plugin_enabled unraid-api-plugin-connect; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ uninstall() {
|
||||
# Service control functions
|
||||
start() {
|
||||
echo "Starting Unraid API service..."
|
||||
|
||||
|
||||
# Restore vendored API plugins if they were installed
|
||||
if [ -x "$scripts_dir/dependencies.sh" ]; then
|
||||
"$scripts_dir/dependencies.sh" restore || {
|
||||
@@ -37,21 +37,24 @@ start() {
|
||||
else
|
||||
echo "Warning: dependencies.sh script not found or not executable"
|
||||
fi
|
||||
|
||||
|
||||
# Create log directory if it doesn't exist
|
||||
mkdir -p /var/log/unraid-api
|
||||
|
||||
|
||||
# Copy env file if needed
|
||||
if [ -f "${api_base_dir}/.env.production" ] && [ ! -f "${api_base_dir}/.env" ]; then
|
||||
cp "${api_base_dir}/.env.production" "${api_base_dir}/.env"
|
||||
fi
|
||||
|
||||
# Start the flash backup service if available
|
||||
|
||||
# Start the flash backup service if available and connect plugin is enabled
|
||||
if [ -x "/etc/rc.d/rc.flash_backup" ]; then
|
||||
echo "Starting flash backup service..."
|
||||
/etc/rc.d/rc.flash_backup start
|
||||
# Check if connect plugin is enabled before starting flash backup
|
||||
if [ -x "$scripts_dir/api_utils.sh" ] && "$scripts_dir/api_utils.sh" is_api_plugin_enabled "unraid-api-plugin-connect"; then
|
||||
echo "Starting flash backup service..."
|
||||
/etc/rc.d/rc.flash_backup start
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# Start the API service
|
||||
if [ -x "${unraid_binary_path}" ]; then
|
||||
"${unraid_binary_path}" start
|
||||
@@ -96,7 +99,7 @@ case "$1" in
|
||||
'stop')
|
||||
stop
|
||||
;;
|
||||
'restart'|'reload')
|
||||
'restart' | 'reload')
|
||||
restart
|
||||
;;
|
||||
'status')
|
||||
|
||||
+5
@@ -14,6 +14,7 @@ Tag="globe"
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
require_once "$docroot/plugins/dynamix.my.servers/include/state.php";
|
||||
require_once "$docroot/plugins/dynamix.my.servers/include/api-config.php";
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
$serverState = new ServerState();
|
||||
|
||||
@@ -28,6 +29,8 @@ $hasMyUnraidNetCert = preg_match('/.*\.myunraid\.net$/', $serverState->nginxCfg[
|
||||
$isRegistered = $serverState->registered;
|
||||
$isMiniGraphConnected = $serverState->myServersMiniGraphConnected;
|
||||
|
||||
$isConnectPluginInstalled = ApiConfig::isConnectPluginEnabled();
|
||||
|
||||
$flashbackup_status = $serverState->flashbackupStatus;
|
||||
|
||||
$passwd_result = exec('/usr/bin/passwd --status root');
|
||||
@@ -486,6 +489,7 @@ $('body').on('click', '.js-setCurrentHostExtraOrigins', function(e) {
|
||||
});
|
||||
</script>
|
||||
|
||||
<?if($isConnectPluginInstalled):?>
|
||||
<div markdown="1" class="<?=$shade?>"><!-- begin Flash Backup section -->
|
||||
_(Flash backup)_:
|
||||
<?if(!$isRegistered):?>
|
||||
@@ -563,6 +567,7 @@ $(function() {
|
||||
</script>
|
||||
<?endif // end show flash backup form ?>
|
||||
</div><!-- end Flash Backup section -->
|
||||
<?endif // end connect plugin check ?>
|
||||
|
||||
<!-- legacy search compatibility -->
|
||||
<div style="display:none;">
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* API Configuration utilities
|
||||
* Centralized functions for checking API plugin status
|
||||
*/
|
||||
class ApiConfig
|
||||
{
|
||||
private static $scriptsDir = "/usr/local/share/dynamix.unraid.net/scripts";
|
||||
|
||||
/**
|
||||
* Get the path to api_utils.sh script
|
||||
* @return string
|
||||
*/
|
||||
private static function getApiUtilsScript()
|
||||
{
|
||||
return self::$scriptsDir . "/api_utils.sh";
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command safely with proper error handling
|
||||
* @param string $command The command to execute
|
||||
* @param int &$exitCode Reference to store the exit code
|
||||
* @return string The command output
|
||||
*/
|
||||
private static function executeCommand($command, &$exitCode = null)
|
||||
{
|
||||
$output = [];
|
||||
$exitCode = 0;
|
||||
|
||||
exec($command, $output, $exitCode);
|
||||
|
||||
return implode("\n", $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a specific API plugin is enabled
|
||||
* @param string $pluginName The name of the plugin to check
|
||||
* @return bool True if plugin is enabled, false otherwise
|
||||
*/
|
||||
public static function isApiPluginEnabled($pluginName)
|
||||
{
|
||||
if (empty($pluginName) || !is_string($pluginName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$apiUtilsScript = self::getApiUtilsScript();
|
||||
|
||||
if (!is_executable($apiUtilsScript)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$escapedScript = escapeshellarg($apiUtilsScript);
|
||||
$escapedPlugin = escapeshellarg($pluginName);
|
||||
$command = "$escapedScript is_api_plugin_enabled $escapedPlugin 2>/dev/null";
|
||||
|
||||
$exitCode = 0;
|
||||
self::executeCommand($command, $exitCode);
|
||||
|
||||
return $exitCode === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the unraid-api-plugin-connect is enabled
|
||||
* @return bool True if connect plugin is enabled, false otherwise
|
||||
*/
|
||||
public static function isConnectPluginEnabled()
|
||||
{
|
||||
return self::isApiPluginEnabled('unraid-api-plugin-connect');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get API version from api_utils.sh
|
||||
* @return string The API version or 'unknown' if not found
|
||||
*/
|
||||
public static function getApiVersion()
|
||||
{
|
||||
$apiUtilsScript = self::getApiUtilsScript();
|
||||
|
||||
if (!is_executable($apiUtilsScript)) {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
$escapedScript = escapeshellarg($apiUtilsScript);
|
||||
$command = "$escapedScript get_api_version 2>/dev/null";
|
||||
|
||||
$exitCode = 0;
|
||||
$output = self::executeCommand($command, $exitCode);
|
||||
|
||||
if ($exitCode !== 0) {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
$version = trim($output);
|
||||
return !empty($version) ? $version : 'unknown';
|
||||
}
|
||||
}
|
||||
+5
-23
@@ -17,6 +17,7 @@ $docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
require_once "$docroot/plugins/dynamix.my.servers/include/reboot-details.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/UnraidCheck.php";
|
||||
require_once "$docroot/plugins/dynamix.my.servers/include/api-config.php";
|
||||
/**
|
||||
* ServerState class encapsulates server-related information and settings.
|
||||
*
|
||||
@@ -146,31 +147,12 @@ class ServerState
|
||||
|
||||
private function setConnectValues()
|
||||
{
|
||||
$apiConfigPath = '/boot/config/plugins/dynamix.my.servers/configs/api.json';
|
||||
if (!file_exists($apiConfigPath)) {
|
||||
if (!ApiConfig::isConnectPluginEnabled()) {
|
||||
return; // plugin is not installed; exit early
|
||||
}
|
||||
|
||||
$apiConfig = @json_decode(file_get_contents($apiConfigPath), true);
|
||||
$pluginName = 'unraid-api-plugin-connect'; // name of connect plugin's npm package
|
||||
if ($apiConfig && is_array($apiConfig['plugins'])) {
|
||||
foreach ($apiConfig['plugins'] as $plugin) {
|
||||
// recognize npm version identifiers inside $apiConfig['plugins']
|
||||
if ($plugin === $pluginName || strpos($plugin, $pluginName . '@') === 0) {
|
||||
$this->connectPluginInstalled = 'dynamix.unraid.net.plg';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exit early if the plugin is not installed
|
||||
if (!$this->connectPluginInstalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get version directly using api_utils.sh get_api_version function
|
||||
$this->connectPluginVersion = trim(@exec('/usr/local/share/dynamix.unraid.net/scripts/api_utils.sh get_api_version 2>/dev/null')) ?: 'unknown';
|
||||
|
||||
|
||||
$this->connectPluginInstalled = 'dynamix.unraid.net.plg';
|
||||
$this->connectPluginVersion = ApiConfig::getApiVersion();
|
||||
$this->getMyServersCfgValues();
|
||||
$this->getConnectKnownOrigins();
|
||||
$this->getFlashBackupStatus();
|
||||
|
||||
+72
-9
@@ -9,7 +9,7 @@ CONFIG_FILE="/usr/local/share/dynamix.unraid.net/config/vendor_archive.json"
|
||||
# Returns the API version string or empty if not found
|
||||
get_api_version() {
|
||||
local api_version=""
|
||||
|
||||
|
||||
# Get version from config file
|
||||
if [ -f "$CONFIG_FILE" ] && command -v jq >/dev/null 2>&1; then
|
||||
api_version=$(jq -r '.api_version' "$CONFIG_FILE")
|
||||
@@ -18,23 +18,23 @@ get_api_version() {
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# No version found
|
||||
return 1
|
||||
}
|
||||
|
||||
# Get vendor archive configuration information
|
||||
# Get vendor archive configuration information
|
||||
# Returns an array of values: api_version, vendor_store_url, vendor_store_path
|
||||
get_archive_information() {
|
||||
# Define all local variables at the top
|
||||
local api_version=""
|
||||
local vendor_store_path=""
|
||||
|
||||
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
echo "Vendor archive config file not found at $CONFIG_FILE" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# Read values from JSON config using jq
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
api_version=$(jq -r '.api_version' "$CONFIG_FILE")
|
||||
@@ -43,20 +43,83 @@ get_archive_information() {
|
||||
echo "jq not found, can't parse config file" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# Validate that all required values exist and are not null
|
||||
if [ -z "$api_version" ] || [ "$api_version" = "null" ]; then
|
||||
echo "Invalid or missing api_version in config file" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
if [ -z "$vendor_store_path" ] || [ "$vendor_store_path" = "null" ]; then
|
||||
echo "Invalid or missing vendor_store_path in config file" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# Return the values
|
||||
echo "$api_version"
|
||||
echo "$vendor_store_path"
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
# Check if an API plugin is enabled
|
||||
# Usage: is_api_plugin_enabled <plugin_name>
|
||||
# Returns 0 if enabled, 1 if not enabled or error
|
||||
is_api_plugin_enabled() {
|
||||
local plugin_name="$1"
|
||||
local api_config_path="/boot/config/plugins/dynamix.my.servers/configs/api.json"
|
||||
|
||||
# Check if plugin name is provided
|
||||
if [ -z "$plugin_name" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if API config file exists
|
||||
if [ ! -f "$api_config_path" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if jq is available
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Parse JSON and check for plugin
|
||||
local plugins
|
||||
plugins=$(jq -r '.plugins[]?' "$api_config_path" 2>/dev/null)
|
||||
if [ $? -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check each plugin entry
|
||||
while IFS= read -r plugin; do
|
||||
if [ "$plugin" = "$plugin_name" ] || [[ "$plugin" == "$plugin_name@"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
done <<<"$plugins"
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Main execution when script is called directly
|
||||
# Handle command line arguments
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
case "$1" in
|
||||
"get_api_version")
|
||||
get_api_version
|
||||
;;
|
||||
"get_archive_information")
|
||||
get_archive_information
|
||||
;;
|
||||
"is_api_plugin_enabled")
|
||||
if [ -z "$2" ]; then
|
||||
echo "Error: Plugin name required" >&2
|
||||
exit 1
|
||||
fi
|
||||
is_api_plugin_enabled "$2"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {get_api_version|get_archive_information|is_api_plugin_enabled <plugin_name>}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user