Add validation for options when creating and starting containers

This commit is contained in:
Pablo Carranza Velez 2016-07-22 07:24:43 +00:00
parent 54288f036a
commit e41ebbb52b
3 changed files with 82 additions and 12 deletions

View File

@ -8,6 +8,7 @@ fs = Promise.promisifyAll(require('fs'))
mkdirp = Promise.promisify(require('mkdirp'))
path = require 'path'
utils = require './utils'
config = require './config'
composePathSrc = (appId) ->
return "/mnt/root#{config.dataPath}/#{appId}/docker-compose.yml"
@ -39,12 +40,6 @@ writeComposeFile = (composeSpec, dstPath) ->
.then ->
execAsync('sync')
validateServiceOptions = (service) ->
Promise.try ->
options = _.keys(service)
_.each options, (option) ->
throw new Error("Using #{option} is not allowed.") if !_.includes(utils.validComposeOptions, option)
# Runs docker-compose up using the compose YAML at "path".
# Reports status and errors in JSON to the onStatus function.
# Copies the compose file from srcPath to dstPath adding default volumes
@ -68,11 +63,11 @@ exports.up = (appId, onStatus) ->
.catch ->
dockerUtils.pullAndProtectImage(service.image, reportStatus)
.then ->
validateServiceOptions(service)
utils.validateKeys(service, utils.validComposeOptions)
.then ->
services[serviceName].volumes = utils.defaultBinds(composeDataPath(appId, serviceName))
.then ->
writeComposeFile(composeSpec, dstPath)
writeComposeFile(composeSpec, composePathDst(appId))
.then ->
runComposeCommand(['up', '-d'], appId, reportStatus)
.catch (err) ->
@ -82,7 +77,7 @@ exports.up = (appId, onStatus) ->
# Runs docker-compose down using the compose YAML at "path".
# Reports status and errors in JSON to the onStatus function.
exports.down = (appId, onStatus)
exports.down = (appId, onStatus) ->
onStatus ?= console.log.bind(console)
reportStatus = (status) ->
try onStatus(status)

View File

@ -8,6 +8,7 @@ _ = require 'lodash'
knex = require './db'
{ request } = require './request'
Lock = require 'rwlock'
utils = require './utils'
docker = new Docker(socketPath: config.dockerSocket)
@ -270,7 +271,11 @@ do ->
404: 'no such container'
406: 'impossible to attach'
500: 'server error'
docker.modem.dialAsync(optsf)
utils.validateKeys(options, utils.validContainerOptions)
.then ->
utils.validateKeys(options.HostConfig, utils.validHostConfigOptions)
.then ->
docker.modem.dialAsync(optsf)
.then (data) ->
containerId = data.Id
trx('container').update({ containerId }).where({ id })
@ -284,7 +289,9 @@ do ->
res.status(500).send(err?.message or err or 'Unknown error')
startContainer = (containerId, options) ->
docker.getContainer(containerId).startAsync(options)
utils.validateKeys(options, utils.validHostConfigOptions)
.then ->
docker.getContainer(containerId).startAsync(options)
exports.startContainer = (req, res) ->
startContainer(req.params.id, req.body)
.then (data) ->
@ -342,7 +349,7 @@ do ->
deleteContainer(oldContainerId, v: true)
.then ->
createContainer(req.body, oldContainer.id)
.then ->
.then (data) ->
startContainer(data.Id)
.then (data) ->
res.json(data)

View File

@ -267,3 +267,71 @@ exports.validComposeOptions = [
'networks'
'pid'
]
exports.validContainerOptions = [
'Hostname'
'Domainname'
'User'
'Tty'
'Env'
'Labels'
'Cmd'
'Entrypoint'
'Image'
'Volumes'
'WorkingDir'
'NetworkDisabled'
'ExposedPorts'
'HostConfig'
]
exports.validHostConfigOptions = [
'Binds'
'Links'
'Memory'
'MemorySwap'
'MemoryReservation'
'KernelMemory'
'CpuShares'
'CpuPeriod'
'CpuQuota'
'CpusetCpus'
'CpusetMems'
'BlkioWeight'
'BlkioWeightDevice'
'BlkioDeviceReadBps'
'BlkioDeviceWriteBps'
'BlkioDeviceReadIOps'
'BlkioDeviceWriteIOps'
'MemorySwappiness'
'OomKillDisable'
'OomScoreAdj'
'PidMode'
'PortBindings'
'PublishAllPorts'
'Privileged'
'ReadonlyRootfs'
'Dns'
'DnsOptions'
'DnsSearch'
'ExtraHosts'
'VolumesFrom'
'CapAdd'
'CapDrop'
'GroupAdd'
'RestartPolicy'
'NetworkMode'
'Devices'
'Ulimits'
'SecurityOpt'
'ShmSize'
]
exports.validateKeys = (options, validSet) ->
Promise.try ->
return if !options?
keys = _.keys(options)
invalidKeys = []
_.each keys, (key) ->
invalidKeys.push(key) if !_.includes(validSet, key)
throw new Error("Using #{invalidKeys.join(', ')} is not allowed.") if !_.isEmpty(invalidKeys)