mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-21 02:01:35 +00:00
Only remove volumes when we're moving between applications
Change-type: major Signed-off-by: Cameron Diver <cameron@balena.io>
This commit is contained in:
parent
9fdd1d7427
commit
5357d4729d
@ -156,11 +156,10 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
@networks.create(step.target)
|
||||
else
|
||||
@volumes.create(step.target)
|
||||
removeNetworkOrVolume: (step) =>
|
||||
if step.model is 'network'
|
||||
@networks.remove(step.current)
|
||||
else
|
||||
@volumes.remove(step.current)
|
||||
removeNetwork: (step) =>
|
||||
@networks.remove(step.current)
|
||||
removeVolume: (step) =>
|
||||
@volumes.remove(step.current)
|
||||
ensureSupervisorNetwork: =>
|
||||
@networks.ensureSupervisorNetwork()
|
||||
}
|
||||
@ -467,7 +466,9 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
dependencies = _.filter currentApp.services, (service) ->
|
||||
dependencyComparisonFn(service, current)
|
||||
if _.isEmpty(dependencies)
|
||||
return [{ action: 'removeNetworkOrVolume', model, current }]
|
||||
if model is 'network'
|
||||
return [{ action: 'removeNetwork', current }]
|
||||
return []
|
||||
else
|
||||
# If the current update doesn't require killing the services that use this network/volume,
|
||||
# we have to kill them before removing the network/volume (e.g. when we're only updating the network config)
|
||||
@ -858,11 +859,33 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
return { imagesToSave, imagesToRemove }
|
||||
|
||||
_inferNextSteps: (cleanupNeeded, availableImages, downloading, supervisorNetworkReady, current, target, ignoreImages, { localMode, delta }) =>
|
||||
volumePromises = []
|
||||
Promise.try =>
|
||||
if localMode
|
||||
ignoreImages = true
|
||||
currentByAppId = current.local.apps ? {}
|
||||
targetByAppId = target.local.apps ? {}
|
||||
|
||||
# Given we need to detect when a device is moved
|
||||
# between applications, we do it this way. This code
|
||||
# is going to change to an application-manager +
|
||||
# application model, which means that we can just
|
||||
# detect when an application is no longer referenced
|
||||
# in the target state, and run the teardown that way.
|
||||
# Until then, this essentially does the same thing. We
|
||||
# check when every other part of the teardown for an
|
||||
# application has been complete, and then append the
|
||||
# volume removal steps
|
||||
# multi-app warning: this will break
|
||||
currentAppIds = _.keys(current.local.apps).map((n) -> checkInt(n))
|
||||
targetAppIds = _.keys(target.local.apps).map((n) -> checkInt(n))
|
||||
oldApps = null
|
||||
if targetAppIds.length > 1
|
||||
throw new Error('Current supervisor does not support multiple applications')
|
||||
diff = _.difference(currentAppIds, targetAppIds)
|
||||
if diff.length > 0
|
||||
oldApps = diff
|
||||
|
||||
nextSteps = []
|
||||
if !supervisorNetworkReady
|
||||
# if the supervisor0 network isn't ready and there's any containers using it, we need
|
||||
@ -894,6 +917,12 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
allAppIds = _.union(_.keys(currentByAppId), _.keys(targetByAppId))
|
||||
for appId in allAppIds
|
||||
nextSteps = nextSteps.concat(@_nextStepsForAppUpdate(currentByAppId[appId], targetByAppId[appId], localMode, availableImages, downloading))
|
||||
if oldApps != null and _.includes(oldApps, checkInt(appId))
|
||||
# We check if everything else has been done for
|
||||
# the old app to be removed. If it has, we then
|
||||
# remove all of the volumes
|
||||
if _.every(nextSteps, { action: 'noop' })
|
||||
volumePromises.push(@removeAllVolumesForApp(checkInt(appId)))
|
||||
newDownloads = _.filter(nextSteps, (s) -> s.action == 'fetch').length
|
||||
if !ignoreImages and delta and newDownloads > 0
|
||||
downloadsToBlock = downloading.length + newDownloads - constants.maxDeltaDownloads
|
||||
@ -903,6 +932,11 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
if !ignoreImages and _.isEmpty(nextSteps) and !_.isEmpty(downloading)
|
||||
nextSteps.push({ action: 'noop' })
|
||||
return _.uniqWith(nextSteps, _.isEqual)
|
||||
.then (nextSteps) ->
|
||||
Promise.all(volumePromises).then (volSteps) ->
|
||||
nextSteps = nextSteps.concat(_.flatten(volSteps))
|
||||
return nextSteps
|
||||
|
||||
|
||||
stopAll: ({ force = false, skipLock = false } = {}) =>
|
||||
Promise.resolve(@services.getAll())
|
||||
@ -962,4 +996,8 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
svc.serviceId == serviceId
|
||||
.get('serviceName')
|
||||
|
||||
removeAllVolumesForApp: (appId) =>
|
||||
@volumes.getAllByAppId(appId).then (volumes) ->
|
||||
return volumes.map((v) -> { action: 'removeVolume', current: v })
|
||||
|
||||
localModeSwitchCompletion: => @localModeManager.switchCompletion()
|
||||
|
Loading…
x
Reference in New Issue
Block a user