fix(upgrade): keep self-upgrades alive after stopping the service

This commit is contained in:
2026-05-25 11:41:52 +00:00
parent a3327cdd98
commit 3b179075a8
4 changed files with 93 additions and 53 deletions
+9
View File
@@ -2,7 +2,16 @@
## Pending
### Fixes
- keep self-upgrades alive after stopping the Onebox service
- Launch dashboard-triggered upgrades as transient systemd units outside the onebox.service cgroup.
- Download and validate installer binaries before stopping the running service.
- Restart the previous service if installation fails after the service was stopped.
- keep self-upgrades alive after stopping the service (upgrade)
- Launch dashboard-triggered upgrades as transient systemd units outside the service cgroup.
- Download and validate installer binaries before stopping the running service.
- Restart the previous service if installation fails after it was stopped.
## 2026-05-25 - 2.1.1
+51 -41
View File
@@ -170,14 +170,55 @@ DOWNLOAD_URL="${GITEA_BASE_URL}/${GITEA_REPO}/releases/download/${VERSION}/${BIN
echo "Download URL: $DOWNLOAD_URL"
echo ""
# Check if service is running and stop it
# Check whether the service should be restarted after a successful install.
SERVICE_WAS_RUNNING=0
if systemctl is-enabled --quiet "$SERVICE_NAME" 2>/dev/null || systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
SERVICE_WAS_RUNNING=1
if systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
echo "Stopping Onebox service..."
systemctl stop "$SERVICE_NAME"
fi
# Download and validate the new binary before touching the running service.
echo "Downloading Onebox binary..."
TEMP_DIR=$(mktemp -d)
TEMP_FILE="$TEMP_DIR/$BINARY_NAME"
cleanup_temp() {
rm -rf "$TEMP_DIR"
}
trap cleanup_temp EXIT
if ! curl -fSL "$DOWNLOAD_URL" -o "$TEMP_FILE"; then
echo "Error: Failed to download binary from $DOWNLOAD_URL"
echo ""
echo "Please check:"
echo " 1. Your internet connection"
echo " 2. The specified version exists: ${GITEA_BASE_URL}/${GITEA_REPO}/releases"
echo " 3. The platform binary is available for this release"
exit 1
fi
if [ ! -s "$TEMP_FILE" ]; then
echo "Error: Downloaded file is empty or does not exist"
exit 1
fi
chmod +x "$TEMP_FILE"
if ! "$TEMP_FILE" --version >/dev/null 2>&1; then
echo "Error: Downloaded file is not an executable Onebox binary"
exit 1
fi
SERVICE_STOPPED=0
restart_previous_service_on_error() {
if [ $SERVICE_STOPPED -eq 1 ]; then
echo "Installation failed after stopping Onebox; restarting previous service..."
systemctl start "$SERVICE_NAME" || true
fi
}
trap 'restart_previous_service_on_error; cleanup_temp' ERR
if [ $SERVICE_WAS_RUNNING -eq 1 ] && systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
echo "Stopping Onebox service..."
systemctl stop "$SERVICE_NAME"
SERVICE_STOPPED=1
fi
# Clean installation directory - ensure only binary exists
@@ -190,44 +231,10 @@ fi
echo "Creating installation directory: $INSTALL_DIR"
mkdir -p "$INSTALL_DIR"
# Download binary
echo "Downloading Onebox binary..."
TEMP_FILE="$INSTALL_DIR/onebox.download"
curl -sSL "$DOWNLOAD_URL" -o "$TEMP_FILE"
if [ $? -ne 0 ]; then
echo "Error: Failed to download binary from $DOWNLOAD_URL"
echo ""
echo "Please check:"
echo " 1. Your internet connection"
echo " 2. The specified version exists: ${GITEA_BASE_URL}/${GITEA_REPO}/releases"
echo " 3. The platform binary is available for this release"
rm -f "$TEMP_FILE"
exit 1
fi
# Check if download was successful (file exists and not empty)
if [ ! -s "$TEMP_FILE" ]; then
echo "Error: Downloaded file is empty or does not exist"
rm -f "$TEMP_FILE"
exit 1
fi
# Move to final location
# Install binary
BINARY_PATH="$INSTALL_DIR/onebox"
mv "$TEMP_FILE" "$BINARY_PATH"
if [ $? -ne 0 ] || [ ! -f "$BINARY_PATH" ]; then
echo "Error: Failed to move binary to $BINARY_PATH"
rm -f "$TEMP_FILE" 2>/dev/null
exit 1
fi
# Make executable
chmod +x "$BINARY_PATH"
if [ $? -ne 0 ]; then
echo "Error: Failed to make binary executable"
if ! install -m 0755 "$TEMP_FILE" "$BINARY_PATH" || [ ! -f "$BINARY_PATH" ]; then
echo "Error: Failed to install binary to $BINARY_PATH"
exit 1
fi
@@ -256,10 +263,13 @@ if [ $SERVICE_WAS_RUNNING -eq 1 ]; then
onebox systemd enable
echo "Restarting Onebox service..."
systemctl restart "$SERVICE_NAME"
SERVICE_STOPPED=0
echo "Service restarted successfully."
echo ""
fi
trap - ERR
echo "================================================"
echo " Onebox Installation Complete!"
echo "================================================"
+31 -11
View File
@@ -66,24 +66,43 @@ export class OneboxUpdateManager {
};
}
const command = new Deno.Command('bash', {
args: ['-c', this.createDetachedUpgradeScript()],
const unitName = `onebox-upgrade-${Date.now()}`;
const command = new Deno.Command('systemd-run', {
args: [
'--unit',
unitName,
'--description',
`Onebox upgrade to ${targetVersion}`,
'--collect',
'--property=Type=oneshot',
'--setenv=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
'bash',
'-lc',
this.createDetachedUpgradeScript(),
],
stdin: 'null',
stdout: 'null',
stderr: 'null',
detached: true,
stdout: 'piped',
stderr: 'piped',
});
const child = command.spawn();
child.unref();
const result = await command.output();
if (!result.success) {
const stderr = new TextDecoder().decode(result.stderr).trim();
const stdout = new TextDecoder().decode(result.stdout).trim();
throw new Error(
`Failed to start Onebox upgrade systemd unit: ${
stderr || stdout || `exit code ${result.code}`
}`,
);
}
this.upgradeStartedAt = Date.now();
logger.info(`Started detached Onebox upgrade process ${child.pid}`);
logger.info(`Started Onebox upgrade systemd unit ${unitName}`);
return {
accepted: true,
currentVersion: status.currentVersion,
targetVersion,
message: 'Onebox upgrade started. The service will restart automatically.',
pid: child.pid,
unitName,
logPath: UPGRADE_LOG_PATH,
};
}
@@ -107,7 +126,7 @@ export class OneboxUpdateManager {
}
const installCommand = new Deno.Command('bash', {
args: ['-c', `curl -sSL ${ONEBOX_INSTALL_SCRIPT_URL} | bash`],
args: ['-c', `set -o pipefail; curl -fsSL ${ONEBOX_INSTALL_SCRIPT_URL} | bash`],
stdin: 'inherit',
stdout: 'inherit',
stderr: 'inherit',
@@ -202,11 +221,12 @@ export class OneboxUpdateManager {
private createDetachedUpgradeScript(): string {
return `
set -e
set -o pipefail
mkdir -p /var/log
{
echo "==== Onebox upgrade started $(date -Is) ===="
sleep 2
curl -sSL ${ONEBOX_INSTALL_SCRIPT_URL} | bash
curl -fsSL ${ONEBOX_INSTALL_SCRIPT_URL} | bash
echo "==== Onebox upgrade finished $(date -Is) ===="
} >> ${UPGRADE_LOG_PATH} 2>&1
`;
+2 -1
View File
@@ -2,7 +2,7 @@
* System status data shapes for Onebox
*/
import type { TPlatformServiceType, TPlatformServiceStatus } from './platform.ts';
import type { TPlatformServiceStatus, TPlatformServiceType } from './platform.ts';
export interface IOneboxUpdateStatus {
currentVersion: string;
@@ -20,6 +20,7 @@ export interface IOneboxUpgradeStartResult {
targetVersion: string;
message: string;
pid?: number;
unitName?: string;
logPath?: string;
}