diff --git a/src/addons.js b/src/addons.js index b4c8dc323..a7664b253 100644 --- a/src/addons.js +++ b/src/addons.js @@ -993,13 +993,15 @@ function startMysql(existingInfra, callback) { --label isCloudronManaged=true \ --read-only -v /tmp -v /run "${tag}"`; - shell.execSync('startMysql', cmd); - - waitForAddon('mysql', 'CLOUDRON_MYSQL_TOKEN', function (error) { + shell.exec('startMysql', cmd, function (error) { if (error) return callback(error); - if (!upgrading) return callback(null); - importDatabase('mysql', callback); + waitForAddon('mysql', 'CLOUDRON_MYSQL_TOKEN', function (error) { + if (error) return callback(error); + if (!upgrading) return callback(null); + + importDatabase('mysql', callback); + }); }); } @@ -1200,13 +1202,15 @@ function startPostgresql(existingInfra, callback) { --label isCloudronManaged=true \ --read-only -v /tmp -v /run "${tag}"`; - shell.execSync('startPostgresql', cmd); - - waitForAddon('postgresql', 'CLOUDRON_POSTGRESQL_TOKEN', function (error) { + shell.exec('startPostgresql', cmd, function (error) { if (error) return callback(error); - if (!upgrading) return callback(null); - importDatabase('postgresql', callback); + waitForAddon('postgresql', 'CLOUDRON_POSTGRESQL_TOKEN', function (error) { + if (error) return callback(error); + if (!upgrading) return callback(null); + + importDatabase('postgresql', callback); + }); }); } @@ -1370,13 +1374,15 @@ function startMongodb(existingInfra, callback) { --label isCloudronManaged=true \ --read-only -v /tmp -v /run "${tag}"`; - shell.execSync('startMongodb', cmd); - - waitForAddon('mongodb', 'CLOUDRON_MONGODB_TOKEN', function (error) { + shell.exec('startMongodb', cmd, function (error) { if (error) return callback(error); - if (!upgrading) return callback(null); - importDatabase('mongodb', callback); + waitForAddon('mongodb', 'CLOUDRON_MONGODB_TOKEN', function (error) { + if (error) return callback(error); + if (!upgrading) return callback(null); + + importDatabase('mongodb', callback); + }); }); } @@ -1570,7 +1576,7 @@ function setupRedis(app, options, callback) { ]; async.series([ - shell.execSync.bind(null, 'startRedis', cmd), + shell.exec.bind(null, 'startRedis', cmd), appdb.setAddonConfig.bind(null, app.id, 'redis', env), waitForAddon.bind(null, 'redis-' + app.id, 'CLOUDRON_REDIS_TOKEN') ], function (error) { diff --git a/src/graphs.js b/src/graphs.js index 2285d8fde..aa6224048 100644 --- a/src/graphs.js +++ b/src/graphs.js @@ -36,7 +36,5 @@ function startGraphite(existingInfra, callback) { --label isCloudronManaged=true \ --read-only -v /tmp -v /run "${tag}"`; - shell.execSync('startGraphite', cmd); - - callback(); + shell.exec('startGraphite', cmd, callback); } diff --git a/src/mail.js b/src/mail.js index a33099a87..7a2edfb99 100644 --- a/src/mail.js +++ b/src/mail.js @@ -58,7 +58,6 @@ var assert = require('assert'), mailer = require('./mailer.js'), net = require('net'), nodemailer = require('nodemailer'), - os = require('os'), path = require('path'), paths = require('./paths.js'), reverseProxy = require('./reverseproxy.js'), @@ -567,34 +566,34 @@ function restartMail(callback) { if (!safe.child_process.execSync(`cp ${bundle.certFilePath} ${mailCertFilePath}`)) return callback(new Error('Could not create cert file:' + safe.error.message)); if (!safe.child_process.execSync(`cp ${bundle.keyFilePath} ${mailKeyFilePath}`)) return callback(new Error('Could not create key file:' + safe.error.message)); - shell.execSync('startMail', 'docker rm -f mail || true'); - - createMailConfig(function (error, allowInbound) { + shell.exec('startMail', 'docker rm -f mail || true', function (error) { if (error) return callback(error); - var ports = allowInbound ? '-p 587:2525 -p 993:9993 -p 4190:4190 -p 25:2525' : ''; + createMailConfig(function (error, allowInbound) { + if (error) return callback(error); - const cmd = `docker run --restart=always -d --name="mail" \ - --net cloudron \ - --net-alias mail \ - --log-driver syslog \ - --log-opt syslog-address=udp://127.0.0.1:2514 \ - --log-opt syslog-format=rfc5424 \ - --log-opt tag=mail \ - -m ${memoryLimit}m \ - --memory-swap ${memoryLimit * 2}m \ - --dns 172.18.0.1 \ - --dns-search=. \ - -v "${paths.MAIL_DATA_DIR}:/app/data" \ - -v "${paths.PLATFORM_DATA_DIR}/addons/mail:/etc/mail" \ - ${ports} \ - -p 127.0.0.1:2020:2020 \ - --label isCloudronManaged=true \ - --read-only -v /run -v /tmp ${tag}`; + var ports = allowInbound ? '-p 587:2525 -p 993:9993 -p 4190:4190 -p 25:2525' : ''; - shell.execSync('startMail', cmd); + const cmd = `docker run --restart=always -d --name="mail" \ + --net cloudron \ + --net-alias mail \ + --log-driver syslog \ + --log-opt syslog-address=udp://127.0.0.1:2514 \ + --log-opt syslog-format=rfc5424 \ + --log-opt tag=mail \ + -m ${memoryLimit}m \ + --memory-swap ${memoryLimit * 2}m \ + --dns 172.18.0.1 \ + --dns-search=. \ + -v "${paths.MAIL_DATA_DIR}:/app/data" \ + -v "${paths.PLATFORM_DATA_DIR}/addons/mail:/etc/mail" \ + ${ports} \ + -p 127.0.0.1:2020:2020 \ + --label isCloudronManaged=true \ + --read-only -v /run -v /tmp ${tag}`; - callback(); + shell.exec('startMail', cmd, callback); + }); }); }); } diff --git a/src/platform.js b/src/platform.js index 446aa13cb..82dac7ca1 100644 --- a/src/platform.js +++ b/src/platform.js @@ -132,8 +132,10 @@ function stopContainers(existingInfra, callback) { if (existingInfra.version !== infra.version) { // TODO: only nuke containers with isCloudronManaged=true debug('stopping all containers for infra upgrade'); - shell.execSync('stopContainers', 'docker ps -qa | xargs --no-run-if-empty docker stop'); - shell.execSync('stopContainers', 'docker ps -qa | xargs --no-run-if-empty docker rm -f'); + async.series([ + shell.exec.bind(null, 'stopContainers', 'docker ps -qa | xargs --no-run-if-empty docker stop'), + shell.exec.bind(null, 'stopContainers', 'docker ps -qa | xargs --no-run-if-empty docker rm -f') + ], callback); } else { assert(typeof infra.images, 'object'); var changedAddons = [ ]; @@ -144,11 +146,11 @@ function stopContainers(existingInfra, callback) { debug('stopContainer: stopping addons for incremental infra update: %j', changedAddons); let filterArg = changedAddons.map(function (c) { return `--filter 'name=${c}'`; }).join(' '); // name=c matches *c*. required for redis-{appid} // ignore error if container not found (and fail later) so that this code works across restarts - shell.execSync('stopContainers', `docker ps -qa ${filterArg} | xargs --no-run-if-empty docker stop || true`); - shell.execSync('stopContainers', `docker ps -qa ${filterArg} | xargs --no-run-if-empty docker rm -f || true`); + async.series([ + shell.exec.bind(null, 'stopContainers', `docker ps -qa ${filterArg} | xargs --no-run-if-empty docker stop || true`), + shell.exec.bind(null, 'stopContainers', `docker ps -qa ${filterArg} | xargs --no-run-if-empty docker rm -f || true`) + ], callback); } - - callback(); } function startApps(existingInfra, callback) { diff --git a/src/shell.js b/src/shell.js index c476307aa..fbad0d512 100644 --- a/src/shell.js +++ b/src/shell.js @@ -3,7 +3,6 @@ exports = module.exports = { spawn: spawn, exec: exec, - execSync: execSync, sudo: sudo, sudoSync: sudoSync }; @@ -16,20 +15,6 @@ var assert = require('assert'), var SUDO = '/usr/bin/sudo'; -function execSync(tag, cmd, callback) { - assert.strictEqual(typeof tag, 'string'); - assert.strictEqual(typeof cmd, 'string'); - - debug(cmd); - try { - child_process.execSync(cmd, { stdio: 'inherit' }); - } catch (e) { - if (callback) return callback(e); - throw e; - } - if (callback) callback(); -} - function exec(tag, cmd, callback) { assert.strictEqual(typeof tag, 'string'); assert.strictEqual(typeof cmd, 'string'); @@ -37,7 +22,7 @@ function exec(tag, cmd, callback) { debug(`${tag} exec: ${cmd}`); - child_process.execSync(cmd, function (error, stdout, stderr) { + child_process.exec(cmd, function (error, stdout, stderr) { debug(`${tag} (stdout): %s`, stdout.toString('utf8')); debug(`${tag} (stderr): %s`, stderr.toString('utf8')); diff --git a/src/test/shell-test.js b/src/test/shell-test.js index b371746c8..a6fec6ead 100644 --- a/src/test/shell-test.js +++ b/src/test/shell-test.js @@ -1,8 +1,6 @@ /* jslint node:true */ /* global it:false */ /* global describe:false */ -/* global after:false */ -/* global before:false */ 'use strict'; @@ -20,21 +18,21 @@ describe('shell', function () { }); it('fails on invalid program', function (done) { - var cp = shell.spawn('test', 'randomprogram', [ ], { }, function (error) { + shell.spawn('test', 'randomprogram', [ ], { }, function (error) { expect(error).to.be.ok(); done(); }); }); it('fails on failing program', function (done) { - var cp = shell.spawn('test', '/usr/bin/false', [ ], { }, function (error) { + shell.spawn('test', '/usr/bin/false', [ ], { }, function (error) { expect(error).to.be.ok(); done(); }); }); it('cannot sudo invalid program', function (done) { - var cp = shell.sudo('test', [ 'randomprogram' ], function (error) { + shell.sudo('test', [ 'randomprogram' ], function (error) { expect(error).to.be.ok(); done(); }); @@ -42,24 +40,30 @@ describe('shell', function () { it('can sudo valid program', function (done) { var RELOAD_NGINX_CMD = path.join(__dirname, '../src/scripts/reloadnginx.sh'); - var cp = shell.sudo('test', [ RELOAD_NGINX_CMD ], function (error) { + shell.sudo('test', [ RELOAD_NGINX_CMD ], function (error) { expect(error).to.be.ok(); done(); }); }); - it('execSync a valid program', function (done) { - shell.execSync('test', 'ls -l | wc -c'); - done(); + it('execSync a valid shell program', function (done) { + shell.exec('test', 'ls -l | wc -c', function (error) { + console.log(error); + done(error); + }); }); it('execSync throws for invalid program', function (done) { - expect(function () { shell.execSync('test', 'cannotexist') }).to.throwException(); - done(); + shell.exec('test', 'cannotexist', function (error) { + expect(error).to.be.ok(); + done(); + }); }); it('execSync throws for failed program', function (done) { - expect(function () { shell.execSync('test', 'false'); }).to.throwException(); - done(); + shell.exec('test', 'false', function (error) { + expect(error).to.be.ok(); + done(); + }); }); });