Namespaces: =: io.murano.apps.docker.kubernetes docker: io.murano.apps.docker std: io.murano sys: io.murano.system Name: KubernetesPod Extends: - docker:DockerContainerHost - docker:DockerHelpers Properties: name: Contract: $.string().notNull() kubernetesCluster: Contract: $.class(KubernetesCluster).notNull() labels: Contract: $.string().notNull() # convert to key-value map as soon as it will be possible to input it in UI Default: '' replicas: Contract: $.int().notNull().check($ >= 0) Methods: initialize: Body: - $._environment: $.find(std:Environment).require() - $podName: $._getPodName() - $podDefinition: $.getAttr(lastPodDeployed, null) - If: $podDefinition = null Then: - $podDefinition: apiVersion: v1beta3 kind: Pod metadata: name: $podName labels: $._getPodLabels($podName) spec: containers: [] volumes: [] - $.setAttr(lastPodDeployed, $podDefinition) - $._podDefinition: $podDefinition _getPodName: Body: - Return: toLower($.name) _getPodLabels: Arguments: - podName: Contract: $.string().notNull() Body: Return: $.labels2Map(toLower($.labels)).mergeWith(dict(id => $podName)) hostContainer: Arguments: - container: Contract: $.class(docker:DockerContainer) Body: - $podName: $._getPodName() - For: port In: $container.ports Do: - $endpoints: $.kubernetesCluster.serviceEndpoints.where( $.containerPort = $port.port and $.protocol = $port.protocol and $.podId = $podName) - If: len($endpoints) > 0 Then: - $msg: format('Port {0} is already used in the Pod {1}', $port.port, $.name) - Throw: PortConflictException Message: $msg - $._deleteContainer($container.name) - $containerDef: name: toLower($container.name) image: $container.image args: $container.commands ports: $container.ports.select($this._getPortDefinition($)) volumeMounts: $container.volumes.keys().select(dict(name => $this._generateVolumeName($container.volumes.get($)), mountPath => $)) env: $container.env.keys().select(dict(key => $, value => $container.env.get($))) - $newVolumes: $container.volumes.values().where(not $this._generateVolumeName($) in $this._podDefinition.spec.volumes.name). select($this._buildVolumeEntry($)) - $diff: - $diff: spec: containers: [$containerDef] volumes: $newVolumes - $._podDefinition: $._podDefinition.mergeWith($diff) - $.deploy() - $._environment.reporter.report($, 'Creating services for Pod {0}'.format($.name)) - $.kubernetesCluster.createService( applicationName => $container.name, applicationPorts => $container.ports, podId => $podName) - Return: $.getEndpoints($container.name) getEndpoints: Arguments: - applicationName: Contract: $.string().notNull() Body: - Return: $.kubernetesCluster.serviceEndpoints.where($.applicationName = $applicationName) _getPortDefinition: Arguments: - port: Contract: $.class(docker:ApplicationPort).notNull() Body: - $result: containerPort: $port.port - If: $port.scope = node Then: $result.hostPort: $port.port - Return: $result _buildVolumeEntry: Arguments: - volume: Contract: $.class(docker:DockerVolume).notNull() Body: - $type: $volume.getType() - Value: $type Match: HostDir: - $spec: hostDir: path: $volume.getParameters() TempVolume: - $spec: emptyDir: {} Default: - Throw: UnknownDockerVolumeType Message: format('Unknown docker volume type {0}', $type) - Return: name: $._generateVolumeName($volume) source: $spec _deleteContainer: Arguments: - name: Contract: $.string().notNull() Body: - $lenBefore: len($._podDefinition.spec.containers) + len($._podDefinition.spec.volumes) - $newContainers: $._podDefinition.spec.containers.where($.name != $name) - $newVolumes: $._podDefinition.spec.volumes.where( $.name in $._podDefinition.spec.containers.volumeMounts.name) - If: len($newContainers) + len($newVolumes) != $lenBefore Then: - $._podDefinition.spec.containers: $newContainers - $._podDefinition.spec.volumes: $newVolumes deleteContainer: Arguments: - name: Contract: $.string().notNull() Body: - $._deleteContainer($name) - $.kubernetesCluster.deleteService( applicationName => $name, podId => $._getPodName()) - $.deploy() _generateVolumeName: Arguments: - volume: Contract: $.class(docker:DockerVolume).notNull() Body: Return: toLower($volume.name) deploy: Body: - $prevPod: $.getAttr(lastPodDeployed, null) - $prevReplicas: $.getAttr(lastReplicas, 0) - $podDefinition: $._podDefinition - $replicas: $.replicas - If: len($podDefinition.spec.containers) = 0 Then: - $replicas: 0 - $.setAttr(lastReplicas, $replicas) - If: $replicas != $prevReplicas or $prevPod != $podDefinition Then: - If: $replicas > 0 Then: - $._environment.reporter.report($, 'Deploying Replication Controller for Pod {0}'.format($.name)) - $rcDefinition: $._buildReplicationControllerDefinition($podDefinition) - $.kubernetesCluster.createReplicationController( definition => $rcDefinition, isNew => $prevReplicas = 0) - If: $replicas = 0 and $prevReplicas > 0 Then: - $.kubernetesCluster.deleteReplicationController($._getReplicationControllerId()) - If: $prevPod != $podDefinition and len($prevPod.spec.containers) > 0 Then: - $.kubernetesCluster.deletePods(dict(id => $._getPodName())) - If: $.replicas = 0 and len($podDefinition.spec.containers) > 0 Then: - $.kubernetesCluster.createPod(definition => $podDefinition, isNew => true) - $._environment.reporter.report($, 'Pod {0} is ready'.format($.name)) - $.setAttr(lastPodDeployed, $podDefinition) _buildReplicationControllerDefinition: Arguments: - podDefinition: Contract: {} Body: Return: apiVersion: v1beta3 kind: ReplicationController metadata: name: $._getReplicationControllerId() labels: $podDefinition.metadata.labels spec: replicas: $.replicas selector: id: $._getPodName() template: metadata: labels: $podDefinition.metadata.labels spec: $podDefinition.spec _getReplicationControllerId: Body: - Return: $._getPodName() getInternalScopeId: Body: Return: $.kubernetesCluster.id()