Add auto-update system for DashCaddy instances
- self-updater.js: polls for new versions, downloads/verifies tarballs, triggers host-side rebuild via systemd path unit - dashcaddy-update.sh + systemd units: host-side container rebuild with automatic rollback on health check failure - 7 new /api/v1/system/* endpoints for version info, update check/apply, rollback, and update history - Frontend: DashCaddy tab in Updates modal with version display, changelog, update button, rollback, and notification dot - install.sh: updater service installation, volume mounts, env vars - build-release.sh + webhook-handler.js: release server pipeline (Gitea webhook → build tarball → deploy to get.dashcaddy.net) - Dockerfile: DASHCADDY_COMMIT build arg → VERSION file - Version bump to 1.1.0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -59,5 +59,69 @@ module.exports = function(ctx) {
|
||||
res.json({ success: true, message: 'Update scheduled', scheduledTime });
|
||||
}, 'updates-schedule'));
|
||||
|
||||
// ===== DASHCADDY SELF-UPDATE ENDPOINTS =====
|
||||
|
||||
// Get current version
|
||||
router.get('/system/version', ctx.asyncHandler(async (req, res) => {
|
||||
const local = ctx.selfUpdater.getLocalVersion();
|
||||
res.json({ success: true, name: 'DashCaddy', version: local.version, commit: local.commit });
|
||||
}, 'system-version'));
|
||||
|
||||
// Check for DashCaddy update
|
||||
router.get('/system/update-check', ctx.asyncHandler(async (req, res) => {
|
||||
const result = await ctx.selfUpdater.checkForUpdate();
|
||||
res.json({ success: true, ...result });
|
||||
}, 'system-update-check'));
|
||||
|
||||
// Apply available update
|
||||
router.post('/system/update-apply', ctx.asyncHandler(async (req, res) => {
|
||||
const check = await ctx.selfUpdater.checkForUpdate();
|
||||
if (!check.available) {
|
||||
return res.json({ success: true, message: 'Already up to date' });
|
||||
}
|
||||
// Start async — container may restart
|
||||
ctx.selfUpdater.applyUpdate(check.remote).catch(err => {
|
||||
ctx.logError('self-update', err);
|
||||
});
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Update initiated',
|
||||
fromVersion: check.local.version,
|
||||
toVersion: check.remote.version,
|
||||
});
|
||||
}, 'system-update-apply'));
|
||||
|
||||
// Get update status
|
||||
router.get('/system/update-status', ctx.asyncHandler(async (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
status: ctx.selfUpdater.getStatus(),
|
||||
lastCheck: ctx.selfUpdater.lastCheckTime,
|
||||
lastResult: ctx.selfUpdater.lastCheckResult,
|
||||
});
|
||||
}, 'system-update-status'));
|
||||
|
||||
// Get self-update history
|
||||
router.get('/system/update-history', ctx.asyncHandler(async (req, res) => {
|
||||
const history = ctx.selfUpdater.getUpdateHistory();
|
||||
res.json({ success: true, history });
|
||||
}, 'system-update-history'));
|
||||
|
||||
// List rollback versions
|
||||
router.get('/system/rollback-versions', ctx.asyncHandler(async (req, res) => {
|
||||
const versions = ctx.selfUpdater.getAvailableRollbacks();
|
||||
res.json({ success: true, versions });
|
||||
}, 'system-rollback-versions'));
|
||||
|
||||
// Rollback to a previous version
|
||||
router.post('/system/rollback', ctx.asyncHandler(async (req, res) => {
|
||||
const { version } = req.body;
|
||||
if (!version) return ctx.errorResponse(res, 400, 'version is required');
|
||||
ctx.selfUpdater.rollbackToVersion(version).catch(err => {
|
||||
ctx.logError('self-rollback', err);
|
||||
});
|
||||
res.json({ success: true, message: `Rollback to ${version} initiated` });
|
||||
}, 'system-rollback'));
|
||||
|
||||
return router;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user