mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-05-05 10:32:56 +00:00
Use rwlock together with lockfile
Select app to kill from DB within lock (otherwise, if some other part kills and restarts the app, the containerId will have changed and the real container will not be removed).
This commit is contained in:
parent
d1b317399e
commit
c7c4aed746
@ -67,11 +67,11 @@ module.exports = (secret) ->
|
||||
utils.mixpanelTrack('Purge /data', appId)
|
||||
if !appId?
|
||||
return res.status(400).send('Missing app id')
|
||||
Promise.using application.lockUpdates(app), ->
|
||||
knex('app').select().where({ appId })
|
||||
.then ([ app ]) ->
|
||||
if !app?
|
||||
throw new Error('App not found')
|
||||
Promise.using application.lockUpdates(app), ->
|
||||
application.kill(app)
|
||||
.then ->
|
||||
new Promise (resolve, reject) ->
|
||||
|
@ -251,13 +251,19 @@ exports.unlockAndStart = unlockAndStart = (app) ->
|
||||
.then ->
|
||||
start(app)
|
||||
|
||||
exports.lockUpdates = lockUpdates = (app, force) ->
|
||||
Promise.try ->
|
||||
exports.lockUpdates = lockUpdates = do ->
|
||||
_lock = new Lock()
|
||||
_writeLock = Promise.promisify(_lock.async.writeLock)
|
||||
return (app, force) ->
|
||||
_writeLock(lockPath(app))
|
||||
.tap ->
|
||||
lockFile.unlockAsync(lockPath(app)) if force == true
|
||||
.then ->
|
||||
.tap ->
|
||||
lockFile.lockAsync(lockPath(app))
|
||||
.disposer ->
|
||||
.disposer (release) ->
|
||||
lockFile.unlockAsync(lockPath(app))
|
||||
.then ->
|
||||
release()
|
||||
|
||||
joinErrorMessages = (failures) ->
|
||||
s = if failures.length > 1 then 's' else ''
|
||||
@ -354,7 +360,13 @@ exports.update = update = (force) ->
|
||||
# Then delete all the ones to remove in one go
|
||||
Promise.map toBeRemoved, (appId) ->
|
||||
Promise.using lockUpdates(apps[appId], force), ->
|
||||
kill(apps[appId])
|
||||
# We get the app from the DB again in case someone restarted it
|
||||
# (which would have changed its containerId)
|
||||
knex('app').select().where({ appId })
|
||||
.then ([ app ]) ->
|
||||
if !app?
|
||||
throw new Error('App not found')
|
||||
kill(app)
|
||||
.then ->
|
||||
knex('app').where('appId', appId).delete()
|
||||
.catch (err) ->
|
||||
@ -372,6 +384,10 @@ exports.update = update = (force) ->
|
||||
app = remoteApps[appId]
|
||||
logSystemEvent(logTypes.updateApp, app) if localApp.imageId == app.imageId
|
||||
Promise.using lockUpdates(localApp, force), ->
|
||||
knex('app').select().where({ appId })
|
||||
.then ([ localApp ]) ->
|
||||
if !localApp?
|
||||
throw new Error('App not found')
|
||||
kill(localApp)
|
||||
.then ->
|
||||
start(app)
|
||||
|
Loading…
x
Reference in New Issue
Block a user