mirror of
https://github.com/unraid/webgui.git
synced 2026-02-08 01:49:19 -06:00
- Enhanced the `generate-pr-plugin.sh` script to check for existing backups before creating new ones, preserving original backups across updates. - Added verbose output during file extraction to provide clearer status updates. - Implemented a new update method that restores original files before applying new changes, ensuring a clean installation state.
325 lines
9.4 KiB
Bash
Executable File
325 lines
9.4 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
IFS=$'\n\t'
|
|
|
|
# Generate PR plugin file for Unraid
|
|
# Usage: ./generate-pr-plugin.sh <version> <pr_number> <commit_sha> <tarball_name> <txz_url> [plugin_url]
|
|
|
|
VERSION=$1
|
|
PR_NUMBER=$2
|
|
COMMIT_SHA=$3
|
|
TARBALL_NAME=$4
|
|
TXZ_URL=$5
|
|
PLUGIN_URL=${6:-""} # Optional plugin URL for updates
|
|
|
|
if [ -z "$VERSION" ] || [ -z "$PR_NUMBER" ] || [ -z "$COMMIT_SHA" ] || [ -z "$TARBALL_NAME" ] || [ -z "$TXZ_URL" ]; then
|
|
echo "Usage: $0 <version> <pr_number> <commit_sha> <tarball_name> <txz_url> [plugin_url]"
|
|
exit 1
|
|
fi
|
|
|
|
# If no plugin URL provided, generate one based on R2 location
|
|
if [ -z "$PLUGIN_URL" ]; then
|
|
# Extract base URL from TXZ_URL and use consistent filename
|
|
PLUGIN_URL=$(echo "$TXZ_URL" | sed "s|\.tar\.gz|.plg|")
|
|
fi
|
|
|
|
# Use consistent filename (no version in filename, version is inside the plugin)
|
|
PLUGIN_NAME="webgui-pr-${PR_NUMBER}.plg"
|
|
TARBALL_SHA256=$(sha256sum "$TARBALL_NAME" | awk '{print $1}')
|
|
|
|
echo "Generating plugin: $PLUGIN_NAME"
|
|
echo "Tarball SHA256: $TARBALL_SHA256"
|
|
|
|
cat > "$PLUGIN_NAME" << 'EOF'
|
|
<?xml version='1.0' standalone='yes'?>
|
|
<!DOCTYPE PLUGIN [
|
|
<!ENTITY name "webgui-pr-PR_PLACEHOLDER">
|
|
<!ENTITY version "VERSION_PLACEHOLDER">
|
|
<!ENTITY author "unraid">
|
|
<!ENTITY pluginURL "PLUGIN_URL_PLACEHOLDER">
|
|
<!ENTITY tarball "TARBALL_PLACEHOLDER">
|
|
<!ENTITY sha256 "SHA256_PLACEHOLDER">
|
|
<!ENTITY pr "PR_PLACEHOLDER">
|
|
<!ENTITY commit "COMMIT_PLACEHOLDER">
|
|
]>
|
|
|
|
<PLUGIN name="&name;-&version;"
|
|
author="&author;"
|
|
version="&version;"
|
|
pluginURL="&pluginURL;"
|
|
min="6.12.0"
|
|
icon="wrench"
|
|
support="&pluginURL;/pull/≺">
|
|
|
|
<CHANGES>
|
|
##&version;
|
|
- Test build for PR #≺ (commit &commit;)
|
|
- This plugin installs modified files from the PR for testing
|
|
- Original files are backed up and restored upon removal
|
|
</CHANGES>
|
|
|
|
<!-- Create backup directory -->
|
|
<FILE Run="/bin/bash" Method="install">
|
|
<INLINE>
|
|
<![CDATA[
|
|
echo "===================================="
|
|
echo "WebGUI PR Test Plugin Installation"
|
|
echo "===================================="
|
|
echo "Version: VERSION_PLACEHOLDER"
|
|
echo "PR: #PR_PLACEHOLDER"
|
|
echo "Commit: COMMIT_PLACEHOLDER"
|
|
echo ""
|
|
|
|
# Create directories
|
|
mkdir -p /boot/config/plugins/&name;
|
|
mkdir -p /boot/config/plugins/&name;/backups
|
|
|
|
echo "Created plugin directories"
|
|
]]>
|
|
</INLINE>
|
|
</FILE>
|
|
|
|
<!-- Download tarball from GitHub -->
|
|
<FILE Name="/boot/config/plugins/&name;/&tarball;">
|
|
<URL>TXZ_URL_PLACEHOLDER</URL>
|
|
<SHA256>&sha256;</SHA256>
|
|
</FILE>
|
|
|
|
<!-- Backup and install files -->
|
|
<FILE Run="/bin/bash" Method="install">
|
|
<INLINE>
|
|
<![CDATA[
|
|
BACKUP_DIR="/boot/config/plugins/&name;/backups"
|
|
TARBALL="/boot/config/plugins/&name;/&tarball;"
|
|
MANIFEST="/boot/config/plugins/&name;/installed_files.txt"
|
|
|
|
echo "Starting file deployment..."
|
|
echo "Tarball: $TARBALL"
|
|
echo "Backup directory: $BACKUP_DIR"
|
|
|
|
# Clear manifest
|
|
> "$MANIFEST"
|
|
|
|
# Get file list first
|
|
echo "Examining tarball contents..."
|
|
tar -tzf "$TARBALL" | head -20
|
|
echo ""
|
|
|
|
# Count total files
|
|
FILE_COUNT=$(tar -tzf "$TARBALL" | grep -v '/$' | wc -l)
|
|
echo "Total files to process: $FILE_COUNT"
|
|
echo ""
|
|
|
|
# Get file list
|
|
tar -tzf "$TARBALL" > /tmp/plugin_files.txt
|
|
|
|
# Backup original files BEFORE extraction
|
|
while IFS= read -r file; do
|
|
# Skip directories
|
|
if [[ "$file" == */ ]]; then
|
|
continue
|
|
fi
|
|
|
|
# The tarball contains usr/local/emhttp/... (no leading slash)
|
|
# When we extract with -C /, it becomes /usr/local/emhttp/...
|
|
SYSTEM_FILE="/${file}"
|
|
BACKUP_FILE="$BACKUP_DIR/$(echo "$file" | tr '/' '_')"
|
|
|
|
echo "Processing: $file"
|
|
|
|
# Only backup if we haven't already backed up this file
|
|
# (preserves original backups across updates)
|
|
if [ -f "$BACKUP_FILE" ]; then
|
|
echo " → Using existing backup: $BACKUP_FILE"
|
|
echo "$SYSTEM_FILE|$BACKUP_FILE" >> "$MANIFEST"
|
|
elif [ -f "$SYSTEM_FILE" ]; then
|
|
echo " → Creating backup of original: $SYSTEM_FILE"
|
|
cp -p "$SYSTEM_FILE" "$BACKUP_FILE"
|
|
echo "$SYSTEM_FILE|$BACKUP_FILE" >> "$MANIFEST"
|
|
else
|
|
echo " → Will create new: $SYSTEM_FILE"
|
|
echo "$SYSTEM_FILE|NEW" >> "$MANIFEST"
|
|
fi
|
|
done < /tmp/plugin_files.txt
|
|
|
|
# Clean up temp file
|
|
rm -f /tmp/plugin_files.txt
|
|
|
|
# Extract the tarball to root with verbose output
|
|
# Since tarball contains usr/local/emhttp/..., extracting to / makes it /usr/local/emhttp/...
|
|
echo ""
|
|
echo "Extracting files to system (verbose mode)..."
|
|
echo "----------------------------------------"
|
|
tar -xzvf "$TARBALL" -C /
|
|
EXTRACT_STATUS=$?
|
|
echo "----------------------------------------"
|
|
echo "Extraction completed with status: $EXTRACT_STATUS"
|
|
echo ""
|
|
|
|
# Verify extraction
|
|
echo "Verifying installation..."
|
|
INSTALLED_COUNT=0
|
|
while IFS='|' read -r file backup; do
|
|
if [ -f "$file" ]; then
|
|
INSTALLED_COUNT=$((INSTALLED_COUNT + 1))
|
|
fi
|
|
done < "$MANIFEST"
|
|
|
|
echo "Successfully installed $INSTALLED_COUNT files"
|
|
|
|
echo ""
|
|
echo "✅ Installation complete!"
|
|
echo ""
|
|
echo "Summary:"
|
|
echo "--------"
|
|
echo "Files deployed: $INSTALLED_COUNT"
|
|
echo ""
|
|
if [ $INSTALLED_COUNT -gt 0 ]; then
|
|
echo "Modified files:"
|
|
while IFS='|' read -r file backup; do
|
|
if [ -f "$file" ]; then
|
|
if [ "$backup" == "NEW" ]; then
|
|
echo " [NEW] $file"
|
|
else
|
|
echo " [MOD] $file"
|
|
fi
|
|
fi
|
|
done < "$MANIFEST"
|
|
else
|
|
echo "⚠️ WARNING: No files were installed!"
|
|
echo "Check that the tarball structure matches the expected format."
|
|
fi
|
|
|
|
echo ""
|
|
echo "⚠️ This is a TEST plugin for PR #PR_PLACEHOLDER"
|
|
echo "⚠️ Remove this plugin before applying production updates"
|
|
]]>
|
|
</INLINE>
|
|
</FILE>
|
|
|
|
<!-- Update method - restore originals first, then apply new changes -->
|
|
<FILE Run="/bin/bash" Method="update">
|
|
<INLINE>
|
|
<![CDATA[
|
|
echo "===================================="
|
|
echo "WebGUI PR Test Plugin Update"
|
|
echo "===================================="
|
|
echo "Version: &version;"
|
|
echo ""
|
|
|
|
BACKUP_DIR="/boot/config/plugins/&name;/backups"
|
|
MANIFEST="/boot/config/plugins/&name;/installed_files.txt"
|
|
|
|
# First restore original files to ensure clean state
|
|
if [ -f "$MANIFEST" ]; then
|
|
echo "Step 1: Restoring original files before update..."
|
|
echo "------------------------------------------------"
|
|
|
|
while IFS='|' read -r system_file backup_file; do
|
|
if [ "$backup_file" == "NEW" ]; then
|
|
# This was a new file from previous version, remove it
|
|
if [ -f "$system_file" ]; then
|
|
echo "Removing PR file: $system_file"
|
|
rm -f "$system_file"
|
|
fi
|
|
else
|
|
# Restore original from backup
|
|
if [ -f "$backup_file" ]; then
|
|
echo "Restoring original: $system_file"
|
|
cp -f "$backup_file" "$system_file"
|
|
fi
|
|
fi
|
|
done < "$MANIFEST"
|
|
|
|
echo ""
|
|
echo "✅ Original files restored"
|
|
echo ""
|
|
else
|
|
echo "⚠️ No previous manifest found, proceeding with fresh install"
|
|
echo ""
|
|
fi
|
|
|
|
# Clear the old manifest for the new version
|
|
> "$MANIFEST"
|
|
|
|
echo "Step 2: Update will now proceed with installation of new PR files..."
|
|
echo ""
|
|
]]>
|
|
</INLINE>
|
|
</FILE>
|
|
|
|
<!-- Removal script -->
|
|
<FILE Run="/bin/bash" Method="remove">
|
|
<INLINE>
|
|
<![CDATA[
|
|
echo "===================================="
|
|
echo "WebGUI PR Test Plugin Removal"
|
|
echo "===================================="
|
|
echo ""
|
|
|
|
BACKUP_DIR="/boot/config/plugins/&name;/backups"
|
|
MANIFEST="/boot/config/plugins/&name;/installed_files.txt"
|
|
|
|
if [ -f "$MANIFEST" ]; then
|
|
echo "Restoring original files..."
|
|
|
|
while IFS='|' read -r system_file backup_file; do
|
|
if [ "$backup_file" == "NEW" ]; then
|
|
# This was a new file, remove it
|
|
if [ -f "$system_file" ]; then
|
|
echo "Removing new file: $system_file"
|
|
rm -f "$system_file"
|
|
fi
|
|
else
|
|
# Restore from backup
|
|
if [ -f "$backup_file" ]; then
|
|
echo "Restoring: $system_file"
|
|
mv -f "$backup_file" "$system_file"
|
|
fi
|
|
fi
|
|
done < "$MANIFEST"
|
|
|
|
echo ""
|
|
echo "✅ Original files restored"
|
|
else
|
|
echo "⚠️ No manifest found, cannot restore files"
|
|
fi
|
|
|
|
# Clean up
|
|
echo "Cleaning up plugin files..."
|
|
# Remove the plugin directory (which includes the tarball and backups)
|
|
rm -rf "/boot/config/plugins/&name;"
|
|
# Remove the plugin file itself
|
|
rm -f "/boot/config/plugins/webgui-pr-&version;.plg"
|
|
|
|
echo ""
|
|
echo "✅ Plugin removed successfully"
|
|
]]>
|
|
</INLINE>
|
|
</FILE>
|
|
|
|
</PLUGIN>
|
|
EOF
|
|
|
|
# Replace placeholders (compatible with both Linux and macOS)
|
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
# macOS requires backup extension with -i
|
|
sed -i '' "s/VERSION_PLACEHOLDER/${VERSION}/g" "$PLUGIN_NAME"
|
|
sed -i '' "s/TARBALL_PLACEHOLDER/${TARBALL_NAME}/g" "$PLUGIN_NAME"
|
|
sed -i '' "s/SHA256_PLACEHOLDER/${TARBALL_SHA256}/g" "$PLUGIN_NAME"
|
|
sed -i '' "s/PR_PLACEHOLDER/${PR_NUMBER}/g" "$PLUGIN_NAME"
|
|
sed -i '' "s/COMMIT_PLACEHOLDER/${COMMIT_SHA}/g" "$PLUGIN_NAME"
|
|
sed -i '' "s|TXZ_URL_PLACEHOLDER|${TXZ_URL}|g" "$PLUGIN_NAME"
|
|
sed -i '' "s|PLUGIN_URL_PLACEHOLDER|${PLUGIN_URL}|g" "$PLUGIN_NAME"
|
|
else
|
|
# Linux sed
|
|
sed -i "s/VERSION_PLACEHOLDER/${VERSION}/g" "$PLUGIN_NAME"
|
|
sed -i "s/TARBALL_PLACEHOLDER/${TARBALL_NAME}/g" "$PLUGIN_NAME"
|
|
sed -i "s/SHA256_PLACEHOLDER/${TARBALL_SHA256}/g" "$PLUGIN_NAME"
|
|
sed -i "s/PR_PLACEHOLDER/${PR_NUMBER}/g" "$PLUGIN_NAME"
|
|
sed -i "s/COMMIT_PLACEHOLDER/${COMMIT_SHA}/g" "$PLUGIN_NAME"
|
|
sed -i "s|TXZ_URL_PLACEHOLDER|${TXZ_URL}|g" "$PLUGIN_NAME"
|
|
sed -i "s|PLUGIN_URL_PLACEHOLDER|${PLUGIN_URL}|g" "$PLUGIN_NAME"
|
|
fi
|
|
|
|
echo "Plugin generated: $PLUGIN_NAME" |