Add listener for container events and reattach on restart

This commit is contained in:
Pablo Carranza Velez 2016-06-10 18:41:46 -03:00
parent 891376dd2c
commit a8677a4401
4 changed files with 57 additions and 6 deletions

View File

@ -1,3 +1,4 @@
* Add listener for container events and reattach on restart [Pablo]
* fix deltas by not using the supervisor as source [Pablo]
# v1.11.2

View File

@ -6,6 +6,7 @@
"start": "./entry.sh"
},
"dependencies": {
"JSONStream": "^1.1.2",
"blinking": "~0.0.2",
"bluebird": "^2.9.24",
"body-parser": "^1.12.0",

View File

@ -14,6 +14,7 @@ lockFile = Promise.promisifyAll(require('lockfile'))
bootstrap = require './bootstrap'
TypedError = require 'typed-error'
fs = Promise.promisifyAll(require('fs'))
JSONStream = require 'JSONStream'
class UpdatesLockedError extends TypedError
@ -67,6 +68,14 @@ logTypes =
eventName: 'Application update error'
humanName: 'Failed to update application'
appExit:
eventName: 'Application exit'
humanName: 'Application exited'
appRestart:
eventName: 'Application restart'
humanName: 'Restarting application'
logSystemMessage = (message, obj, eventName) ->
logger.log({ message, isSystem: true })
utils.mixpanelTrack(eventName ? message, obj)
@ -644,7 +653,38 @@ application.update = update = (force) ->
# Set the updating as finished in its own block, so it never has to worry about other code stopping this.
updateStatus.state = UPDATE_IDLE
listenToEvents = do ->
appHasDied = {}
return ->
docker.getEventsAsync()
.then (stream) ->
stream.on 'error', (err) ->
console.error('Error on docker events stream:', err, err.stack)
parser = JSONStream.parse()
parser.on 'error', (err) ->
console.error('Error on docker events JSON stream:', err, err.stack)
parser.on 'data', (data) ->
if data?.Type? && data.Type == 'container' && data.status in ['die', 'start']
knex('app').select().where({ containerId: data.id })
.then ([ app ]) ->
if app?
if data.status == 'die'
logSystemEvent(logTypes.appExit, app)
appHasDied[app.containerId] = true
else if data.status == 'start' and appHasDied[app.containerId]
logSystemEvent(logTypes.appRestart, app)
logger.attach(app)
.catch (err) ->
console.error('Error on docker event:', err, err.stack)
parser.on 'end', ->
console.error('Docker events stream ended, this should never happen')
listenToEvents()
stream.pipe(parser)
.catch (err) ->
console.error('Error listening to events:', err, err.stack)
application.initialize = ->
listenToEvents()
knex('app').select()
.then (apps) ->
Promise.map apps, (app) ->

View File

@ -51,9 +51,18 @@ exports.disableLogPublishing = (disable) ->
exports.log = ->
publish(arguments...)
exports.attach = (app) ->
dockerPromise.then (docker) ->
docker.getContainer(app.containerId)
.attachAsync({ stream: true, stdout: true, stderr: true, tty: true })
.then (stream) ->
stream.pipe(es.split()).on('data', publish)
do ->
attached = {}
exports.attach = (app) ->
if !attached[app.containerId]
dockerPromise.then (docker) ->
docker.getContainer(app.containerId)
.attachAsync({ stream: true, stdout: true, stderr: true, tty: true })
.then (stream) ->
attached[app.containerId] = true
stream.pipe(es.split())
.on('data', publish)
.on 'error', ->
attached[app.containerId] = false
.on 'end', ->
attached[app.containerId] = false