From ba90daf4d60a56a0a46240ee992f137676481087 Mon Sep 17 00:00:00 2001 From: Sven van Ginkel Date: Wed, 19 Aug 2026 17:37:11 +0200 Subject: [PATCH] fix(scripts): update agent env vars on reinstall instead of skipping (#2107) Co-authored-by: henrygd --- supplemental/scripts/install-agent.ps1 | 48 +++++++++++++--- supplemental/scripts/install-agent.sh | 80 ++++++++++++++++++++++---- 2 files changed, 109 insertions(+), 19 deletions(-) diff --git a/supplemental/scripts/install-agent.ps1 b/supplemental/scripts/install-agent.ps1 index d795b503..3bf41bcf 100644 --- a/supplemental/scripts/install-agent.ps1 +++ b/supplemental/scripts/install-agent.ps1 @@ -9,9 +9,21 @@ param ( [string]$NSSMPath = "", [switch]$ConfigureFirewall, [ValidateSet("Auto", "Scoop", "WinGet")] - [string]$InstallMethod = "Auto" + [string]$InstallMethod = "Auto", + # Set automatically from $PSBoundParameters below, or forwarded through an elevated relaunch. + # Used so a reinstall only overwrites Token/Url/Port on an existing service if the caller + # actually asked to change them, instead of wiping them with their unset defaults. + [switch]$TokenProvided, + [switch]$UrlProvided, + [switch]$PortProvided ) +if (-not $Elevated) { + $TokenProvided = $PSBoundParameters.ContainsKey('Token') + $UrlProvided = $PSBoundParameters.ContainsKey('Url') + $PortProvided = $PSBoundParameters.ContainsKey('Port') +} + # Check if required parameters are provided if ([string]::IsNullOrWhiteSpace($Key)) { Write-Host "ERROR: SSH Key is required." -ForegroundColor Red @@ -312,7 +324,10 @@ function Install-NSSMService { [string]$HubUrl = "", [Parameter(Mandatory=$true)] [int]$Port, - [string]$NSSMPath = "" + [string]$NSSMPath = "", + [switch]$TokenProvided, + [switch]$UrlProvided, + [switch]$PortProvided ) Write-Host "Installing beszel-agent service..." @@ -330,15 +345,26 @@ function Install-NSSMService { $existingService = Get-Service -Name "beszel-agent" -ErrorAction SilentlyContinue if ($existingService) { Write-Host "Service already exists. Checking if path update is needed..." - - # Get current service path + + # Get current service path + $pathNeedsUpdate = $true try { $currentPath = & $nssmCommand get beszel-agent Application if ($LASTEXITCODE -eq 0 -and $currentPath.Trim() -eq $AgentPath) { - Write-Host "Service already configured with correct path. Skipping service recreation." -ForegroundColor Green + Write-Host "Service path is already correct. Updating environment variables..." + & $nssmCommand set beszel-agent AppEnvironmentExtra "+KEY=$Key" + if ($TokenProvided) { & $nssmCommand set beszel-agent AppEnvironmentExtra "+TOKEN=$Token" } + if ($UrlProvided) { & $nssmCommand set beszel-agent AppEnvironmentExtra "+HUB_URL=$HubUrl" } + if ($PortProvided) { & $nssmCommand set beszel-agent AppEnvironmentExtra "+PORT=$Port" } + + # Restart the service so the running process picks up the new environment variables + if ($existingService.Status -eq "Running") { + Write-Host "Restarting service to apply updated environment variables..." + & $nssmCommand restart beszel-agent + } return } - + Write-Host "Service path needs updating. Stopping and removing existing service..." Write-Host " Current path: $($currentPath.Trim())" Write-Host " New path: $AgentPath" @@ -346,7 +372,7 @@ function Install-NSSMService { Write-Host "Could not retrieve current service path, will recreate service: $($_.Exception.Message)" -ForegroundColor Yellow Write-Host "Service path needs updating. Stopping and removing existing service..." } - + try { & $nssmCommand stop beszel-agent & $nssmCommand remove beszel-agent confirm @@ -589,6 +615,12 @@ try { $argumentList += "`"$NSSMPath`"" } + # Forward which optional values were explicitly provided, so the elevated + # instance knows whether to overwrite them on an existing service + if ($TokenProvided) { $argumentList += "-TokenProvided" } + if ($UrlProvided) { $argumentList += "-UrlProvided" } + if ($PortProvided) { $argumentList += "-PortProvided" } + if ($ConfigureFirewall) { $argumentList += "-ConfigureFirewall" } @@ -601,7 +633,7 @@ try { # Third: If we have admin rights, install service and configure firewall if ($isAdmin -or $Elevated) { # Install the service - Install-NSSMService -AgentPath $AgentPath -Key $Key -Token $Token -HubUrl $Url -Port $Port -NSSMPath $NSSMPath + Install-NSSMService -AgentPath $AgentPath -Key $Key -Token $Token -HubUrl $Url -Port $Port -NSSMPath $NSSMPath -TokenProvided:$TokenProvided -UrlProvided:$UrlProvided -PortProvided:$PortProvided if ($ConfigureFirewall) { Configure-Firewall -Port $Port diff --git a/supplemental/scripts/install-agent.sh b/supplemental/scripts/install-agent.sh index dbbda569..8398d0eb 100755 --- a/supplemental/scripts/install-agent.sh +++ b/supplemental/scripts/install-agent.sh @@ -97,6 +97,13 @@ ensure_trailing_slash() { fi } +# Escape text for use in the replacement portion of a sed s command whose +# delimiter is |. This only escapes sed replacement metacharacters; quoting +# for the destination configuration syntax is handled separately. +escape_sed_replacement() { + printf '%s' "$1" | sed 's/[\\&|]/\\&/g' +} + # Generate FreeBSD rc service content generate_freebsd_rc_service() { cat <<'EOF' @@ -264,6 +271,12 @@ KEY="" TOKEN="" HUB_URL="" AUTO_UPDATE_FLAG="" # empty string means prompt, "true" means auto-enable, "false" means skip +# Track which of the reconfigurable values were explicitly passed as arguments, +# so a reinstall only overwrites the fields the caller actually asked to change. +KEY_PROVIDED=false +PORT_PROVIDED=false +TOKEN_PROVIDED=false +HUB_URL_PROVIDED=false VERSION="latest" # Check for help flag @@ -294,10 +307,10 @@ build_sudo_args() { if [ -n "$QUOTED_ARGS" ]; then QUOTED_ARGS="$QUOTED_ARGS " fi - QUOTED_ARGS="$QUOTED_ARGS'$(echo "$1" | sed "s/'/'\\\\''/g")'" + QUOTED_ARGS="$QUOTED_ARGS'$(printf '%s' "$1" | sed "s/'/'\\\\''/g")'" shift done - echo "$QUOTED_ARGS" + printf '%s\n' "$QUOTED_ARGS" } # Check if running as root and re-execute with sudo if needed @@ -319,18 +332,22 @@ while [ $# -gt 0 ]; do -k) shift KEY="$1" + KEY_PROVIDED=true ;; -p) shift PORT="$1" + PORT_PROVIDED=true ;; -t) shift TOKEN="$1" + TOKEN_PROVIDED=true ;; -url) shift HUB_URL="$1" + HUB_URL_PROVIDED=true ;; -v | --version) shift @@ -566,7 +583,7 @@ if [ -z "$KEY" ]; then fi # Remove newlines from KEY -KEY=$(echo "$KEY" | tr -d '\n') +KEY=$(printf '%s' "$KEY" | tr -d '\n') # TOKEN and HUB_URL are optional for backwards compatibility - no interactive prompts # They will be set as empty environment variables if not provided @@ -804,7 +821,15 @@ EOF chmod +x /etc/init.d/beszel-agent rc-update add beszel-agent default else - echo "Alpine OpenRC service file already exists. Skipping creation." + echo "Alpine OpenRC service file already exists. Updating environment variables..." + SED_PORT=$(escape_sed_replacement "$PORT") + SED_KEY=$(escape_sed_replacement "$KEY") + SED_TOKEN=$(escape_sed_replacement "$TOKEN") + SED_HUB_URL=$(escape_sed_replacement "$HUB_URL") + [ "$PORT_PROVIDED" = "true" ] && sed -i "s|^export PORT=.*|export PORT=\"$SED_PORT\"|" /etc/init.d/beszel-agent + [ "$KEY_PROVIDED" = "true" ] && sed -i "s|^export KEY=.*|export KEY=\"$SED_KEY\"|" /etc/init.d/beszel-agent + [ "$TOKEN_PROVIDED" = "true" ] && sed -i "s|^export TOKEN=.*|export TOKEN=\"$SED_TOKEN\"|" /etc/init.d/beszel-agent + [ "$HUB_URL_PROVIDED" = "true" ] && sed -i "s|^export HUB_URL=.*|export HUB_URL=\"$SED_HUB_URL\"|" /etc/init.d/beszel-agent fi # Create log files with proper permissions @@ -886,7 +911,24 @@ EOF chmod +x /etc/init.d/beszel-agent /etc/init.d/beszel-agent enable else - echo "OpenWRT init script already exists. Skipping creation." + echo "OpenWRT init script already exists. Updating environment variables..." + # The env vars live on a single procd_set_param line, so merge any values + # that weren't explicitly provided in from the existing line before rewriting it. + CUR_ENV_LINE=$(sed -n '/^[[:space:]]*procd_set_param env PORT=/{p;q;}' /etc/init.d/beszel-agent) + if [ -z "$CUR_ENV_LINE" ] || ! printf '%s\n' "$CUR_ENV_LINE" | grep -q 'PORT="[^"]*" KEY="[^"]*" TOKEN="[^"]*" HUB_URL="[^"]*"'; then + echo "Error: Could not parse the existing environment configuration in /etc/init.d/beszel-agent." + echo "Expected a procd_set_param env line containing PORT, KEY, TOKEN, and HUB_URL." + exit 1 + fi + [ "$PORT_PROVIDED" = "true" ] || PORT=$(printf '%s\n' "$CUR_ENV_LINE" | sed -n 's/.*PORT="\([^"]*\)".*/\1/p') + [ "$KEY_PROVIDED" = "true" ] || KEY=$(printf '%s\n' "$CUR_ENV_LINE" | sed -n 's/.*KEY="\([^"]*\)".*/\1/p') + [ "$TOKEN_PROVIDED" = "true" ] || TOKEN=$(printf '%s\n' "$CUR_ENV_LINE" | sed -n 's/.*TOKEN="\([^"]*\)".*/\1/p') + [ "$HUB_URL_PROVIDED" = "true" ] || HUB_URL=$(printf '%s\n' "$CUR_ENV_LINE" | sed -n 's/.*HUB_URL="\([^"]*\)".*/\1/p') + SED_PORT=$(escape_sed_replacement "$PORT") + SED_KEY=$(escape_sed_replacement "$KEY") + SED_TOKEN=$(escape_sed_replacement "$TOKEN") + SED_HUB_URL=$(escape_sed_replacement "$HUB_URL") + sed -i "s|procd_set_param env PORT=.*|procd_set_param env PORT=\"$SED_PORT\" KEY=\"$SED_KEY\" TOKEN=\"$SED_TOKEN\" HUB_URL=\"$SED_HUB_URL\"|" /etc/init.d/beszel-agent fi # Start the service @@ -929,17 +971,25 @@ elif is_freebsd; then # Ensure rc.d directory exists on minimal FreeBSD installs mkdir -p /usr/local/etc/rc.d - # Create environment configuration file with proper permissions if it doesn't exist - if [ ! -f "$AGENT_DIR/env" ]; then - echo "Creating environment configuration file..." + # Create or update environment configuration file + if [ -f "$AGENT_DIR/env" ]; then + echo "Environment configuration file already exists. Updating environment variables..." + SED_PORT=$(escape_sed_replacement "$PORT") + SED_KEY=$(escape_sed_replacement "$KEY") + SED_TOKEN=$(escape_sed_replacement "$TOKEN") + SED_HUB_URL=$(escape_sed_replacement "$HUB_URL") + [ "$PORT_PROVIDED" = "true" ] && sed -i '' -e "s|^LISTEN=.*|LISTEN=$SED_PORT|" "$AGENT_DIR/env" + [ "$KEY_PROVIDED" = "true" ] && sed -i '' -e "s|^KEY=.*|KEY=\"$SED_KEY\"|" "$AGENT_DIR/env" + [ "$TOKEN_PROVIDED" = "true" ] && sed -i '' -e "s|^TOKEN=.*|TOKEN=$SED_TOKEN|" "$AGENT_DIR/env" + [ "$HUB_URL_PROVIDED" = "true" ] && sed -i '' -e "s|^HUB_URL=.*|HUB_URL=$SED_HUB_URL|" "$AGENT_DIR/env" + else + echo "Writing environment configuration file..." cat >"$AGENT_DIR/env" <