updateInfo: move updateInfo into apps table

this has many advantages:
* easy to deliver the updateInfo via the apps object
* after updating, the task can clear it
* when apps are deleted, the info is automatically gone

otherwise, it's a mess of deps between apps/updater/apptask/rest routes

box update info is still in a file
This commit is contained in:
Girish Ramakrishnan
2025-06-26 15:19:28 +02:00
parent abd640d36b
commit 19c9d7d59d
13 changed files with 141 additions and 149 deletions
+12 -10
View File
@@ -180,7 +180,6 @@ const appTaskManager = require('./apptaskmanager.js'),
tasks = require('./tasks.js'),
tgz = require('./backupformat/tgz.js'),
TransformStream = require('stream').Transform,
updater = require('./updater.js'),
users = require('./users.js'),
util = require('util'),
uuid = require('uuid'),
@@ -192,7 +191,7 @@ const APPS_FIELDS_PREFIXED = [ 'apps.id', 'apps.appStoreId', 'apps.installationS
'apps.health', 'apps.containerId', 'apps.manifestJson', 'apps.accessRestrictionJson', 'apps.memoryLimit', 'apps.cpuQuota',
'apps.label', 'apps.notes', 'apps.tagsJson', 'apps.taskId', 'apps.reverseProxyConfigJson', 'apps.servicesConfigJson', 'apps.operatorsJson',
'apps.sso', 'apps.devicesJson', 'apps.debugModeJson', 'apps.enableBackup', 'apps.proxyAuth', 'apps.containerIp', 'apps.crontab',
'apps.creationTime', 'apps.updateTime', 'apps.enableAutomaticUpdate', 'apps.upstreamUri', 'apps.checklistJson',
'apps.creationTime', 'apps.updateTime', 'apps.enableAutomaticUpdate', 'apps.upstreamUri', 'apps.checklistJson', 'apps.updateInfoJson',
'apps.enableMailbox', 'apps.mailboxDisplayName', 'apps.mailboxName', 'apps.mailboxDomain', 'apps.enableInbox', 'apps.inboxName', 'apps.inboxDomain',
'apps.enableTurn', 'apps.enableRedis', 'apps.storageVolumeId', 'apps.storageVolumePrefix', 'apps.ts', 'apps.healthTime', '(apps.icon IS NOT NULL) AS hasIcon', '(apps.appStoreIcon IS NOT NULL) AS hasAppStoreIcon' ].join(',');
@@ -656,6 +655,10 @@ function postProcess(result) {
result.checklist = safe.JSON.parse(result.checklistJson) || {};
delete result.checklistJson;
assert(result.updateInfoJson === null || typeof result.updateInfoJson === 'string');
result.updateInfo = safe.JSON.parse(result.updateInfoJson) || null;
delete result.updateInfoJson;
assert(result.reverseProxyConfigJson === null || typeof result.reverseProxyConfigJson === 'string');
result.reverseProxyConfig = safe.JSON.parse(result.reverseProxyConfigJson) || {};
delete result.reverseProxyConfigJson;
@@ -768,7 +771,7 @@ function canAutoupdateAppSync(app, updateInfo) {
if (!app.enableAutomaticUpdate) return { code: false, reason: 'Automatic updates for the app is disabled' };
// for invalid subscriptions the appstore does not return a dockerImage
if (!manifest.dockerImage) return { code: false, reason: 'Invalid or Expired subscription '};
if (!manifest.dockerImage) return { code: false, reason: 'Invalid or Expired subscription' };
if (updateInfo.unstable) return { code: false, reason: 'Update is marked as unstable' }; // only manual update allowed for unstable updates
@@ -801,13 +804,11 @@ function attachProperties(app, domainObjectMap) {
app.redirectDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
app.aliasDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
const updateInfo = updater.getAppUpdateInfoSync(app.id);
if (updateInfo) {
const { code, reason } = canAutoupdateAppSync(app, updateInfo); // isAutoUpdatable is not cached since it depends on enableAutomaticUpdate and runState
updateInfo.isAutoUpdatable = code;
updateInfo.manualUpdateReason = reason;
if (app.updateInfo) {
const { code, reason } = canAutoupdateAppSync(app, app.updateInfo); // isAutoUpdatable is not cached since it depends on enableAutomaticUpdate and runState
app.updateInfo.isAutoUpdatable = code;
app.updateInfo.manualUpdateReason = reason;
}
app.updateInfo = updateInfo;
}
function isAdmin(user) {
@@ -1069,7 +1070,8 @@ async function updateWithConstraints(id, app, constraints) {
const fields = [ ], values = [ ];
for (const p in app) {
if (p === 'manifest' || p === 'tags' || p === 'checklist' || p === 'accessRestriction' || p === 'devices' || p === 'debugMode' || p === 'error' || p === 'reverseProxyConfig' || p === 'servicesConfig' || p === 'operators') {
if (p === 'manifest' || p === 'tags' || p === 'checklist' || p === 'accessRestriction' || p === 'devices' || p === 'debugMode' || p === 'error'
|| p === 'reverseProxyConfig' || p === 'servicesConfig' || p === 'operators' || p === 'updateInfo') {
fields.push(`${p}Json = ?`);
values.push(JSON.stringify(app[p]));
} else if (p !== 'portBindings' && p !== 'subdomain' && p !== 'domain' && p !== 'secondaryDomains' && p !== 'redirectDomains' && p !== 'aliasDomains' && p !== 'env' && p !== 'mounts') {