Skip to content

Instantly share code, notes, and snippets.

@ShoGinn
Created August 10, 2025 15:36
Show Gist options
  • Save ShoGinn/2177a045f992cc027f023ec309b5fd3a to your computer and use it in GitHub Desktop.
Save ShoGinn/2177a045f992cc027f023ec309b5fd3a to your computer and use it in GitHub Desktop.
Update the Blocky app
#!/usr/bin/env bash
# Blocky Update Helper Script
# Updates Blocky to the latest version and restarts the service
# Configuration - Modify these variables if needed
BLOCKY_DIR="/opt/blocky"
SERVICE_NAME="blocky"
CONFIG_FILE="config.yml"
# Function to detect OS and architecture
detect_platform() {
local os=""
local arch=""
# Detect OS
case "$(uname -s)" in
Linux*) os="Linux" ;;
Darwin*) os="Darwin" ;;
FreeBSD*) os="Freebsd" ;;
NetBSD*) os="Netbsd" ;;
OpenBSD*) os="Openbsd" ;;
CYGWIN*|MINGW*|MSYS*) os="Windows" ;;
*)
msg_error "Unsupported operating system: $(uname -s)"
exit 1
;;
esac
# Detect architecture
case "$(uname -m)" in
x86_64|amd64) arch="x86_64" ;;
aarch64|arm64) arch="arm64" ;;
armv7l) arch="armv7" ;;
armv6l) arch="armv6" ;;
*)
msg_error "Unsupported architecture: $(uname -m)"
msg_error "Supported architectures: x86_64, arm64, armv7, armv6"
exit 1
;;
esac
echo "${os}_${arch}"
}
# Function to get download URL and file extension
get_download_info() {
local platform="$1"
local release="$2"
local file_ext=""
# Determine file extension based on OS
if [[ "$platform" == Windows_* ]]; then
file_ext="zip"
else
file_ext="tar.gz"
fi
echo "https://github.com/0xERR0R/blocky/releases/download/v${release}/blocky_v${release}_${platform}.${file_ext}|${file_ext}"
}
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored messages
msg_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
msg_ok() {
echo -e "${GREEN}[OK]${NC} $1"
}
msg_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
msg_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Function to run commands with appropriate privileges
run_privileged() {
if [[ $EUID -eq 0 ]]; then
# Already running as root
"$@"
else
# Use sudo
sudo "$@"
fi
}
# Function to check if we can get root privileges
check_privileges() {
if [[ $EUID -eq 0 ]]; then
return 0
fi
# Check if sudo is available and user can use it
if ! command -v sudo >/dev/null 2>&1; then
msg_error "This script requires root privileges and sudo is not available"
msg_error "Please run as root: sudo $0"
exit 1
fi
# Test sudo access without prompting for password if cached
if ! sudo -n true 2>/dev/null; then
msg_info "This script requires root privileges for system operations"
msg_info "You may be prompted for your password..."
# Test sudo access with password prompt
if ! sudo true; then
msg_error "Failed to obtain root privileges"
exit 1
fi
fi
msg_ok "Root privileges confirmed"
}
# Check for proper privileges early
check_privileges
# Check if Blocky is installed
if [ ! -d "$BLOCKY_DIR" ]; then
msg_error "Blocky installation not found in $BLOCKY_DIR"
exit 1
fi
# Function to create/recreate Blocky service
create_blocky_service() {
msg_info "Creating/updating Blocky service..."
run_privileged tee /etc/systemd/system/${SERVICE_NAME}.service > /dev/null <<EOF
[Unit]
Description=Blocky
After=network.target
[Service]
User=root
WorkingDirectory=$BLOCKY_DIR
ExecStart=$BLOCKY_DIR/blocky --config $CONFIG_FILE
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd and enable service
run_privileged systemctl daemon-reload
run_privileged systemctl enable $SERVICE_NAME
msg_ok "Blocky service created/updated"
}
# Function to validate service file
validate_service() {
local service_file="/etc/systemd/system/${SERVICE_NAME}.service"
if [ ! -f "$service_file" ]; then
return 1
fi
# Check if service file contains required sections
if ! grep -q "\[Unit\]" "$service_file" || \
! grep -q "\[Service\]" "$service_file" || \
! grep -q "\[Install\]" "$service_file" || \
! grep -q "ExecStart=$BLOCKY_DIR/blocky" "$service_file" || \
! grep -q "WorkingDirectory=$BLOCKY_DIR" "$service_file"; then
return 1
fi
return 0
}
# Check and validate Blocky service
msg_info "Checking Blocky service..."
SERVICE_NEEDS_CREATION=false
if ! run_privileged systemctl list-unit-files | grep -q "${SERVICE_NAME}.service"; then
msg_warn "Blocky service not found in systemd"
SERVICE_NEEDS_CREATION=true
elif ! validate_service; then
msg_warn "Blocky service file appears to be corrupted or incomplete"
SERVICE_NEEDS_CREATION=true
else
msg_ok "Blocky service found and appears valid"
fi
# Create/recreate service if needed
if [ "$SERVICE_NEEDS_CREATION" = true ]; then
create_blocky_service
fi
msg_info "Starting Blocky update process..."
# Detect platform
PLATFORM=$(detect_platform)
msg_info "Detected platform: $PLATFORM"
# Get current version if binary exists
CURRENT_VERSION=""
if [ -f "$BLOCKY_DIR/blocky" ]; then
CURRENT_VERSION=$($BLOCKY_DIR/blocky version 2>/dev/null | grep -oP 'Version: \K[^\s]+' || echo "unknown")
msg_info "Current Blocky version: $CURRENT_VERSION"
fi
# Get latest release version
msg_info "Checking for latest Blocky release..."
RELEASE=$(curl -fsSL https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [ -z "$RELEASE" ]; then
msg_error "Failed to fetch latest release version"
exit 1
fi
msg_info "Latest Blocky version: $RELEASE"
# Normalize versions for comparison (remove 'v' prefix if present)
CURRENT_VERSION_CLEAN="${CURRENT_VERSION#v}"
RELEASE_CLEAN="${RELEASE#v}"
# Compare versions (skip if current version is unknown)
if [ "$CURRENT_VERSION_CLEAN" != "unknown" ] && [ "$CURRENT_VERSION_CLEAN" = "$RELEASE_CLEAN" ]; then
msg_ok "Blocky is already up to date (v$RELEASE_CLEAN)"
exit 0
fi
# Stop Blocky service if it's running
msg_info "Stopping Blocky service..."
if run_privileged systemctl is-active --quiet $SERVICE_NAME; then
if ! run_privileged systemctl stop $SERVICE_NAME; then
msg_error "Failed to stop Blocky service"
exit 1
fi
msg_ok "Blocky service stopped"
else
msg_ok "Blocky service was not running"
fi
# Backup current binary (if exists)
if [ -f "$BLOCKY_DIR/blocky" ]; then
msg_info "Backing up current Blocky binary..."
# Use sudo for cp if we don't have write access to the directory
if [[ $EUID -eq 0 ]] || [ -w "$BLOCKY_DIR" ]; then
cp $BLOCKY_DIR/blocky $BLOCKY_DIR/blocky.backup
else
run_privileged cp $BLOCKY_DIR/blocky $BLOCKY_DIR/blocky.backup
fi
msg_ok "Current binary backed up as blocky.backup"
fi
# Download and install new version
DOWNLOAD_INFO=$(get_download_info "$PLATFORM" "$RELEASE")
DOWNLOAD_URL=$(echo "$DOWNLOAD_INFO" | cut -d'|' -f1)
FILE_EXT=$(echo "$DOWNLOAD_INFO" | cut -d'|' -f2)
msg_info "Downloading Blocky v${RELEASE} for ${PLATFORM}..."
TEMP_DIR=$(mktemp -d)
DOWNLOAD_FILE="$TEMP_DIR/blocky.$FILE_EXT"
if ! curl -fsSL "$DOWNLOAD_URL" -o "$DOWNLOAD_FILE"; then
msg_error "Failed to download Blocky v${RELEASE} for ${PLATFORM}"
msg_error "Download URL: $DOWNLOAD_URL"
# Restore backup if download fails
if [ -f "$BLOCKY_DIR/blocky.backup" ]; then
if [[ $EUID -eq 0 ]] || [ -w "$BLOCKY_DIR" ]; then
mv $BLOCKY_DIR/blocky.backup $BLOCKY_DIR/blocky
else
run_privileged mv $BLOCKY_DIR/blocky.backup $BLOCKY_DIR/blocky
fi
msg_warn "Restored backup binary"
fi
run_privileged systemctl start $SERVICE_NAME
rm -rf "$TEMP_DIR"
exit 1
fi
msg_info "Extracting Blocky v${RELEASE}..."
if [[ "$FILE_EXT" == "tar.gz" ]]; then
if [[ $EUID -eq 0 ]] || [ -w "$BLOCKY_DIR" ]; then
if ! tar -xzf "$DOWNLOAD_FILE" -C $BLOCKY_DIR/; then
msg_error "Failed to extract Blocky"
# Restore backup if extraction fails
if [ -f "$BLOCKY_DIR/blocky.backup" ]; then
mv $BLOCKY_DIR/blocky.backup $BLOCKY_DIR/blocky
msg_warn "Restored backup binary"
fi
run_privileged systemctl start $SERVICE_NAME
rm -rf "$TEMP_DIR"
exit 1
fi
else
if ! run_privileged tar -xzf "$DOWNLOAD_FILE" -C $BLOCKY_DIR/; then
msg_error "Failed to extract Blocky"
# Restore backup if extraction fails
if [ -f "$BLOCKY_DIR/blocky.backup" ]; then
run_privileged mv $BLOCKY_DIR/blocky.backup $BLOCKY_DIR/blocky
msg_warn "Restored backup binary"
fi
run_privileged systemctl start $SERVICE_NAME
rm -rf "$TEMP_DIR"
exit 1
fi
fi
elif [[ "$FILE_EXT" == "zip" ]]; then
if [[ $EUID -eq 0 ]] || [ -w "$BLOCKY_DIR" ]; then
if ! unzip -q "$DOWNLOAD_FILE" -d $BLOCKY_DIR/; then
msg_error "Failed to extract Blocky"
msg_error "Note: unzip command is required for Windows builds"
# Restore backup if extraction fails
if [ -f "$BLOCKY_DIR/blocky.backup" ]; then
mv $BLOCKY_DIR/blocky.backup $BLOCKY_DIR/blocky
msg_warn "Restored backup binary"
fi
run_privileged systemctl start $SERVICE_NAME
rm -rf "$TEMP_DIR"
exit 1
fi
else
if ! run_privileged unzip -q "$DOWNLOAD_FILE" -d $BLOCKY_DIR/; then
msg_error "Failed to extract Blocky"
msg_error "Note: unzip command is required for Windows builds"
# Restore backup if extraction fails
if [ -f "$BLOCKY_DIR/blocky.backup" ]; then
run_privileged mv $BLOCKY_DIR/blocky.backup $BLOCKY_DIR/blocky
msg_warn "Restored backup binary"
fi
run_privileged systemctl start $SERVICE_NAME
rm -rf "$TEMP_DIR"
exit 1
fi
fi
fi
# Clean up temp directory
rm -rf "$TEMP_DIR"
# Make sure the binary is executable (not needed for Windows, but doesn't hurt)
if [[ $EUID -eq 0 ]] || [ -w "$BLOCKY_DIR/blocky" ]; then
chmod +x $BLOCKY_DIR/blocky
else
run_privileged chmod +x $BLOCKY_DIR/blocky
fi
# Verify the installation
msg_info "Verifying installation..."
NEW_VERSION=$($BLOCKY_DIR/blocky version 2>/dev/null | grep -oP 'Version: \K[^\s]+' || echo "unknown")
NEW_VERSION_CLEAN="${NEW_VERSION#v}"
RELEASE_CLEAN="${RELEASE#v}"
if [ "$NEW_VERSION_CLEAN" = "$RELEASE_CLEAN" ]; then
msg_ok "Successfully installed Blocky $NEW_VERSION"
# Remove backup if verification successful
if [ -f "$BLOCKY_DIR/blocky.backup" ]; then
if [[ $EUID -eq 0 ]] || [ -w "$BLOCKY_DIR" ]; then
rm $BLOCKY_DIR/blocky.backup
else
run_privileged rm $BLOCKY_DIR/blocky.backup
fi
fi
else
msg_error "Version verification failed. Expected: $RELEASE_CLEAN, Got: $NEW_VERSION_CLEAN"
# Restore backup if verification fails
if [ -f "$BLOCKY_DIR/blocky.backup" ]; then
if [[ $EUID -eq 0 ]] || [ -w "$BLOCKY_DIR" ]; then
mv $BLOCKY_DIR/blocky.backup $BLOCKY_DIR/blocky
else
run_privileged mv $BLOCKY_DIR/blocky.backup $BLOCKY_DIR/blocky
fi
msg_warn "Restored backup binary"
fi
fi
# Start Blocky service
msg_info "Starting Blocky service..."
# Ensure service is enabled
if ! run_privileged systemctl is-enabled --quiet $SERVICE_NAME; then
msg_info "Enabling Blocky service..."
run_privileged systemctl enable $SERVICE_NAME
fi
if ! run_privileged systemctl start $SERVICE_NAME; then
msg_error "Failed to start Blocky service"
msg_error "Check service status with: systemctl status $SERVICE_NAME"
exit 1
fi
# Wait a moment and check service status
sleep 2
if run_privileged systemctl is-active --quiet $SERVICE_NAME; then
msg_ok "Blocky service started successfully"
msg_ok "Update completed! Blocky is now running version $NEW_VERSION"
else
msg_error "Blocky service failed to start properly"
msg_error "Check service status with: systemctl status $SERVICE_NAME"
msg_error "Check logs with: journalctl -u $SERVICE_NAME -f"
exit 1
fi
# Optional: Show service status
echo
msg_info "Service Status:"
run_privileged systemctl status $SERVICE_NAME --no-pager -l
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment