mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-20 17:52:51 +00:00
Add listener for container events and reattach on restart
This commit is contained in:
parent
891376dd2c
commit
a8677a4401
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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) ->
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user