diff --git a/src/tasks.js b/src/tasks.js index 0054d68c2..10d7bffd6 100644 --- a/src/tasks.js +++ b/src/tasks.js @@ -1,54 +1,5 @@ 'use strict'; -exports = module.exports = { - get, - add, - update, - setCompleted, - setCompletedByType, - list, - - getLogs, - - startTask, - stopTask, - stopAllTasks, - - removePrivateFields, - - _del: del, - - // task types. if you add a task here, fill up the function table in taskworker and dashboard constants.js - // '_' prefix is removed for lookup - TASK_APP: 'app', - - // "prefix" allows us to locate the tasks of a specific app or backup site - TASK_APP_BACKUP_PREFIX: 'appBackup_', - TASK_FULL_BACKUP_PREFIX: 'backup_', // full backup - TASK_CLEAN_BACKUPS_PREFIX: 'cleanBackups_', - - TASK_BOX_UPDATE: 'boxUpdate', - TASK_CHECK_CERTS: 'checkCerts', - TASK_SYNC_DYNDNS: 'syncDyndns', - TASK_PREPARE_DASHBOARD_LOCATION: 'prepareDashboardLocation', - TASK_SYNC_EXTERNAL_LDAP: 'syncExternalLdap', - TASK_CHANGE_MAIL_LOCATION: 'changeMailLocation', - TASK_SYNC_DNS_RECORDS: 'syncDnsRecords', - - TASK_CHECK_BACKUP_INTEGRITY: 'checkBackupIntegrity', - - // error codes - ESTOPPED: 'stopped', - ECRASHED: 'crashed', - ETIMEOUT: 'timeout', - - // testing - _TASK_IDENTITY: 'identity', - _TASK_CRASH: 'crash', - _TASK_ERROR: 'error', - _TASK_SLEEP: 'sleep' -}; - const assert = require('node:assert'), BoxError = require('./boxerror.js'), database = require('./database.js'), @@ -140,6 +91,31 @@ async function setCompleted(id, task) { await update(id, Object.assign({ completed: true }, task)); } +async function list(page, perPage, options) { + assert.strictEqual(typeof page, 'number'); + assert.strictEqual(typeof perPage, 'number'); + assert.strictEqual(typeof options, 'object'); + + const data = []; + let query = `SELECT ${TASKS_FIELDS} FROM tasks`; + + if (options.type) { + query += ' WHERE TYPE=?'; + data.push(options.type); + } else if (options.prefix) { + query += ' WHERE TYPE LIKE ' + mysql.escape(options.prefix + '%'); + } + + query += ' ORDER BY creationTime DESC, id DESC LIMIT ?,?'; // put latest task first + + data.push((page-1)*perPage); + data.push(perPage); + + const results = await database.query(query, data); + results.forEach(postProcess); + return results; +} + async function setCompletedByType(type, task) { assert.strictEqual(typeof type, 'string'); assert.strictEqual(typeof task, 'object'); @@ -158,6 +134,16 @@ async function add(type, args) { return String(result.insertId); } +async function stopTask(id) { + assert.strictEqual(typeof id, 'string'); + + if (!gTasks[id]) throw new BoxError(BoxError.BAD_STATE, 'task is not active'); + + debug(`stopTask: stopping task ${id}`); + + await shell.sudo([ STOP_TASK_CMD, id, ], {}); // note: this is stopping the systemd-run task. the sudo will exit when this exits +} + async function startTask(id, options) { assert.strictEqual(typeof id, 'string'); assert.strictEqual(typeof options, 'object'); @@ -214,16 +200,6 @@ async function startTask(id, options) { throw taskError; } -async function stopTask(id) { - assert.strictEqual(typeof id, 'string'); - - if (!gTasks[id]) throw new BoxError(BoxError.BAD_STATE, 'task is not active'); - - debug(`stopTask: stopping task ${id}`); - - await shell.sudo([ STOP_TASK_CMD, id, ], {}); // note: this is stopping the systemd-run task. the sudo will exit when this exits -} - async function stopAllTasks() { const acs = Object.values(gTasks); debug(`stopAllTasks: ${acs.length} tasks are running. sending abort signal`); @@ -233,31 +209,6 @@ async function stopAllTasks() { if (error) debug(`stopAllTasks: error stopping stasks: ${error.message}`); } -async function list(page, perPage, options) { - assert.strictEqual(typeof page, 'number'); - assert.strictEqual(typeof perPage, 'number'); - assert.strictEqual(typeof options, 'object'); - - const data = []; - let query = `SELECT ${TASKS_FIELDS} FROM tasks`; - - if (options.type) { - query += ' WHERE TYPE=?'; - data.push(options.type); - } else if (options.prefix) { - query += ' WHERE TYPE LIKE ' + mysql.escape(options.prefix + '%'); - } - - query += ' ORDER BY creationTime DESC, id DESC LIMIT ?,?'; // put latest task first - - data.push((page-1)*perPage); - data.push(perPage); - - const results = await database.query(query, data); - results.forEach(postProcess); - return results; -} - async function getLogs(task, options) { assert.strictEqual(typeof task, 'object'); assert(options && typeof options === 'object'); @@ -290,3 +241,52 @@ async function del(id) { const result = await database.query('DELETE FROM tasks WHERE id = ?', [ id ]); if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Task not found'); } + +exports = module.exports = { + get, + add, + update, + setCompleted, + setCompletedByType, + list, + + getLogs, + + startTask, + stopTask, + stopAllTasks, + + removePrivateFields, + + _del: del, + + // task types. if you add a task here, fill up the function table in taskworker and dashboard constants.js + // '_' prefix is removed for lookup + TASK_APP: 'app', + + // "prefix" allows us to locate the tasks of a specific app or backup site + TASK_APP_BACKUP_PREFIX: 'appBackup_', + TASK_FULL_BACKUP_PREFIX: 'backup_', // full backup + TASK_CLEAN_BACKUPS_PREFIX: 'cleanBackups_', + + TASK_BOX_UPDATE: 'boxUpdate', + TASK_CHECK_CERTS: 'checkCerts', + TASK_SYNC_DYNDNS: 'syncDyndns', + TASK_PREPARE_DASHBOARD_LOCATION: 'prepareDashboardLocation', + TASK_SYNC_EXTERNAL_LDAP: 'syncExternalLdap', + TASK_CHANGE_MAIL_LOCATION: 'changeMailLocation', + TASK_SYNC_DNS_RECORDS: 'syncDnsRecords', + + TASK_CHECK_BACKUP_INTEGRITY: 'checkBackupIntegrity', + + // error codes + ESTOPPED: 'stopped', + ECRASHED: 'crashed', + ETIMEOUT: 'timeout', + + // testing + _TASK_IDENTITY: 'identity', + _TASK_CRASH: 'crash', + _TASK_ERROR: 'error', + _TASK_SLEEP: 'sleep' +};