diff --git a/package-lock.json b/package-lock.json index 3d383420b..b3469aa1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3218,6 +3218,32 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, + "fs-extra": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.6.4.tgz", + "integrity": "sha1-9G8MdbeEH40gCzNIzU1pHVoJnRU=", + "dev": true, + "requires": { + "jsonfile": "1.0.1", + "mkdirp": "0.3.5", + "ncp": "0.4.2", + "rimraf": "2.2.8" + }, + "dependencies": { + "mkdirp": { + "version": "0.3.5", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true + }, + "rimraf": { + "version": "2.2.8", + "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + } + } + }, "fstream": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", @@ -4548,6 +4574,12 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, + "jsonfile": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-1.0.1.tgz", + "integrity": "sha1-6l7+QLg2kLmGZ2FKc5L8YOhCwN0=", + "dev": true + }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -5151,6 +5183,22 @@ } } }, + "mock-aws-s3": { + "version": "git+https://github.com/cloudron-io/mock-aws-s3.git#1306f1722b82897382a2339d52a94ded15003d8c", + "dev": true, + "requires": { + "fs-extra": "0.6.4", + "underscore": "1.8.3" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + } + } + }, "modelo": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/modelo/-/modelo-4.2.3.tgz", @@ -5383,6 +5431,12 @@ "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", "optional": true }, + "ncp": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", + "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", + "dev": true + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", diff --git a/src/apptask.js b/src/apptask.js index 36a939e17..b9e748786 100644 --- a/src/apptask.js +++ b/src/apptask.js @@ -10,8 +10,8 @@ exports = module.exports = { _reserveHttpPort: reserveHttpPort, _configureReverseProxy: configureReverseProxy, _unconfigureReverseProxy: unconfigureReverseProxy, - _createVolume: createVolume, - _deleteVolume: deleteVolume, + _createAppDir: createAppDir, + _deleteAppDir: deleteAppDir, _verifyManifest: verifyManifest, _registerSubdomain: registerSubdomain, _unregisterSubdomain: unregisterSubdomain, @@ -160,14 +160,14 @@ function deleteContainers(app, callback) { }); } -function createVolume(app, callback) { +function createAppDir(app, callback) { assert.strictEqual(typeof app, 'object'); assert.strictEqual(typeof callback, 'function'); mkdirp(path.join(paths.APPS_DATA_DIR, app.id), callback); } -function deleteVolume(app, options, callback) { +function deleteAppDir(app, options, callback) { assert.strictEqual(typeof app, 'object'); assert.strictEqual(typeof options, 'object'); assert.strictEqual(typeof callback, 'function'); @@ -479,7 +479,7 @@ function install(app, callback) { addons.teardownAddons(app, addonsToRemove, next); }, - deleteVolume.bind(null, app, { removeDirectory: false }), // do not remove any symlinked volume + deleteAppDir.bind(null, app, { removeDirectory: false }), // do not remove any symlinked volume // for restore case function deleteImageIfChanged(done) { @@ -500,7 +500,7 @@ function install(app, callback) { docker.downloadImage.bind(null, app.manifest), updateApp.bind(null, app, { installationProgress: '50, Creating volume' }), - createVolume.bind(null, app), + createAppDir.bind(null, app), function restoreFromBackup(next) { if (!restoreConfig) { @@ -607,7 +607,7 @@ function configure(app, callback) { docker.downloadImage.bind(null, app.manifest), updateApp.bind(null, app, { installationProgress: '45, Ensuring volume' }), - createVolume.bind(null, app), + createAppDir.bind(null, app), // re-setup addons since they rely on the app's fqdn (e.g oauth) updateApp.bind(null, app, { installationProgress: '50, Setting up addons' }), @@ -776,7 +776,7 @@ function uninstall(app, callback) { addons.teardownAddons.bind(null, app, app.manifest.addons), updateApp.bind(null, app, { installationProgress: '40, Deleting volume' }), - deleteVolume.bind(null, app, { removeDirectory: true }), + deleteAppDir.bind(null, app, { removeDirectory: true }), updateApp.bind(null, app, { installationProgress: '50, Deleting image' }), docker.deleteImage.bind(null, app.manifest), diff --git a/src/routes/test/apps-test.js b/src/routes/test/apps-test.js index 03846889d..08f2275e8 100644 --- a/src/routes/test/apps-test.js +++ b/src/routes/test/apps-test.js @@ -745,7 +745,13 @@ describe('App installation', function () { it('installation - volume created', function (done) { expect(fs.existsSync(paths.APPS_DATA_DIR + '/' + APP_ID)); - done(); + let volume = docker.getVolume(APP_ID + '-localstorage'); + volume.inspect(function (error, volume) { + expect(error).to.be(null); + expect(volume.Labels.appId).to.eql(APP_ID); + expect(volume.Options.device).to.eql(paths.APPS_DATA_DIR + '/' + APP_ID + '/data'); + done(); + }); }); it('installation - http is up and running', function (done) { @@ -781,13 +787,7 @@ describe('App installation', function () { it('installation - running container has volume mounted', function (done) { docker.getContainer(appEntry.containerId).inspect(function (error, data) { expect(error).to.not.be.ok(); - - // support newer docker versions - if (data.Volumes) { - expect(data.Volumes['/app/data']).to.eql(paths.APPS_DATA_DIR + '/' + APP_ID + '/data'); - } else { - expect(data.Mounts.filter(function (mount) { return mount.Destination === '/app/data'; })[0].Source).to.eql(paths.APPS_DATA_DIR + '/' + APP_ID + '/data'); - } + expect(data.Mounts.filter(function (mount) { return mount.Destination === '/app/data'; })[0].Type).to.eql('volume'); done(); }); diff --git a/src/test/apptask-test.js b/src/test/apptask-test.js index 9518b7c29..fe4f92702 100644 --- a/src/test/apptask-test.js +++ b/src/test/apptask-test.js @@ -164,16 +164,16 @@ describe('apptask', function () { }); it('create volume', function (done) { - apptask._createVolume(APP, function (error) { - expect(fs.existsSync(paths.APPS_DATA_DIR + '/' + APP.id + '/data')).to.be(true); + apptask._createAppDir(APP, function (error) { + expect(fs.existsSync(paths.APPS_DATA_DIR + '/' + APP.id)).to.be(true); + expect(fs.existsSync(paths.APPS_DATA_DIR + '/' + APP.id + '/data')).to.be(false); expect(error).to.be(null); done(); }); }); it('delete volume - removeDirectory (false) ', function (done) { - apptask._deleteVolume(APP, { removeDirectory: false }, function (error) { - expect(!fs.existsSync(paths.APPS_DATA_DIR + '/' + APP.id + '/data')).to.be(true); + apptask._deleteAppDir(APP, { removeDirectory: false }, function (error) { expect(fs.existsSync(paths.APPS_DATA_DIR + '/' + APP.id)).to.be(true); expect(fs.readdirSync(paths.APPS_DATA_DIR + '/' + APP.id).length).to.be(0); // empty expect(error).to.be(null); @@ -182,7 +182,7 @@ describe('apptask', function () { }); it('delete volume - removeDirectory (true) ', function (done) { - apptask._deleteVolume(APP, { removeDirectory: true }, function (error) { + apptask._deleteAppDir(APP, { removeDirectory: true }, function (error) { expect(!fs.existsSync(paths.APPS_DATA_DIR + '/' + APP.id)).to.be(true); expect(error).to.be(null); done();