Browse Source

add percona-cluster recipes

- add recipes and specs to deploy percona-cluster as db backend

Depends-On: Iae7e302973805af3cb44be1b29d0e61e76eb0aa0
Implements Blueprint: galera-and-percona-support
Change-Id: Ie69e71dce8fa22ef5edc17ed094840fcfb9d4c82
Jan Klare 4 years ago
parent
commit
856c3a24ab

+ 1
- 0
metadata.rb View File

@@ -20,6 +20,7 @@ recipe 'openstack-db', 'Creates necessary tables, users, and grants for OpenStac
20 20
 end
21 21
 
22 22
 depends 'mariadb', '~> 0.3.1'
23
+depends 'percona', '~> 0.16.1'
23 24
 depends 'mysql', '~> 6.0.13'
24 25
 depends 'mysql2_chef_gem', '~> 1.0.1'
25 26
 depends 'postgresql', '~> 3.4.18'

+ 1
- 1
recipes/openstack-db.rb View File

@@ -29,7 +29,7 @@ node['openstack']['common']['services'].each do |service, project|
29 29
       user node['openstack']['db'][service]['username']
30 30
       pass password
31 31
     end
32
-  rescue Net::HTTPServerException
32
+  rescue Net::HTTPServerException, ChefVault::Exceptions::KeysNotFound
33 33
     log "No databag item containing the database password for #{project} was found, so no database was created"
34 34
   end
35 35
 end

+ 28
- 0
recipes/percona-cluster-client.rb View File

@@ -0,0 +1,28 @@
1
+# encoding: UTF-8
2
+#
3
+# Cookbook Name:: openstack-ops-database
4
+# Recipe:: percona-cluster-client
5
+#
6
+# Licensed under the Apache License, Version 2.0 (the "License");
7
+# you may not use this file except in compliance with the License.
8
+# You may obtain a copy of the License at
9
+#
10
+#     http://www.apache.org/licenses/LICENSE-2.0
11
+#
12
+# Unless required by applicable law or agreed to in writing, software
13
+# distributed under the License is distributed on an "AS IS" BASIS,
14
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+# See the License for the specific language governing permissions and
16
+# limitations under the License.
17
+#
18
+
19
+include_recipe 'percona::client'
20
+
21
+mysql2_chef_gem 'default' do
22
+  provider Chef::Provider::Mysql2ChefGem::Percona
23
+  action :install
24
+end
25
+
26
+node['openstack']['db']['python_packages']['percona-cluster'].each do |pkg|
27
+  package pkg
28
+end

+ 62
- 0
recipes/percona-cluster-server.rb View File

@@ -0,0 +1,62 @@
1
+# encoding: UTF-8
2
+#
3
+# Cookbook Name:: openstack-ops-database
4
+# Recipe:: percona-cluster-server
5
+#
6
+# Licensed under the Apache License, Version 2.0 (the "License");
7
+# you may not use this file except in compliance with the License.
8
+# You may obtain a copy of the License at
9
+#
10
+#     http://www.apache.org/licenses/LICENSE-2.0
11
+#
12
+# Unless required by applicable law or agreed to in writing, software
13
+# distributed under the License is distributed on an "AS IS" BASIS,
14
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+# See the License for the specific language governing permissions and
16
+# limitations under the License.
17
+#
18
+
19
+class ::Chef::Recipe # rubocop:disable Documentation
20
+  include ::Openstack
21
+end
22
+
23
+## INFO: to use this recipe, set node['percona']['server']['role'] = %w(cluster) in your environment
24
+
25
+bind_db = node['openstack']['bind_service']['db']
26
+if bind_db['interface']
27
+  listen_address = address_for bind_db['interface']
28
+  node.normal['percona']['cluster']['wsrep_sst_receive_address'] = listen_address
29
+  node.normal['percona']['server']['bind_address'] = listen_address
30
+  node.normal['percona']['server']['port'] = bind_db['port']
31
+else
32
+  listen_address = bind_db['host']
33
+  node.normal['percona']['server']['bind_address'] = listen_address
34
+  node.normal['percona']['server']['port'] = node['openstack']['endpoints']['db']['port']
35
+end
36
+
37
+## CLUSTER SPECIFIC CONFIG
38
+node.normal['percona']['cluster']['wsrep_node_name'] = node['fqdn']
39
+node.normal['percona']['cluster']['wsrep_cluster_name'] = 'openstack'
40
+node.normal['percona']['cluster']['wsrep_provider_options'] = "\"gmcast.listen_addr=tcp://#{listen_address}:4567;\""
41
+# query_cache is not supported with wsrep
42
+node.normal['percona']['server']['query_cache_size'] = 0
43
+# find all nodes in the percona cluster
44
+cluster_nodes = search(:node, 'recipes:"percona\:\:cluster"')
45
+# if it's the first node make sure that wsrep_cluster_address is set to nothing to be able to bootstrap.
46
+is_first_node = cluster_nodes.empty? || (cluster_nodes.size == 1 && cluster_nodes.first['fqdn'] == node['fqdn'])
47
+if is_first_node
48
+  node.normal['percona']['cluster']['wsrep_cluster_address'] = 'gcomm://'
49
+else
50
+  # otherwise set the correct cluster address with all cluster nodes
51
+  family = node['openstack']['endpoints']['family']
52
+  cluster_nodes_addresses = []
53
+  cluster_nodes.each do |cluster_node|
54
+    address = address_for bind_db['interface'], family, cluster_node
55
+    cluster_nodes_addresses << address
56
+  end
57
+  cluster_address = cluster_nodes_addresses.join(',')
58
+  node.normal['percona']['cluster']['wsrep_cluster_address'] = "gcomm://#{cluster_address}"
59
+end
60
+
61
+include_recipe 'openstack-ops-database::percona-cluster-client'
62
+include_recipe 'percona::cluster'

