From a3fbf2e8cb9ef76d2ee960cc8087c62736f7de6c Mon Sep 17 00:00:00 2001 From: Emilien Macchi Date: Wed, 7 Jan 2015 18:40:33 -0500 Subject: [PATCH] Implement Ceilometer-API as a WSGI process support Ceilometer API can be run as a WSGI process. Let's use openstacklib to run this service under WSGI process by using Apache2. Change-Id: I004d7e7a9bfccc4677d5d629503a92a15b6263c6 --- .fixtures.yml | 2 + manifests/params.pp | 5 + manifests/wsgi/apache.pp | 121 ++++++++++++++++++ metadata.json | 1 + spec/classes/ceilometer_wsgi_apache_spec.rb | 128 ++++++++++++++++++++ 5 files changed, 257 insertions(+) create mode 100644 manifests/wsgi/apache.pp create mode 100644 spec/classes/ceilometer_wsgi_apache_spec.rb diff --git a/.fixtures.yml b/.fixtures.yml index cf0f5e52..4e87fe1f 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -1,5 +1,7 @@ fixtures: repositories: + 'apache': 'git://github.com/puppetlabs/puppetlabs-apache.git' + 'concat': 'git://github.com/puppetlabs/puppetlabs-concat.git' 'inifile': 'git://github.com/puppetlabs/puppetlabs-inifile' 'keystone': 'git://github.com/stackforge/puppet-keystone.git' 'mysql': diff --git a/manifests/params.pp b/manifests/params.pp index 6ddaf2b5..b91ef577 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -36,6 +36,9 @@ class ceilometer::params { $sqlite_package_name = 'python-sqlite2' } + $ceilometer_wsgi_script_path = '/var/www/cgi-bin/ceilometer' + $ceilometer_wsgi_script_source = '/usr/lib/python2.7/site-packages/ceilometer/api/app.wsgi' + } 'Debian': { # package names @@ -69,6 +72,8 @@ class ceilometer::params { $libvirt_group = 'libvirt' } } + $ceilometer_wsgi_script_path = '/usr/lib/cgi-bin/ceilometer' + $ceilometer_wsgi_script_source = '/usr/share/ceilometer/app.wsgi' } default: { fail("Unsupported osfamily: ${::osfamily} operatingsystem: \ diff --git a/manifests/wsgi/apache.pp b/manifests/wsgi/apache.pp new file mode 100644 index 00000000..8171512d --- /dev/null +++ b/manifests/wsgi/apache.pp @@ -0,0 +1,121 @@ +# +# Copyright (C) 2015 eNovance SAS +# +# Author: Emilien Macchi +# +# 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. +# +# Class to serve Ceilometer API with apache mod_wsgi in place of ceilometer-api service. +# +# Serving Ceilometer API from apache is the recommended way to go for production +# systems as the current keystone implementation is not multi-processor aware, +# thus limiting the performance for concurrent accesses. +# +# When using this class you should disable your ceilometer-api service. +# +# == Parameters +# +# [*servername*] +# The servername for the virtualhost. +# Optional. Defaults to $::fqdn +# +# [*port*] +# The port. +# Optional. Defaults to 8777 +# +# [*bind_host*] +# The host/ip address Apache will listen on. +# Optional. Defaults to undef (listen on all ip addresses). +# +# [*path*] +# The prefix for the endpoint. +# Optional. Defaults to '/' +# +# [*ssl*] +# Use ssl ? (boolean) +# Optional. Defaults to true +# +# [*workers*] +# Number of WSGI workers to spawn. +# Optional. Defaults to 1 +# +# [*ssl_cert*] +# [*ssl_key*] +# [*ssl_chain*] +# [*ssl_ca*] +# [*ssl_crl_path*] +# [*ssl_crl*] +# [*ssl_certs_dir*] +# apache::vhost ssl parameters. +# Optional. Default to apache::vhost 'ssl_*' defaults. +# +# == Dependencies +# +# requires Class['apache'] & Class['ceilometer'] +# +# == Examples +# +# include apache +# +# class { 'ceilometer::wsgi::apache': } +# +class ceilometer::wsgi::apache ( + $servername = $::fqdn, + $port = 8777, + $bind_host = undef, + $path = '/', + $ssl = true, + $workers = 1, + $ssl_cert = undef, + $ssl_key = undef, + $ssl_chain = undef, + $ssl_ca = undef, + $ssl_crl_path = undef, + $ssl_crl = undef, + $ssl_certs_dir = undef, + $threads = $::processorcount, + $priority = '10', +) { + + include ::ceilometer::params + include ::apache + include ::apache::mod::wsgi + if $ssl { + include ::apache::mod::ssl + } + + openstacklib::wsgi::apache { 'ceilometer_wsgi': + bind_host => $bind_host, + bind_port => $port, + group => 'ceilometer', + path => $path, + priority => $priority, + servername => $servername, + ssl => $ssl, + ssl_ca => $ssl_ca, + ssl_cert => $ssl_cert, + ssl_certs_dir => $ssl_certs_dir, + ssl_chain => $ssl_chain, + ssl_crl => $ssl_crl, + ssl_crl_path => $ssl_crl_path, + ssl_key => $ssl_key, + threads => $threads, + user => 'ceilometer', + workers => $workers, + wsgi_daemon_process => 'ceilometer', + wsgi_process_group => 'ceilometer', + wsgi_script_dir => $::ceilometer::params::ceilometer_wsgi_script_path, + wsgi_script_file => 'app', + wsgi_script_source => $::ceilometer::params::ceilometer_wsgi_script_source, + } +} diff --git a/metadata.json b/metadata.json index 77a27e3e..3d52cb62 100644 --- a/metadata.json +++ b/metadata.json @@ -31,6 +31,7 @@ ], "description": "Installs and configures OpenStack Ceilometer (Telemetry).", "dependencies": [ + { "name": "puppetlabs/apache", "version_requirement": ">=1.0.0 <2.0.0" }, { "name": "puppetlabs/inifile", "version_requirement": ">=1.0.0 <2.0.0" }, { "name": "stackforge/keystone", "version_requirement": ">=5.0.0 <6.0.0" }, { "name": "puppetlabs/stdlib", "version_requirement": ">=4.0.0 <5.0.0" }, diff --git a/spec/classes/ceilometer_wsgi_apache_spec.rb b/spec/classes/ceilometer_wsgi_apache_spec.rb new file mode 100644 index 00000000..3613066d --- /dev/null +++ b/spec/classes/ceilometer_wsgi_apache_spec.rb @@ -0,0 +1,128 @@ +require 'spec_helper' + +describe 'ceilometer::wsgi::apache' do + + let :global_facts do + { + :processorcount => 42, + :concat_basedir => '/var/lib/puppet/concat', + :fqdn => 'some.host.tld' + } + end + + let :pre_condition do + "class { 'ceilometer': metering_secret => 's3cr3t' }" + end + + shared_examples_for 'apache serving ceilometer with mod_wsgi' do + it { should contain_service('httpd').with_name(platform_parameters[:httpd_service_name]) } + it { should contain_class('ceilometer::params') } + it { should contain_class('apache') } + it { should contain_class('apache::mod::wsgi') } + + describe 'with default parameters' do + + it { should contain_file("#{platform_parameters[:wsgi_script_path]}").with( + 'ensure' => 'directory', + 'owner' => 'ceilometer', + 'group' => 'ceilometer', + 'require' => 'Package[httpd]' + )} + + + it { should contain_file('ceilometer_wsgi').with( + 'ensure' => 'file', + 'path' => "#{platform_parameters[:wsgi_script_path]}/app", + 'source' => platform_parameters[:wsgi_script_source], + 'owner' => 'ceilometer', + 'group' => 'ceilometer', + 'mode' => '0644', + 'require' => ["File[#{platform_parameters[:wsgi_script_path]}]"] + )} + + it { should contain_apache__vhost('ceilometer_wsgi').with( + 'servername' => 'some.host.tld', + 'ip' => nil, + 'port' => '8777', + 'docroot' => "#{platform_parameters[:wsgi_script_path]}", + 'docroot_owner' => 'ceilometer', + 'docroot_group' => 'ceilometer', + 'ssl' => 'true', + 'wsgi_daemon_process' => 'ceilometer', + 'wsgi_process_group' => 'ceilometer', + 'wsgi_script_aliases' => { '/' => "#{platform_parameters[:wsgi_script_path]}/app" }, + 'require' => 'File[ceilometer_wsgi]' + )} + it { should contain_file("#{platform_parameters[:httpd_ports_file]}") } + end + + describe 'when overriding parameters using different ports' do + let :params do + { + :servername => 'dummy.host', + :bind_host => '10.42.51.1', + :port => 12345, + :ssl => false, + :workers => 37, + } + end + + it { should contain_apache__vhost('ceilometer_wsgi').with( + 'servername' => 'dummy.host', + 'ip' => '10.42.51.1', + 'port' => '12345', + 'docroot' => "#{platform_parameters[:wsgi_script_path]}", + 'docroot_owner' => 'ceilometer', + 'docroot_group' => 'ceilometer', + 'ssl' => 'false', + 'wsgi_daemon_process' => 'ceilometer', + 'wsgi_process_group' => 'ceilometer', + 'wsgi_script_aliases' => { '/' => "#{platform_parameters[:wsgi_script_path]}/app" }, + 'require' => 'File[ceilometer_wsgi]' + )} + + it { should contain_file("#{platform_parameters[:httpd_ports_file]}") } + end + end + + context 'on RedHat platforms' do + let :facts do + global_facts.merge({ + :osfamily => 'RedHat', + :operatingsystemrelease => '7.0' + }) + end + + let :platform_parameters do + { + :httpd_service_name => 'httpd', + :httpd_ports_file => '/etc/httpd/conf/ports.conf', + :wsgi_script_path => '/var/www/cgi-bin/ceilometer', + :wsgi_script_source => '/usr/lib/python2.7/site-packages/ceilometer/api/app.wsgi' + } + end + + it_configures 'apache serving ceilometer with mod_wsgi' + end + + context 'on Debian platforms' do + let :facts do + global_facts.merge({ + :osfamily => 'Debian', + :operatingsystem => 'Debian', + :operatingsystemrelease => '7.0' + }) + end + + let :platform_parameters do + { + :httpd_service_name => 'apache2', + :httpd_ports_file => '/etc/apache2/ports.conf', + :wsgi_script_path => '/usr/lib/cgi-bin/ceilometer', + :wsgi_script_source => '/usr/share/ceilometer/app.wsgi' + } + end + + it_configures 'apache serving ceilometer with mod_wsgi' + end +end