Files
cloudron-box/src/cron.js

281 lines
9.0 KiB
JavaScript
Raw Normal View History

'use strict';
exports = module.exports = {
initialize: initialize,
uninitialize: uninitialize
};
var apps = require('./apps.js'),
2017-04-13 01:07:07 -07:00
appstore = require('./appstore.js'),
assert = require('assert'),
backups = require('./backups.js'),
2018-01-02 12:47:33 -08:00
caas = require('./caas.js'),
cloudron = require('./cloudron.js'),
2015-10-20 11:33:19 -07:00
config = require('./config.js'),
constants = require('./constants.js'),
CronJob = require('cron').CronJob,
debug = require('debug')('box:cron'),
2017-07-21 16:13:44 +02:00
digest = require('./digest.js'),
2018-01-25 14:03:42 -08:00
dyndns = require('./dyndns.js'),
2016-07-25 12:36:43 -07:00
eventlog = require('./eventlog.js'),
janitor = require('./janitor.js'),
reverseProxy = require('./reverseproxy.js'),
scheduler = require('./scheduler.js'),
settings = require('./settings.js'),
updateChecker = require('./updatechecker.js');
2017-11-27 12:40:13 -08:00
var gJobs = {
alive: null, // send periodic stats
appAutoUpdater: null,
boxAutoUpdater: null,
2017-11-27 12:40:13 -08:00
appUpdateChecker: null,
backup: null,
boxUpdateChecker: null,
caasHeartbeat: null,
checkDiskSpace: null,
certificateRenew: null,
cleanupBackups: null,
cleanupEventlog: null,
cleanupTokens: null,
digestEmail: null,
dockerVolumeCleaner: null,
dynamicDNS: null,
schedulerSync: null
};
var NOOP_CALLBACK = function (error) { if (error) console.error(error); };
2016-06-02 18:47:09 -07:00
var AUDIT_SOURCE = { userId: null, username: 'cron' };
// cron format
// Seconds: 0-59
// Minutes: 0-59
// Hours: 0-23
// Day of Month: 1-31
// Months: 0-11
// Day of Week: 0-6
function initialize(callback) {
assert.strictEqual(typeof callback, 'function');
if (config.provider() === 'caas') {
// hack: send the first heartbeat only after we are running for 60 seconds
// required as we end up sending a heartbeat and then cloudron-setup reboots the server
var seconds = (new Date()).getSeconds() - 1;
2017-11-27 15:41:24 -08:00
if (seconds === -1) seconds = 59;
2017-11-27 12:40:13 -08:00
gJobs.caasHeartbeat = new CronJob({
cronTime: `${seconds} */1 * * * *`, // every minute
2018-01-02 12:47:33 -08:00
onTick: caas.sendHeartbeat,
start: true
});
}
2016-12-19 11:56:35 -08:00
var randomHourMinute = Math.floor(60*Math.random());
2017-11-27 12:40:13 -08:00
gJobs.alive = new CronJob({
cronTime: '00 ' + randomHourMinute + ' * * * *', // every hour on a random minute
2017-04-13 01:07:07 -07:00
onTick: appstore.sendAliveStatus,
2016-11-15 15:25:21 +01:00
start: true
});
settings.events.on(settings.TIME_ZONE_KEY, recreateJobs);
settings.events.on(settings.APP_AUTOUPDATE_PATTERN_KEY, appAutoupdatePatternChanged);
settings.events.on(settings.BOX_AUTOUPDATE_PATTERN_KEY, boxAutoupdatePatternChanged);
2018-01-25 14:03:42 -08:00
settings.events.on(settings.DYNAMIC_DNS_KEY, dynamicDnsChanged);
settings.getAll(function (error, allSettings) {
if (error) return callback(error);
recreateJobs(allSettings[settings.TIME_ZONE_KEY]);
appAutoupdatePatternChanged(allSettings[settings.APP_AUTOUPDATE_PATTERN_KEY]);
boxAutoupdatePatternChanged(allSettings[settings.BOX_AUTOUPDATE_PATTERN_KEY]);
2018-01-25 14:03:42 -08:00
dynamicDnsChanged(allSettings[settings.DYNAMIC_DNS_KEY]);
2015-10-27 17:05:56 -07:00
callback();
});
}
function recreateJobs(tz) {
assert.strictEqual(typeof tz, 'string');
debug('Creating jobs with timezone %s', tz);
2017-11-27 12:40:13 -08:00
if (gJobs.backup) gJobs.backup.stop();
gJobs.backup = new CronJob({
cronTime: '00 00 */6 * * *', // every 6 hours. backups.ensureBackup() will only trigger a backup once per day
onTick: backups.ensureBackup.bind(null, AUDIT_SOURCE, NOOP_CALLBACK),
start: true,
timeZone: tz
});
2017-11-27 12:40:13 -08:00
if (gJobs.checkDiskSpace) gJobs.checkDiskSpace.stop();
gJobs.checkDiskSpace = new CronJob({
cronTime: '00 30 */4 * * *', // every 4 hours
onTick: cloudron.checkDiskSpace,
start: true,
timeZone: tz
});
// randomized pattern per cloudron every hour
var randomMinute = Math.floor(60*Math.random());
2017-11-27 12:40:13 -08:00
if (gJobs.boxUpdateCheckerJob) gJobs.boxUpdateCheckerJob.stop();
gJobs.boxUpdateCheckerJob = new CronJob({
cronTime: '00 ' + randomMinute + ' * * * *', // once an hour
onTick: updateChecker.checkBoxUpdates,
start: true,
timeZone: tz
});
2017-11-27 12:40:13 -08:00
if (gJobs.appUpdateChecker) gJobs.appUpdateChecker.stop();
gJobs.appUpdateChecker = new CronJob({
cronTime: '00 ' + randomMinute + ' * * * *', // once an hour
onTick: updateChecker.checkAppUpdates,
start: true,
timeZone: tz
});
2017-11-27 12:40:13 -08:00
if (gJobs.cleanupTokens) gJobs.cleanupTokens.stop();
gJobs.cleanupTokens = new CronJob({
cronTime: '00 */30 * * * *', // every 30 minutes
onTick: janitor.cleanupTokens,
start: true,
timeZone: tz
});
2017-11-27 12:40:13 -08:00
if (gJobs.cleanupBackups) gJobs.cleanupBackups.stop();
gJobs.cleanupBackups = new CronJob({
cronTime: '00 45 */6 * * *', // every 6 hours. try not to overlap with ensureBackup job
2017-10-01 09:29:42 -07:00
onTick: backups.cleanup.bind(null, AUDIT_SOURCE, NOOP_CALLBACK),
start: true,
timeZone: tz
});
2017-11-27 12:40:13 -08:00
if (gJobs.cleanupEventlog) gJobs.cleanupEventlog.stop();
gJobs.cleanupEventlog = new CronJob({
cronTime: '00 */30 * * * *', // every 30 minutes
onTick: eventlog.cleanup,
start: true,
timeZone: tz
});
2017-11-27 12:40:13 -08:00
if (gJobs.dockerVolumeCleaner) gJobs.dockerVolumeCleaner.stop();
gJobs.dockerVolumeCleaner = new CronJob({
cronTime: '00 00 */12 * * *', // every 12 hours
onTick: janitor.cleanupDockerVolumes,
start: true,
timeZone: tz
});
2017-11-27 12:40:13 -08:00
if (gJobs.schedulerSync) gJobs.schedulerSync.stop();
gJobs.schedulerSync = new CronJob({
cronTime: config.TEST ? '*/10 * * * * *' : '00 */1 * * * *', // every minute
onTick: scheduler.sync,
start: true,
timeZone: tz
});
2017-11-27 12:40:13 -08:00
if (gJobs.certificateRenew) gJobs.certificateRenew.stop();
gJobs.certificateRenew = new CronJob({
cronTime: '00 00 */12 * * *', // every 12 hours
onTick: reverseProxy.renewAll.bind(null, AUDIT_SOURCE, NOOP_CALLBACK),
start: true,
timeZone: tz
});
2017-07-21 16:13:44 +02:00
2017-11-27 12:40:13 -08:00
if (gJobs.digestEmail) gJobs.digestEmail.stop();
gJobs.digestEmail = new CronJob({
cronTime: '00 00 00 * * 3', // every wednesday
2017-07-21 16:13:44 +02:00
onTick: digest.maybeSend,
start: true,
timeZone: tz
});
}
function boxAutoupdatePatternChanged(pattern) {
assert.strictEqual(typeof pattern, 'string');
2017-11-27 12:40:13 -08:00
assert(gJobs.boxUpdateCheckerJob);
debug('Box auto update pattern changed to %s', pattern);
if (gJobs.boxAutoUpdater) gJobs.boxAutoUpdater.stop();
if (pattern === constants.AUTOUPDATE_PATTERN_NEVER) return;
gJobs.boxAutoUpdater = new CronJob({
cronTime: pattern,
onTick: function() {
var updateInfo = updateChecker.getUpdateInfo();
if (updateInfo.box) {
debug('Starting autoupdate to %j', updateInfo.box);
cloudron.updateToLatest(AUDIT_SOURCE, NOOP_CALLBACK);
} 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);
2017-07-31 11:57:23 -07:00
apps.autoupdateApps(updateInfo.apps, AUDIT_SOURCE, NOOP_CALLBACK);
} else {
debug('No app auto updates available');
}
},
start: true,
2017-11-27 12:40:13 -08:00
timeZone: gJobs.boxUpdateCheckerJob.cronTime.zone // hack
});
}
2018-01-25 14:03:42 -08:00
function dynamicDnsChanged(enabled) {
2017-01-02 13:14:03 +01:00
assert.strictEqual(typeof enabled, 'boolean');
2017-11-27 12:40:13 -08:00
assert(gJobs.boxUpdateCheckerJob);
2017-01-02 13:14:03 +01:00
debug('Dynamic DNS setting changed to %s', enabled);
if (enabled) {
2017-11-27 12:40:13 -08:00
gJobs.dynamicDNS = new CronJob({
2017-01-02 13:14:03 +01:00
cronTime: '00 */10 * * * *',
2018-01-25 14:03:42 -08:00
onTick: dyndns.sync,
2017-01-02 13:14:03 +01:00
start: true,
2017-11-27 12:40:13 -08:00
timeZone: gJobs.boxUpdateCheckerJob.cronTime.zone // hack
2017-01-02 13:14:03 +01:00
});
} else {
2017-11-27 12:40:13 -08:00
if (gJobs.dynamicDNS) gJobs.dynamicDNS.stop();
gJobs.dynamicDNS = null;
2017-01-02 13:14:03 +01:00
}
}
function uninitialize(callback) {
assert.strictEqual(typeof callback, 'function');
2015-11-03 15:19:06 -08:00
settings.events.removeListener(settings.TIME_ZONE_KEY, recreateJobs);
settings.events.removeListener(settings.APP_AUTOUPDATE_PATTERN_KEY, appAutoupdatePatternChanged);
settings.events.removeListener(settings.BOX_AUTOUPDATE_PATTERN_KEY, boxAutoupdatePatternChanged);
2018-01-25 14:03:42 -08:00
settings.events.removeListener(settings.DYNAMIC_DNS_KEY, dynamicDnsChanged);
2015-11-03 15:19:06 -08:00
2017-11-27 12:40:13 -08:00
for (var job in gJobs) {
if (!gJobs[job]) continue;
gJobs[job].stop();
gJobs[job] = null;
}
2017-07-21 16:13:44 +02:00
callback();
}