+ 28
- 0
spec/percona-cluster-client_spec.rb View File

@@ -0,0 +1,28 @@
1
+# encoding: UTF-8
2
+
3
+require_relative 'spec_helper'
4
+
5
+describe 'openstack-ops-database::percona-cluster-client' do
6
+  include_context 'database-stubs'
7
+  describe 'ubuntu' do
8
+    let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
9
+    let(:node) do
10
+      runner.node.set['openstack']['db']['service_type'] = 'percona-cluster'
11
+      runner.node
12
+    end
13
+    let(:chef_run) { runner.converge(described_recipe) }
14
+
15
+    it 'includes percona client recipes' do
16
+      expect(chef_run).to include_recipe('percona::client')
17
+    end
18
+
19
+    it 'install mysql2 gem package' do
20
+      expect(chef_run).to install_mysql2_chef_gem('default')
21
+        .with(provider: Chef::Provider::Mysql2ChefGem::Percona)
22
+    end
23
+
24
+    it 'installs percona python client packages' do
25
+      expect(chef_run).to install_package('python-mysqldb')
26
+    end
27
+  end
28
+end

+ 19
- 0
spec/percona-cluster-server_spec.rb View File

@@ -0,0 +1,19 @@
1
+# encoding: UTF-8
2
+
3
+require_relative 'spec_helper'
4
+
5
+describe 'openstack-ops-database::percona-cluster-server' do
6
+  include_context 'database-stubs'
7
+  describe 'ubuntu' do
8
+    let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
9
+    let(:node) do
10
+      runner.node.set['openstack']['db']['service_type'] = 'percona-cluster'
11
+      runner.node
12
+    end
13
+    let(:chef_run) { runner.converge(described_recipe) }
14
+
15
+    it 'includes percona client recipes' do
16
+      expect(chef_run).to include_recipe('percona::cluster')
17
+    end
18
+  end
19
+end

+ 5
- 0
spec/spec_helper.rb View File

@@ -22,12 +22,17 @@ shared_context 'database-stubs' do
22 22
     stub_command("/usr/bin/mysql -u root -e 'show databases;'")
23 23
     # for debian
24 24
     stub_command("\"/usr/bin/mysql\" -u root -e 'show databases;'")
25
+    stub_command("mysqladmin --user=root --password='' version")
25 26
     # for postgresql
26 27
     stub_command('ls /var/lib/postgresql/9.3/main/recovery.conf')
28
+    stub_search('node', "recipes:\"percona\\:\\:cluster\"").and_return([])
27 29
 
28 30
     allow_any_instance_of(Chef::Recipe).to receive(:address_for)
29 31
       .with('lo')
30 32
       .and_return('127.0.0.1')
33
+    allow_any_instance_of(Chef::Recipe).to receive(:address_for)
34
+      .with('all')
35
+      .and_return('0.0.0.0')
31 36
     allow_any_instance_of(Chef::Recipe).to receive(:get_password)
32 37
       .with('db', anything)
33 38
       .and_return('test-pass')

Loading…
Cancel
Save