From f813a16a6999a300760ceb3939f90d9f683e6d69 Mon Sep 17 00:00:00 2001 From: iberezovskiy Date: Wed, 18 Nov 2015 13:57:36 +0300 Subject: [PATCH] Support of PyMySQL driver for MySQL backend Add ability to use python-pymysql library as backend for MySQL connections. Update acceptance tests to use pyMySQL. Docs: https://wiki.openstack.org/wiki/PyMySQL_evaluation The same implementation as it's done for keystone: https://review.openstack.org/#/c/242134/ Change-Id: Ibc5b9717d681d9a090777d4fe64b906c3c07ec5d --- manifests/db.pp | 10 +++++++--- manifests/params.pp | 2 ++ spec/acceptance/basic_nova_spec.rb | 2 +- spec/classes/nova_db_spec.rb | 32 ++++++++++++++++++++++++++---- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/manifests/db.pp b/manifests/db.pp index 5fb320137..65144ef0e 100644 --- a/manifests/db.pp +++ b/manifests/db.pp @@ -81,13 +81,17 @@ class nova::db ( if $database_connection_real { validate_re($database_connection_real, - '(sqlite|mysql|postgresql):\/\/(\S+:\S+@\S+\/\S+)?') + '^(sqlite|mysql(\+pymysql)?|postgresql):\/\/(\S+:\S+@\S+\/\S+)?') case $database_connection_real { - /^mysql:\/\//: { - $backend_package = false + /^mysql(\+pymysql)?:\/\//: { require 'mysql::bindings' require 'mysql::bindings::python' + if $database_connection_real =~ /^mysql\+pymysql/ { + $backend_package = $::nova::params::pymysql_package_name + } else { + $backend_package = false + } } /^postgresql:\/\//: { $backend_package = false diff --git a/manifests/params.pp b/manifests/params.pp index 6c9628cd0..29e9b0f95 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -27,6 +27,7 @@ class nova::params { $serialproxy_package_name = 'openstack-nova-serialproxy' $spicehtml5proxy_package_name = 'openstack-nova-console' $sqlite_package_name = undef + $pymysql_package_name = 'python2-PyMySQL' # service names $api_service_name = 'openstack-nova-api' $cells_service_name = 'openstack-nova-cells' @@ -82,6 +83,7 @@ class nova::params { $tgt_package_name = 'tgt' $serialproxy_package_name = 'nova-serialproxy' $sqlite_package_name = 'python-pysqlite2' + $pymysql_package_name = 'python-pymysql' # service names $api_service_name = 'nova-api' $cells_service_name = 'nova-cells' diff --git a/spec/acceptance/basic_nova_spec.rb b/spec/acceptance/basic_nova_spec.rb index 0465bdfa9..644889852 100644 --- a/spec/acceptance/basic_nova_spec.rb +++ b/spec/acceptance/basic_nova_spec.rb @@ -29,7 +29,7 @@ describe 'basic nova' do # Nova resources class { '::nova': - database_connection => 'mysql://nova:a_big_secret@127.0.0.1/nova?charset=utf8', + database_connection => 'mysql+pymysql://nova:a_big_secret@127.0.0.1/nova?charset=utf8', rabbit_userid => 'nova', rabbit_password => 'an_even_bigger_secret', image_service => 'nova.image.glance.GlanceImageService', diff --git a/spec/classes/nova_db_spec.rb b/spec/classes/nova_db_spec.rb index 9c841cb58..2a76aa0c5 100644 --- a/spec/classes/nova_db_spec.rb +++ b/spec/classes/nova_db_spec.rb @@ -20,17 +20,18 @@ describe 'nova::db' do context 'with overriden parameters' do before :each do params.merge!( - :database_connection => 'mysql://user:pass@db/db', - :slave_connection => 'mysql://user:pass@slave/db', + :database_connection => 'mysql+pymysql://user:pass@db/db', + :slave_connection => 'mysql+pymysql://user:pass@slave/db', ) end - it { is_expected.to contain_nova_config('database/connection').with_value('mysql://user:pass@db/db').with_secret(true) } - it { is_expected.to contain_nova_config('database/slave_connection').with_value('mysql://user:pass@slave/db').with_secret(true) } + it { is_expected.to contain_nova_config('database/connection').with_value('mysql+pymysql://user:pass@db/db').with_secret(true) } + it { is_expected.to contain_nova_config('database/slave_connection').with_value('mysql+pymysql://user:pass@slave/db').with_secret(true) } it { is_expected.to contain_nova_config('database/idle_timeout').with_value('3600') } it { is_expected.to contain_nova_config('database/min_pool_size').with_value('1') } it { is_expected.to contain_nova_config('database/max_retries').with_value('10') } it { is_expected.to contain_nova_config('database/retry_interval').with_value('10') } + it { is_expected.to contain_package('nova-backend-package').with({ :ensure => 'present', :name => platform_params[:pymysql_package_name] }) } end @@ -45,6 +46,14 @@ describe 'nova::db' do end + context 'with MySQL-python library as backend package' do + let :params do + { :database_connection => 'mysql://user:pass@db/db', } + end + + it { is_expected.to contain_package('python-mysqldb').with(:ensure => 'present') } + end + context 'with incorrect database_connection string' do let :params do { :database_connection => 'redis://nova:nova@localhost/nova', } @@ -53,6 +62,13 @@ describe 'nova::db' do it_raises 'a Puppet::Error', /validate_re/ end + context 'with incorrect pymysql database_connection string' do + let :params do + { :database_connection => 'foo+pymysql://user:pass@db/db', } + end + + it_raises 'a Puppet::Error', /validate_re/ + end end context 'on Debian platforms' do @@ -63,6 +79,10 @@ describe 'nova::db' do } end + let :platform_params do + { :pymysql_package_name => 'python-pymysql' } + end + it_configures 'nova::db' context 'with sqlite backend' do @@ -88,6 +108,10 @@ describe 'nova::db' do } end + let :platform_params do + { :pymysql_package_name => 'python2-PyMySQL' } + end + it_configures 'nova::db' end