Stan Lagun 52a4621626 Fixes port acquiring logic in DockerStandaloneHost
Previous code used integer keys in port map. But because
JSON doesn't support integer keys they were converted
to corresponding string representations and were not
found on subsequent deployments

Change-Id: I0477a043854a5ed78545d3b944397cdbf2352bd8
Closes-Bug: #1444681
2015-04-16 03:05:36 +03:00

279 lines
8.6 KiB
YAML

Namespaces:
=: io.murano.apps.docker
res: io.murano.resources
std: io.murano
sys: io.murano.system
Name: DockerStandaloneHost
Extends:
- DockerContainerHost
Properties:
name:
Contract: $.string().notNull()
instance:
Contract: $.class(res:LinuxMuranoInstance).notNull()
dockerRegistry:
Contract: $.string()
applicationEndpoints:
Contract:
- port: $.int().notNull().check($ > 0)
address: $.string().notNull()
scope: $.string().notNull().check($ in list(public, cloud, internal, host))
portScope: $.string().notNull().check($ in list(public, cloud, internal, host))
containerPort: $.int().notNull().check($ > 0)
applicationName: $.string().notNull()
protocol: $.string().notNull().check($ in list(TCP, UDP))
Default: []
Usage: Out
containers:
Contract:
- $.string().notNull()
Default: []
Usage: Out
Methods:
initialize:
Body:
- $._environment: $.find(std:Environment).require()
deploy:
Body:
- If: not $.getAttr(deployed, false)
Then:
- $._environment.reporter.report($this, 'Create VM for Docker Server')
- $.instance.deploy()
- If: $.dockerRegistry != null and $.dockerRegistry != ''
Then:
- $._environment.reporter.report($this, 'Configuring Docker registry')
- $resources: new(sys:Resources)
- $template: $resources.yaml('SetupDockerRegistry.template').bind(dict(
dockerRegistry => $.dockerRegistry
))
- $.instance.agent.call($template, $resources)
- $._environment.reporter.report($this, 'Docker Server is up and running')
- $.setAttr(deployed, true)
hostContainer:
Arguments:
- container:
Contract: $.class(DockerContainer).notNull()
Body:
- $.deploy()
- $.deleteContainer($container.name)
- $portBindings: {}
- $newEndpoints: []
- $._pullImage(image => $container.image)
- For: applicationPort
In: $container.ports
Do:
- If: $applicationPort.scope != host
Then:
- $hostPort: $._acquirePort($applicationPort, $container.name)
- $containerPort: $._getPortSpec($applicationPort)
- $portBindings[$hostPort]: $containerPort
- If: $applicationPort.scope = public
Then:
- $rule:
- ToPort: $hostPort
FromPort: $hostPort
IpProtocol: toLower($applicationPort.protocol)
External: true
- $._environment.securityGroupManager.addGroupIngress($rule)
- $record:
port: $hostPort
address: $.instance.ipAddresses[0]
scope: cloud
containerPort: $applicationPort.port
portScope: $applicationPort.scope
protocol: $applicationPort.protocol
applicationName: $container.name
- $newEndpoints: $newEndpoints + list($record)
- If: $applicationPort.scope = public and $.instance.floatingIpAddress != null
Then:
- $record.address: $.instance.floatingIpAddress
- $record.scope: public
- $newEndpoints: $newEndpoints + list($record)
- $volumeMap: {}
- For: path
In: $container.volumes
Do:
- $volume: $container.volumes.get($path)
- If: $volume.getType() = HostDir
Then:
- $hostDir: $volume.getParameters()
- $volumeMap[$hostDir]: $path
- $._environment.reporter.report($this, 'Adding Docker Application')
- $resources: new(sys:Resources)
- $template: $resources.yaml('RunContainer.template').bind(dict(
appName => $container.name,
image => $container.image,
env => $container.env,
portMap => $portBindings,
volumeMap => $volumeMap,
commands => $container.commands
))
- $._removeApplicationEndpoints($container.name)
- $privateIp: $.instance.agent.call($template, $resources)
- $record:
port: $applicationPort.port
address: $privateIp
scope: host
containerPort: $applicationPort.port
portScope: $applicationPort.scope
protocol: $applicationPort.protocol
applicationName: $container.name
- $newEndpoints: $newEndpoints + list($record)
- $._environment.stack.push()
- If: not $container.name in $.containers
Then:
- $.containers: $.containers + list($container.name)
- $.applicationEndpoints: $.applicationEndpoints + $newEndpoints
- Return: $.getEndpoints($container.name)
getEndpoints:
Arguments:
- applicationName:
Contract: $.string().notNull()
Body:
- Return: $.applicationEndpoints.where($.applicationName = $applicationName)
_getPortSpec:
Arguments:
- applicationPort:
Contract: $.class(ApplicationPort).notNull()
Body:
- If: $applicationPort.protocol = UDP
Then:
- Return: format('{0}/udp', $applicationPort.port)
Else:
- Return: str($applicationPort.port)
_pullImage:
Arguments:
- image:
Contract: $.string().notNull()
Body:
- $._environment.reporter.report($this, 'Pulling app image {0}'.format($image))
- $resources: new(sys:Resources)
- $template: $resources.yaml('PullImage.template').bind(dict(
image => $image
))
- $.instance.agent.call($template, $resources)
- $._environment.reporter.report($this, 'Image saved')
_acquirePort:
Arguments:
- applicationPort:
Contract: $.class(ApplicationPort).notNull()
- applicationName:
Contract: $.string().notNull()
Body:
- $portMap: $.getAttr(portMap, dict())
- $applicationPorts: $.getAttr(applicationPorts, dict())
- $key: format('{0}-{1}-{2}', $applicationPort.port, $applicationPort.protocol, $applicationName)
- If: $key in $applicationPorts
Then:
- Return: $applicationPorts.get($key)
- $port: str($applicationPort.port)
- If: $port in $portMap
Then:
- $port: '1025'
- While: $port in $portMap
Do:
- $port: str(int($port) + 1)
- $portMap[$port]: $applicationName
- $applicationPorts[$key]: $port
- $.setAttr(portMap, $portMap)
- $.setAttr(applicationPorts, $applicationPorts)
- Return: int($port)
_releaseApplicationPorts:
Arguments:
- applicationName:
Contract: $.string().notNull()
Body:
- $portMap: $.getAttr(portMap, dict())
- $applicationPorts: $.getAttr(applicationPorts, dict())
- $newPortMap: {}
- $newApplicationPorts: {}
- $portsToDelete: []
- For: port
In: $portMap.keys()
Do:
- $value: $portMap.get($port)
- If: $value = $applicationName
Then:
- $portsToDelete: $portsToDelete + list($port)
Else:
- $newPortMap[$port]: $value
- For: key
In: $applicationPorts.keys()
Do:
- $value: $applicationPorts.get($port)
- If: not $value in $portsToDelete
Then:
- $newApplicationPorts[$key]: $value
- $.setAttr(portMap, $newPortMap)
- $.setAttr(applicationPorts, $newApplicationPorts)
_getResourceName:
Arguments:
- applicationName:
Contract: $.string().notNull()
Body:
- Return: format('{0}-{1}', $applicationName, $.id())
_removeApplicationEndpoints:
Arguments:
- applicationName:
Contract: $.string().notNull()
Body:
- $.applicationEndpoints: $.applicationEndpoints.where($.applicationName != $applicationName)
deleteContainer:
Arguments:
- name:
Contract: $.string().notNull()
Body:
- If: $name in $.containers
Then:
- $._environment.reporter.report($this, 'Deleting container {0}'.format($name))
- $._removeApplicationEndpoints($name)
- $._releaseApplicationPorts($name)
- $.containers: $.containers.where($ != $name)
- $resources: new(sys:Resources)
- $template: $resources.yaml('RemoveContainer.template').bind(dict(
name => $name
))
- $.instance.agent.call($template, $resources)
- $._environment.reporter.report($this, 'Container {0} deleted'.format($name))
getInternalScopeId:
Body:
Return: $.id()