Compare commits
11 Commits
authserver
...
v5.2.4
| Author | SHA1 | Date | |
|---|---|---|---|
| f422b8533f | |||
| 234dfe59e2 | |||
| 9973a3c809 | |||
| 5aa426b8e2 | |||
| 70807d4551 | |||
| ca6665dd20 | |||
| c226b94f17 | |||
| 2dc7342f09 | |||
| 02b4b0f7d2 | |||
| 4267f5ea0a | |||
| 2e76b8bed9 |
@@ -1935,6 +1935,8 @@
|
|||||||
* stopping an app will stop dependent services
|
* stopping an app will stop dependent services
|
||||||
* Add new wasabi s3 storage region us-east-2
|
* Add new wasabi s3 storage region us-east-2
|
||||||
* mail: Fix bug where SRS translation was done on the main domain instead of mailing list domain
|
* mail: Fix bug where SRS translation was done on the main domain instead of mailing list domain
|
||||||
|
* backups: add retention policy
|
||||||
|
* Drop `NET_RAW` caps from container preventing sniffing of network traffic
|
||||||
|
|
||||||
[5.2.1]
|
[5.2.1]
|
||||||
* Fix app disk graphs
|
* Fix app disk graphs
|
||||||
@@ -1949,3 +1951,13 @@
|
|||||||
* import: fix crash because encryption is unset
|
* import: fix crash because encryption is unset
|
||||||
* create redis with the correct label
|
* create redis with the correct label
|
||||||
|
|
||||||
|
[5.2.3]
|
||||||
|
* Do not restart stopped apps
|
||||||
|
|
||||||
|
[5.2.4]
|
||||||
|
* mail: enable/disable incoming mail was showing an error
|
||||||
|
* Do not trigger backup of stopped apps. Instead, we will just retain it's existing backups
|
||||||
|
based on retention policy
|
||||||
|
* remove broken disk graphs
|
||||||
|
* fix OVH backups
|
||||||
|
|
||||||
|
|||||||
@@ -696,6 +696,11 @@ function checkAppState(app, state) {
|
|||||||
if (state !== exports.ISTATE_PENDING_UNINSTALL && state !== exports.ISTATE_PENDING_RESTORE) return new BoxError(BoxError.BAD_STATE, 'Not allowed in error state');
|
if (state !== exports.ISTATE_PENDING_UNINSTALL && state !== exports.ISTATE_PENDING_RESTORE) return new BoxError(BoxError.BAD_STATE, 'Not allowed in error state');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (app.runState === exports.RSTATE_STOPPED) {
|
||||||
|
// can't backup or restore since app addons are down. can't update because migration scripts won't run
|
||||||
|
if (state === exports.ISTATE_PENDING_UPDATE || state === exports.ISTATE_PENDING_BACKUP || state === exports.ISTATE_PENDING_RESTORE) return new BoxError(BoxError.BAD_STATE, 'Not allowed in stopped state');
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2001,6 +2006,7 @@ function restartAppsUsingAddons(changedAddons, callback) {
|
|||||||
apps = apps.filter(app => app.manifest.addons && _.intersection(Object.keys(app.manifest.addons), changedAddons).length !== 0);
|
apps = apps.filter(app => app.manifest.addons && _.intersection(Object.keys(app.manifest.addons), changedAddons).length !== 0);
|
||||||
apps = apps.filter(app => app.installationState !== exports.ISTATE_ERROR); // remove errored apps. let them be 'repaired' by hand
|
apps = apps.filter(app => app.installationState !== exports.ISTATE_ERROR); // remove errored apps. let them be 'repaired' by hand
|
||||||
apps = apps.filter(app => app.installationState !== exports.ISTATE_PENDING_RESTART); // safeguard against tasks being created non-stop restart if we crash on startup
|
apps = apps.filter(app => app.installationState !== exports.ISTATE_PENDING_RESTART); // safeguard against tasks being created non-stop restart if we crash on startup
|
||||||
|
apps = apps.filter(app => app.runState !== exports.RSTATE_STOPPED); // don't start stopped apps
|
||||||
|
|
||||||
async.eachSeries(apps, function (app, iteratorDone) {
|
async.eachSeries(apps, function (app, iteratorDone) {
|
||||||
debug(`restartAppsUsingAddons: marking ${app.fqdn} for restart`);
|
debug(`restartAppsUsingAddons: marking ${app.fqdn} for restart`);
|
||||||
|
|||||||
+14
-1
@@ -1026,6 +1026,10 @@ function backupBoxWithAppBackupIds(appBackupIds, tag, progressCallback, callback
|
|||||||
|
|
||||||
function canBackupApp(app) {
|
function canBackupApp(app) {
|
||||||
// only backup apps that are installed or specific pending states
|
// only backup apps that are installed or specific pending states
|
||||||
|
|
||||||
|
// stopped apps cannot be backed up because addons might be down (redis)
|
||||||
|
if (app.runState === apps.RSTATE_STOPPED) return false;
|
||||||
|
|
||||||
// we used to check the health here but that doesn't work for stopped apps. it's better to just fail
|
// we used to check the health here but that doesn't work for stopped apps. it's better to just fail
|
||||||
// and inform the user if the backup fails and the app addons have not been setup yet.
|
// and inform the user if the backup fails and the app addons have not been setup yet.
|
||||||
return app.installationState === apps.ISTATE_INSTALLED ||
|
return app.installationState === apps.ISTATE_INSTALLED ||
|
||||||
@@ -1141,7 +1145,16 @@ function backupAppWithTag(app, tag, options, progressCallback, callback) {
|
|||||||
assert.strictEqual(typeof progressCallback, 'function');
|
assert.strictEqual(typeof progressCallback, 'function');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
if (!canBackupApp(app)) return callback(); // nothing to do
|
if (!canBackupApp(app)) { // if we cannot backup, reuse it's most recent backup
|
||||||
|
getByAppIdPaged(1, 1, app.id, function (error, results) {
|
||||||
|
if (error) return callback(error);
|
||||||
|
if (results.length === 0) return callback(null, null); // no backup to re-use
|
||||||
|
|
||||||
|
callback(null, results[0].id);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
settings.getBackupConfig(function (error, backupConfig) {
|
settings.getBackupConfig(function (error, backupConfig) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|||||||
+17
-6
@@ -1,11 +1,22 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
// IMPORTANT: These patterns are together because they spin tasks which acquire a lock
|
||||||
|
// If the patterns overlap all the time, then the task may not ever get a chance to run!
|
||||||
|
const DEFAULT_CLEANUP_BACKUPS_PATTERN = '00 30 1,3,5,23 * * *',
|
||||||
|
DEFAULT_BOX_ENSURE_BACKUP_PATTERN_LT_6HOURS = '00 45 1,7,13,19 * * *',
|
||||||
|
DEFAULT_BOX_ENSURE_BACKUP_PATTERN_GT_6HOURS = '00 45 1,3,5,23 * * *',
|
||||||
|
DEFAULT_BOX_AUTOUPDATE_PATTERN = '00 00 1,3,5,23 * * *',
|
||||||
|
DEFAULT_APP_AUTOUPDATE_PATTERN = '00 15 1,3,5,23 * * *';
|
||||||
|
|
||||||
exports = module.exports = {
|
exports = module.exports = {
|
||||||
startJobs: startJobs,
|
startJobs,
|
||||||
|
|
||||||
stopJobs: stopJobs,
|
stopJobs,
|
||||||
|
|
||||||
handleSettingsChanged: handleSettingsChanged
|
handleSettingsChanged,
|
||||||
|
|
||||||
|
DEFAULT_BOX_AUTOUPDATE_PATTERN,
|
||||||
|
DEFAULT_APP_AUTOUPDATE_PATTERN
|
||||||
};
|
};
|
||||||
|
|
||||||
var appHealthMonitor = require('./apphealthmonitor.js'),
|
var appHealthMonitor = require('./apphealthmonitor.js'),
|
||||||
@@ -98,7 +109,7 @@ function startJobs(callback) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gJobs.cleanupBackups = new CronJob({
|
gJobs.cleanupBackups = new CronJob({
|
||||||
cronTime: '00 45 1,3,5,23 * * *', // every 6 hours. try not to overlap with ensureBackup job
|
cronTime: DEFAULT_CLEANUP_BACKUPS_PATTERN,
|
||||||
onTick: backups.startCleanupTask.bind(null, auditSource.CRON, NOOP_CALLBACK),
|
onTick: backups.startCleanupTask.bind(null, auditSource.CRON, NOOP_CALLBACK),
|
||||||
start: true
|
start: true
|
||||||
});
|
});
|
||||||
@@ -177,9 +188,9 @@ function backupConfigChanged(value, tz) {
|
|||||||
if (gJobs.backup) gJobs.backup.stop();
|
if (gJobs.backup) gJobs.backup.stop();
|
||||||
let pattern;
|
let pattern;
|
||||||
if (value.intervalSecs <= 6 * 60 * 60) {
|
if (value.intervalSecs <= 6 * 60 * 60) {
|
||||||
pattern = '00 00 1,7,13,19 * * *'; // no option but to backup in the middle of the day
|
pattern = DEFAULT_BOX_ENSURE_BACKUP_PATTERN_LT_6HOURS; // no option but to backup in the middle of the day
|
||||||
} else {
|
} else {
|
||||||
pattern = '00 00 1,3,5,23 * * *'; // avoid middle of the day backups
|
pattern = DEFAULT_BOX_ENSURE_BACKUP_PATTERN_GT_6HOURS; // avoid middle of the day backups. it's 45 to not overlap auto-updates
|
||||||
}
|
}
|
||||||
|
|
||||||
gJobs.backup = new CronJob({
|
gJobs.backup = new CronJob({
|
||||||
|
|||||||
+2
-2
@@ -131,8 +131,8 @@ var addons = require('./addons.js'),
|
|||||||
|
|
||||||
let gDefaults = (function () {
|
let gDefaults = (function () {
|
||||||
var result = { };
|
var result = { };
|
||||||
result[exports.APP_AUTOUPDATE_PATTERN_KEY] = '00 30 1,3,5,23 * * *';
|
result[exports.APP_AUTOUPDATE_PATTERN_KEY] = cron.DEFAULT_APP_AUTOUPDATE_PATTERN;
|
||||||
result[exports.BOX_AUTOUPDATE_PATTERN_KEY] = '00 00 1,3,5,23 * * *';
|
result[exports.BOX_AUTOUPDATE_PATTERN_KEY] = cron.DEFAULT_BOX_AUTOUPDATE_PATTERN;
|
||||||
result[exports.TIME_ZONE_KEY] = 'America/Los_Angeles';
|
result[exports.TIME_ZONE_KEY] = 'America/Los_Angeles';
|
||||||
result[exports.CLOUDRON_NAME_KEY] = 'Cloudron';
|
result[exports.CLOUDRON_NAME_KEY] = 'Cloudron';
|
||||||
result[exports.DYNAMIC_DNS_KEY] = false;
|
result[exports.DYNAMIC_DNS_KEY] = false;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ describe('Settings', function () {
|
|||||||
it('can get default app_autoupdate_pattern', function (done) {
|
it('can get default app_autoupdate_pattern', function (done) {
|
||||||
settings.getAppAutoupdatePattern(function (error, pattern) {
|
settings.getAppAutoupdatePattern(function (error, pattern) {
|
||||||
expect(error).to.be(null);
|
expect(error).to.be(null);
|
||||||
expect(pattern).to.be('00 30 1,3,5,23 * * *');
|
expect(pattern).to.be('00 15 1,3,5,23 * * *');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ function checkAppUpdates(options, callback) {
|
|||||||
|
|
||||||
async.eachSeries(result, function (app, iteratorDone) {
|
async.eachSeries(result, function (app, iteratorDone) {
|
||||||
if (app.appStoreId === '') return iteratorDone(); // appStoreId can be '' for dev apps
|
if (app.appStoreId === '') return iteratorDone(); // appStoreId can be '' for dev apps
|
||||||
if (app.runState === apps.RSTATE_STOPPED) return iteratorDone(); // stopped apps won't run migration scripts and shouldn't be updated
|
|
||||||
|
|
||||||
appstore.getAppUpdate(app, options, function (error, updateInfo) {
|
appstore.getAppUpdate(app, options, function (error, updateInfo) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user