Merge pull request #138 from resin-io/133-stop-app-before-reboot-shutdown

Stop all apps before rebooting or shutting down
This commit is contained in:
Pablo Carranza Vélez 2016-10-27 20:32:19 -03:00 committed by GitHub
commit 70da009c4e
4 changed files with 50 additions and 19 deletions

View File

@ -1,3 +1,4 @@
* Stop all apps before rebooting or shutting down [Pablo]
* Update request-progress to v2.0.1 [Pablo] * Update request-progress to v2.0.1 [Pablo]
# v2.7.1 # v2.7.1

View File

@ -47,25 +47,51 @@ module.exports = (application) ->
application.update(req.body.force) application.update(req.body.force)
res.sendStatus(204) res.sendStatus(204)
unparsedRouter.post '/v1/reboot', (req, res) -> parsedRouter.post '/v1/reboot', (req, res) ->
new Promise (resolve, reject) -> force = req.body.force
application.logSystemMessage('Rebooting', {}, 'Reboot') Promise.map utils.getKnexApps(), (theApp) ->
utils.gosuper.post('/v1/reboot') Promise.using application.lockUpdates(theApp.appId, force), ->
.on('error', reject) # There's a slight chance the app changed after the previous select
.on('response', -> resolve()) # So we fetch it again now the lock is acquired
.pipe(res) utils.getKnexApp(theApp.appId)
.then (app) ->
application.kill(app, removeContainer: false) if app?
.then ->
new Promise (resolve, reject) ->
application.logSystemMessage('Rebooting', {}, 'Reboot')
utils.gosuper.post('/v1/reboot')
.on('error', reject)
.on('response', -> resolve())
.pipe(res)
.catch (err) -> .catch (err) ->
res.status(503).send(err?.message or err or 'Unknown error') if err instanceof application.UpdatesLockedError
status = 423
else
status = 500
res.status(status).send(err?.message or err or 'Unknown error')
unparsedRouter.post '/v1/shutdown', (req, res) -> parsedRouter.post '/v1/shutdown', (req, res) ->
new Promise (resolve, reject) -> force = req.body.force
application.logSystemMessage('Shutting down', {}, 'Shutdown') Promise.map utils.getKnexApps(), (theApp) ->
utils.gosuper.post('/v1/shutdown') Promise.using application.lockUpdates(theApp.appId, force), ->
.on('error', reject) # There's a slight chance the app changed after the previous select
.on('response', -> resolve()) # So we fetch it again now the lock is acquired
.pipe(res) utils.getKnexApp(theApp.appId)
.then (app) ->
application.kill(app, removeContainer: false) if app?
.then ->
new Promise (resolve, reject) ->
application.logSystemMessage('Shutting down', {}, 'Shutdown')
utils.gosuper.post('/v1/shutdown')
.on('error', reject)
.on('response', -> resolve())
.pipe(res)
.catch (err) -> .catch (err) ->
res.status(503).send(err?.message or err or 'Unknown error') if err instanceof application.UpdatesLockedError
status = 423
else
status = 500
res.status(status).send(err?.message or err or 'Unknown error')
parsedRouter.post '/v1/purge', (req, res) -> parsedRouter.post '/v1/purge', (req, res) ->
appId = req.body.appId appId = req.body.appId
@ -130,7 +156,7 @@ module.exports = (application) ->
Promise.using application.lockUpdates(appId, force), -> Promise.using application.lockUpdates(appId, force), ->
utils.getKnexApp(appId) utils.getKnexApp(appId)
.tap (app) -> .tap (app) ->
application.kill(app, true, false) application.kill(app, removeContainer: false)
.then (app) -> .then (app) ->
res.json(_.pick(app, 'containerId')) res.json(_.pick(app, 'containerId'))
.catch utils.AppNotFoundError, (e) -> .catch utils.AppNotFoundError, (e) ->

View File

@ -105,6 +105,7 @@ logTypes =
humanName: 'Failed to update config for application' humanName: 'Failed to update config for application'
application = {} application = {}
application.UpdatesLockedError = UpdatesLockedError
application.logSystemMessage = logSystemMessage = (message, obj, eventName) -> application.logSystemMessage = logSystemMessage = (message, obj, eventName) ->
logger.log({ m: message, s: 1 }) logger.log({ m: message, s: 1 })
@ -132,7 +133,7 @@ logSpecialAction = (action, value, success) ->
msg = "Applying config variable #{action} = #{value}" msg = "Applying config variable #{action} = #{value}"
logSystemMessage(msg, {}, "Apply special action #{if success then "success" else "in progress"}") logSystemMessage(msg, {}, "Apply special action #{if success then "success" else "in progress"}")
application.kill = kill = (app, updateDB = true, removeContainer = true) -> application.kill = kill = (app, { updateDB = true, removeContainer = true } = {}) ->
logSystemEvent(logTypes.stopApp, app) logSystemEvent(logTypes.stopApp, app)
device.updateState(status: 'Stopping') device.updateState(status: 'Stopping')
container = docker.getContainer(app.containerId) container = docker.getContainer(app.containerId)
@ -512,7 +513,7 @@ updateStrategies =
.then -> .then ->
waitToKill(localApp, timeout) waitToKill(localApp, timeout)
.then -> .then ->
kill(localApp, false) kill(localApp, updateDB: false)
.catch (err) -> .catch (err) ->
logSystemEvent(logTypes.updateAppError, app, err) unless err instanceof UpdatesLockedError logSystemEvent(logTypes.updateAppError, app, err) unless err instanceof UpdatesLockedError
throw err throw err

View File

@ -225,6 +225,9 @@ exports.getKnexApp = (appId, columns) ->
throw new AppNotFoundError('App not found') throw new AppNotFoundError('App not found')
return app return app
exports.getKnexApps = (columns) ->
knex('app').select(columns)
exports.getOSVersion = (path) -> exports.getOSVersion = (path) ->
fs.readFileAsync(path) fs.readFileAsync(path)
.then (releaseData) -> .then (releaseData) ->