Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ The `update-tailscale.sh` script supports the following arguments:
| `--no-download` | Skips downloading binaries. Use pre-downloaded archive at `/tmp/tailscale.tar.gz`. |
| `--no-tiny` | Uses full Tailscale binaries instead of tiny version. Not recommended for GL.iNet routers. |
| `--select-release` | Displays available releases and lets you choose a specific version. ⚠️ Downgrading not officially supported! |
| `--background` | Runs script in background mode, survives SSH disconnection. Logs to `/tmp/tailscale-update.log`. Recommended when using `--ssh`! |
| `--testing` | Uses prerelease/testing versions from the testing branch. ⚠️ **Use at your own risk!** May contain bugs or experimental features. |
| `--ssh` | Enables Tailscale SSH feature after installation. |
| `--log` | Shows timestamps in all log messages. Useful for debugging and tracking execution time. |
Expand All @@ -83,6 +84,27 @@ The `update-tailscale.sh` script supports the following arguments:

## 📚 Usage Examples

### Background Mode (Recommended for SSH over Tailscale)

Run the script in background mode to prevent interruption when Tailscale restarts:

```bash
wget -O update-tailscale.sh https://raw.githubusercontent.com/Admonstrator/glinet-tailscale-updater/main/update-tailscale.sh && sh update-tailscale.sh --background --force
```

This is especially useful when:
- Connected via Tailscale SSH (prevents session termination)
- Running over an unstable connection
- Enabling Tailscale SSH with `--ssh` flag

Monitor the background execution:

```bash
tail -f /tmp/tailscale-update.log
```

> **💡 Tip:** The script automatically saves your preferences and continues running even if SSH disconnects!

### Testing/Prerelease Versions

Install prerelease versions from the testing branch for early access to new features:
Expand Down Expand Up @@ -164,7 +186,15 @@ The script automatically adds `--stateful-filtering=false` to the `gl_tailscale`

