From ac02d507153de62dfc4c1578812cef416bfcf29f Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Thu, 27 Oct 2016 18:36:25 -0300 Subject: [PATCH] Improvements in container create/start: * Add HostConfig in container create instead of start * Make it clear in logs when container was already running --- CHANGELOG.md | 2 ++ src/application.coffee | 54 +++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a510c13..b03f7191 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +* Add HostConfig in container create instead of start [Pablo] +* Make it clear in logs when container was already running [Pablo] * Stop all apps before rebooting or shutting down [Pablo] * Update request-progress to v2.0.1 [Pablo] diff --git a/src/application.coffee b/src/application.coffee index 11b2098f..2c9a377c 100644 --- a/src/application.coffee +++ b/src/application.coffee @@ -75,6 +75,9 @@ logTypes = startAppSuccess: eventName: 'Application started' humanName: 'Started application' + startAppNoop: + eventName: 'Application already running' + humanName: 'Application is already running' startAppError: eventName: 'Application start error' humanName: 'Failed to start application' @@ -218,6 +221,7 @@ shouldMountKmod = (image) -> application.start = start = (app) -> volumes = utils.defaultVolumes binds = utils.defaultBinds(app.appId) + alreadyStarted = false Promise.try -> # Parse the env vars before trying to access them, that's because they have to be stringified for knex.. return [ JSON.parse(app.env), JSON.parse(app.config) ] @@ -243,23 +247,35 @@ application.start = start = (app) -> device.updateState(status: 'Installing') ports = {} + portBindings = {} if portList? portList.forEach (port) -> ports[port + '/tcp'] = {} + portBindings[port + '/tcp'] = [ HostPort: port ] if imageInfo?.Config?.Cmd cmd = imageInfo.Config.Cmd else cmd = [ '/bin/bash', '-c', '/start' ] - docker.createContainerAsync( - Image: app.imageId - Cmd: cmd - Tty: true - Volumes: volumes - Env: _.map env, (v, k) -> k + '=' + v - ExposedPorts: ports - ) + restartPolicy = createRestartPolicy({ name: conf['RESIN_APP_RESTART_POLICY'], maximumRetryCount: conf['RESIN_APP_RESTART_RETRIES'] }) + shouldMountKmod(app.imageId) + .then (shouldMount) -> + binds.push('/bin/kmod:/bin/kmod:ro') if shouldMount + docker.createContainerAsync( + Image: app.imageId + Cmd: cmd + Tty: true + Volumes: volumes + Env: _.map env, (v, k) -> k + '=' + v + ExposedPorts: ports + HostConfig: + Privileged: true + NetworkMode: 'host' + PortBindings: portBindings + Binds: binds + RestartPolicy: restartPolicy + ) .tap -> logSystemEvent(logTypes.installAppSuccess, app) .catch (err) -> @@ -268,25 +284,12 @@ application.start = start = (app) -> .tap (container) -> logSystemEvent(logTypes.startApp, app) device.updateState(status: 'Starting') - ports = {} - if portList? - portList.forEach (port) -> - ports[port + '/tcp'] = [ HostPort: port ] - restartPolicy = createRestartPolicy({ name: conf['RESIN_APP_RESTART_POLICY'], maximumRetryCount: conf['RESIN_APP_RESTART_RETRIES'] }) - shouldMountKmod(app.imageId) - .then (shouldMount) -> - binds.push('/bin/kmod:/bin/kmod:ro') if shouldMount - container.startAsync( - Privileged: true - NetworkMode: 'host' - PortBindings: ports - Binds: binds - RestartPolicy: restartPolicy - ) + container.startAsync() .catch (err) -> statusCode = '' + err.statusCode # 304 means the container was already started, precisely what we want :) if statusCode is '304' + alreadyStarted = true return if statusCode is '500' and err.json.trim().match(/exec format error$/) @@ -316,7 +319,10 @@ application.start = start = (app) -> .then (affectedRows) -> knex('app').insert(app) if affectedRows == 0 .tap -> - logSystemEvent(logTypes.startAppSuccess, app) + if alreadyStarted + logSystemEvent(logTypes.startAppNoop, app) + else + logSystemEvent(logTypes.startAppSuccess, app) .finally -> device.updateState(status: 'Idle')