diff --git a/setup/start/sudoers b/setup/start/sudoers index 7dc2dad20..2438f7492 100644 --- a/setup/start/sudoers +++ b/setup/start/sudoers @@ -36,3 +36,6 @@ yellowtent ALL=(root) NOPASSWD: /home/yellowtent/box/src/scripts/update.sh Defaults!/home/yellowtent/box/src/scripts/authorized_keys.sh env_keep="HOME BOX_ENV" yellowtent ALL=(root) NOPASSWD: /home/yellowtent/box/src/scripts/authorized_keys.sh + +Defaults!/home/yellowtent/box/src/backuptask.js env_keep="HOME BOX_ENV" +yellowtent ALL=(root) NOPASSWD: /home/yellowtent/box/src/backuptask.js diff --git a/src/backups.js b/src/backups.js index 7f55ef89b..23d9b2b69 100644 --- a/src/backups.js +++ b/src/backups.js @@ -47,8 +47,7 @@ var addons = require('./addons.js'), SettingsError = require('./settings.js').SettingsError, util = require('util'); -var BACKUP_BOX_CMD = path.join(__dirname, 'scripts/backupbox.sh'), - BACKUP_APP_CMD = path.join(__dirname, 'scripts/backupapp.sh'); +var BACKUPTASK_CMD = path.join(__dirname, 'backuptask.js'); var NOOP_CALLBACK = function (error) { if (error) debug(error); }; @@ -182,18 +181,23 @@ function backupBoxWithAppBackupIds(appBackupIds, prefix, callback) { settings.getBackupConfig(function (error, backupConfig) { if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error)); - shell.sudo('backupBox', [ BACKUP_BOX_CMD, backupId ], function (error) { + var mysqlDumpArgs = 'mysqldump -u root -ppassword --single-transaction --routines --triggers box > "' + paths.BOX_DATA_DIR + '/box.mysqldump"'; + shell.exec('backupBox', '/bin/bash', mysqlDumpArgs.split(' '), function (error) { if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error)); - debug('backupBoxWithAppBackupIds: success'); - - backupdb.add({ id: backupId, version: config.version(), type: backupdb.BACKUP_TYPE_BOX, dependsOn: appBackupIds }, function (error) { + shell.sudo('backupBox', [ BACKUPTASK_CMD, backupId ], function (error) { if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error)); - // FIXME this is only needed for caas, is it really??? - api(backupConfig.provider).backupDone(backupId, null /* app */, appBackupIds, function (error) { - if (error) return callback(error); - callback(null, backupId); + debug('backupBoxWithAppBackupIds: success'); + + backupdb.add({ id: backupId, version: config.version(), type: backupdb.BACKUP_TYPE_BOX, dependsOn: appBackupIds }, function (error) { + if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error)); + + // FIXME this is only needed for caas, is it really??? + api(backupConfig.provider).backupDone(backupId, null /* app */, appBackupIds, function (error) { + if (error) return callback(error); + callback(null, backupId); + }); }); }); }); @@ -221,7 +225,7 @@ function createNewAppBackup(app, manifest, prefix, callback) { // FIXME move addon backup into backuptask async.series([ addons.backupAddons.bind(null, app, manifest.addons), - shell.sudo.bind(null, 'backupApp', [ BACKUP_APP_CMD, backupId, app.id ]) + shell.sudo.bind(null, 'backupApp', [ BACKUPTASK_CMD, backupId, app.id ]) ], function (error) { if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error)); diff --git a/src/backuptask.js b/src/backuptask.js index 4648a27d7..4cacb33bd 100755 --- a/src/backuptask.js +++ b/src/backuptask.js @@ -2,6 +2,16 @@ 'use strict'; +if (process.geteuid() !== 0) { + console.log('This script should be run as root.'); + process.exit(1); +} + +if (process.argv[2] === '--check') { + console.log('OK'); + process.exit(0); +} + require('supererror')({ splatchError: true }); // remove timestamp from debug() based output @@ -82,31 +92,30 @@ function backupBox(backupId, callback) { }); } -if (require.main === module) { - var backupId = process.argv[2]; - var appId = process.argv[3]; +// Main process starts here +var backupId = process.argv[2]; +var appId = process.argv[3]; - if (appId) debug('Backuptask for the app %s with id %s', appId, backupId); - else debug('Backuptask for the whole Cloudron with id %s', backupId); +if (appId) debug('Backuptask for the app %s with id %s', appId, backupId); +else debug('Backuptask for the whole Cloudron with id %s', backupId); - process.on('SIGTERM', function () { - process.exit(0); - }); +process.on('SIGTERM', function () { + process.exit(0); +}); - initialize(function (error) { - if (error) throw error; +initialize(function (error) { + if (error) throw error; - function resultHandler(error) { - if (error) debug('Backuptask completed with error', error); + function resultHandler(error) { + if (error) debug('Backuptask completed with error', error); - debug('Backuptask completed'); + debug('Backuptask completed'); - // https://nodejs.org/api/process.html are exit codes used by node. apps.js uses the value below - // to check apptask crashes - process.exit(error ? 50 : 0); - } + // https://nodejs.org/api/process.html are exit codes used by node. apps.js uses the value below + // to check apptask crashes + process.exit(error ? 50 : 0); + } - if (appId) backupApp(backupId, appId, resultHandler); - else backupBox(backupId, resultHandler); - }); -} + if (appId) backupApp(backupId, appId, resultHandler); + else backupBox(backupId, resultHandler); +}); diff --git a/src/test/checkInstall b/src/test/checkInstall index 2d23ca83e..1c42b4c38 100755 --- a/src/test/checkInstall +++ b/src/test/checkInstall @@ -19,7 +19,8 @@ scripts=("${SOURCE_DIR}/src/scripts/rmappdir.sh" \ "${SOURCE_DIR}/src/scripts/update.sh" \ "${SOURCE_DIR}/src/scripts/collectlogs.sh" \ "${SOURCE_DIR}/src/scripts/reloadcollectd.sh" \ - "${SOURCE_DIR}/src/scripts/authorized_keys.sh") + "${SOURCE_DIR}/src/scripts/authorized_keys.sh" \ + "${SOURCE_DIR}/src/backuptask.js") for script in "${scripts[@]}"; do if [[ $(sudo -n "${script}" --check 2>/dev/null) != "OK" ]]; then