mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-05-06 10:58:14 +00:00
Add default binds to containers created with API, add /v1/containers/update endpoint, and add a /data bind with an internal id
This commit is contained in:
parent
d652e13005
commit
b97fe634d5
@ -170,6 +170,7 @@ module.exports = (application) ->
|
|||||||
unparsedRouter.delete '/v1/images/*', dockerUtils.deleteImage
|
unparsedRouter.delete '/v1/images/*', dockerUtils.deleteImage
|
||||||
unparsedRouter.get '/v1/images', dockerUtils.listImages
|
unparsedRouter.get '/v1/images', dockerUtils.listImages
|
||||||
parsedRouter.post '/v1/containers/create', dockerUtils.createContainer
|
parsedRouter.post '/v1/containers/create', dockerUtils.createContainer
|
||||||
|
parsedRouter.post '/v1/containers/update', dockerUtils.updateContainer
|
||||||
parsedRouter.post '/v1/containers/:id/start', dockerUtils.startContainer
|
parsedRouter.post '/v1/containers/:id/start', dockerUtils.startContainer
|
||||||
unparsedRouter.post '/v1/containers/:id/stop', dockerUtils.stopContainer
|
unparsedRouter.post '/v1/containers/:id/stop', dockerUtils.stopContainer
|
||||||
unparsedRouter.delete '/v1/containers/:id', dockerUtils.deleteContainer
|
unparsedRouter.delete '/v1/containers/:id', dockerUtils.deleteContainer
|
||||||
|
@ -176,21 +176,8 @@ shouldMountKmod = (image) ->
|
|||||||
return false
|
return false
|
||||||
|
|
||||||
application.start = start = (app) ->
|
application.start = start = (app) ->
|
||||||
volumes =
|
volumes = utils.defaultVolumes
|
||||||
'/data': {}
|
binds = utils.defaultBinds(app.appId)
|
||||||
'/lib/modules': {}
|
|
||||||
'/lib/firmware': {}
|
|
||||||
'/host/var/lib/connman': {}
|
|
||||||
'/host/run/dbus': {}
|
|
||||||
binds = [
|
|
||||||
config.dataPath + '/' + app.appId + ':/data'
|
|
||||||
'/lib/modules:/lib/modules'
|
|
||||||
'/lib/firmware:/lib/firmware'
|
|
||||||
'/run/dbus:/host_run/dbus'
|
|
||||||
'/run/dbus:/host/run/dbus'
|
|
||||||
'/etc/resolv.conf:/etc/resolv.conf:rw'
|
|
||||||
'/var/lib/connman:/host/var/lib/connman'
|
|
||||||
]
|
|
||||||
Promise.try ->
|
Promise.try ->
|
||||||
# Parse the env vars before trying to access them, that's because they have to be stringified for knex..
|
# Parse the env vars before trying to access them, that's because they have to be stringified for knex..
|
||||||
JSON.parse(app.env)
|
JSON.parse(app.env)
|
||||||
|
@ -46,6 +46,12 @@ knex.init = Promise.all([
|
|||||||
knex.schema.createTable 'image', (t) ->
|
knex.schema.createTable 'image', (t) ->
|
||||||
t.increments('id').primary()
|
t.increments('id').primary()
|
||||||
t.string('repoTag')
|
t.string('repoTag')
|
||||||
|
knex.schema.hasTable('container')
|
||||||
|
.then (exists) ->
|
||||||
|
if not exists
|
||||||
|
knex.schema.createTable 'container', (t) ->
|
||||||
|
t.increments('id').primary()
|
||||||
|
t.string('containerId')
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -244,57 +244,81 @@ do ->
|
|||||||
res.status(500).send(err?.message or err or 'Unknown error')
|
res.status(500).send(err?.message or err or 'Unknown error')
|
||||||
|
|
||||||
docker.modem.dialAsync = Promise.promisify(docker.modem.dial)
|
docker.modem.dialAsync = Promise.promisify(docker.modem.dial)
|
||||||
exports.createContainer = (req, res) ->
|
createContainer = (options, internalId) ->
|
||||||
Promise.using writeLockImages(), ->
|
Promise.using writeLockImages(), ->
|
||||||
knex('image').select().where('repoTag', req.body.Image)
|
knex('image').select().where('repoTag', options.Image)
|
||||||
.then (images) ->
|
.then (images) ->
|
||||||
throw new Error('Only images created via the Supervisor can be used for creating containers.') if images.length == 0
|
throw new Error('Only images created via the Supervisor can be used for creating containers.') if images.length == 0
|
||||||
optsf =
|
knex.transaction (trx) ->
|
||||||
path: '/containers/create?'
|
Promise.try ->
|
||||||
method: 'POST'
|
return internalId if internalId?
|
||||||
options: req.body
|
trx.insert({}, 'id').into('container')
|
||||||
statusCodes:
|
.then ([ id ]) ->
|
||||||
200: true
|
return id
|
||||||
201: true
|
.then (id) ->
|
||||||
404: 'no such container'
|
options.HostConfig ?= {}
|
||||||
406: 'impossible to attach'
|
options.Volumes ?= {}
|
||||||
500: 'server error'
|
_.assign(options.Volumes, utils.defaultVolumes)
|
||||||
docker.modem.dialAsync(optsf)
|
options.HostConfig.Binds = utils.defaultBinds("containers/#{id}")
|
||||||
.then (data) ->
|
optsf =
|
||||||
res.json(data)
|
path: '/containers/create?'
|
||||||
.catch (err) ->
|
method: 'POST'
|
||||||
res.status(500).send(err?.message or err or 'Unknown error')
|
options: options
|
||||||
|
statusCodes:
|
||||||
exports.startContainer = (req, res) ->
|
200: true
|
||||||
docker.getContainer(req.params.id).startAsync(req.body)
|
201: true
|
||||||
|
404: 'no such container'
|
||||||
|
406: 'impossible to attach'
|
||||||
|
500: 'server error'
|
||||||
|
docker.modem.dialAsync(optsf)
|
||||||
|
.then (data) ->
|
||||||
|
containerId = data.Id
|
||||||
|
trx('container').update({ containerId }).where({ id })
|
||||||
|
.then ->
|
||||||
|
return data
|
||||||
|
exports.createContainer = (req, res) ->
|
||||||
|
createContainer(req.body)
|
||||||
.then (data) ->
|
.then (data) ->
|
||||||
res.json(data)
|
res.json(data)
|
||||||
.catch (err) ->
|
.catch (err) ->
|
||||||
res.status(500).send(err?.message or err or 'Unknown error')
|
res.status(500).send(err?.message or err or 'Unknown error')
|
||||||
|
|
||||||
exports.stopContainer = (req, res) ->
|
startContainer = (containerId, options) ->
|
||||||
container = docker.getContainer(req.params.id)
|
docker.getContainer(containerId).startAsync(options)
|
||||||
|
exports.startContainer = (req, res) ->
|
||||||
|
startContainer(req.params.id, req.body)
|
||||||
|
.then (data) ->
|
||||||
|
res.json(data)
|
||||||
|
.catch (err) ->
|
||||||
|
res.status(500).send(err?.message or err or 'Unknown error')
|
||||||
|
|
||||||
|
stopContainer = (containerId, options) ->
|
||||||
|
container = docker.getContainer(containerId)
|
||||||
knex('app').select()
|
knex('app').select()
|
||||||
.then (apps) ->
|
.then (apps) ->
|
||||||
throw new Error('Cannot stop an app container') if _.any(apps, containerId: req.params.id)
|
throw new Error('Cannot stop an app container') if _.any(apps, { containerId })
|
||||||
container.inspectAsync()
|
container.inspectAsync()
|
||||||
.then (cont) ->
|
.then (cont) ->
|
||||||
throw new Error('Cannot stop supervisor container') if cont.Name == '/resin_supervisor' or _.any(cont.Names, (n) -> n == '/resin_supervisor')
|
throw new Error('Cannot stop supervisor container') if cont.Name == '/resin_supervisor' or _.any(cont.Names, (n) -> n == '/resin_supervisor')
|
||||||
container.stopAsync(sanitizeQuery(req.query))
|
container.stopAsync(options)
|
||||||
|
exports.stopContainer = (req, res) ->
|
||||||
|
stopContainer(req.params.id, sanitizeQuery(req.query))
|
||||||
.then (data) ->
|
.then (data) ->
|
||||||
res.json(data)
|
res.json(data)
|
||||||
.catch (err) ->
|
.catch (err) ->
|
||||||
res.status(500).send(err?.message or err or 'Unknown error')
|
res.status(500).send(err?.message or err or 'Unknown error')
|
||||||
|
|
||||||
exports.deleteContainer = (req, res) ->
|
deleteContainer = (containerId, options) ->
|
||||||
container = docker.getContainer(req.params.id)
|
container = docker.getContainer(containerId)
|
||||||
knex('app').select()
|
knex('app').select()
|
||||||
.then (apps) ->
|
.then (apps) ->
|
||||||
throw new Error('Cannot remove an app container') if _.any(apps, containerId: req.params.id)
|
throw new Error('Cannot remove an app container') if _.any(apps, { containerId })
|
||||||
container.inspectAsync()
|
container.inspectAsync()
|
||||||
.then (cont) ->
|
.then (cont) ->
|
||||||
throw new Error('Cannot remove supervisor container') if cont.Name == '/resin_supervisor' or _.any(cont.Names, (n) -> n == '/resin_supervisor')
|
throw new Error('Cannot remove supervisor container') if cont.Name == '/resin_supervisor' or _.any(cont.Names, (n) -> n == '/resin_supervisor')
|
||||||
container.removeAsync(sanitizeQuery(req.query))
|
container.removeAsync(options)
|
||||||
|
exports.deleteContainer = (req, res) ->
|
||||||
|
deleteContainer(req.params.id, sanitizeQuery(req.query))
|
||||||
.then (data) ->
|
.then (data) ->
|
||||||
res.json(data)
|
res.json(data)
|
||||||
.catch (err) ->
|
.catch (err) ->
|
||||||
@ -306,3 +330,21 @@ do ->
|
|||||||
res.json(containers)
|
res.json(containers)
|
||||||
.catch (err) ->
|
.catch (err) ->
|
||||||
res.status(500).send(err?.message or err or 'Unknown error')
|
res.status(500).send(err?.message or err or 'Unknown error')
|
||||||
|
|
||||||
|
exports.updateContainer = (req, res) ->
|
||||||
|
{ oldContainerId } = req.query
|
||||||
|
return res.status(400).send('Missing oldContainerId') if !oldContainerId?
|
||||||
|
knex('container').select().where({ containerId: oldContainerId })
|
||||||
|
.then ([ oldContainer ]) ->
|
||||||
|
return res.status(404).send('Old container not found') if !oldContainer?
|
||||||
|
stopContainer(oldContainerId, t: 10)
|
||||||
|
.then ->
|
||||||
|
deleteContainer(oldContainerId, v: true)
|
||||||
|
.then ->
|
||||||
|
createContainer(req.body, oldContainer.id)
|
||||||
|
.then ->
|
||||||
|
startContainer(data.Id)
|
||||||
|
.then (data) ->
|
||||||
|
res.json(data)
|
||||||
|
.catch (err) ->
|
||||||
|
res.status(500).send(err?.message or err or 'Unknown error')
|
@ -204,3 +204,22 @@ exports.getOSVersion = (path) ->
|
|||||||
.catch (err) ->
|
.catch (err) ->
|
||||||
console.log('Could not get OS Version: ', err, err.stack)
|
console.log('Could not get OS Version: ', err, err.stack)
|
||||||
return undefined
|
return undefined
|
||||||
|
|
||||||
|
exports.defaultVolumes = {
|
||||||
|
'/data': {}
|
||||||
|
'/lib/modules': {}
|
||||||
|
'/lib/firmware': {}
|
||||||
|
'/host/var/lib/connman': {}
|
||||||
|
'/host/run/dbus': {}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.defaultBinds = (dataPath) ->
|
||||||
|
return [
|
||||||
|
config.dataPath + '/' + dataPath + ':/data'
|
||||||
|
'/lib/modules:/lib/modules'
|
||||||
|
'/lib/firmware:/lib/firmware'
|
||||||
|
'/run/dbus:/host_run/dbus'
|
||||||
|
'/run/dbus:/host/run/dbus'
|
||||||
|
'/etc/resolv.conf:/etc/resolv.conf:rw'
|
||||||
|
'/var/lib/connman:/host/var/lib/connman'
|
||||||
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user