From 3c0ac8112eba3a40f1fa191e623b012d9af54e3d Mon Sep 17 00:00:00 2001 From: iberezovskiy Date: Tue, 24 Nov 2015 14:22:46 +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: I937aa59984e6ff2f7aff28f56ce79e117e5aa0a9 --- manifests/db.pp | 12 +++++++++--- manifests/params.pp | 2 ++ spec/acceptance/basic_trove_spec.rb | 2 +- spec/classes/trove_db_spec.rb | 29 +++++++++++++++++++++++++++-- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/manifests/db.pp b/manifests/db.pp index 17a1faff..9368ba7e 100644 --- a/manifests/db.pp +++ b/manifests/db.pp @@ -43,6 +43,8 @@ class trove::db ( $database_max_overflow = 20, ) { + include ::trove::params + # NOTE(spredzy): In order to keep backward compatibility we rely on the pick function # to use trove:: if trove::db:: isn't specified. $database_connection_real = pick($::trove::database_connection, $database_connection) @@ -54,14 +56,18 @@ class trove::db ( $database_max_overflow_real = pick($::trove::database_max_overflow, $database_max_overflow) validate_re($database_connection_real, - '(sqlite|mysql|postgresql):\/\/(\S+:\S+@\S+\/\S+)?') + '^(sqlite|mysql(\+pymysql)?|postgresql):\/\/(\S+:\S+@\S+\/\S+)?') if $database_connection_real { 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 = $::trove::params::pymysql_package_name + } else { + $backend_package = false + } } /^postgresql:\/\//: { $backend_package = false diff --git a/manifests/params.pp b/manifests/params.pp index c1192e7a..47cdbdad 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -15,6 +15,7 @@ class trove::params { $taskmanager_package_name = 'openstack-trove-taskmanager' $taskmanager_service_name = 'openstack-trove-taskmanager' $sqlite_package_name = undef + $pymysql_package_name = 'python2-PyMySQL' } 'Debian': { $client_package_name = 'python-troveclient' @@ -28,6 +29,7 @@ class trove::params { $taskmanager_package_name = 'trove-taskmanager' $taskmanager_service_name = 'trove-taskmanager' $sqlite_package_name = 'python-pysqlite2' + $pymysql_package_name = 'python-pymysql' } default: { fail("Unsupported osfamily: ${::osfamily} operatingsystem") diff --git a/spec/acceptance/basic_trove_spec.rb b/spec/acceptance/basic_trove_spec.rb index 0a30141d..c51fcecd 100644 --- a/spec/acceptance/basic_trove_spec.rb +++ b/spec/acceptance/basic_trove_spec.rb @@ -29,7 +29,7 @@ describe 'basic trove' do # Trove resources class { '::trove': - database_connection => 'mysql://trove:a_big_secret@127.0.0.1/trove?charset=utf8', + database_connection => 'mysql+pymysql://trove:a_big_secret@127.0.0.1/trove?charset=utf8', rabbit_userid => 'trove', rabbit_password => 'an_even_bigger_secret', rabbit_host => '127.0.0.1', diff --git a/spec/classes/trove_db_spec.rb b/spec/classes/trove_db_spec.rb index f297a831..e6578c43 100644 --- a/spec/classes/trove_db_spec.rb +++ b/spec/classes/trove_db_spec.rb @@ -18,7 +18,7 @@ describe 'trove::db' do context 'with specific parameters' do let :params do - { :database_connection => 'mysql://trove:trove@localhost/trove', + { :database_connection => 'mysql+pymysql://trove:trove@localhost/trove', :database_idle_timeout => '3601', :database_min_pool_size => '2', :database_max_pool_size => '21', @@ -27,16 +27,25 @@ describe 'trove::db' do :database_retry_interval => '11', } end - it { is_expected.to contain_trove_config('database/connection').with_value('mysql://trove:trove@localhost/trove').with_secret(true) } + it { is_expected.to contain_trove_config('database/connection').with_value('mysql+pymysql://trove:trove@localhost/trove').with_secret(true) } it { is_expected.to contain_trove_config('database/idle_timeout').with_value('3601') } it { is_expected.to contain_trove_config('database/min_pool_size').with_value('2') } it { is_expected.to contain_trove_config('database/max_retries').with_value('11') } it { is_expected.to contain_trove_config('database/max_pool_size').with_value('21') } it { is_expected.to contain_trove_config('database/max_overflow').with_value('21') } it { is_expected.to contain_trove_config('database/retry_interval').with_value('11') } + it { is_expected.to contain_package('trove-backend-package').with({ :ensure => 'present', :name => platform_params[:pymysql_package_name] }) } end + context 'with MySQL-python library as backend package' do + let :params do + { :database_connection => 'mysql://trove:trove@localhost/trove', } + end + + it { is_expected.to contain_package('python-mysqldb').with(:ensure => 'present') } + end + context 'with postgresql backend' do let :params do { :database_connection => 'postgresql://trove:trove@localhost/trove', } @@ -56,6 +65,14 @@ describe 'trove::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://trove:trove@localhost/trove', } + end + + it_raises 'a Puppet::Error', /validate_re/ + end + end context 'on Debian platforms' do @@ -66,6 +83,10 @@ describe 'trove::db' do } end + let :platform_params do + { :pymysql_package_name => 'python-pymysql' } + end + it_configures 'trove::db' end @@ -76,6 +97,10 @@ describe 'trove::db' do } end + let :platform_params do + { :pymysql_package_name => 'python2-PyMySQL' } + end + it_configures 'trove::db' end