Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 809bd015a0 | |||
| ed46ecd4db | |||
| 4a76e520e7 | |||
| d9e1fc17f8 | |||
| 3b179075a8 |
@@ -3,6 +3,24 @@
|
||||
## Pending
|
||||
|
||||
|
||||
## 2026-05-25 - 2.1.3
|
||||
|
||||
### Fixes
|
||||
|
||||
- deduplicate dees-catalog in the admin UI bundle (web)
|
||||
- Collapse transitive `@design.estate/dees-catalog` resolution to a single version to avoid duplicate custom element registration.
|
||||
- deduplicate dees-catalog in the admin UI bundle (web)
|
||||
- Collapse transitive @design.estate/dees-catalog resolution to a single version to avoid duplicate custom element registration.
|
||||
- Update the bundled web artifact with the deduplicated dependency resolution.
|
||||
|
||||
## 2026-05-25 - 2.1.2
|
||||
|
||||
### Fixes
|
||||
|
||||
- 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
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@serve.zone/onebox",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.3",
|
||||
"exports": "./mod.ts",
|
||||
"tasks": {
|
||||
"test": "deno test --allow-all test/",
|
||||
|
||||
+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 "================================================"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@serve.zone/onebox",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.3",
|
||||
"description": "Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers",
|
||||
"main": "mod.ts",
|
||||
"type": "module",
|
||||
|
||||
Generated
+3
-57
@@ -48,9 +48,6 @@ packages:
|
||||
'@api.global/typedrequest-interfaces@3.0.19':
|
||||
resolution: {integrity: sha512-uuHUXJeOy/inWSDrwD0Cwax2rovpxYllDhM2RWh+6mVpQuNmZ3uw6IVg6dA2G1rOe24Ebs+Y9SzEogo+jYN7vw==}
|
||||
|
||||
'@api.global/typedrequest@3.3.0':
|
||||
resolution: {integrity: sha512-Jwobqla+9k2IBG0duwrCFtc6GU6wsvHS3f0gJJsxTrpapylBW1YSF7NnGHPGs7F9hbATsO6IoUBpR2ScoKyGJA==}
|
||||
|
||||
'@api.global/typedrequest@3.3.1':
|
||||
resolution: {integrity: sha512-uJ8uGS7T4OvnpvKlc1T6ML/CHOGKZIrgRFYYxnPKho2SZGnBFEfazWKshxlgqPsiWMZDFwX9i8c8sp+l3AGI2w==}
|
||||
|
||||
@@ -78,9 +75,6 @@ packages:
|
||||
'@configvault.io/interfaces@1.0.17':
|
||||
resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==}
|
||||
|
||||
'@design.estate/dees-catalog@3.81.0':
|
||||
resolution: {integrity: sha512-N7ocwSKVdjDQWmVV2XWiyg3dotGEuxP4/jhyB6duH8zJ3k63wmGm8+FeoP+LzRc8/U0Bl8w7UZrewlkIEMstUA==}
|
||||
|
||||
'@design.estate/dees-catalog@3.82.0':
|
||||
resolution: {integrity: sha512-OvPglDHI8J8K8+hmtxHyvVLzKMr8rQSFXVxf6xT60q/om3QoQacwS8cPI/RmnEKT+mzvDk/vnNpt9/Tw0cTmWA==}
|
||||
|
||||
@@ -2418,18 +2412,6 @@ snapshots:
|
||||
|
||||
'@api.global/typedrequest-interfaces@3.0.19': {}
|
||||
|
||||
'@api.global/typedrequest@3.3.0':
|
||||
dependencies:
|
||||
'@api.global/typedrequest-interfaces': 3.0.19
|
||||
'@push.rocks/isounique': 1.0.5
|
||||
'@push.rocks/lik': 6.4.1
|
||||
'@push.rocks/smartbuffer': 3.0.6
|
||||
'@push.rocks/smartdelay': 3.1.0
|
||||
'@push.rocks/smartguard': 3.1.0
|
||||
'@push.rocks/smartpromise': 4.2.4
|
||||
'@push.rocks/webrequest': 4.0.5
|
||||
'@push.rocks/webstream': 1.0.10
|
||||
|
||||
'@api.global/typedrequest@3.3.1':
|
||||
dependencies:
|
||||
'@api.global/typedrequest-interfaces': 3.0.19
|
||||
@@ -2448,7 +2430,7 @@ snapshots:
|
||||
'@api.global/typedrequest-interfaces': 3.0.19
|
||||
'@api.global/typedsocket': 4.1.3(@push.rocks/smartserve@2.0.4)
|
||||
'@cloudflare/workers-types': 4.20260507.1
|
||||
'@design.estate/dees-catalog': 3.81.0(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-catalog': 3.82.0(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-comms': 1.0.30
|
||||
'@push.rocks/lik': 6.4.1
|
||||
'@push.rocks/smartdelay': 3.1.0
|
||||
@@ -2513,42 +2495,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@api.global/typedrequest-interfaces': 3.0.19
|
||||
|
||||
'@design.estate/dees-catalog@3.81.0(@tiptap/pm@2.27.2)':
|
||||
dependencies:
|
||||
'@design.estate/dees-domtools': 2.5.6
|
||||
'@design.estate/dees-element': 2.2.4
|
||||
'@design.estate/dees-wcctools': 3.9.0
|
||||
'@fortawesome/fontawesome-svg-core': 7.2.0
|
||||
'@fortawesome/free-brands-svg-icons': 7.2.0
|
||||
'@fortawesome/free-regular-svg-icons': 7.2.0
|
||||
'@fortawesome/free-solid-svg-icons': 7.2.0
|
||||
'@push.rocks/smarti18n': 1.1.0
|
||||
'@push.rocks/smartpromise': 4.2.4
|
||||
'@push.rocks/smartstring': 4.1.1
|
||||
'@tempfix/webcontainer__api': 1.6.1
|
||||
'@tiptap/core': 2.27.2(@tiptap/pm@2.27.2)
|
||||
'@tiptap/extension-link': 2.27.2(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)
|
||||
'@tiptap/extension-text-align': 2.27.2(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))
|
||||
'@tiptap/extension-typography': 2.27.2(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))
|
||||
'@tiptap/extension-underline': 2.27.2(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))
|
||||
'@tiptap/starter-kit': 2.27.2
|
||||
'@tsclass/tsclass': 9.5.1
|
||||
echarts: 5.6.0
|
||||
highlight.js: 11.11.1
|
||||
ibantools: 4.5.4
|
||||
lightweight-charts: 5.2.0
|
||||
lucide: 1.14.0
|
||||
monaco-editor: 0.55.1
|
||||
pdfjs-dist: 4.10.38
|
||||
xterm: 5.3.0
|
||||
xterm-addon-fit: 0.8.0(xterm@5.3.0)
|
||||
transitivePeerDependencies:
|
||||
- '@nuxt/kit'
|
||||
- '@tiptap/pm'
|
||||
- react
|
||||
- supports-color
|
||||
- vue
|
||||
|
||||
'@design.estate/dees-catalog@3.82.0(@tiptap/pm@2.27.2)':
|
||||
dependencies:
|
||||
'@design.estate/dees-domtools': 2.5.6
|
||||
@@ -2587,7 +2533,7 @@ snapshots:
|
||||
|
||||
'@design.estate/dees-comms@1.0.30':
|
||||
dependencies:
|
||||
'@api.global/typedrequest': 3.3.0
|
||||
'@api.global/typedrequest': 3.3.1
|
||||
'@api.global/typedrequest-interfaces': 3.0.19
|
||||
'@push.rocks/smartdelay': 3.1.0
|
||||
broadcast-channel: 7.3.0
|
||||
@@ -3629,7 +3575,7 @@ snapshots:
|
||||
|
||||
'@serve.zone/catalog@2.12.6(@tiptap/pm@2.27.2)':
|
||||
dependencies:
|
||||
'@design.estate/dees-catalog': 3.81.0(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-catalog': 3.82.0(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-domtools': 2.5.6
|
||||
'@design.estate/dees-element': 2.2.4
|
||||
'@design.estate/dees-wcctools': 3.9.0
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/onebox',
|
||||
version: '2.1.1',
|
||||
version: '2.1.3',
|
||||
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
|
||||
}
|
||||
|
||||
@@ -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
|
||||
`;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/onebox',
|
||||
version: '2.1.1',
|
||||
version: '2.1.3',
|
||||
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user