diff --git a/io.murano.apps.docker.DockerCAdvisor/Classes/DockerCAdvisor.yaml b/io.murano.apps.docker.DockerCAdvisor/Classes/DockerCAdvisor.yaml new file mode 100644 index 0000000..fd0a1be --- /dev/null +++ b/io.murano.apps.docker.DockerCAdvisor/Classes/DockerCAdvisor.yaml @@ -0,0 +1,55 @@ +Namespaces: + =: io.murano.apps.docker + std: io.murano + +Name: DockerCAdvisor + +Extends: std:Application + +Properties: + name: + Contract: $.string().notNull() + host: + Contract: $.class(DockerContainerHost).notNull() + port: + Contract: $.int().check($ > 0 and $ < 65536) + + +Methods: + initialize: + Body: + - $._environment: $.find(std:Environment).require() + + deploy: + Body: + - If: not $.getAttr(deployed, false) + Then: + - $._environment.reporter.report($this, 'Installing Application') + + - $volumes: + - name: varrun + source: + hostDir: + path: '/var/run' + - name: varlibdocker + source: + hostDir: + path: '/var/lib/docker' + - name: sysfs + source: + hostDir: + path: '/sys' + + - $.host.hostContainer( + name => $.name, + image => 'google/cadvisor:0.8.0', + commands => list(), + env => dict(), + ports => list($.port), + volumes => $volumes + ) + - $.host.deploy() + + - $._environment.reporter.report($this, 'cAdvisor installed') + - $.setAttr(deployed, true) + diff --git a/io.murano.apps.docker.DockerCAdvisor/UI/ui.yaml b/io.murano.apps.docker.DockerCAdvisor/UI/ui.yaml new file mode 100644 index 0000000..974f52b --- /dev/null +++ b/io.murano.apps.docker.DockerCAdvisor/UI/ui.yaml @@ -0,0 +1,34 @@ +Version: 2 + +Application: + ?: + type: io.murano.apps.docker.DockerCAdvisor + name: $.appConfiguration.name + host: $.appConfiguration.host + port: $.appConfiguration.port + + +Forms: + - appConfiguration: + fields: + - name: name + type: string + label: Application Name + initial: 'Google cAdvisor' + description: >- + Enter a desired name for the application. Just A-Z, a-z, 0-9, dash and + underline are allowed + - name: host + type: io.murano.apps.docker.kubernetes.KubernetesPod + label: Container Host + description: >- + Select an instance of Docker contaniner to run the app + - name: port + type: integer + label: Port + minValue: 1 + maxValue: 65535 + initial: 4194 + description: >- + Select a port to run the app + diff --git a/io.murano.apps.docker.DockerCAdvisor/logo.png b/io.murano.apps.docker.DockerCAdvisor/logo.png new file mode 100644 index 0000000..6b92890 Binary files /dev/null and b/io.murano.apps.docker.DockerCAdvisor/logo.png differ diff --git a/io.murano.apps.docker.DockerCAdvisor/manifest.yaml b/io.murano.apps.docker.DockerCAdvisor/manifest.yaml new file mode 100644 index 0000000..f2fa128 --- /dev/null +++ b/io.murano.apps.docker.DockerCAdvisor/manifest.yaml @@ -0,0 +1,10 @@ +Format: 1.0 +Type: Application +FullName: io.murano.apps.docker.DockerCAdvisor +Name: Google cAdvisor +Description: | + This application deploys Google Heapster service in a Kubernetes environment. +Author: 'Mirantis, Inc' +Tags: [docker, heapster, monitoring] +Classes: + io.murano.apps.docker.DockerHeapster: DockerHeapster.yaml diff --git a/io.murano.apps.docker.DockerHTTPd/Classes/DockerHTTPd.yaml b/io.murano.apps.docker.DockerHTTPd/Classes/DockerHTTPd.yaml new file mode 100644 index 0000000..d6c2071 --- /dev/null +++ b/io.murano.apps.docker.DockerHTTPd/Classes/DockerHTTPd.yaml @@ -0,0 +1,40 @@ +Namespaces: + =: io.murano.apps.docker + std: io.murano + +Name: DockerHTTPd + +Extends: std:Application + +Properties: + name: + Contract: $.string().notNull() + host: + Contract: $.class(DockerContainerHost).notNull() + port: + Contract: $.int().check($ > 0 and $ < 65536) + + +Methods: + initialize: + Body: + - $._environment: $.find(std:Environment).require() + + deploy: + Body: + - If: not $.getAttr(deployed, false) + Then: + - $._environment.reporter.report($this, 'Installing Application') + - $.host.hostContainer( + name => $.name, + image => httpd, + commands => list(), + env => dict(), + ports => list($.port), + volumes => dict() + ) + - $.host.deploy() + + - $._environment.reporter.report($this, 'Application HTTPd available at {0}:{1}'.format($.host.getIp(), $.port)) + - $.setAttr(deployed, true) + diff --git a/io.murano.apps.docker.DockerHTTPd/UI/ui.yaml b/io.murano.apps.docker.DockerHTTPd/UI/ui.yaml new file mode 100644 index 0000000..b8e8564 --- /dev/null +++ b/io.murano.apps.docker.DockerHTTPd/UI/ui.yaml @@ -0,0 +1,34 @@ +Version: 2 + +Application: + ?: + type: io.murano.apps.docker.DockerHTTPd + name: $.appConfiguration.name + host: $.appConfiguration.host + port: $.appConfiguration.port + + +Forms: + - appConfiguration: + fields: + - name: name + type: string + label: Application Name + initial: 'DockerHTTPd' + description: >- + Enter a desired name for the application. Just A-Z, a-z, 0-9, dash and + underline are allowed + - name: host + type: io.murano.apps.docker.kubernetes.KubernetesPod + label: Container Host + description: >- + Select an instance of Docker contaniner to run the app + - name: port + type: integer + label: Port + minValue: 1 + maxValue: 65535 + initial: 80 + description: >- + Select a port to run the app + diff --git a/io.murano.apps.docker.DockerHTTPd/logo.png b/io.murano.apps.docker.DockerHTTPd/logo.png new file mode 100644 index 0000000..6b92890 Binary files /dev/null and b/io.murano.apps.docker.DockerHTTPd/logo.png differ diff --git a/io.murano.apps.docker.DockerHTTPd/manifest.yaml b/io.murano.apps.docker.DockerHTTPd/manifest.yaml new file mode 100644 index 0000000..26b0a14 --- /dev/null +++ b/io.murano.apps.docker.DockerHTTPd/manifest.yaml @@ -0,0 +1,10 @@ +Format: 1.0 +Type: Application +FullName: io.murano.apps.docker.DockerHTTPd +Name: Docker HTTPd +Description: | + The Apache HTTP Server, colloquially called Apache, is a Web server application notable for playing a key role in the initial growth of the World Wide Web. +Author: 'Mirantis, Inc' +Tags: [docker, application, HTTPd] +Classes: + io.murano.apps.docker.DockerHTTPd: DockerHTTPd.yaml diff --git a/io.murano.apps.docker.DockerHeapster/Classes/DockerHeapster.yaml b/io.murano.apps.docker.DockerHeapster/Classes/DockerHeapster.yaml new file mode 100644 index 0000000..4c55090 --- /dev/null +++ b/io.murano.apps.docker.DockerHeapster/Classes/DockerHeapster.yaml @@ -0,0 +1,35 @@ +Namespaces: + =: io.murano.apps.docker + kube: io.murano.apps.docker.kubernetes.static + std: io.murano + +Name: DockerHeapster + +Extends: std:Application + +Properties: + name: + Contract: $.string().notNull() + influxdb: + Contract: $.class(DockerInfluxDB).notNull() + heapsterRC: + Contract: $.class(kube:DockerInfluxDB).notNull() + + +Methods: + initialize: + Body: + - $._environment: $.find(std:Environment).require() + + deploy: + Body: + - If: not $.getAttr(deployed, false) + Then: + - $._environment.reporter.report($this, 'Starting deployment') + - $._environment.reporter.report($this, 'Installing Database service') + - $.influxdb.deploy() + - $._environment.reporter.report($this, 'Installing Heapster app') + - $.heapsterRC.deploy() + - $._environment.reporter.report($this, 'Heapster is ready') + - $.setAttr(deployed, true) + diff --git a/io.murano.apps.docker.DockerHeapster/UI/ui.yaml b/io.murano.apps.docker.DockerHeapster/UI/ui.yaml new file mode 100644 index 0000000..00b0e20 --- /dev/null +++ b/io.murano.apps.docker.DockerHeapster/UI/ui.yaml @@ -0,0 +1,59 @@ +Version: 2 +Templates: + heapsterRC: + ?: + type: io.murano.apps.docker.kubernetes.static.ReplicationController + kubernetesCluster: $.appConfiguration.kubernetes + replicationControllerDefinition: + apiVersion: "v1beta1" + id: "monitoring-heapster-controller" + kind: "ReplicationController" + desiredState: + replicas: 1 + replicaSelector: + name: "heapster" + podTemplate: + desiredState: + manifest: + version: "v1beta1" + id: "monitoring-heapster-controller" + containers: + - name: "heapster" + image: "kubernetes/heapster:v0.6" + env: + - name: "INFLUXDB_HOST" + value: "monitoring-influxdb" + labels: + name: "heapster" + uses: "monitoring-influxdb" + labels: + name: "heapster" + +Application: + ?: + type: io.murano.apps.docker.DockerHeapster + name: $.appConfiguration.name + heapsterRC: $heapsterRC + influxdb: $.appConfiguration.influxdb + + +Forms: + - appConfiguration: + fields: + - name: name + type: string + label: Application Name + initial: 'Heapster' + description: >- + Enter a desired name for the application. Just A-Z, a-z, 0-9, dash and + underline are allowed + - name: kubernetes + type: io.murano.apps.docker.kubernetes.KubernetesCluster + label: Kubernetes cluster + description: >- + Kubernetes service + - name: influxdb + type: io.murano.apps.docker.DockerInfluxDB + label: Database + description: >- + Select database service diff --git a/io.murano.apps.docker.DockerHeapster/logo.png b/io.murano.apps.docker.DockerHeapster/logo.png new file mode 100644 index 0000000..d9e9376 Binary files /dev/null and b/io.murano.apps.docker.DockerHeapster/logo.png differ diff --git a/io.murano.apps.docker.DockerHeapster/manifest.yaml b/io.murano.apps.docker.DockerHeapster/manifest.yaml new file mode 100644 index 0000000..da9665c --- /dev/null +++ b/io.murano.apps.docker.DockerHeapster/manifest.yaml @@ -0,0 +1,10 @@ +Format: 1.0 +Type: Application +FullName: io.murano.apps.docker.DockerHeapster +Name: Docker Heapster +Description: | + This application deploys Google Heapster service in a Kubernetes environment. +Author: 'Mirantis, Inc' +Tags: [docker, application, heapster] +Classes: + io.murano.apps.docker.DockerHeapster: DockerHeapster.yaml diff --git a/io.murano.apps.docker.DockerInfluxDB/Classes/DockerInfluxDB.yaml b/io.murano.apps.docker.DockerInfluxDB/Classes/DockerInfluxDB.yaml new file mode 100644 index 0000000..df1d611 --- /dev/null +++ b/io.murano.apps.docker.DockerInfluxDB/Classes/DockerInfluxDB.yaml @@ -0,0 +1,33 @@ +Namespaces: + =: io.murano.apps.docker + kube: io.murano.apps.docker.kubernetes.static + std: io.murano + +Name: DockerInfluxDB + +Extends: std:Application + +Properties: + name: + Contract: $.string().notNull() + influxdbRC: + Contract: $.class(kube:ReplicationController).notNull() + influxdbService: + Contract: $.class(kube:Service).notNull() + + +Methods: + initialize: + Body: + - $._environment: $.find(std:Environment).require() + + deploy: + Body: + - If: not $.getAttr(deployed, false) + Then: + - $._environment.reporter.report($this, 'Installing Application') + - $.influxdbRC.deploy() + - $.influxdbService.deploy() + - $._environment.reporter.report($this, 'Application InfluxDB is ready') + - $.setAttr(deployed, true) + diff --git a/io.murano.apps.docker.DockerInfluxDB/UI/ui.yaml b/io.murano.apps.docker.DockerInfluxDB/UI/ui.yaml new file mode 100644 index 0000000..8622d22 --- /dev/null +++ b/io.murano.apps.docker.DockerInfluxDB/UI/ui.yaml @@ -0,0 +1,84 @@ +Version: 2 +Templates: + influxdbRC: + ?: + type: io.murano.apps.docker.kubernetes.static.ReplicationController + kubernetesCluster: $.appConfiguration.kubernetes + replicationControllerDefinition: + apiVersion: "v1beta1" + kind: "ReplicationController" + id: "monitoring-influx-grafana-controller" + desiredState: + replicas: 1 + replicaSelector: + name: "influxGrafana" + usedby: "heapster" + requiredby: "murano" + podTemplate: + labels: + name: "influxGrafana" + usedby: "heapster" + requiredby: "murano" + desiredState: + manifest: + version: "v1beta1" + id: "monitoring-influx-grafana-controller" + containers: + - name: "influxdb" + image: "kubernetes/heapster_influxdb:v0.3" + ports: + - containerPort: 8083 + hostPort: 8083 + - containerPort: 8086 + hostPort: 8086 + - name: "grafana" + image: "kubernetes/heapster_grafana:v0.3" + ports: + - containerPort: 80 + hostPort: 80 + env: + - name: "HTTP_USER" + value: "admin" + - name: "HTTP_PASS" + value: "**None**" + labels: + name: "influxGrafana" + + influxdbService: + ?: + type: io.murano.apps.docker.kubernetes.static.Service + kubernetesCluster: $.appConfiguration.kubernetes + serviceDefinition: + port: 80 + enabled: true + containerPort: 8086 + externalLB: false + selector: + name: "influxGrafana" + usedby: "heapster" + requiredby: "murano" + +Application: + ?: + type: io.murano.apps.docker.DockerInfluxDB + name: $.appConfiguration.name + influxdbRC: $influxdbRC + influxdbService: $influxdbService + + +Forms: + - appConfiguration: + fields: + - name: name + type: string + label: Application Name + initial: 'Docker InfluxDB' + description: >- + Enter a desired name for the application. Just A-Z, a-z, 0-9, dash and + underline are allowed + - name: kubernetes + type: io.murano.apps.docker.kubernetes.KubernetesCluster + label: Kubernetes cluster + description: >- + Kubernetes service + diff --git a/io.murano.apps.docker.DockerInfluxDB/logo.png b/io.murano.apps.docker.DockerInfluxDB/logo.png new file mode 100644 index 0000000..b5fc98a Binary files /dev/null and b/io.murano.apps.docker.DockerInfluxDB/logo.png differ diff --git a/io.murano.apps.docker.DockerInfluxDB/manifest.yaml b/io.murano.apps.docker.DockerInfluxDB/manifest.yaml new file mode 100644 index 0000000..031d6d2 --- /dev/null +++ b/io.murano.apps.docker.DockerInfluxDB/manifest.yaml @@ -0,0 +1,10 @@ +Format: 1.0 +Type: Application +FullName: io.murano.apps.docker.DockerInfluxDB +Name: Docker InfluxDB +Description: | + InfluxDB is a time series, events, and metrics database. It’s written in Go and has no external dependencies. That means once you install it there’s nothing else to manage (like Redis, HBase, or whatever). +Author: 'Mirantis, Inc' +Tags: [docker, application, InfluxDB] +Classes: + io.murano.apps.docker.DockerInfluxDB: DockerInfluxDB.yaml diff --git a/io.murano.apps.docker.DockerMongoDB/Classes/DockerMongoDB.yaml b/io.murano.apps.docker.DockerMongoDB/Classes/DockerMongoDB.yaml index 8a2cd35..1f1a6e1 100644 --- a/io.murano.apps.docker.DockerMongoDB/Classes/DockerMongoDB.yaml +++ b/io.murano.apps.docker.DockerMongoDB/Classes/DockerMongoDB.yaml @@ -12,7 +12,7 @@ Properties: host: Contract: $.class(DockerContainerHost).notNull() port: - Contract: $.int() + Contract: $.int().check($ > 0 and $ < 65536) Methods: diff --git a/io.murano.apps.docker.DockerMongoDB/UI/ui.yaml b/io.murano.apps.docker.DockerMongoDB/UI/ui.yaml index eae727c..924633b 100644 --- a/io.murano.apps.docker.DockerMongoDB/UI/ui.yaml +++ b/io.murano.apps.docker.DockerMongoDB/UI/ui.yaml @@ -26,6 +26,9 @@ Forms: - name: port type: integer label: Port + minValue: 1 + maxValue: 65535 + initial: 27017 description: >- Select a port to run the app diff --git a/io.murano.apps.docker.DockerStandaloneHost/Classes/DockerStandaloneHost.yaml b/io.murano.apps.docker.DockerStandaloneHost/Classes/DockerStandaloneHost.yaml index 346de1b..151b9c9 100644 --- a/io.murano.apps.docker.DockerStandaloneHost/Classes/DockerStandaloneHost.yaml +++ b/io.murano.apps.docker.DockerStandaloneHost/Classes/DockerStandaloneHost.yaml @@ -1,9 +1,11 @@ -# Standalone (single-VM) Docker server base on DockerInc::Docker::Container Heat resource Namespaces: =: io.murano.apps.docker res: io.murano.resources + std: io.murano + sys: io.murano.system Name: DockerStandaloneHost + Extends: - DockerContainerHost @@ -14,16 +16,82 @@ Properties: instance: Contract: $.class(res:LinuxMuranoInstance).notNull() - # other properties here + publicIp: + Contract: $.string() + Usage: Out + + lastPort: + Contract: $.int() + Default: 1024 + Usage: InOut Methods: + initialize: + Body: + - $._environment: $.find(std:Environment).require() - #TODO Implement Me! + deploy: Body: + - If: not $.getAttr(deployed, false) + Then: + - $._environment.reporter.report($this, 'Setup Security Groups for Docker Server') + - $securityGroupIngress: + - ToPort: 22 + FromPort: 22 + IpProtocol: 'tcp' + External: True + - ToPort: 2375 + FromPort: 2375 + IpProtocol: 'tcp' + External: True + - $._environment.securityGroupManager.addGroupIngress($securityGroupIngress) + + - $._environment.reporter.report($this, 'Create VM for Docker Server') + - $.instance.deploy() + + - $._environment.reporter.report($this, 'Setting Up Docker Server') + - $resources: new(sys:Resources) + - $template: $resources.yaml('DeployDocker.template') + - $.instance.agent.call($template, $resources) + - $._environment.reporter.report($this, 'Docker Server is up and running') + + - $.publicIp: $.instance.floatingIpAddress + - $.setAttr(deployed, true) + + addDockerApp: + Arguments: + name: + Contract: $.string().notNull() + instance: + Contract: $.class(res:Instance).notNull() + dockerImage: + Contract: $.string().notNull() + dockerEnv: + Contract: [$.string()] + dockerAppPorts: + Contract: [] + dockerPortBindings: + Contract: {} + dockerVolumes: + Contract: {} + + Body: + - $resources: new(sys:Resources) + - $._environment.reporter.report($this, 'Adding Docker Application') + - $template: $resources.yaml('dockerApp.hot').bind(dict( + dockerAppName => $name, + dockerServer => $instance.floatingIpAddress, + dockerImage => $dockerImage, + dockerEnv => $dockerEnv, + dockerAppPorts => $dockerAppPorts, + dockerPortBindings => $dockerPortBindings, + dockerVolumes => $dockerVolumes + )) + - $._environment.stack.updateTemplate($template) + - $._environment.stack.push() - #TODO Implement Me! hostContainer: Arguments: - name: @@ -42,15 +110,71 @@ Methods: - volumes: Contract: $.string().notNull(): $.class(DockerVolume).notNull() + Body: + - $.pullImage(instance => $.instance, image => $image) + - $._portBindings: {} + - $._result: {} + - $._securityGroupIngress: [] + - For: port + In: $ports + Do: + - $allocatedPort: $.allocatePort() + - $patch: + - op: add + path: format('/{0}', $port) + value: + HostPort: $allocatedPort + HostIP: '0.0.0.0' + - $patch2: + - op: add + path: format('/{0}', $port) + value: $allocatedPort + - $._portBindings: $._portBindings.patch($patch) + - $._result: $._result.patch($patch2) + - $rule: + ToPort: $allocatedPort + FromPort: $allocatedPort + IpProtocol: 'tcp' + External: true + - $._securityGroupIngress: $._securityGroupIngress + list($rule) + + - $._environment.securityGroupManager.addGroupIngress($._securityGroupIngress) + - $.addDockerApp( + name => $.name, + instance => $.instance, + dockerImage => $image, + dockerEnv => $env, + dockerAppPorts => $ports, + dockerPortBindings => $._portBindings, + dockerVolumes => $volumes + ) + + pullImage: + Arguments: + instance: + Contract: $.class(res:Instance).notNull() + 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') + + allocatePort: + Body: + - $.lastPort: $.lastPort + 1 + - Return: $.lastPort - #TODO Implement Me! deleteContainer: Arguments: - name: Contract: $.string().notNull() Body: - #TODO Implement Me! getIp: Body: - + - Return: $.instance.ipAddresses[0] diff --git a/io.murano.apps.docker.DockerStandaloneHost/Resources/DeployDocker.template b/io.murano.apps.docker.DockerStandaloneHost/Resources/DeployDocker.template new file mode 100644 index 0000000..4b7fcb9 --- /dev/null +++ b/io.murano.apps.docker.DockerStandaloneHost/Resources/DeployDocker.template @@ -0,0 +1,18 @@ +FormatVersion: 2.0.0 +Version: 1.0.0 +Name: Deploy Docker + +Parameters: + appName: $appName + +Body: | + return deploy(args.appName).stdout + +Scripts: + deploy: + Type: Application + Version: 1.0.0 + EntryPoint: dockerInstallUbuntu.sh + Options: + captureStdout: true + captureStderr: true diff --git a/io.murano.apps.docker.DockerStandaloneHost/Resources/PullImage.template b/io.murano.apps.docker.DockerStandaloneHost/Resources/PullImage.template new file mode 100644 index 0000000..6756900 --- /dev/null +++ b/io.murano.apps.docker.DockerStandaloneHost/Resources/PullImage.template @@ -0,0 +1,18 @@ +FormatVersion: 2.0.0 +Version: 1.0.0 +Name: Pull Image + +Parameters: + image: $image + +Body: | + return deploy('{0}'.format(args.image)).stdout + +Scripts: + deploy: + Type: Application + Version: 1.0.0 + EntryPoint: pullImage.sh + Options: + captureStdout: true + captureStderr: true diff --git a/io.murano.apps.docker.DockerStandaloneHost/Resources/dockerApp.hot b/io.murano.apps.docker.DockerStandaloneHost/Resources/dockerApp.hot new file mode 100644 index 0000000..c7f526f --- /dev/null +++ b/io.murano.apps.docker.DockerStandaloneHost/Resources/dockerApp.hot @@ -0,0 +1,14 @@ +resources: + $dockerAppName: + type: "DockerInc::Docker::Container" + properties: + dockerEndpoint: $tcp://{dockerServer}:2375 + image: $dockerImage + env: + $dockerEnv + portSpecs: + $dockerAppPorts + portBindings: + $dockerPortBindings + volumes: + $dockerVolumes diff --git a/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/common.sh b/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/common.sh new file mode 100644 index 0000000..8afef14 --- /dev/null +++ b/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/common.sh @@ -0,0 +1,204 @@ +#!/bin/bash +# +DEBUGLVL=3 +LOGFILE=/tmp/muranodeployment.log +PIPAPPS="pip python-pip pip-python" +PIPCMD="" +if [ "$DEBUGLVL" -eq 4 ]; then + set -x +fi +function log { + if [ "$DEBUGLVL" -gt 0 ]; then + chars=$(echo "@$" | wc -c) + case $DEBUGLVL in + 1 ) + echo -e "LOG:>$@" + ;; + 2) + echo -e "$(date +"%m-%d-%Y %H:%M") LOG:>$@" | tee --append $LOGFILE + ;; + 3) + echo -e "$(date +"%m-%d-%Y %H:%M") LOG:>$@" >> $LOGFILE + ;; + 4) + echo -e "$(date +"%m-%d-%Y %H:%M") LOG:>$@" | tee --append $LOGFILE + ;; + esac + fi +} +function lowercase(){ + echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" +} +function find_pip() +{ + for cmd in $PIPAPPS + do + _cmd=$(which $cmd 2>/dev/null) + if [ $? -eq 0 ];then + break + fi + done + if [ -z $_cmd ];then + echo "Can't find \"pip\" in system, please install it first, exiting!" + exit 1 + else + PIPCMD=$_cmd + fi +} +OPTIND=1 # Reset if getopts used previously +function collect_args(){ + _n=$1 + shift + ARGS='' + while true + do + if [[ "$_n" == -* ]] || [ -z "$_n" ]; then + OPTIND=$((OPTIND - 1)) + break + fi + #echo "_n=$_n ; $OPTIND" + if [ -z "$ARGS" ]; then + ARGS=$OPTARG + else + ARGS="$ARGS $_n" + fi + eval _n=\$$OPTIND + OPTIND=$((OPTIND + 1)) + #sleep 1 + done + echo $ARGS + unset _n + unset ARGS +} +function get_os(){ + KERNEL=$(uname -r) + MACH=$(uname -m) + OS=$(uname) + if [ "${OS}" = "Linux" ] ; then + if [ -f /etc/redhat-release ] ; then + DistroBasedOn='RedHat' + Packager='yum' + DIST=$(cat /etc/redhat-release |sed s/\ release.*//) + PSUEDONAME=$(cat /etc/redhat-release | sed s/.*\(// | sed s/\)//) + REV=$(cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//) + elif [ -f /etc/SuSE-release ] ; then + DistroBasedOn='SuSe' + Packager='zypper' + PSUEDONAME=$(cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//) + REV=$(cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //) + elif [ -f /etc/mandrake-release ] ; then + DistroBasedOn='Mandrake' + Packager='urpmi urpme' + PSUEDONAME=$(cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//) + REV=$(cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//) + elif [ -f /etc/debian_version ] ; then + DistroBasedOn='Debian' + Packager='apt-get' + DIST=$(cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F= '{ print $2 }') + PSUEDONAME=$(cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F= '{ print $2 }') + REV=$(cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F= '{ print $2 }') + fi + if [ -f /etc/UnitedLinux-release ] ; then + DIST="${DIST}[$(cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//)]" + fi + OS=$(lowercase $OS) + DistroBasedOn=$(lowercase $DistroBasedOn) + readonly OS + readonly DIST + readonly DistroBasedOn + readonly PSUEDONAME + readonly REV + readonly KERNEL + readonly MACH + #readonly Packager + else + OS=unknown + readonly OS + log "OS:$OS" + exit 1 + fi +} +function add_fw_rule(){ + _rule_string=$@ + _tmp_fw_port=$(echo $_rule_string | grep -o -e "dport [0-9]*\s") + _tmp_fw_proto=$(echo $_rule_string | grep -o -e "-p \w*\s") + _fw_port=$(echo $_tmp_fw_port | awk '{print $2}') + _fw_proto=$(echo $_tmp_fw_proto |awk '{print $2}') + _fw_reload="" + #find iptables and add rule + case $DIST in + "Fedora") + _fw_cmd=$(which firewall-cmd) + _fw_port=$(echo $_rule_string | grep -o -e "dport [0-9]*\s" | awk '{print $2}') + _fw_proto=$(echo $_rule_string | grep -o -e "-p \w*\s" | awk '{print $2}') + _fw_rule="--permanent --add-port=$_fw_port/$_fw_proto" + _fw_enable_rules="$_fw_cmd --reload" + ;; + *) + _fw_cmd=$(which iptables) + _fw_rule=$_rule_string + _fw_enable_rules="service $(basename $_fw_cmd) save" + ;; + esac + iptcmdsave=$(which iptables-save) + if [[ "$_fw_cmd" != '' ]] && [[ "$iptcmdsave" != '' ]]; then + eval "$iptcmdsave | grep -e \"$_tmp_fw_port\" | grep -e \"$_tmp_fw_proto\"" > /dev/null 2>&1 + if [ $? -ne 0 ]; then + eval $_fw_cmd $_fw_rule + if [ $? -ne 0 ]; then + log "Can't set firewall rules, exiting..." + exit 1 + else + if [ -n "$_fw_enable_rules" ]; then + log "Running \"$_fw_enable_rules\"" + $_fw_enable_rules > /dev/null + fi + log "$_fw_cmd rule with $_fw_rule set." + fi + else + log "$_fw_cmd rule exists." + fi + else + log "There are no fw found..." + fi +} +function enable_init(){ + _initctrl="" + _init_suffix="" + _service=$1 + case $DistroBasedOn in + "debian") + _initctrl="update-rc.d" + _init_suffix="defaults" + ;; + *) + _initctrl="chkconfig" + _init_suffix="on" + ;; + esac + $_initctrl $_service $_init_suffix + if [ $? -ne 0 ]; then + log "$_initctrl $_service $_init_suffix - fails!" + exit 1 + fi +} +function restart_service(){ + _service=$1 + service $_service restart > /dev/null 2>&1 + if [ $? -ne 0 ]; then + log "Can't start $_service service!" + exit 1 + fi +} +function package_renamer(){ + _pkg=$1 + case $DistroBasedOn in + "debian") + _pkg=$(echo $_pkg | sed 's/-devel$/-dev/') + ;; + *) + _pkg=$(echo $_pkg | sed 's/-dev$/-devel/') + ;; + esac + echo $_pkg +} \ No newline at end of file diff --git a/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/dockerInstallUbuntu.sh b/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/dockerInstallUbuntu.sh new file mode 100644 index 0000000..a606c42 --- /dev/null +++ b/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/dockerInstallUbuntu.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +ADDR=`ip addr show eth0 | grep 'inet ' | cut -d' ' -f 6 | cut -d'/' -f1` +sudo echo "DOCKER_OPTS=\"-H $ADDR:2375\"" >> /etc/default/docker + +sudo service docker restart + diff --git a/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/installer.sh b/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/installer.sh new file mode 100644 index 0000000..9d4baa5 --- /dev/null +++ b/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/installer.sh @@ -0,0 +1,142 @@ +#!/bin/bash +# +INSTALLER_OPTS="" +UNINSTALLER_OPTS="" +PMGR="" +PMGR_LIST_OPTS="" + +function include(){ + curr_dir=$(cd $(dirname "$0") && pwd) + inc_file_path=$curr_dir/$1 + if [ -f "$inc_file_path" ]; then + . $inc_file_path + else + exit 1 + fi +} +function set_install_options(){ + case $1 in + apt-get ) + INSTALLER_OPTS="-y -q install" + UNINSTALLER_OPTS="-y -q remove" + PMGR="dpkg" + PMGR_LIST_OPTS="-s" + ;; + yum ) + INSTALLER_OPTS="--assumeyes install" + UNINSTALLER_OPTS="--assumeyes erase" + PMGR="rpm" + PMGR_LIST_OPTS="-q" + ;; + urpm* ) + INSTALLER_OPTS="-y" + UNINSTALLER_OPTS="" + PMGR="rpm" + PMGR_LIST_OPTS="-q" + ;; + zypper ) + INSTALLER_OPTS="install" + UNINSTALLER_OPTS="remove --quiet" + PMGR="rpm" + PMGR_LIST_OPTS="-q" + ;; + pip ) + INSTALLER_OPTS="install" + UNINSTALLER_OPTS="uninstall --yes" + find_pip + PACKAGER=$PIPCMD + PMGR=$PIPCMD + PMGR_LIST_OPTS="freeze | grep" + ;; + * ) + exit 1 + ;; + esac + PACKAGER=$(which $1) + if [ $? -ne 0 ]; then + log "Can't find \"$1\", exiting!" + exit 1 + fi +} +function package_install(){ + PKG=$1 + eval "$PMGR $PMGR_LIST_OPTS $PKG" > /dev/null 2>&1 + if [ $? -eq 0 ]; then + log "\"$PKG\" already installed" + else + log "Installing \"$PKG\" ..." + $PACKAGER $INSTALLER_OPTS $PKG > /dev/null 2>&1 + if [ $? -ne 0 ]; then + log "\"$PKG\" installation fails, exiting!" + exit 1 + else + log "\t\t...success" + fi + fi +} +function package_uninstall(){ + PKG=$1 + eval "$PMGR $PMGR_LIST_OPTS $PKG" > /dev/null 2>&1 + if [ $? -eq 1 ]; then + log "\"$PKG\" not installed" + else + log "Unnstalling \"$PKG\" ..." + $PACKAGER $UNINSTALLER_OPTS $PKG > /dev/null 2>&1 + if [ $? -ne 0 ]; then + log "\"$PKG\" uninstallation fails, exiting!" + exit 1 + else + log "\t\t...success" + fi + fi +} +function run_install(){ + for PKG in $@ + do + package_install $PKG + done +} +function run_uninstall(){ + for PKG in $@ + do + package_uninstall $PKG + done +} +# Main workflow +include "common.sh" +if [ $# -eq 0 ]; then + script=$(basename $0) + echo -e "Usage:\n\t* install packages -- ./$script -p package_manager -i package0 [packageN]\n\t* remove packages -- ./$script -p package_manager -r package0 [packageN]" + exit 1 +fi +Packager='' +get_os +if [ $? -ne 0 ]; then + log "Unsupported *nix version ($DistroBasedOn - $DIST/$PSUEDONAME/$REV/$MACH)" + exit 1 +fi +while getopts ":p:i:r:" opt ; do + case "$opt" in + p) + if [[ "$OPTARG" != sys ]]; then + Packager=$OPTARG + fi + set_install_options $Packager + ;; + i) + n=$OPTARG + run_install $(collect_args $n $@) + break; + ;; + r) + n=$OPTARG + run_uninstall $(collect_args $n $@) + break; + ;; + \?) + log "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + esac +done +shift $((OPTIND-1)) \ No newline at end of file diff --git a/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/pullImage.sh b/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/pullImage.sh new file mode 100644 index 0000000..1ad8d6d --- /dev/null +++ b/io.murano.apps.docker.DockerStandaloneHost/Resources/scripts/pullImage.sh @@ -0,0 +1,5 @@ +#!/bin/bash +ADDR=`ip addr show eth0 | grep 'inet ' | cut -d' ' -f 6 | cut -d'/' -f1` +DOCKER_OPTS="-H $ADDR:2375" + +sudo docker $DOCKER_OPTS pull $1 diff --git a/io.murano.apps.docker.DockerStandaloneHost/UI/ui.yaml b/io.murano.apps.docker.DockerStandaloneHost/UI/ui.yaml index 78681a6..5b5e3a7 100644 --- a/io.murano.apps.docker.DockerStandaloneHost/UI/ui.yaml +++ b/io.murano.apps.docker.DockerStandaloneHost/UI/ui.yaml @@ -12,6 +12,7 @@ Application: image: $.instanceConfiguration.osImage keyname: $.instanceConfiguration.keyPair assignFloatingIp: $.appConfiguration.assignFloatingIP + availabilityZone: $.instanceConfiguration.availabilityZone Forms: - appConfiguration: diff --git a/io.murano.apps.docker.Interfaces/Classes/DockerHelpers.yaml b/io.murano.apps.docker.Interfaces/Classes/DockerHelpers.yaml index c362bce..7c0a17d 100644 --- a/io.murano.apps.docker.Interfaces/Classes/DockerHelpers.yaml +++ b/io.murano.apps.docker.Interfaces/Classes/DockerHelpers.yaml @@ -14,6 +14,9 @@ Methods: In: $labelsString.replace(',', ';').split(';') Do: - $pair: $t.split('=') + - If: len($pair) < 2 + Then: + Continue: - $key: $pair[0].trim() - $result[$key]: $pair[1].trim() - Return: $result diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesCluster.yaml b/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesCluster.yaml index 3cecee0..cbb9455 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesCluster.yaml +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesCluster.yaml @@ -18,10 +18,12 @@ Properties: minionNodes: Contract: - $.class(KubernetesMinionNode).notNull() + - 1 nodeCount: - Contract: $.int().notNull() - + Contract: $.int().notNull().check($ > 0) + Usage: InOut + Methods: initialize: Body: @@ -31,7 +33,6 @@ Methods: Body: - If: not $.getAttr(deployed, false) Then: - #TODO(ddovbii): Check rules! - $._environment.reporter.report($this, 'Creating VMs for Kubernetes cluster') - $securityGroupIngress: - ToPort: 4001 @@ -54,13 +55,38 @@ Methods: - $._environment.reporter.report($this, 'Setting up Kubernetes cluster') - $.masterNode.deploy() - $.setAttr(deployed, true) - + - Parallel: - Do: - $.minionNodes.take($.nodeCount).pselect($.deploy()) - Do: - $.minionNodes.skip($.nodeCount).pselect($.removeFromCluster()) + scaleUP: + Usage: Action + Body: + - $._environment.reporter.report($this, 'Scaling up Kubernetes containers cluster up') + + - If: $.nodeCount < len($.minionNodes): + Then: + - $minion: $.minionNodes[$.nodeCount] + - $._environment.reporter.report($this, 'Creating a new VM') + - $minion.deploy() + - $.nodeCount: $.nodeCount + 1 + - $._environment.reporter.report($this, 'Scaling Kubernetes containers cluster complete') + + + exportConfig: + Usage: Action + Body: + - $._environment.reporter.report($this, 'Action exportConfig is called') + - $resources: new(sys:Resources) + - $template: $resources.yaml('ExportConfig.template') + - $result: $.masterNode.instance.agent.call($template, $resources) + - $._environment.reporter.report($this, 'Got archive from Kubernetes') + - Return: new(std:File, base64Content=>$result.content, + filename => 'application.tar.gz') + getIp: Body: Return: $.masterNode.getIp() diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesMasterNode.yaml b/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesMasterNode.yaml index 8085ef0..dbbec55 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesMasterNode.yaml +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesMasterNode.yaml @@ -27,10 +27,10 @@ Methods: - $.super($.deploy()) - $.setupNode() - $.setAttr(deployed, true) - + setupNode: Body: - - $._environment.reporter.report($, 'Configuring ETCD muster node') + - $._environment.reporter.report($, 'Configuring ETCD master node') - $resources: new(sys:Resources) - $template: $resources.yaml('MasterEtcdSetup.template').bind(dict( name => $.instance.name, diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesMinionNode.yaml b/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesMinionNode.yaml index 966f439..c9146e2 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesMinionNode.yaml +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesMinionNode.yaml @@ -58,8 +58,12 @@ Methods: removeFromCluster: Body: - #TODO implement me!!!!!!!!!!! - If: $.getAttr(deployed, false) - Then: - # - code here - - $.setAttr(deployed, false) + Then: + - $._environment.reporter.report($this, 'Deleting Kubernetes Minion') + - $resources: new(sys:Resources) + - $template: $resources.yaml('RemoveMinion.template').bind(dict(name=>$.getIp())) + - $._cluster.masterNode.instance.agent.call($template, $resources) + - $._environment.reporter.report($this, 'Node {0} deleted'.format($.getIp())) + - $.setAttr(deployed, false) + diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesNode.yaml b/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesNode.yaml index 4e20248..04cb954 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesNode.yaml +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesNode.yaml @@ -14,7 +14,7 @@ Methods: getIp: Body: Return: $.instance.ipAddresses[0] - + deploy: Body: - $.instance.deploy() diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/ExportConfig.template b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/ExportConfig.template new file mode 100644 index 0000000..57d2e95 --- /dev/null +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/ExportConfig.template @@ -0,0 +1,23 @@ +FormatVersion: 2.0.0 +Version: 1.0.0 +Name: Export Config + +Parameters: + name: $name + +Body: | + log=setup('{0}'.format(args.name)).stdout + filename='/var/run/murano-kubernetes/application.tgz.b64' + with open(filename,'r') as f: + content=f.read() + return {'log': log, 'content': content} + +Scripts: + setup: + Type: Application + Version: 1.0.0 + EntryPoint: exportConfig.sh + Files: [] + Options: + captureStdout: true + captureStderr: true diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/RemoveMinion.template b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/RemoveMinion.template new file mode 100644 index 0000000..5ecb433 --- /dev/null +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/RemoveMinion.template @@ -0,0 +1,20 @@ +FormatVersion: 2.0.0 +Version: 1.0.0 +Name: Remove Minion + +Parameters: + name: $name + +Body: | + return removeMinion('{0}'.format(args.name)).stdout + +Scripts: + removeMinion: + Type: Application + Version: 1.0.0 + EntryPoint: removeMinion.sh + Files: [] + Options: + captureStdout: true + captureStderr: true + diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/exportConfig.sh b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/exportConfig.sh new file mode 100644 index 0000000..afee8dc --- /dev/null +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/exportConfig.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +DEFINITION_DIR=/var/run/murano-kubernetes +cd $DEFINITION_DIR +rm /tmp/application.tgz +rm ./application.tgz.b64 + +echo "#!/bin/bash" > setup.sh +while read line +do + name=`echo $line | cut -d' ' -f1` + kind=`echo $line | cut -d' ' -f2` + file=`echo $line | cut -d' ' -f3` + echo "echo 'Creating $kind $name'" >> setup.sh + echo "kubectl create -f $file" >> setup.sh +done < ./elements.list + +tar czf /tmp/application.tgz ./ +base64 /tmp/application.tgz > ./application.tgz.b64 diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/master-kube-setup.sh b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/master-kube-setup.sh index 2c06ab0..aa31ef1 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/master-kube-setup.sh +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/master-kube-setup.sh @@ -15,6 +15,7 @@ service kube-apiserver stop #Create log folder for Kubernetes services mkdir /var/log/kubernetes +mkdir -p /var/run/murano-kubernetes #Preapre service configs #sed -i.bkp "s/%%PORTAL_NET%%/$3/g" kube-apiserver.conf @@ -41,4 +42,4 @@ service kube-controller-manager start /opt/bin/kubectl delete node 127.0.0.1 -sleep 1 \ No newline at end of file +sleep 1 diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/minion-kube-setup.sh b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/minion-kube-setup.sh index 7ac1daa..cd02d4a 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/minion-kube-setup.sh +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/minion-kube-setup.sh @@ -21,6 +21,7 @@ else fi #Create log folder for Kubernetes services mkdir /var/log/kubernetes +mkdir -p /var/run/murano-kubernetes #Preapre service configs @@ -38,4 +39,4 @@ cp -f kubelet.conf /etc/default/kubelet service kubelet start service kube-proxy start -sleep 1 \ No newline at end of file +sleep 1 diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/removeMinion.sh b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/removeMinion.sh new file mode 100644 index 0000000..9e6db2f --- /dev/null +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts/removeMinion.sh @@ -0,0 +1,3 @@ +#!/bin/bash +echo "Deleting a Minion" >> /tmp/murano-kube.log +/opt/bin/kubectl delete node $1 >> /tmp/murano-kube.log diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/UI/ui.yaml b/io.murano.apps.docker.kubernetes.KubernetesCluster/UI/ui.yaml index e32f40e..7875778 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesCluster/UI/ui.yaml +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/UI/ui.yaml @@ -3,7 +3,7 @@ Templates: masterNode: ?: type: io.murano.apps.docker.kubernetes.KubernetesMasterNode - portalNet: $.appConfiguration.portalNet +# portalNet: $.appConfiguration.portalNet instance: ?: type: io.murano.resources.LinuxMuranoInstance @@ -12,6 +12,7 @@ Templates: image: $.instanceConfiguration.osImage assignFloatingIp: $.appConfiguration.assignFloatingIP keyname: $.instanceConfiguration.keyPair + availabilityZone: $.instanceConfiguration.availabilityZone minionNode: ?: @@ -33,7 +34,6 @@ Application: minionNodes: repeat($minionNode, $.appConfiguration.maxMinionCount) nodeCount: $.appConfiguration.minionCount - Forms: - appConfiguration: fields: @@ -46,24 +46,26 @@ Forms: underline are allowed - name: minionCount type: integer - label: Current minion Count + label: Initial/current number of minions initial: 3 + minValue: 1 required: true description: >- Select number of minions - name: maxMinionCount type: integer - label: Maximum minion Count + label: Maximum number of minions initial: 3 required: true + minValue: 1 description: >- Select number of minions - - name: portalNet - type: string - initial: '11.1.1.1/24' - label: Select portalNet - description: >- - TODO +# - name: portalNet +# type: string +# initial: '11.1.1.1/24' +# label: Select portalNet +# description: >- +# TODO - name: assignFloatingIP type: boolean initial: true @@ -72,12 +74,11 @@ Forms: Select to true to assign floating IP automatically initial: false required: false - widgetMedia: - css: {all: ['muranodashboard/css/checkbox.css']} - name: unitNamingPattern type: string initial: 'kube-0#' required: false + regexpValidator: '^(([a-zA-Z0-9#][a-zA-Z0-9-#]*[a-zA-Z0-9#])\.)*([A-Za-z0-9#]|[A-Za-z0-9#][A-Za-z0-9-#]*[A-Za-z0-9#])$' label: Hostname widgetMedia: js: ['muranodashboard/js/support_placeholder.js'] diff --git a/io.murano.apps.docker.kubernetes.KubernetesCluster/manifest.yaml b/io.murano.apps.docker.kubernetes.KubernetesCluster/manifest.yaml index 011a1b5..013a07a 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesCluster/manifest.yaml +++ b/io.murano.apps.docker.kubernetes.KubernetesCluster/manifest.yaml @@ -1,7 +1,7 @@ Format: 1.0 Type: Application FullName: io.murano.apps.docker.kubernetes.KubernetesCluster -Name: Kubernetes +Name: Kubernetes Cluster Description: | Kubernetes is an open source system for managing containerized applications across multiple hosts, providing basic mechanisms for deployment, maintenance, and scaling of applications. diff --git a/io.murano.apps.docker.kubernetes.KubernetesPod/Classes/KubernetesPod.yaml b/io.murano.apps.docker.kubernetes.KubernetesPod/Classes/KubernetesPod.yaml index 41de2e5..3d0ce50 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesPod/Classes/KubernetesPod.yaml +++ b/io.murano.apps.docker.kubernetes.KubernetesPod/Classes/KubernetesPod.yaml @@ -22,7 +22,7 @@ Properties: Default: '' replicationFactor: - Contract: $.int().notNull() + Contract: $.int().notNull().check($ >= 0) exposePorts: Contract: $.string().notNull() @@ -30,7 +30,7 @@ Properties: exposePortsMap: Contract: - $.int().notNull(): $.int().notNull() + $.int().notNull().check($ > 0 and $ < 65536): $.int().notNull().check($ > 0 and $ < 65536) Usage: Runtime Methods: @@ -69,6 +69,9 @@ Methods: In: $mappingString.replace(',', ';').split(';') Do: - $pair: $t.split('=') + - If: len($pair) != 2 + Then: + Continue: - $key: int($pair[0].trim()) - $result[$key]: int($pair[0-1].trim()) # yaql 0.2.x doesn't support unary operators - Return: $result @@ -181,7 +184,6 @@ Methods: Arguments: - podName: Contract: $.string().notNull() - Contract: $.string().notNull() Body: Return: $.labels2Map(toLower($.labels)).mergeWith(dict(id => $podName)) @@ -255,13 +257,24 @@ Methods: Contract: $.string().notNull(): $.string().notNull() - ports: - Contract: + Contract: - $.int().notNull() - volumes: Contract: $.string().notNull(): $.class(doc:DockerVolume).notNull() Body: - $.deleteContainer($name) + + - For: port + In: $ports + Do: + - $securityGroupIngress: + - ToPort: $port + FromPort: $port + IpProtocol: tcp + External: true + - $._environment.securityGroupManager.addGroupIngress($securityGroupIngress) + - $container: name: toLower($name) image: $image @@ -270,7 +283,7 @@ Methods: ports: $ports.select(dict(containerPort => $, hostPort => $)) volumeMounts: $volumes.select(dict(name => $this.generateVolumeName($env.get($)), mountPath => $)) env: $env.select(dict(key => $, value => $env.get($))) - + - $newVolumes: $volumes.where(not $this.generateVolumeName($) in $._podDefinition.desiredState.volumes.name). select($this.buildVolumeEntry($volumes.get($))) diff --git a/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/UpdatePod.template b/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/UpdatePod.template index 1e77e6b..4aaee1c 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/UpdatePod.template +++ b/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/UpdatePod.template @@ -8,9 +8,12 @@ Parameters: Body: | import json - with open('/tmp/pod.json', 'w') as f: + import uuid + fileName = '/var/run/murano-kubernetes/' + str(uuid.uuid4()) + '.json' + with open(fileName, 'w') as f: json.dump(args.podDefinition, f) - return updatePod('{0}'.format(args.isNew)).stdout + + return updatePod('{0} {1} {2} {3}'.format(args.isNew, args.podDefinition['id'], args.podDefinition['kind'], fileName )).stdout Scripts: updatePod: diff --git a/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/UpdateService.template b/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/UpdateService.template index e9bd016..e16b048 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/UpdateService.template +++ b/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/UpdateService.template @@ -8,10 +8,12 @@ Parameters: Body: | import json - with open('/tmp/service.json', 'w') as f: + import uuid + fileName = '/var/run/murano-kubernetes/' + str(uuid.uuid4()) + '.json' + with open(fileName, 'w') as f: json.dump(args.serviceDefinition, f) - return updateService('{0}'.format(args.isNew)).stdout - + + return updateService('{0} {1} {2} {3}'.format(args.isNew, args.serviceDefinition['id'], args.serviceDefinition['kind'], fileName )).stdout Scripts: updateService: Type: Application diff --git a/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/scripts/updatePod.sh b/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/scripts/updatePod.sh index 36c7e37..c4b855e 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/scripts/updatePod.sh +++ b/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/scripts/updatePod.sh @@ -2,12 +2,19 @@ # File with pod is /tmp/pod.json # $1 new or update +DEFINITION_DIR=/var/run/murano-kubernetes +mkdir -p $DEFINITION_DIR + +podId=$2 +kind=$3 +fileName=$4 +echo "$podId $kind $fileName" >> $DEFINITION_DIR/elements.list if [ "$1" == "True" ]; then #new Pod echo "Creating a new Pod" >> /tmp/murano-kube.log - /opt/bin/kubectl create -f /tmp/pod.json >> /tmp/murano-kube.log + /opt/bin/kubectl create -f $fileName >> /tmp/murano-kube.log else echo "Updating a Pod" >> /tmp/murano-kube.log - /opt/bin/kubectl update -f /tmp/pod.json >> /tmp/murano-kube.log + /opt/bin/kubectl update -f $fileName >> /tmp/murano-kube.log fi diff --git a/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/scripts/updateService.sh b/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/scripts/updateService.sh index 01a2487..5361ddd 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/scripts/updateService.sh +++ b/io.murano.apps.docker.kubernetes.KubernetesPod/Resources/scripts/updateService.sh @@ -1,8 +1,19 @@ #!/bin/bash + +# File with service is /tmp/service.json +# $1 new or update +DEFINITION_DIR=/var/run/murano-kubernetes +mkdir -p $DEFINITION_DIR +serviceId=$2 +kind=$3 +fileName=$4 + +echo "$serviceId $kind $fileName" >> $DEFINITION_DIR/elements.list + if [ "$1" == "True" ]; then echo "Creating a new Service" >> /tmp/murano-kube.log - /opt/bin/kubectl create -f /tmp/service.json >> /tmp/murano-kube.log + /opt/bin/kubectl create -f $fileName >> /tmp/murano-kube.log else echo "Updating a Service" >> /tmp/murano-kube.log - /opt/bin/kubectl update -f /tmp/service.json >> /tmp/murano-kube.log + /opt/bin/kubectl update -f $fileName >> /tmp/murano-kube.log fi diff --git a/io.murano.apps.docker.kubernetes.KubernetesPod/UI/ui.yaml b/io.murano.apps.docker.kubernetes.KubernetesPod/UI/ui.yaml index ecdd504..696e9c5 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesPod/UI/ui.yaml +++ b/io.murano.apps.docker.kubernetes.KubernetesPod/UI/ui.yaml @@ -33,13 +33,15 @@ Forms: Kubernetes service - name: replicationFactor type: integer - label: Replication Factor + label: Replication Factor (0 = disabled) initial: 2 - required: false + required: true + minValue: 0 - name: exposePorts type: string label: Expose Ports required: false description: >- - DICTIONARY HERE - + List of ports to expose for the Pod in a form of either + "port1;port2" or + "publicPort1=containerPort1;publicPort2=containerPort2" diff --git a/io.murano.apps.docker.kubernetes.KubernetesPod/manifest.yaml b/io.murano.apps.docker.kubernetes.KubernetesPod/manifest.yaml index fe1908c..484afb3 100644 --- a/io.murano.apps.docker.kubernetes.KubernetesPod/manifest.yaml +++ b/io.murano.apps.docker.kubernetes.KubernetesPod/manifest.yaml @@ -1,7 +1,7 @@ Format: 1.0 Type: Application FullName: io.murano.apps.docker.kubernetes.KubernetesPod -Name: Kubernetes POD +Name: Kubernetes Pod Description: | Kubernes Pod - A collection of containers which will be scheduled onto the same node, which share and an IP and port space, and which can be created/destroyed together. diff --git a/io.murano.apps.docker.kubernetes.static.KubernetesEntities/manifest.yaml b/io.murano.apps.docker.kubernetes.static.KubernetesEntities/manifest.yaml index bfba547..374b1d8 100644 --- a/io.murano.apps.docker.kubernetes.static.KubernetesEntities/manifest.yaml +++ b/io.murano.apps.docker.kubernetes.static.KubernetesEntities/manifest.yaml @@ -1,6 +1,6 @@ Format: 1.0 Type: Library -FullName: io.murano.apps.docker.kubernetes.static.KubernetesPod +FullName: io.murano.apps.docker.kubernetes.static.KubernetesEntities Name: Kubernetes static entities Description: | Kubernes Pod - A collection of containers which will be scheduled onto the same node, @@ -8,6 +8,6 @@ Description: | Author: 'Mirantis, Inc' Tags: [docker, kubernetes, pod] Classes: - io.murano.apps.docker.kubernetes.static.Pod: KubernetesPod.yaml + io.murano.apps.docker.kubernetes.static.Pod: Pod.yaml io.murano.apps.docker.kubernetes.static.Service: Service.yaml io.murano.apps.docker.kubernetes.static.ReplicationController: ReplicationController.yaml diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..46b2ff7 --- /dev/null +++ b/readme.md @@ -0,0 +1,27 @@ +# Google Kubernetes for Murano + +Packages in this folder are required to deploy both Google Kubernetes and applications +on top of it. + +Contents of each folder need to be zipped and uploaded to Murano Application Catalog. +You will also need to build proper Ubuntu image for Kubernetes. +This can be done using diskimage-builder (https://github.com/openstack/diskimage-builder) and +DIB elements (https://github.com/stackforge/murano/tree/master/contrib/elements/kubernetes). + +Brief description of packages located here: + +io.murano.apps.docker.kubernetes.KubernetesCluster – represents scalable +cluster of Kubernetes nodes + +io.murano.apps.docker.kubernetes.KubernetesPod – Kubernetes host for Docker +containers. Several containers may be hosted in single Pod. Also +automatically manages Service endpoints and replication + +io.murano.apps.docker.Interfaces – Interface classes for both Kubernetes and Docker + +io.murano.apps.docker.kubernetes.static.KubernetesEntities – Kubernetes +instances that can be constructed from a JSON definition – Pod, Service +and ReplicationController + +io.murano.apps.docker.DockerHTTPd – Apache web server in Docker container that can be +hosted on Kubernetes