Compare commits

...

5 Commits

Author SHA1 Message Date
jkunz 809bd015a0 v2.1.3
Release / build-and-release (push) Successful in 2m44s
2026-05-25 11:58:40 +00:00
jkunz ed46ecd4db fix(web): deduplicate dees-catalog in the admin UI bundle 2026-05-25 11:57:33 +00:00
jkunz 4a76e520e7 v2.1.2
Release / build-and-release (push) Successful in 2m45s
2026-05-25 11:42:48 +00:00
jkunz d9e1fc17f8 chore(changelog): deduplicate upgrade release notes 2026-05-25 11:42:29 +00:00
jkunz 3b179075a8 fix(upgrade): keep self-upgrades alive after stopping the service 2026-05-25 11:41:52 +00:00
10 changed files with 110 additions and 115 deletions
+18
View File
@@ -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 -1
View File
@@ -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/",
+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 "================================================"
+1 -1
View File
@@ -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",
+3 -57
View File
@@ -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
+1 -1
View File
@@ -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'
}
+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
`;
+1 -1
View File
File diff suppressed because one or more lines are too long
+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;
}
+1 -1
View File
@@ -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'
}