ApplicationManager: when comparing images to save metadata, take docker image ids into account

Otherwise we may skip saving a target image to the db when updating from legacy supervisors,
which in turn prevents from deleting the legacy image entry (with imageId = 1), leaving the
supervisor in a state where it can't report its current state to the API.

While we're at it, we also remove an unused variable in _getStatus.

Change-type: patch
Signed-off-by: Pablo Carranza Velez <pablo@balena.io>
This commit is contained in:
Pablo Carranza Velez 2018-10-23 15:08:51 -07:00
parent 67486146c4
commit 1c5891ec09

View File

@ -200,8 +200,7 @@ module.exports = class ApplicationManager extends EventEmitter
@services.getStatus()
@images.getStatus(localMode)
@config.get('currentCommit')
@db.models('app').select([ 'appId', 'releaseId', 'commit' ])
(services, images, currentCommit, targetApps) ->
(services, images, currentCommit) ->
apps = {}
dependent = {}
releaseId = null
@ -808,10 +807,15 @@ module.exports = class ApplicationManager extends EventEmitter
_.map app.services, (service) ->
img = _.find(available, { dockerImageId: service.config.image, imageId: service.imageId }) ? _.find(available, { dockerImageId: service.config.image })
return _.omit(img, [ 'dockerImageId', 'id' ])
allImageDockerIdsForTargetApp = (app) ->
_(app.services).map((svc) -> [ svc.imageName, svc.config.image ])
.filter((img) -> img[1]?)
.value()
availableWithoutIds = _.map(available, (image) -> _.omit(image, [ 'dockerImageId', 'id' ]))
currentImages = _.flatMap(current.local.apps, allImagesForCurrentApp)
targetImages = _.flatMap(target.local.apps, allImagesForTargetApp)
targetImageDockerIds = _.fromPairs(_.flatMap(target.local.apps, allImageDockerIdsForTargetApp))
availableAndUnused = _.filter availableWithoutIds, (image) ->
!_.some currentImages.concat(targetImages), (imageInUse) -> _.isEqual(image, imageInUse)
@ -823,8 +827,16 @@ module.exports = class ApplicationManager extends EventEmitter
imagesToSave = []
if !localMode
imagesToSave = _.filter targetImages, (targetImage) =>
_.some(available, (availableImage) => @images.isSameImage(availableImage, targetImage)) and
!_.some availableWithoutIds, (img) -> _.isEqual(img, targetImage)
isActuallyAvailable = _.some(
available, (availableImage) =>
if @images.isSameImage(availableImage, targetImage)
return true
if availableImage.dockerImageId == targetImageDockerIds[targetImage.name]
return true
return false
)
isNotSaved = !_.some availableWithoutIds, (img) -> _.isEqual(img, targetImage)
return isActuallyAvailable and isNotSaved
deltaSources = _.map imagesToDownload, (image) =>
return @bestDeltaSource(image, available)