Add automatic flag for update checks

The appstore can then known if a user clicked the check for updates
button manually or if it was done by the automatic updater.

We will fix appstore so that updates are always provided for manual checks.
automatic updates will follow our roll out plan.

We do have one issue that the automatic update checker will reset the manual
updates when it runs, but this is OK.
This commit is contained in:
Girish Ramakrishnan
2020-05-06 16:50:27 -07:00
parent a96fb39a82
commit 2e130ef99d
6 changed files with 51 additions and 34 deletions

View File

@@ -340,7 +340,8 @@ function sendAliveStatus(callback) {
});
}
function getBoxUpdate(callback) {
function getBoxUpdate(options, callback) {
assert.strictEqual(typeof options, 'object');
assert.strictEqual(typeof callback, 'function');
getCloudronToken(function (error, token) {
@@ -348,7 +349,13 @@ function getBoxUpdate(callback) {
const url = `${settings.apiServerOrigin()}/api/v1/boxupdate`;
superagent.get(url).query({ accessToken: token, boxVersion: constants.VERSION }).timeout(10 * 1000).end(function (error, result) {
const query = {
accessToken: token,
boxVersion: constants.VERSION,
automatic: options.automatic
};
superagent.get(url).query(query).timeout(10 * 1000).end(function (error, result) {
if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message));
if (result.statusCode === 401) return callback(new BoxError(BoxError.INVALID_CREDENTIALS));
if (result.statusCode === 422) return callback(new BoxError(BoxError.LICENSE_ERROR, result.body.message));
@@ -374,16 +381,24 @@ function getBoxUpdate(callback) {
});
}
function getAppUpdate(app, callback) {
function getAppUpdate(app, options, callback) {
assert.strictEqual(typeof app, 'object');
assert.strictEqual(typeof options, 'object');
assert.strictEqual(typeof callback, 'function');
getCloudronToken(function (error, token) {
if (error) return callback(error);
const url = `${settings.apiServerOrigin()}/api/v1/appupdate`;
const query = {
accessToken: token,
boxVersion: constants.VERSION,
appId: app.appStoreId,
appVersion: app.manifest.version,
automatic: options.automatic
};
superagent.get(url).query({ accessToken: token, boxVersion: constants.VERSION, appId: app.appStoreId, appVersion: app.manifest.version }).timeout(10 * 1000).end(function (error, result) {
superagent.get(url).query(query).timeout(10 * 1000).end(function (error, result) {
if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error));
if (result.statusCode === 401) return callback(new BoxError(BoxError.INVALID_CREDENTIALS));
if (result.statusCode === 422) return callback(new BoxError(BoxError.LICENSE_ERROR, result.body.message));

View File

@@ -81,13 +81,13 @@ function startJobs(callback) {
gJobs.boxUpdateCheckerJob = new CronJob({
cronTime: '00 ' + randomMinute + ' * * * *', // once an hour
onTick: () => updateChecker.checkBoxUpdates(NOOP_CALLBACK),
onTick: () => updateChecker.checkBoxUpdates({ automatic: true }, NOOP_CALLBACK),
start: true
});
gJobs.appUpdateChecker = new CronJob({
cronTime: '00 ' + randomMinute + ' * * * *', // once an hour
onTick: () => updateChecker.checkAppUpdates(NOOP_CALLBACK),
onTick: () => updateChecker.checkAppUpdates({ automatic: true }, NOOP_CALLBACK),
start: true
});

View File

@@ -218,8 +218,8 @@ function checkForUpdates(req, res, next) {
req.clearTimeout();
async.series([
updateChecker.checkAppUpdates,
updateChecker.checkBoxUpdates
(done) => updateChecker.checkAppUpdates({ automatic: false }, done),
(done) => updateChecker.checkBoxUpdates({ automatic: false }, done),
], function () {
next(new HttpSuccess(200, { update: updateChecker.getUpdateInfo() }));
});

View File

@@ -13,7 +13,6 @@ var appdb = require('../appdb.js'),
database = require('../database.js'),
domains = require('../domains.js'),
expect = require('expect.js'),
mail = require('../mail.js'),
mailer = require('../mailer.js'),
nock = require('nock'),
paths = require('../paths.js'),
@@ -95,10 +94,10 @@ describe('updatechecker - box - manual (email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/boxupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken' })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', automatic: false })
.reply(204, { } );
updatechecker.checkBoxUpdates(function (error) {
updatechecker.checkBoxUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().box).to.be(null);
expect(scope.isDone()).to.be.ok();
@@ -112,10 +111,10 @@ describe('updatechecker - box - manual (email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/boxupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken' })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', automatic: false })
.reply(200, { version: UPDATE_VERSION, changelog: [''], sourceTarballUrl: 'box.tar.gz', sourceTarballSigUrl: 'box.tar.gz.sig', boxVersionsUrl: 'box.versions', boxVersionsSigUrl: 'box.versions.sig' } );
updatechecker.checkBoxUpdates(function (error) {
updatechecker.checkBoxUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().box.version).to.be(UPDATE_VERSION);
expect(updatechecker.getUpdateInfo().box.sourceTarballUrl).to.be('box.tar.gz');
@@ -130,10 +129,10 @@ describe('updatechecker - box - manual (email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/boxupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken' })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', automatic: false })
.reply(404, { version: '2.0.0-pre.0', changelog: [''], sourceTarballUrl: 'box-pre.tar.gz' } );
updatechecker.checkBoxUpdates(function (error) {
updatechecker.checkBoxUpdates({ automatic: false }, function (error) {
expect(error).to.be.ok();
expect(updatechecker.getUpdateInfo().box).to.be(null);
expect(scope.isDone()).to.be.ok();
@@ -165,10 +164,10 @@ describe('updatechecker - box - automatic (no email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/boxupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken' })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', automatic: false })
.reply(200, { version: UPDATE_VERSION, changelog: [''], sourceTarballUrl: 'box.tar.gz', sourceTarballSigUrl: 'box.tar.gz.sig', boxVersionsUrl: 'box.versions', boxVersionsSigUrl: 'box.versions.sig' } );
updatechecker.checkBoxUpdates(function (error) {
updatechecker.checkBoxUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().box.version).to.be(UPDATE_VERSION);
expect(scope.isDone()).to.be.ok();
@@ -200,10 +199,10 @@ describe('updatechecker - box - automatic free (email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/boxupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken' })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', automatic: false })
.reply(200, { version: UPDATE_VERSION, changelog: [''], sourceTarballUrl: 'box.tar.gz', sourceTarballSigUrl: 'box.tar.gz.sig', boxVersionsUrl: 'box.versions', boxVersionsSigUrl: 'box.versions.sig' } );
updatechecker.checkBoxUpdates(function (error) {
updatechecker.checkBoxUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().box.version).to.be(UPDATE_VERSION);
expect(scope.isDone()).to.be.ok();
@@ -265,10 +264,10 @@ describe('updatechecker - app - manual (email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/appupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version, automatic: false })
.reply(204, { } );
updatechecker.checkAppUpdates(function (error) {
updatechecker.checkAppUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().apps).to.eql({});
expect(scope.isDone()).to.be.ok();
@@ -282,10 +281,10 @@ describe('updatechecker - app - manual (email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/appupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version, automatic: false })
.reply(500, { update: { manifest: { version: '1.0.0', changelog: '* some changes' } } } );
updatechecker.checkAppUpdates(function (error) {
updatechecker.checkAppUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().apps).to.eql({});
expect(scope.isDone()).to.be.ok();
@@ -299,10 +298,10 @@ describe('updatechecker - app - manual (email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/appupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version, automatic: false })
.reply(200, { manifest: { version: '2.0.0', changelog: '* some changes' } } );
updatechecker.checkAppUpdates(function (error) {
updatechecker.checkAppUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().apps).to.eql({ 'appid-0': { manifest: { version: '2.0.0', changelog: '* some changes' } } });
expect(scope.isDone()).to.be.ok();
@@ -314,7 +313,7 @@ describe('updatechecker - app - manual (email)', function () {
it('does not offer old version', function (done) {
nock.cleanAll();
updatechecker.checkAppUpdates(function (error) {
updatechecker.checkAppUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().apps).to.eql({ });
checkMails(0, done);
@@ -374,10 +373,10 @@ describe('updatechecker - app - automatic (no email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/appupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version, automatic: false })
.reply(200, { manifest: { version: '2.0.0', changelog: 'c' } } );
updatechecker.checkAppUpdates(function (error) {
updatechecker.checkAppUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().apps).to.eql({ 'appid-0': { manifest: { version: '2.0.0', changelog: 'c' } } });
expect(scope.isDone()).to.be.ok();
@@ -439,10 +438,10 @@ describe('updatechecker - app - automatic free (email)', function () {
var scope = nock('http://localhost:4444')
.get('/api/v1/appupdate')
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version })
.query({ boxVersion: constants.VERSION, accessToken: 'atoken', appId: APP_0.appStoreId, appVersion: APP_0.manifest.version, automatic: false })
.reply(200, { manifest: { version: '2.0.0', changelog: 'c' } } );
updatechecker.checkAppUpdates(function (error) {
updatechecker.checkAppUpdates({ automatic: false }, function (error) {
expect(!error).to.be.ok();
expect(updatechecker.getUpdateInfo().apps).to.eql({ 'appid-0': { manifest: { version: '2.0.0', changelog: 'c' } } });
expect(scope.isDone()).to.be.ok();

View File

@@ -62,7 +62,8 @@ function resetAppUpdateInfo(appId) {
}
}
function checkAppUpdates(callback) {
function checkAppUpdates(options, callback) {
assert.strictEqual(typeof options, 'object');
assert.strictEqual(typeof callback, 'function');
debug('Checking App Updates');
@@ -84,7 +85,7 @@ function checkAppUpdates(callback) {
if (app.appStoreId === '') return iteratorDone(); // appStoreId can be '' for dev apps
if (app.runState === apps.RSTATE_STOPPED) return iteratorDone(); // stopped apps won't run migration scripts and shouldn't be updated
appstore.getAppUpdate(app, function (error, updateInfo) {
appstore.getAppUpdate(app, options, function (error, updateInfo) {
if (error) {
debug('Error getting app update info for %s', app.id, error);
return iteratorDone(); // continue to next
@@ -136,14 +137,15 @@ function checkAppUpdates(callback) {
});
}
function checkBoxUpdates(callback) {
function checkBoxUpdates(options, callback) {
assert.strictEqual(typeof options, 'object');
assert.strictEqual(typeof callback, 'function');
debug('Checking Box Updates');
gBoxUpdateInfo = null;
appstore.getBoxUpdate(function (error, updateInfo) {
appstore.getBoxUpdate(options, function (error, updateInfo) {
if (error || !updateInfo) return callback(error);
gBoxUpdateInfo = updateInfo;