mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-21 02:01:35 +00:00
Add validation for options when creating and starting containers
This commit is contained in:
parent
54288f036a
commit
e41ebbb52b
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user