diff --git a/appstore.js b/appstore.js index a7f9e72..7570e47 100644 --- a/appstore.js +++ b/appstore.js @@ -25,7 +25,7 @@ function AppStore(origin) { AppStore.prototype.getAccessToken = function (user) { var res = request.get(this._origin + '/api/v1/login').auth(user.email, user.password).end(); - common.verifyResponse(res, 'Could not login as user:' + user.email + ' password:' + user.password); + common.verifyResponse2(res, 'Could not login as user:' + user.email + ' password:' + user.password); return res.body.accessToken; }; @@ -50,7 +50,7 @@ AppStore.prototype.getCloudrons = function () { AppStore.prototype.getCloudron = function (boxId) { var res = request.get(this._origin + '/api/v1/cloudrons/' + boxId).query({ accessToken: this._credentials.accessToken, page: 1, per_page: 50 }).end(); if (res.statusCode === 404) return null; - common.verifyResponse(res, 'Could not query cloudron status'); + common.verifyResponse2(res, 'Could not query cloudron status'); return res.body.box; }; @@ -59,11 +59,11 @@ AppStore.prototype.waitForIP = function (boxId) { var res; - while (true) { + for (var i = 0; i < 40; i++) { sleep(10); process.stdout.write('.'); res = request.get(this._origin + '/api/v1/cloudrons/' + boxId).query({ accessToken: this._credentials.accessToken }).end(); - common.verifyResponse(res, 'Could not query cloudron status'); + common.verifyResponse2(res, 'Could not query cloudron status'); if (res.body.box.ip) { debug(); @@ -71,6 +71,8 @@ AppStore.prototype.waitForIP = function (boxId) { } } + if (!res.body || !res.body.box.ip) throw new Error('waitForIP timeout'); + debug('Box IP:%s'.green, res.body.box.ip); return res.body.box.ip; @@ -82,11 +84,11 @@ AppStore.prototype.waitForCloudron = function (boxId) { var boxInfo = null, res; - while (true) { + for (var i = 0; i < 60; i++) { sleep(10); process.stdout.write('.'); res = request.get(this._origin + '/api/v1/cloudrons/' + boxId).query({ accessToken: this._credentials.accessToken }).end(); - common.verifyResponse(res, 'Could not query cloudron status'); + common.verifyResponse2(res, 'Could not query cloudron status'); boxInfo = res.body.box; if (boxInfo.status === 'ready') { @@ -95,24 +97,29 @@ AppStore.prototype.waitForCloudron = function (boxId) { } } + if (!boxInfo) throw new Error('waitForCloudron: could not get cloudron status'); + debug('Box created in %s minutes with IP:%s'.green, (new Date() - creationTime) / 60000, res.body.box.ip); // even if the cloudron sent heartbeat to appstore, doesn't mean we can contact the cloudron thanks to DO networking insanity process.stdout.write('Waiting for Cloudron to be reachable.'); - while (true) { + for (i = 0; i < 60; i++) { sleep(10); process.stdout.write('.'); res = request.get('https://' + boxInfo.ip).end(); if (!res.error) break; debug(res.error); } + + if (res.error) throw new Error('waitForCloudron: could not reach cloudron'); + return boxInfo; }; AppStore.prototype.createCloudron = function (box) { var accessToken = this._credentials.accessToken; var res = request.post(this._origin + '/api/v1/cloudrons').send(box).query({ accessToken: accessToken }).end(); - common.verifyResponse(res, 'Could not create cloudron %j', box); + common.verifyResponse2(res, 'Could not create cloudron %j', box); debug('Cloudron %s created'.green, box.domain); return res.body.box; @@ -129,23 +136,25 @@ AppStore.prototype.deleteCloudron = function (box) { process.stdout.write('Waiting for Cloudron to disappear.'); for (var i = 0; i < 40; i++) { - if (this.getCloudron(box.id) === null) break; + if (this.getCloudron(box.id) === null) return; sleep(10); process.stdout.write('.'); } + + throw new Error('deleteCloudron: timedout waiting for cloudron to disappear'); }; AppStore.prototype.getManifest = function (appId, version) { var res = request.get(this._origin + '/api/v1/apps/' + appId + '/versions/' + version).end(); - common.verifyResponse(res, 'Could not get get app manifest'); + common.verifyResponse2(res, 'Could not get get app manifest'); return res.body.manifest; }; AppStore.prototype.restore = function (boxId, backupId) { var res = request.post(this._origin + '/api/v1/cloudrons/' + boxId + '/restore/' + backupId).query({ accessToken: this._credentials.accessToken }).end(); - common.verifyResponse(res, 'Could not restore cloudron'); + common.verifyResponse2(res, 'Could not restore cloudron'); }; AppStore.prototype.setupBilling = function (user, callback) { @@ -178,7 +187,7 @@ AppStore.prototype.setupBilling = function (user, callback) { }; var res = request.put(that._origin + '/api/v1/users/' + user.id).send(data).query({ accessToken: that._credentials.accessToken }).end(); - common.verifyResponse(res, 'Could not setup billing'); + common.verifyResponse2(res, 'Could not setup billing'); callback(null); }); diff --git a/cloudron.js b/cloudron.js index ea68d41..4f651fc 100644 --- a/cloudron.js +++ b/cloudron.js @@ -127,7 +127,7 @@ Cloudron.prototype.waitForBox = function () { process.stdout.write('.'); } - assert(false, 'waitForBox failed'); + throw new Error('waitForBox failed'); }; Cloudron.prototype.setCredentials = function (password, accessToken) { @@ -204,7 +204,7 @@ Cloudron.prototype.update = function (toVersion) { console.log('Update started'.green); process.stdout.write('Waiting for update.'); - for (var i = 0; i < 40; i++) { + for (i = 0; i < 40; i++) { sleep(10); res = request.get(this._origin + '/api/v1/cloudron/status').end(); if (res.statusCode === 200 && res.body.version === toVersion) { @@ -247,7 +247,7 @@ Cloudron.prototype.backup = function () { res = request.post(this._origin + '/api/v1/backups').query({ access_token: this._credentials.accessToken }).end(); common.verifyResponse2(res, 'Could not schedule backup'); - while (true) { + for (var i = 0; i < 40; i++) { sleep(10); // backup sometimes takes a while to start res = request.get(this._origin + '/api/v1/cloudron/progress').end(); if (res.body.backup === null || res.body.backup.percent === 100) { @@ -257,6 +257,8 @@ Cloudron.prototype.backup = function () { debug('Backing up: %s %s', res.body.backup.percent, res.body.backup.message); } + if (i === 40) throw new Error('backup: timedout'); + res = request.get(this._origin + '/api/v1/backups').query({ access_token: this._credentials.accessToken }).end(); common.verifyResponse2(res, 'Could not get backups'); var latestBackups = res.body.backups; diff --git a/common.js b/common.js index 9bac33e..9272f91 100644 --- a/common.js +++ b/common.js @@ -49,15 +49,6 @@ function verifyResponse2(res, args) { } } -function verifyResponse(res, args) { - if (res.statusCode < 200 || res.statusCode > 299) { - console.log('Response error statusCode:%s error:%s body:%j', res.statusCode, res.error, res.body); - var errorMessage = util.format.apply(util, Array.prototype.slice.call(arguments, 1)); - debug(errorMessage.red); - process.exit(1); - } -} - function getOwner() { return { username: process.env.APPSTORE_USERNAME || gEcosystem.env.APPSTORE_USERNAME, diff --git a/test/cloudron-update-test.js b/test/cloudron-update-test.js index b150d46..88200c9 100644 --- a/test/cloudron-update-test.js +++ b/test/cloudron-update-test.js @@ -41,7 +41,7 @@ describe('Cloudron update testing', function () { it('can query versions', function () { res = request.get('https://s3.amazonaws.com/staging-cloudron-releases/versions.json').end(); - common.verifyResponse(res); + common.verifyResponse2(res); var boxVersions = Object.keys(common.stripUnreachable(res.body)).sort(semver.rcompare); fromVersion = boxVersions[2]; // we released a new version in before() toVersion = boxVersions[1];