Split box and app autoupdate pattern settings

This commit is contained in:
Johannes Zellner
2018-02-06 18:57:30 +01:00
parent 09b33e7ef9
commit 11d740682e
7 changed files with 205 additions and 46 deletions
+37 -10
View File
@@ -27,7 +27,8 @@ var apps = require('./apps.js'),
var gJobs = {
alive: null, // send periodic stats
autoUpdater: null,
appAutoUpdater: null,
boxAutoUpdater: null,
appUpdateChecker: null,
backup: null,
boxUpdateChecker: null,
@@ -78,14 +79,16 @@ function initialize(callback) {
});
settings.events.on(settings.TIME_ZONE_KEY, recreateJobs);
settings.events.on(settings.AUTOUPDATE_PATTERN_KEY, autoupdatePatternChanged);
settings.events.on(settings.APP_AUTOUPDATE_PATTERN_KEY, appAutoupdatePatternChanged);
settings.events.on(settings.BOX_AUTOUPDATE_PATTERN_KEY, boxAutoupdatePatternChanged);
settings.events.on(settings.DYNAMIC_DNS_KEY, dynamicDnsChanged);
settings.getAll(function (error, allSettings) {
if (error) return callback(error);
recreateJobs(allSettings[settings.TIME_ZONE_KEY]);
autoupdatePatternChanged(allSettings[settings.AUTOUPDATE_PATTERN_KEY]);
appAutoupdatePatternChanged(allSettings[settings.APP_AUTOUPDATE_PATTERN_KEY]);
boxAutoupdatePatternChanged(allSettings[settings.BOX_AUTOUPDATE_PATTERN_KEY]);
dynamicDnsChanged(allSettings[settings.DYNAMIC_DNS_KEY]);
callback();
@@ -189,17 +192,17 @@ function recreateJobs(tz) {
});
}
function autoupdatePatternChanged(pattern) {
function boxAutoupdatePatternChanged(pattern) {
assert.strictEqual(typeof pattern, 'string');
assert(gJobs.boxUpdateCheckerJob);
debug('Auto update pattern changed to %s', pattern);
debug('Box auto update pattern changed to %s', pattern);
if (gJobs.autoUpdater) gJobs.autoUpdater.stop();
if (gJobs.boxAutoUpdater) gJobs.boxAutoUpdater.stop();
if (pattern === constants.AUTOUPDATE_PATTERN_NEVER) return;
gJobs.autoUpdater = new CronJob({
gJobs.boxAutoUpdater = new CronJob({
cronTime: pattern,
onTick: function() {
var updateInfo = updateChecker.getUpdateInfo();
@@ -210,11 +213,34 @@ function autoupdatePatternChanged(pattern) {
} else {
debug('Block automatic update for major version');
}
} else if (updateInfo.apps) {
} else {
debug('No box auto updates available');
}
},
start: true,
timeZone: gJobs.boxUpdateCheckerJob.cronTime.zone // hack
});
}
function appAutoupdatePatternChanged(pattern) {
assert.strictEqual(typeof pattern, 'string');
assert(gJobs.boxUpdateCheckerJob);
debug('Apps auto update pattern changed to %s', pattern);
if (gJobs.appAutoUpdater) gJobs.appAutoUpdater.stop();
if (pattern === constants.AUTOUPDATE_PATTERN_NEVER) return;
gJobs.appAutoUpdater = new CronJob({
cronTime: pattern,
onTick: function() {
var updateInfo = updateChecker.getUpdateInfo();
if (updateInfo.apps) {
debug('Starting app update to %j', updateInfo.apps);
apps.autoupdateApps(updateInfo.apps, AUDIT_SOURCE, NOOP_CALLBACK);
} else {
debug('No auto updates available');
debug('No app auto updates available');
}
},
start: true,
@@ -245,7 +271,8 @@ function uninitialize(callback) {
assert.strictEqual(typeof callback, 'function');
settings.events.removeListener(settings.TIME_ZONE_KEY, recreateJobs);
settings.events.removeListener(settings.AUTOUPDATE_PATTERN_KEY, autoupdatePatternChanged);
settings.events.removeListener(settings.APP_AUTOUPDATE_PATTERN_KEY, appAutoupdatePatternChanged);
settings.events.removeListener(settings.BOX_AUTOUPDATE_PATTERN_KEY, boxAutoupdatePatternChanged);
settings.events.removeListener(settings.DYNAMIC_DNS_KEY, dynamicDnsChanged);
for (var job in gJobs) {
+30 -6
View File
@@ -1,8 +1,11 @@
'use strict';
exports = module.exports = {
getAutoupdatePattern: getAutoupdatePattern,
setAutoupdatePattern: setAutoupdatePattern,
getAppAutoupdatePattern: getAppAutoupdatePattern,
setAppAutoupdatePattern: setAppAutoupdatePattern,
getBoxAutoupdatePattern: getBoxAutoupdatePattern,
setBoxAutoupdatePattern: setBoxAutoupdatePattern,
getCloudronName: getCloudronName,
setCloudronName: setCloudronName,
@@ -27,20 +30,41 @@ var assert = require('assert'),
settings = require('../settings.js'),
SettingsError = settings.SettingsError;
function getAutoupdatePattern(req, res, next) {
settings.getAutoupdatePattern(function (error, pattern) {
function getAppAutoupdatePattern(req, res, next) {
settings.getAppAutoupdatePattern(function (error, pattern) {
if (error) return next(new HttpError(500, error));
next(new HttpSuccess(200, { pattern: pattern }));
});
}
function setAutoupdatePattern(req, res, next) {
function setAppAutoupdatePattern(req, res, next) {
assert.strictEqual(typeof req.body, 'object');
if (typeof req.body.pattern !== 'string') return next(new HttpError(400, 'pattern is required'));
settings.setAutoupdatePattern(req.body.pattern, function (error) {
settings.setAppAutoupdatePattern(req.body.pattern, function (error) {
if (error && error.reason === SettingsError.BAD_FIELD) return next(new HttpError(400, error.message));
if (error) return next(new HttpError(500, error));
next(new HttpSuccess(200));
});
}
function getBoxAutoupdatePattern(req, res, next) {
settings.getBoxAutoupdatePattern(function (error, pattern) {
if (error) return next(new HttpError(500, error));
next(new HttpSuccess(200, { pattern: pattern }));
});
}
function setBoxAutoupdatePattern(req, res, next) {
assert.strictEqual(typeof req.body, 'object');
if (typeof req.body.pattern !== 'string') return next(new HttpError(400, 'pattern is required'));
settings.setBoxAutoupdatePattern(req.body.pattern, function (error) {
if (error && error.reason === SettingsError.BAD_FIELD) return next(new HttpError(400, error.message));
if (error) return next(new HttpError(500, error));
+76 -13
View File
@@ -63,9 +63,9 @@ describe('Settings API', function () {
before(setup);
after(cleanup);
describe('autoupdate_pattern', function () {
it('can get auto update pattern (default)', function (done) {
superagent.get(SERVER_URL + '/api/v1/settings/autoupdate_pattern')
describe('app_autoupdate_pattern', function () {
it('can get app auto update pattern (default)', function (done) {
superagent.get(SERVER_URL + '/api/v1/settings/app_autoupdate_pattern')
.query({ access_token: token })
.end(function (err, res) {
expect(res.statusCode).to.equal(200);
@@ -74,8 +74,8 @@ describe('Settings API', function () {
});
});
it('cannot set autoupdate_pattern without pattern', function (done) {
superagent.post(SERVER_URL + '/api/v1/settings/autoupdate_pattern')
it('cannot set app_autoupdate_pattern without pattern', function (done) {
superagent.post(SERVER_URL + '/api/v1/settings/app_autoupdate_pattern')
.query({ access_token: token })
.end(function (err, res) {
expect(res.statusCode).to.equal(400);
@@ -83,13 +83,13 @@ describe('Settings API', function () {
});
});
it('can set autoupdate_pattern', function (done) {
it('can set app_autoupdate_pattern', function (done) {
var eventPattern = null;
settings.events.on(settings.AUTOUPDATE_PATTERN_KEY, function (pattern) {
settings.events.on(settings.APP_AUTOUPDATE_PATTERN_KEY, function (pattern) {
eventPattern = pattern;
});
superagent.post(SERVER_URL + '/api/v1/settings/autoupdate_pattern')
superagent.post(SERVER_URL + '/api/v1/settings/app_autoupdate_pattern')
.query({ access_token: token })
.send({ pattern: '00 30 11 * * 1-5' })
.end(function (err, res) {
@@ -99,13 +99,13 @@ describe('Settings API', function () {
});
});
it('can set autoupdate_pattern to never', function (done) {
it('can set app_autoupdate_pattern to never', function (done) {
var eventPattern = null;
settings.events.on(settings.AUTOUPDATE_PATTERN_KEY, function (pattern) {
settings.events.on(settings.APP_AUTOUPDATE_PATTERN_KEY, function (pattern) {
eventPattern = pattern;
});
superagent.post(SERVER_URL + '/api/v1/settings/autoupdate_pattern')
superagent.post(SERVER_URL + '/api/v1/settings/app_autoupdate_pattern')
.query({ access_token: token })
.send({ pattern: constants.AUTOUPDATE_PATTERN_NEVER })
.end(function (err, res) {
@@ -115,8 +115,71 @@ describe('Settings API', function () {
});
});
it('cannot set invalid autoupdate_pattern', function (done) {
superagent.post(SERVER_URL + '/api/v1/settings/autoupdate_pattern')
it('cannot set invalid app_autoupdate_pattern', function (done) {
superagent.post(SERVER_URL + '/api/v1/settings/app_autoupdate_pattern')
.query({ access_token: token })
.send({ pattern: '1 3 x 5 6' })
.end(function (err, res) {
expect(res.statusCode).to.equal(400);
done();
});
});
});
describe('box_autoupdate_pattern', function () {
it('can get app auto update pattern (default)', function (done) {
superagent.get(SERVER_URL + '/api/v1/settings/box_autoupdate_pattern')
.query({ access_token: token })
.end(function (err, res) {
expect(res.statusCode).to.equal(200);
expect(res.body.pattern).to.be.ok();
done();
});
});
it('cannot set box_autoupdate_pattern without pattern', function (done) {
superagent.post(SERVER_URL + '/api/v1/settings/box_autoupdate_pattern')
.query({ access_token: token })
.end(function (err, res) {
expect(res.statusCode).to.equal(400);
done();
});
});
it('can set box_autoupdate_pattern', function (done) {
var eventPattern = null;
settings.events.on(settings.BOX_AUTOUPDATE_PATTERN_KEY, function (pattern) {
eventPattern = pattern;
});
superagent.post(SERVER_URL + '/api/v1/settings/box_autoupdate_pattern')
.query({ access_token: token })
.send({ pattern: '00 30 11 * * 1-5' })
.end(function (err, res) {
expect(res.statusCode).to.equal(200);
expect(eventPattern === '00 30 11 * * 1-5').to.be.ok();
done();
});
});
it('can set box_autoupdate_pattern to never', function (done) {
var eventPattern = null;
settings.events.on(settings.BOX_AUTOUPDATE_PATTERN_KEY, function (pattern) {
eventPattern = pattern;
});
superagent.post(SERVER_URL + '/api/v1/settings/box_autoupdate_pattern')
.query({ access_token: token })
.send({ pattern: constants.AUTOUPDATE_PATTERN_NEVER })
.end(function (err, res) {
expect(res.statusCode).to.equal(200);
expect(eventPattern).to.eql(constants.AUTOUPDATE_PATTERN_NEVER);
done();
});
});
it('cannot set invalid box_autoupdate_pattern', function (done) {
superagent.post(SERVER_URL + '/api/v1/settings/box_autoupdate_pattern')
.query({ access_token: token })
.send({ pattern: '1 3 x 5 6' })
.end(function (err, res) {
+4 -2
View File
@@ -195,8 +195,10 @@ function initializeExpressSync() {
router.post('/api/v1/apps/:id/upload', appsScope, routes.user.requireAdmin, multipart, routes.apps.uploadFile);
// settings routes (these are for the settings tab - avatar & name have public routes for normal users. see above)
router.get ('/api/v1/settings/autoupdate_pattern', settingsScope, routes.user.requireAdmin, routes.settings.getAutoupdatePattern);
router.post('/api/v1/settings/autoupdate_pattern', settingsScope, routes.user.requireAdmin, routes.settings.setAutoupdatePattern);
router.get ('/api/v1/settings/app_autoupdate_pattern', settingsScope, routes.user.requireAdmin, routes.settings.getAppAutoupdatePattern);
router.post('/api/v1/settings/app_autoupdate_pattern', settingsScope, routes.user.requireAdmin, routes.settings.setAppAutoupdatePattern);
router.get ('/api/v1/settings/box_autoupdate_pattern', settingsScope, routes.user.requireAdmin, routes.settings.getBoxAutoupdatePattern);
router.post('/api/v1/settings/box_autoupdate_pattern', settingsScope, routes.user.requireAdmin, routes.settings.setBoxAutoupdatePattern);
router.get ('/api/v1/settings/cloudron_name', settingsScope, routes.user.requireAdmin, routes.settings.getCloudronName);
router.post('/api/v1/settings/cloudron_name', settingsScope, routes.user.requireAdmin, routes.settings.setCloudronName);
router.get ('/api/v1/settings/cloudron_avatar', settingsScope, routes.user.requireAdmin, routes.settings.getCloudronAvatar);
+44 -10
View File
@@ -6,8 +6,11 @@ exports = module.exports = {
initialize: initialize,
uninitialize: uninitialize,
getAutoupdatePattern: getAutoupdatePattern,
setAutoupdatePattern: setAutoupdatePattern,
getAppAutoupdatePattern: getAppAutoupdatePattern,
setAppAutoupdatePattern: setAppAutoupdatePattern,
getBoxAutoupdatePattern: getBoxAutoupdatePattern,
setBoxAutoupdatePattern: setBoxAutoupdatePattern,
getTimeZone: getTimeZone,
setTimeZone: setTimeZone,
@@ -45,7 +48,8 @@ exports = module.exports = {
CAAS_CONFIG_KEY: 'caas_config',
// strings
AUTOUPDATE_PATTERN_KEY: 'autoupdate_pattern',
APP_AUTOUPDATE_PATTERN_KEY: 'autoupdate_pattern',
BOX_AUTOUPDATE_PATTERN_KEY: 'box_autoupdate_pattern',
TIME_ZONE_KEY: 'time_zone',
CLOUDRON_NAME_KEY: 'cloudron_name',
@@ -69,7 +73,8 @@ var assert = require('assert'),
var gDefaults = (function () {
var result = { };
result[exports.AUTOUPDATE_PATTERN_KEY] = constants.AUTOUPDATE_PATTERN_NEVER;
result[exports.APP_AUTOUPDATE_PATTERN_KEY] = constants.AUTOUPDATE_PATTERN_NEVER;
result[exports.BOX_AUTOUPDATE_PATTERN_KEY] = '00 00 1,3,5,23 * * *';
result[exports.TIME_ZONE_KEY] = 'America/Los_Angeles';
result[exports.CLOUDRON_NAME_KEY] = 'Cloudron';
result[exports.DYNAMIC_DNS_KEY] = false;
@@ -125,7 +130,7 @@ function uninitialize(callback) {
callback();
}
function setAutoupdatePattern(pattern, callback) {
function setAppAutoupdatePattern(pattern, callback) {
assert.strictEqual(typeof pattern, 'string');
assert.strictEqual(typeof callback, 'function');
@@ -134,20 +139,49 @@ function setAutoupdatePattern(pattern, callback) {
if (!job) return callback(new SettingsError(SettingsError.BAD_FIELD, 'Invalid pattern'));
}
settingsdb.set(exports.AUTOUPDATE_PATTERN_KEY, pattern, function (error) {
settingsdb.set(exports.APP_AUTOUPDATE_PATTERN_KEY, pattern, function (error) {
if (error) return callback(new SettingsError(SettingsError.INTERNAL_ERROR, error));
exports.events.emit(exports.AUTOUPDATE_PATTERN_KEY, pattern);
exports.events.emit(exports.APP_AUTOUPDATE_PATTERN_KEY, pattern);
return callback(null);
});
}
function getAutoupdatePattern(callback) {
function getAppAutoupdatePattern(callback) {
assert.strictEqual(typeof callback, 'function');
settingsdb.get(exports.AUTOUPDATE_PATTERN_KEY, function (error, pattern) {
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(null, gDefaults[exports.AUTOUPDATE_PATTERN_KEY]);
settingsdb.get(exports.APP_AUTOUPDATE_PATTERN_KEY, function (error, pattern) {
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(null, gDefaults[exports.APP_AUTOUPDATE_PATTERN_KEY]);
if (error) return callback(new SettingsError(SettingsError.INTERNAL_ERROR, error));
callback(null, pattern);
});
}
function setBoxAutoupdatePattern(pattern, callback) {
assert.strictEqual(typeof pattern, 'string');
assert.strictEqual(typeof callback, 'function');
if (pattern !== constants.AUTOUPDATE_PATTERN_NEVER) { // check if pattern is valid
var job = safe.safeCall(function () { return new CronJob(pattern); });
if (!job) return callback(new SettingsError(SettingsError.BAD_FIELD, 'Invalid pattern'));
}
settingsdb.set(exports.BOX_AUTOUPDATE_PATTERN_KEY, pattern, function (error) {
if (error) return callback(new SettingsError(SettingsError.INTERNAL_ERROR, error));
exports.events.emit(exports.BOX_AUTOUPDATE_PATTERN_KEY, pattern);
return callback(null);
});
}
function getBoxAutoupdatePattern(callback) {
assert.strictEqual(typeof callback, 'function');
settingsdb.get(exports.BOX_AUTOUPDATE_PATTERN_KEY, function (error, pattern) {
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(null, gDefaults[exports.BOX_AUTOUPDATE_PATTERN_KEY]);
if (error) return callback(new SettingsError(SettingsError.INTERNAL_ERROR, error));
callback(null, pattern);
+12 -3
View File
@@ -68,14 +68,22 @@ describe('Settings', function () {
});
});
it('can get default autoupdate_pattern', function (done) {
settings.getAutoupdatePattern(function (error, pattern) {
it('can get default app_autoupdate_pattern', function (done) {
settings.getAppAutoupdatePattern(function (error, pattern) {
expect(error).to.be(null);
expect(pattern).to.be(constants.AUTOUPDATE_PATTERN_NEVER);
done();
});
});
it('can get default box_autoupdate_pattern', function (done) {
settings.getBoxAutoupdatePattern(function (error, pattern) {
expect(error).to.be(null);
expect(pattern).to.be('00 00 1,3,5,23 * * *');
done();
});
});
it ('can get default cloudron name', function (done) {
settings.getCloudronName(function (error, name) {
expect(error).to.be(null);
@@ -131,7 +139,8 @@ describe('Settings', function () {
settings.getAll(function (error, allSettings) {
expect(error).to.be(null);
expect(allSettings[settings.TIME_ZONE_KEY]).to.be.a('string');
expect(allSettings[settings.AUTOUPDATE_PATTERN_KEY]).to.be.a('string');
expect(allSettings[settings.APP_AUTOUPDATE_PATTERN_KEY]).to.be.a('string');
expect(allSettings[settings.BOX_AUTOUPDATE_PATTERN_KEY]).to.be.a('string');
expect(allSettings[settings.CLOUDRON_NAME_KEY]).to.be.a('string');
done();
});
+2 -2
View File
@@ -112,7 +112,7 @@ function checkAppUpdates(callback) {
}
// only send notifications if update pattern is 'never'
settings.getAutoupdatePattern(function (error, result) {
settings.getAppAutoupdatePattern(function (error, result) {
if (error) {
debug(error);
} else if (result === constants.AUTOUPDATE_PATTERN_NEVER) {
@@ -168,7 +168,7 @@ function checkBoxUpdates(callback) {
}
// only send notifications if update pattern is 'never'
settings.getAutoupdatePattern(function (error, result) {
settings.getAppAutoupdatePattern(function (error, result) {
if (error) debug(error);
else if (result === constants.AUTOUPDATE_PATTERN_NEVER) mailer.boxUpdateAvailable(true /* hasSubscription */, updateInfo.version, updateInfo.changelog);