mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-06-06 01:21:39 +00:00
Merge pull request #165 from resin-io/reattach-on-restart
Add listener for container events and reattach on restart
This commit is contained in:
commit
419a4d2510
@ -1,3 +1,4 @@
|
|||||||
|
* Add listener for container events and reattach on restart [Pablo]
|
||||||
* fix deltas by not using the supervisor as source [Pablo]
|
* fix deltas by not using the supervisor as source [Pablo]
|
||||||
|
|
||||||
# v1.11.2
|
# v1.11.2
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"start": "./entry.sh"
|
"start": "./entry.sh"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"JSONStream": "^1.1.2",
|
||||||
"blinking": "~0.0.2",
|
"blinking": "~0.0.2",
|
||||||
"bluebird": "^2.9.24",
|
"bluebird": "^2.9.24",
|
||||||
"body-parser": "^1.12.0",
|
"body-parser": "^1.12.0",
|
||||||
|
@ -14,6 +14,7 @@ lockFile = Promise.promisifyAll(require('lockfile'))
|
|||||||
bootstrap = require './bootstrap'
|
bootstrap = require './bootstrap'
|
||||||
TypedError = require 'typed-error'
|
TypedError = require 'typed-error'
|
||||||
fs = Promise.promisifyAll(require('fs'))
|
fs = Promise.promisifyAll(require('fs'))
|
||||||
|
JSONStream = require 'JSONStream'
|
||||||
|
|
||||||
class UpdatesLockedError extends TypedError
|
class UpdatesLockedError extends TypedError
|
||||||
|
|
||||||
@ -67,6 +68,14 @@ logTypes =
|
|||||||
eventName: 'Application update error'
|
eventName: 'Application update error'
|
||||||
humanName: 'Failed to update application'
|
humanName: 'Failed to update application'
|
||||||
|
|
||||||
|
appExit:
|
||||||
|
eventName: 'Application exit'
|
||||||
|
humanName: 'Application exited'
|
||||||
|
|
||||||
|
appRestart:
|
||||||
|
eventName: 'Application restart'
|
||||||
|
humanName: 'Restarting application'
|
||||||
|
|
||||||
logSystemMessage = (message, obj, eventName) ->
|
logSystemMessage = (message, obj, eventName) ->
|
||||||
logger.log({ message, isSystem: true })
|
logger.log({ message, isSystem: true })
|
||||||
utils.mixpanelTrack(eventName ? message, obj)
|
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.
|
# Set the updating as finished in its own block, so it never has to worry about other code stopping this.
|
||||||
updateStatus.state = UPDATE_IDLE
|
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 = ->
|
application.initialize = ->
|
||||||
|
listenToEvents()
|
||||||
knex('app').select()
|
knex('app').select()
|
||||||
.then (apps) ->
|
.then (apps) ->
|
||||||
Promise.map apps, (app) ->
|
Promise.map apps, (app) ->
|
||||||
|
@ -51,9 +51,18 @@ exports.disableLogPublishing = (disable) ->
|
|||||||
exports.log = ->
|
exports.log = ->
|
||||||
publish(arguments...)
|
publish(arguments...)
|
||||||
|
|
||||||
exports.attach = (app) ->
|
do ->
|
||||||
|
attached = {}
|
||||||
|
exports.attach = (app) ->
|
||||||
|
if !attached[app.containerId]
|
||||||
dockerPromise.then (docker) ->
|
dockerPromise.then (docker) ->
|
||||||
docker.getContainer(app.containerId)
|
docker.getContainer(app.containerId)
|
||||||
.attachAsync({ stream: true, stdout: true, stderr: true, tty: true })
|
.attachAsync({ stream: true, stdout: true, stderr: true, tty: true })
|
||||||
.then (stream) ->
|
.then (stream) ->
|
||||||
stream.pipe(es.split()).on('data', publish)
|
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