diff --git a/src/apptask.js b/src/apptask.js index 980557b7b..abceacd9e 100644 --- a/src/apptask.js +++ b/src/apptask.js @@ -136,27 +136,14 @@ function createContainer(app, callback) { }); } -// Only delete the main container of the app, not destroy any docker addon created ones -function deleteMainContainer(app, callback) { - assert.strictEqual(typeof app, 'object'); - assert.strictEqual(typeof callback, 'function'); - - debugApp(app, 'deleting main app container'); - - docker.deleteContainer(app.containerId, function (error) { - if (error) return callback(new Error('Error deleting container: ' + error)); - - updateApp(app, { containerId: null }, callback); - }); -} - -function deleteContainers(app, callback) { +function deleteContainers(app, options, callback) { assert.strictEqual(typeof app, 'object'); + assert.strictEqual(typeof options, 'object'); assert.strictEqual(typeof callback, 'function'); debugApp(app, 'deleting app containers (app, scheduler)'); - docker.deleteContainers(app.id, function (error) { + docker.deleteContainers(app.id, options, function (error) { if (error) return callback(new Error('Error deleting container: ' + error)); updateApp(app, { containerId: null }, callback); @@ -511,7 +498,7 @@ function install(app, callback) { removeCollectdProfile.bind(null, app), removeLogrotateConfig.bind(null, app), stopApp.bind(null, app), - deleteMainContainer.bind(null, app), + deleteContainers.bind(null, app, { managedOnly: true }), function teardownAddons(next) { // when restoring, app does not require these addons anymore. remove carefully to preserve the db passwords var addonsToRemove = !isRestoring ? app.manifest.addons : _.omit(app.oldConfig.manifest.addons, Object.keys(app.manifest.addons)); @@ -628,7 +615,7 @@ function configure(app, callback) { removeCollectdProfile.bind(null, app), removeLogrotateConfig.bind(null, app), stopApp.bind(null, app), - deleteMainContainer.bind(null, app), + deleteContainers.bind(null, app, { managedOnly: true }), unregisterAlternateDomains.bind(null, app, false /* all */), function (next) { if (!locationChanged) return next(); @@ -636,7 +623,6 @@ function configure(app, callback) { unregisterSubdomain(app, app.oldConfig.location, app.oldConfig.domain, next); }, - reserveHttpPort.bind(null, app), updateApp.bind(null, app, { installationProgress: '20, Downloading icon' }), @@ -736,7 +722,7 @@ function update(app, callback) { removeCollectdProfile.bind(null, app), removeLogrotateConfig.bind(null, app), stopApp.bind(null, app), - deleteMainContainer.bind(null, app), + deleteContainers.bind(null, app, { managedOnly: true }), function deleteImageIfChanged(done) { if (app.manifest.dockerImage === app.updateConfig.manifest.dockerImage) return done(); @@ -822,7 +808,7 @@ function uninstall(app, callback) { stopApp.bind(null, app), updateApp.bind(null, app, { installationProgress: '20, Deleting container' }), - deleteContainers.bind(null, app), + deleteContainers.bind(null, app, {}), updateApp.bind(null, app, { installationProgress: '30, Teardown addons' }), addons.teardownAddons.bind(null, app, app.manifest.addons), diff --git a/src/docker.js b/src/docker.js index 31a9061b3..12f9781c0 100644 --- a/src/docker.js +++ b/src/docker.js @@ -371,15 +371,19 @@ function deleteContainer(containerId, callback) { }); } -function deleteContainers(appId, callback) { +function deleteContainers(appId, options, callback) { assert.strictEqual(typeof appId, 'string'); + assert.strictEqual(typeof options, 'object'); assert.strictEqual(typeof callback, 'function'); var docker = exports.connection; debug('deleting containers of %s', appId); - docker.listContainers({ all: 1, filters: JSON.stringify({ label: [ 'appId=' + appId ] }) }, function (error, containers) { + let labels = [ 'appId=' + appId ]; + if (options.managedOnly) labels.push('isCloudronManaged=true'); + + docker.listContainers({ all: 1, filters: JSON.stringify({ label: labels }) }, function (error, containers) { if (error) return callback(error); async.eachSeries(containers, function (container, iteratorDone) { diff --git a/src/dockerproxy.js b/src/dockerproxy.js index 756bb8d54..1019d2235 100644 --- a/src/dockerproxy.js +++ b/src/dockerproxy.js @@ -70,7 +70,7 @@ function attachDockerRequest(req, res, next) { function containersCreate(req, res, next) { safe.set(req.body, 'HostConfig.NetworkMode', 'cloudron'); // overwrite the network the container lives in safe.set(req.body, 'NetworkingConfig', {}); // drop any custom network configs - safe.set(req.body, 'Labels', _.extend({ }, safe.query(req.body, 'Labels'), { appId: req.app.id })); // overwrite the app id to track containers of an app + safe.set(req.body, 'Labels', _.extend({ }, safe.query(req.body, 'Labels'), { appId: req.app.id, isCloudronManaged: String(false) })); // overwrite the app id to track containers of an app safe.set(req.body, 'HostConfig.LogConfig', { Type: 'syslog', Config: { 'tag': req.app.id, 'syslog-address': 'udp://127.0.0.1:2514', 'syslog-format': 'rfc5424' }}); const appDataDir = path.join(paths.APPS_DATA_DIR, req.app.id, 'data'), diff --git a/src/scripts/rmvolume.sh b/src/scripts/rmvolume.sh index a8d4f1580..f83aebeda 100755 --- a/src/scripts/rmvolume.sh +++ b/src/scripts/rmvolume.sh @@ -24,6 +24,8 @@ if [[ "${BOX_ENV}" == "test" ]]; then [[ "${volume_dir}" != *"./cloudron_test/"* ]] && exit 1 fi -rm -rf "${volume_dir}"/* -# mount points cannot be deleted +# this removes hidden files +find "${volume_dir}" -maxdepth 1 -mindepth 1 -exec rm -rf '{}' \; +# volume could be a mount point that cannot be deleted rmdir "${volume_dir}" || true +