diff --git a/murano-apps/Nodepool/package/Classes/Nodepool.yaml b/murano-apps/Nodepool/package/Classes/Nodepool.yaml new file mode 100644 index 0000000..578200e --- /dev/null +++ b/murano-apps/Nodepool/package/Classes/Nodepool.yaml @@ -0,0 +1,88 @@ +Namespaces: + =: io.murano.opaas + std: io.murano + res: io.murano.resources + sys: io.murano.system + opaas: io.murano.opaas + puppet: io.murano.opaas.puppet + +Name: Nodepool + +Extends: std:Application + +Properties: + instance: + Contract: $.class(puppet:PuppetInstance).notNull() + name: + Contract: $.string().notNull() + jenkins: + Contract: $.class(opaas:Jenkins).notNull() + # TODO(nmakhotkin) Add zuul property. + +Methods: + .init: + Body: + - $._environment: $.find(std:Environment).require() + + deploy: + Body: + - $.super($.deploy()) + - If: $.getAttr(deployed, false) + Then: + Return: + + - $securityGroupIngress: + - ToPort: 80 + FromPort: 80 + IpProtocol: tcp + External: true + - $._environment.securityGroupManager.addGroupIngress($securityGroupIngress) + - $._environment.reporter.report($this, 'Creating instance for Nodepool...') + - $.instance.deploy() + - $._environment.reporter.report($this, 'Nodepool instance is created.') + + - $._environment.reporter.report($this, 'Installing needed puppets for Nodepool...') + + - $this.systemConfig: new(puppet:ProjectConfig) + - $this.systemConfig.installOnTheNode($this.instance) + + - $._environment.reporter.report($this, 'Waiting while Jenkins is being deployed...') + - $.jenkins.deploy() + + - $.createConfiguration() + + - $resources: new(sys:Resources) + - $template: $resources.yaml('DeployNodepool.template') + - $._environment.reporter.report($this, 'Installing Nodepool...') + - $.instance.agent.call($template, $resources) + - $._environment.reporter.report($this, 'Nodepool is installed.') + - $host: $.detectPrimaryIP($.instance) + - $._environment.reporter.report($this, 'Nodepool is available at host {}.'.format($host)) + - $.setAttr(deployed, true) + + createConfiguration: + Body: + - $.instance.setHieraValue('nodepool_mysql_password', 'nodepool') + - $.instance.setHieraValue('nodepool_mysql_root_password', 'root') + - $.instance.setHieraValue('jenkins_api_user', $.jenkins.ldap.ldapRootUser) + - $.instance.setHieraValue('jenkins_api_key', $.jenkins.ldap.ldapRootPass) + - $jenkinsHost: $.detectPrimaryIP($.jenkins.instance) + - $.instance.setHieraValue('jenkins_host', $jenkinsHost) + + + detectPrimaryIP: + Arguments: + - instance: + Contract: $.class(res:Instance).notNull() + Body: + - If: $instance.assignFloatingIp + Then: + - $host: $instance.floatingIpAddress + Else: + - $host: $instance.ipAddresses[0] + - Return: $host + + destroy: + Body: + - $.reportDestroyed() + - $.setAttr(deployed, false) diff --git a/murano-apps/Nodepool/package/Resources/DeployNodepool.template b/murano-apps/Nodepool/package/Resources/DeployNodepool.template new file mode 100644 index 0000000..d3819b3 --- /dev/null +++ b/murano-apps/Nodepool/package/Resources/DeployNodepool.template @@ -0,0 +1,24 @@ +FormatVersion: 2.1.0 +Version: 1.0.0 +Name: Deploy Nodepool + +Parameters: + +Body: | + deployNodepool() + +Scripts: + deployNodepool: + Type: Application + Version: 1.0.0 + EntryPoint: deploy_nodepool.sh + Files: + - 'gen_rsa_key.sh' + - 'site.pp' + - 'nodepool_configure/templates/nodepool.yaml.erb' + - 'nodepool_configure/manifests/init.pp' + Options: + captureStdout: false + captureStderr: true + verifyExitcode: true + diff --git a/murano-apps/Nodepool/package/Resources/scripts/deploy_nodepool.sh b/murano-apps/Nodepool/package/Resources/scripts/deploy_nodepool.sh new file mode 100644 index 0000000..5b2b16a --- /dev/null +++ b/murano-apps/Nodepool/package/Resources/scripts/deploy_nodepool.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +logger Deploying Nodepool... + +/bin/bash ./gen_rsa_key.sh + +mkdir /etc/puppet/modules/nodepool_configure +mkdir /etc/puppet/modules/nodepool_configure/manifests +mkdir /etc/puppet/modules/nodepool_configure/templates + +cp nodepool_configure/manifests/init.pp /etc/puppet/modules/nodepool_configure/manifests/ +cp nodepool_configure/templates/nodepool.yaml.erb /etc/puppet/modules/nodepool_configure/templates/ + +puppet apply site.pp + +exit diff --git a/murano-apps/Nodepool/package/Resources/scripts/gen_rsa_key.sh b/murano-apps/Nodepool/package/Resources/scripts/gen_rsa_key.sh new file mode 100644 index 0000000..c367c24 --- /dev/null +++ b/murano-apps/Nodepool/package/Resources/scripts/gen_rsa_key.sh @@ -0,0 +1,14 @@ +#!/bin/bash +logger Generate SSH Private key for nodepool + +datafile='/etc/puppet/hieradata/murano.yaml' + +# +# nodepool ssh key +# +ssh-keygen -t rsa -N "" -f nodepool_ssh.key -q + +content=`cat nodepool_ssh.key` +puppet apply --execute "yaml_setting { 'example': target=>'$datafile', key=>'nodepool_ssh_private_key', value=>'$content', }" + +exit \ No newline at end of file diff --git a/murano-apps/Nodepool/package/Resources/scripts/nodepool_configure/manifests/init.pp b/murano-apps/Nodepool/package/Resources/scripts/nodepool_configure/manifests/init.pp new file mode 100644 index 0000000..fb2bb24 --- /dev/null +++ b/murano-apps/Nodepool/package/Resources/scripts/nodepool_configure/manifests/init.pp @@ -0,0 +1,12 @@ +class nodepool_configure ( + $jenkins_host = undef, + $zuul_host = undef, +) { + file { '/etc/nodepool/nodepool.yaml': + ensure => present, + owner => 'nodepool', + group => 'nodepool', + mode => '0644', + content => template('nodepool_configure/nodepool.yaml.erb') + } +} \ No newline at end of file diff --git a/murano-apps/Nodepool/package/Resources/scripts/nodepool_configure/templates/nodepool.yaml.erb b/murano-apps/Nodepool/package/Resources/scripts/nodepool_configure/templates/nodepool.yaml.erb new file mode 100644 index 0000000..1ce65d0 --- /dev/null +++ b/murano-apps/Nodepool/package/Resources/scripts/nodepool_configure/templates/nodepool.yaml.erb @@ -0,0 +1,60 @@ +script-dir: /etc/nodepool/scripts +elements-dir: /etc/nodepool/elements +images-dir: /opt/nodepool_dib + + +cron: + check: '*/15 * * * *' + cleanup: '0 * * * *' + image-update: '30 * * * *' + +zmq-publishers: + - tcp://localhost:8888 # Jenkins host + +gearman-servers: # Zuul host + - host: localhost + port: 4730 + +diskimages: +- name: ubuntu-trusty + elements: + - ubuntu + - vm + - simple-init + release: trusty + env-vars: + DIB_IMAGE_CACHE: /opt/dib_cache + +labels: + - name: ubuntu-server + image: ubuntu-trusty-node + min-ready: 2 + providers: + - name: openstack-provider + +providers: + - name: openstack-provider + keypair: 'nmakhotkin' + region-name: 'RegionOne' + username: 'dev-user' + password: 'sw0rdfish' + auth-url: 'http://172.16.167.137:5000/v2.0' + project-name: 'dev' + image-type: qcow2 + max-servers: 20 + use-neutron: true + networks: + - name: dev-net + #- id: uuid + images: + - name: ubuntu-trusty-node + diskimage: ubuntu-trusty + min-ram: 2048 + private-key: /home/nodepool/.ssh/id_rsa + setup: prepare_node.sh + username: ubuntu + +targets: + - name: jenkins + hostname: '{label.name}-{provider.name}-{node_id}' + subnode-hostname: '{label.name}-{provider.name}-{node_id}-{subnode_id}' diff --git a/murano-apps/Nodepool/package/Resources/scripts/site.pp b/murano-apps/Nodepool/package/Resources/scripts/site.pp new file mode 100644 index 0000000..ef91855 --- /dev/null +++ b/murano-apps/Nodepool/package/Resources/scripts/site.pp @@ -0,0 +1,33 @@ +node default { + class { 'openstack_project::server': + sysadmins => hiera('sysadmins', []), + iptables_public_tcp_ports => [80], + } + + class { 'nodepool': + mysql_root_password => hiera('nodepool_mysql_root_password'), + mysql_password => hiera('nodepool_mysql_password'), + nodepool_ssh_private_key => hiera('nodepool_ssh_private_key'), + git_source_repo => 'https://git.openstack.org/openstack-infra/nodepool', + revision => 'master', + vhost_name => $::fqdn, + statsd_host => '', + image_log_document_root => '/var/log/nodepool/image', + image_log_periodic_cleanup => true, + enable_image_log_via_http => true, + environment => {}, + jenkins_masters => [ + { + name => 'jenkins', + url => sprintf('http://%s:8080', hiera('jenkins_host')), + user => hiera('jenkins_api_user', 'username'), + apikey => hiera('jenkins_api_key') + } + ] + } + + class { 'nodepool_configure': + jenkins_host => hiera('jenkins_host'), + require => Class['nodepool'] + } +} diff --git a/murano-apps/Nodepool/package/UI/ui.yaml b/murano-apps/Nodepool/package/UI/ui.yaml new file mode 100644 index 0000000..d715aa4 --- /dev/null +++ b/murano-apps/Nodepool/package/UI/ui.yaml @@ -0,0 +1,86 @@ +Version: 2 + +Application: + ?: + type: io.murano.opaas.Nodepool + name: $.appConfiguration.name + jenkins: $.appConfiguration.Jenkins + instance: + ?: + type: io.murano.opaas.puppet.PuppetInstance + name: generateHostname($.instanceConfiguration.unitNamingPattern, 1) + flavor: $.instanceConfiguration.flavor + image: $.instanceConfiguration.osImage + keyname: $.instanceConfiguration.keyPair + availabilityZone: $.instanceConfiguration.availabilityZone + assignFloatingIp: $.appConfiguration.assignFloatingIP + +Forms: + - appConfiguration: + fields: + - name: name + type: string + label: Application Name + initial: Nodepool + description: >- + Enter a desired name for the application. Just A-Z, a-z, 0-9, dash and + underline are allowed + - name: assignFloatingIP + type: boolean + label: Assign Floating IP + description: >- + Select to true to assign floating IP automatically + initial: true + required: false + - name: Jenkins + type: io.murano.opaas.Jenkins + required: true + description: >- + Specify Jenkins. + + - instanceConfiguration: + fields: + - name: title + type: string + required: false + hidden: true + description: Specify some instance parameters on which the application would be created + - name: flavor + type: flavor + label: Instance flavor + description: >- + Select registered in Openstack flavor. Consider that application performance + depends on this parameter. + initial: m1.tiny + required: false + - name: osImage + type: image + imageType: linux + label: Instance image + description: >- + Select a valid image for the application. Image should already be prepared and + registered in glance. + - name: keyPair + type: keypair + label: Key Pair + description: >- + Select a Key Pair to control access to instances. You can login to + instances using this KeyPair after the deployment of application. + required: false + - name: availabilityZone + type: azone + label: Availability zone + description: Select availability zone where the application would be installed. + required: false + - name: unitNamingPattern + type: string + label: Instance Naming Pattern + required: false + maxLength: 200 + regexpValidator: '^[-_\w]+$' + errorMessages: + invalid: Just letters, numbers, underscores and hyphens are allowed. + helpText: Just letters, numbers, underscores and hyphens are allowed. + description: >- + Specify a string, that will be used in instance hostname. + Just A-Z, a-z, 0-9, dash and underline are allowed. diff --git a/murano-apps/Nodepool/package/logo.png b/murano-apps/Nodepool/package/logo.png new file mode 100644 index 0000000..0afb470 Binary files /dev/null and b/murano-apps/Nodepool/package/logo.png differ diff --git a/murano-apps/Nodepool/package/manifest.yaml b/murano-apps/Nodepool/package/manifest.yaml new file mode 100644 index 0000000..138d41b --- /dev/null +++ b/murano-apps/Nodepool/package/manifest.yaml @@ -0,0 +1,20 @@ +Format: 1.0 +Type: Application +FullName: io.murano.opaas.Nodepool +Name: Nodepool +Description: | + Nodepool is a system for launching single-use test nodes on demand based on + images built with cached data. It is designed to work with any OpenStack + based cloud, and is part of a suite of tools that form a comprehensive + test system including Jenkins and Zuul. +Author: 'Mirantis, Inc' +Tags: [Images, CI, Zuul, Jenkins] +Classes: + io.murano.opaas.Nodepool: Nodepool.yaml +UI: ui.yaml +Logo: logo.png +Require: + io.murano.opaas.puppet.ProjectConfig: + io.murano.opaas.puppet.Puppet: + io.murano.opaas.Jenkins: +# TODO(nmakhotkin): Add zuul to requirements.