Check against application source for target applications

The supervisor will now check that a source of an application matches
the current source, and only start it if so.

Change-type: patch
Closes: #658
Signed-off-by: Cameron Diver <cameron@resin.io>
This commit is contained in:
Cameron Diver 2018-05-18 13:27:41 +01:00
parent 343989f487
commit bc37ee56e4
No known key found for this signature in database
GPG Key ID: 69264F9C923F55C1
3 changed files with 25 additions and 14 deletions

View File

@ -440,7 +440,8 @@ module.exports = class ApplicationManager extends EventEmitter
).get(appId)
getTargetApp: (appId) =>
@db.models('app').where({ appId }).select()
@config.get('resinApiEndpoint').then (endpoint = '') ->
@db.models('app').where({ appId, source: endpoint }).select()
.then ([ app ]) =>
if !app?
return
@ -776,6 +777,7 @@ module.exports = class ApplicationManager extends EventEmitter
appId: app.appId
commit: app.commit
name: app.name
source: app.source
releaseId: app.releaseId
services: JSON.stringify(services)
networks: JSON.stringify(app.networks ? {})
@ -839,12 +841,13 @@ module.exports = class ApplicationManager extends EventEmitter
return outApp
)
setTarget: (apps, dependent , trx) =>
setTarget: (apps, dependent , source, trx) =>
setInTransaction = (trx) =>
Promise.try =>
appsArray = _.map apps, (app, appId) ->
appClone = _.clone(app)
appClone.appId = checkInt(appId)
appClone.source = source
return appClone
Promise.map(appsArray, @normaliseAppForDB)
.tap (appsForDB) =>
@ -872,7 +875,8 @@ module.exports = class ApplicationManager extends EventEmitter
@_targetVolatilePerImageId[imageId] = {}
getTargetApps: =>
Promise.map(@db.models('app').select(), @normaliseAndExtendAppFromDB)
@config.get('resinApiEndpoint'). then (source = '') =>
Promise.map(@db.models('app').where({ source }), @normaliseAndExtendAppFromDB)
.map (app) =>
if !_.isEmpty(app.services)
app.services = _.map app.services, (service) =>

View File

@ -241,17 +241,20 @@ module.exports = class DeviceState extends EventEmitter
Promise.using @_inferStepsLock, -> fn()
setTarget: (target) ->
validateState(target)
.then =>
@usingWriteLockTarget =>
# Apps, deviceConfig, dependent
@db.transaction (trx) =>
Promise.try =>
@config.set({ name: target.local.name }, trx)
.then =>
@deviceConfig.setTarget(target.local.config, trx)
.then =>
@applications.setTarget(target.local.apps, target.dependent, trx)
Promise.join(
@config.get('resinApiEndpoint'),
validateState(target),
(source) =>
@usingWriteLockTarget =>
# Apps, deviceConfig, dependent
@db.transaction (trx) =>
Promise.try =>
@config.set({ name: target.local.name }, trx)
.then =>
@deviceConfig.setTarget(target.local.config, trx)
.then =>
@applications.setTarget(target.local.apps, target.dependent, source, trx)
)
getTarget: ({ initial = false, intermediate = false } = {}) =>
@usingReadLockTarget =>

View File

@ -19,6 +19,7 @@ appDBFormatNormalised = {
commit: 'bar'
releaseId: 2
name: 'app'
source: 'https://api.resin.io'
services: JSON.stringify([
{
appId: 1234
@ -41,6 +42,9 @@ appStateFormat = {
commit: 'bar'
releaseId: 2
name: 'app'
# This technically is not part of the appStateFormat, but in general
# usage is added before calling normaliseAppForDB
source: 'https://api.resin.io'
services: {
'4': {
appId: 1234