# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. Namespaces: =: com.mirantis.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() dockerMirror: Contract: $.string() gcloudKey: 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: .init: 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() - $resources: new(sys:Resources) - $template: $resources.yaml('StartDocker.template') - $.instance.agent.call($template, $resources) - If: $.dockerMirror != null and $.dockerMirror != '' or $.dockerRegistry != null and $.dockerRegistry != '' Then: - $._environment.reporter.report($this, 'Configuring Docker options') - $template: $resources.yaml('SetupDockerOptions.template').bind(dict( dockerRegistry => $.dockerRegistry, dockerMirror => $.dockerMirror )) - $.instance.agent.call($template, $resources) - If: $.gcloudKey != null and $.gcloudKey != '' Then: - $._environment.reporter.report($this, 'Authenticating to Google Container Registry') - $template: $resources.yaml('LoginToGoogleRegistry.template').bind(dict( gcloudKey => $.gcloudKey )) - $.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: $applicationPort.protocol.toLower() 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, privileged => $container.privileged )) - $._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.keys() Then: - Return: $applicationPorts.get($key) - $port: str($applicationPort.port) - If: $port in $portMap.keys() Then: - $port: '1025' - While: $port in $portMap.keys() 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($key) - 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 and $.instance.isDeployed() 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($)