fix(upgrade): keep self-upgrades alive after stopping the service
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
+50
-40
@@ -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
|
||||
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"
|
||||
fi
|
||||
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 "================================================"
|
||||
|
||||
@@ -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,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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user