If you agree to enable Tailscale SSH during installation (manually or by using `--ssh`), the script will automatically configure Tailscale SSH after updating. You can read more about Tailscale SSH [here](https://tailscale.com/kb/1193/tailscale-ssh).

**⚠️ Warning:** If you are connected to your router via Tailscale SSH, you will be disconnected when SSH support is enabled. This might cause the script to terminate prematurely. It is recommended to run the script via local SSH or via GoodCloud SSH terminal.
**⚠️ Warning:** If you are connected to your router via Tailscale SSH, you will be disconnected when SSH support is enabled. This might cause the script to terminate prematurely.

**💡 Solution:** Use the `--background` flag to run the script in background mode, which will continue execution even if your SSH session disconnects:

```bash
sh update-tailscale.sh --background --ssh --force
```

Alternatively, run the script via local SSH or via GoodCloud SSH terminal.

### 📦 Tiny-Tailscale

Expand Down
174 changes: 174 additions & 0 deletions update-tailscale.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,125 @@ SHOW_LOG=0
ASCII_MODE=0
TESTING=0
ENABLE_SSH=0
BACKGROUND_MODE=0
WRAPPED_EXECUTION=0
USER_WANTS_UPX=""
USER_WANTS_SSH=""
USER_WANTS_PERSISTENCE=""
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
INFO='\033[0m' # No Color
ENV_FILE="/tmp/tailscale-update.env"
LOG_FILE="/tmp/tailscale-update.log"
WRAPPER_SCRIPT="/tmp/update-tailscale-wrapper.sh"

# Wrapper Functions
save_environment() {
log "INFO" "Saving execution environment to $ENV_FILE"
cat > "$ENV_FILE" << EOF
# Tailscale Update Environment
# Generated: $(date)
IGNORE_FREE_SPACE=$IGNORE_FREE_SPACE
FORCE=$FORCE
FORCE_UPGRADE=$FORCE_UPGRADE
RESTORE=$RESTORE
NO_UPX=$NO_UPX
NO_DOWNLOAD=$NO_DOWNLOAD
NO_TINY=$NO_TINY
SELECT_RELEASE=$SELECT_RELEASE
SHOW_LOG=$SHOW_LOG
ASCII_MODE=$ASCII_MODE
TESTING=$TESTING
ENABLE_SSH=$ENABLE_SSH
BACKGROUND_MODE=$BACKGROUND_MODE
WRAPPED_EXECUTION=1
USER_WANTS_UPX="$USER_WANTS_UPX"
USER_WANTS_SSH="$USER_WANTS_SSH"
USER_WANTS_PERSISTENCE="$USER_WANTS_PERSISTENCE"
EOF
log "SUCCESS" "Environment saved successfully"
}

load_environment() {
if [ -f "$ENV_FILE" ]; then
log "INFO" "Loading saved environment from $ENV_FILE"
# shellcheck source=/dev/null
. "$ENV_FILE"
log "SUCCESS" "Environment loaded successfully"
return 0
else
log "WARNING" "No saved environment found at $ENV_FILE"
return 1
fi
}

invoke_wrapper() {
log "INFO" "Starting background execution wrapper"

# Get the current script path (portable method for OpenWrt/BusyBox)
if command -v readlink >/dev/null 2>&1 && readlink -f "$0" >/dev/null 2>&1; then
SCRIPT_PATH=$(readlink -f "$0")
else
# Fallback for systems without readlink -f (e.g., some BusyBox versions)
SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")"
fi

# Copy script to temp location
log "INFO" "Copying script to $WRAPPER_SCRIPT"
cp "$SCRIPT_PATH" "$WRAPPER_SCRIPT"
chmod +x "$WRAPPER_SCRIPT"

# Save all current flags and user responses
save_environment

# Create a wrapper invocation message
echo "============================================================"
echo ""
echo " Background Execution Mode"
echo ""
echo "============================================================"
echo ""
echo " The script will now run in the background to prevent"
echo " interruption if your SSH session disconnects."
echo ""
echo " You can monitor progress by checking:"
echo " tail -f $LOG_FILE"
echo ""
echo " The script will continue running even if you disconnect."
echo ""
echo "============================================================"
echo ""

# Start the wrapped script in background with nohup
log "INFO" "Starting background execution..."

# Launch the wrapped script with appropriate method
if command -v nohup >/dev/null 2>&1; then
nohup "$WRAPPER_SCRIPT" --wrapped >> "$LOG_FILE" 2>&1 &
WRAPPER_PID=$!
log "SUCCESS" "Background process started with PID: $WRAPPER_PID (using nohup)"
elif command -v setsid >/dev/null 2>&1; then
setsid "$WRAPPER_SCRIPT" --wrapped >> "$LOG_FILE" 2>&1 &
WRAPPER_PID=$!
log "SUCCESS" "Background process started with PID: $WRAPPER_PID (using setsid)"
else
# Fallback to simple background execution
"$WRAPPER_SCRIPT" --wrapped >> "$LOG_FILE" 2>&1 &
WRAPPER_PID=$!
log "WARNING" "Started without nohup/setsid (PID: $WRAPPER_PID)"
fi

echo ""
echo "To view the log in real-time, run:"
echo " tail -f $LOG_FILE"
echo ""
echo "The script is now running in the background."
echo "You can safely disconnect from SSH."
echo ""

exit 0
}

# Functions
invoke_intro() {
Expand All @@ -58,6 +170,12 @@ invoke_intro() {
}

collect_user_preferences() {
# If running in wrapped mode, load from saved environment
if [ "$WRAPPED_EXECUTION" -eq 1 ]; then
log "INFO" "Running in wrapped execution mode - using saved preferences"
return 0
fi

log "INFO" "Collecting user preferences before starting the update process"
echo ""

Expand Down Expand Up @@ -564,6 +682,38 @@ invoke_outro() {
tailscale set --ssh --accept-risk=lose-ssh
log "SUCCESS" "Tailscale SSH support enabled."
fi

# Clean up wrapper files if running in wrapped mode
if [ "$WRAPPED_EXECUTION" -eq 1 ]; then
log "INFO" "Cleaning up wrapper files"
# Validate paths before deletion to ensure they're in /tmp
# Using case pattern matching for robust path validation
case "$ENV_FILE" in
/tmp/*)
if [ -f "$ENV_FILE" ]; then
rm -f "$ENV_FILE"
log "SUCCESS" "Removed environment file: $ENV_FILE"
fi
;;
*)
log "WARNING" "Skipping cleanup of ENV_FILE - path outside /tmp: $ENV_FILE"
;;
esac

case "$WRAPPER_SCRIPT" in
/tmp/*)
if [ -f "$WRAPPER_SCRIPT" ]; then
rm -f "$WRAPPER_SCRIPT"
log "SUCCESS" "Removed wrapper script: $WRAPPER_SCRIPT"
fi
;;
*)
log "WARNING" "Skipping cleanup of WRAPPER_SCRIPT - path outside /tmp: $WRAPPER_SCRIPT"
;;
esac

log "SUCCESS" "Wrapper cleanup complete"
fi
}

invoke_help() {
Expand All @@ -578,13 +728,20 @@ invoke_help() {
printf " \033[93m--no-tiny\033[0m \033[97mDo not use the tiny version of tailscale\033[0m\n"
printf " \033[93m--select-release\033[0m \033[97mSelect a specific release version\033[0m\n"
printf " \033[93m--ssh\033[0m \033[97mEnable Tailscale SSH support automatically\033[0m\n"
printf " \033[93m--background\033[0m \033[97mRun in background mode (survives SSH disconnection)\033[0m\n"
printf " \033[93m--testing\033[0m \033[97mUse testing/prerelease versions from testing branch\033[0m\n"
printf " \033[93m--log\033[0m \033[97mShow timestamps in log messages\033[0m\n"
printf " \033[93m--ascii\033[0m \033[97mUse ASCII characters instead of emojis\033[0m\n"
printf " \033[93m--help\033[0m \033[97mShow this help\033[0m\n"
}

invoke_update() {
# Skip update check if running in wrapped mode
if [ "$WRAPPED_EXECUTION" -eq 1 ]; then
log "INFO" "Running in wrapped mode - skipping update check"
return 0
fi

log "INFO" "Checking for script updates"
local update_url="$UPDATE_URL"
if [ "$TESTING" -eq 1 ]; then
Expand Down Expand Up @@ -826,6 +983,12 @@ for arg in "$@"; do
--ssh)
ENABLE_SSH=1
;;
--background)
BACKGROUND_MODE=1
;;
--wrapped)
WRAPPED_EXECUTION=1
;;
*)
echo "Unknown argument: $arg"
invoke_help
Expand All @@ -835,6 +998,17 @@ for arg in "$@"; do
done

# Main
# Check if running in wrapped mode - if so, load environment
if [ "$WRAPPED_EXECUTION" -eq 1 ]; then
load_environment
fi

# Check if background mode is requested and not already wrapped
if [ "$BACKGROUND_MODE" -eq 1 ] && [ "$WRAPPED_EXECUTION" -eq 0 ]; then
invoke_wrapper
# invoke_wrapper will exit, so we never reach here
fi

# Check if --restore flag is used, if yes, restore tailscale
if [ "$RESTORE" -eq 1 ]; then
restore
Expand Down
Loading