From e001e294147d7ea5ddaa0e3be9f019fc4c099318 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:05:12 -0700 Subject: [PATCH 01/19] - Update cookbook metadata to add dependent cookbooks and add support for RHEL platform_family - Add the LICENSE file - Add berks and test-kitchen config which are needed for cookbook testing --- chef/cookbooks/corosync/.gitignore | 12 ++ chef/cookbooks/corosync/.kitchen.yml | 38 +++++ chef/cookbooks/corosync/Berksfile | 3 + chef/cookbooks/corosync/LICENSE | 202 +++++++++++++++++++++++++++ chef/cookbooks/corosync/metadata.rb | 17 ++- 5 files changed, 265 insertions(+), 7 deletions(-) create mode 100644 chef/cookbooks/corosync/.kitchen.yml create mode 100644 chef/cookbooks/corosync/Berksfile create mode 100644 chef/cookbooks/corosync/LICENSE diff --git a/chef/cookbooks/corosync/.gitignore b/chef/cookbooks/corosync/.gitignore index 54e2457d..f4dd71dc 100644 --- a/chef/cookbooks/corosync/.gitignore +++ b/chef/cookbooks/corosync/.gitignore @@ -1 +1,13 @@ metadata.json + +.vagrant +Berksfile.lock +Gemfile.lock +/cookbooks + +# Bundler +bin/* +.bundle/* + +.kitchen/ +.kitchen.local.yml diff --git a/chef/cookbooks/corosync/.kitchen.yml b/chef/cookbooks/corosync/.kitchen.yml new file mode 100644 index 00000000..940c1654 --- /dev/null +++ b/chef/cookbooks/corosync/.kitchen.yml @@ -0,0 +1,38 @@ +--- +driver: + name: vagrant + +provisioner: + name: chef_zero + +platforms: +- name: centos-6.4 + +suites: +- name: node-1 + driver: + network: + - ["private_network", {ip: "192.168.33.33"}] + run_list: + - recipe[corosync::default] + attributes: + corosync: + cluster_name: test_cluster + bind_addr: "192.168.33.0" + members: ["192.168.33.33", "192.168.33.34"] + transport: "udpu" + authkey: "6g4AqkD6s/1+CiH/6UWq78oMxXrkWd7wApBGsossAFy4smoFAIq5GUgTlwiz\nkzoPaSU7J7YSo9dmkZJv3oAWYCMPxpMBpWdleVZVyufomqPXKssfj0AwW0Gh\n5OBNcBToVaf6UD2dUSZiWnh2+3G30zdhqWwKrmcT2TVi8xJdCC8=\n" + +- name: node-2 + driver: + network: + - ["private_network", {ip: "192.168.33.34"}] + run_list: + - recipe[corosync::default] + attributes: + corosync: + cluster_name: test_cluster + bind_addr: "192.168.33.0" + members: ["192.168.33.33", "192.168.33.34"] + transport: "udpu" + authkey: "6g4AqkD6s/1+CiH/6UWq78oMxXrkWd7wApBGsossAFy4smoFAIq5GUgTlwiz\nkzoPaSU7J7YSo9dmkZJv3oAWYCMPxpMBpWdleVZVyufomqPXKssfj0AwW0Gh\n5OBNcBToVaf6UD2dUSZiWnh2+3G30zdhqWwKrmcT2TVi8xJdCC8=\n" diff --git a/chef/cookbooks/corosync/Berksfile b/chef/cookbooks/corosync/Berksfile new file mode 100644 index 00000000..0ac9b78c --- /dev/null +++ b/chef/cookbooks/corosync/Berksfile @@ -0,0 +1,3 @@ +source "https://supermarket.getchef.com" + +metadata diff --git a/chef/cookbooks/corosync/LICENSE b/chef/cookbooks/corosync/LICENSE new file mode 100644 index 00000000..ad5aed42 --- /dev/null +++ b/chef/cookbooks/corosync/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/chef/cookbooks/corosync/metadata.rb b/chef/cookbooks/corosync/metadata.rb index 546323cd..8fe74bfd 100644 --- a/chef/cookbooks/corosync/metadata.rb +++ b/chef/cookbooks/corosync/metadata.rb @@ -1,10 +1,13 @@ -name "corosync" -maintainer "SUSE, GmbH" -license "Apache 2.0" -description "Installs and configures a base corosync installation" -long_description IO.read(File.join(File.dirname(__FILE__), "README.md")) -version "1.1.0" +name "corosync" +maintainer "SUSE, GmbH" +license "Apache 2.0" +description "Installs and configures a base corosync installation" +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version "1.1.1" -%w(suse).each do |os| +depends "yum" +depends "yum-epel", '<= 0.6.0' + +%w{ redhat centos suse }.each do |os| supports os end From ac8c8a6cd50f52330371af4d737b3b4ab7c7b481 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:10:07 -0700 Subject: [PATCH 02/19] - The pacemaker plugin version in corosync config is now set based on platform_family. The version is kept at '0' on suse but on RHEL version '1' is used. - Reformat the template content --- .../templates/default/corosync.conf.erb | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/chef/cookbooks/corosync/templates/default/corosync.conf.erb b/chef/cookbooks/corosync/templates/default/corosync.conf.erb index 16f73120..45bbad5f 100644 --- a/chef/cookbooks/corosync/templates/default/corosync.conf.erb +++ b/chef/cookbooks/corosync/templates/default/corosync.conf.erb @@ -5,63 +5,65 @@ # Please read the corosync.conf.5 manual page service { - # http://blog.clusterlabs.org/blog/2010/introducing-the-pacemaker-master-control-process-for-corosync-based-clusters/ - ver: 0 <%# FIXME: what should this be for non-SUSE distros? %> - name: pacemaker + # http://blog.clusterlabs.org/blog/2010/introducing-the-pacemaker-master-control-process-for-corosync-based-clusters/ + ver: <%= node[:corosync][:pacemaker_plugin][:version] %> + name: pacemaker - # This is required for hb_gui (a.k.a. crm_gui) to work +<% if node.platform == 'suse' -%> + # This is required for hb_gui (a.k.a. crm_gui) to work use_mgmtd: yes use_logd: yes +<% end -%> } totem { - version: 2 + version: 2 - cluster_name: <%= @cluster_name %> + cluster_name: <%= @cluster_name %> - # How long before declaring a token lost (ms) - token: 5000 + # How long before declaring a token lost (ms) + token: 5000 - # How many token retransmits before forming a new configuration - token_retransmits_before_loss_const: 10 + # How many token retransmits before forming a new configuration + token_retransmits_before_loss_const: 10 - # How long to wait for join messages in the membership protocol (ms) - join: 60 + # How long to wait for join messages in the membership protocol (ms) + join: 60 - # How long to wait for consensus to be achieved before starting a new round of membership configuration (ms) - consensus: 6000 + # How long to wait for consensus to be achieved before starting a new round of membership configuration (ms) + consensus: 6000 - # Turn off the virtual synchrony filter - vsftype: none + # Turn off the virtual synchrony filter + vsftype: none - # Number of messages that may be sent by one processor on receipt of the token - max_messages: 20 + # Number of messages that may be sent by one processor on receipt of the token + max_messages: 20 - # Limit generated nodeids to 31-bits (positive signed integers) - clear_node_high_bit: new + # Limit generated nodeids to 31-bits (positive signed integers) + clear_node_high_bit: new - secauth: on + secauth: on - # This specifies the mode of redundant ring, which may be none, active, or passive. - rrp_mode: none + # This specifies the mode of redundant ring, which may be none, active, or passive. + rrp_mode: none - interface { - ringnumber: 0 - bindnetaddr: <%= @bind_addr %> + interface { + ringnumber: 0 + bindnetaddr: <%= @bind_addr %> <% if @transport == 'udp' -%> - mcastaddr: <%= @mcast_addr %> + mcastaddr: <%= @mcast_addr %> <% elsif @transport == 'udpu' -%> <% @members.sort.each do |memberaddr| -%> - member { - memberaddr: <%= memberaddr %> - } + member { + memberaddr: <%= memberaddr %> + } <% end -%> <% end -%> - mcastport: <%= @mcast_port %> - ttl: 1 - } + mcastport: <%= @mcast_port %> + ttl: 1 + } - transport: <%= @transport %> + transport: <%= @transport %> } amf { From ac8ea0d66be3443806b2538b1788a8bc2b1c4fa7 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:17:16 -0700 Subject: [PATCH 03/19] Add attributes necessary for RHEL support --- chef/cookbooks/corosync/attributes/default.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/chef/cookbooks/corosync/attributes/default.rb b/chef/cookbooks/corosync/attributes/default.rb index 7e4a9ff3..58bd9fce 100644 --- a/chef/cookbooks/corosync/attributes/default.rb +++ b/chef/cookbooks/corosync/attributes/default.rb @@ -1,4 +1,5 @@ # Copyright 2011, Dell, Inc. +# Copyright 2015, Ovais Tariq # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,14 +16,14 @@ default[:corosync][:cluster_name] = "hacluster" -default[:corosync][:bind_addr] = "192.168.124.0" +default[:corosync][:bind_addr ] = "192.168.124.0" default[:corosync][:mcast_addr] = "239.1.2.3" default[:corosync][:mcast_port] = 5405 default[:corosync][:members] = [] default[:corosync][:transport] = "udp" -case node.platform -when "suse" +case node["platform_family"] +when 'suse' if node.platform_version.to_f >= 12.0 default[:corosync][:platform][:packages] = %w(sle-ha-release corosync) default[:corosync][:platform][:service_name] = "corosync" @@ -34,10 +35,18 @@ # The UNIX user for the cluster is typically determined by the # cluster-glue package: default[:corosync][:platform][:packages].push "cluster-glue" -else - # FIXME: untested, probably wrong + + default[:corosync][:pacemaker_plugin][:version] = "0" +when 'rhel' default[:corosync][:platform][:packages] = %w(corosync) default[:corosync][:platform][:service_name] = "corosync" + default[:corosync][:pacemaker_plugin][:version] = "1" + + # Disabling sslverify for EPEL repository because of a bug with SSL verification + # on the 6.4 image, otherwise the package ca-certificates needs to be upgraded + # together with disabling the epel repo when upgrading + # sudo yum upgrade ca-certificates --disablerepo=epel + default['yum']['epel']['sslverify'] = false end # values should be 'yes' or 'no'. From 5c38dfc903246100fc393bf9483530351618f0ec Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:28:42 -0700 Subject: [PATCH 04/19] Add support to be able to use the authkey set as a node level attribute --- chef/cookbooks/corosync/recipes/authkey.rb | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/chef/cookbooks/corosync/recipes/authkey.rb b/chef/cookbooks/corosync/recipes/authkey.rb index 96002a65..6359d8f9 100644 --- a/chef/cookbooks/corosync/recipes/authkey.rb +++ b/chef/cookbooks/corosync/recipes/authkey.rb @@ -3,6 +3,7 @@ # Recipe:: authkey # # Copyright 2012, Rackspace US, Inc. +# Copyright 2015, Ovais Tariq # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +18,7 @@ # limitations under the License. # -require "base64" +require 'base64' if Chef::Config[:solo] Chef::Application.fatal! "This recipe uses search. Chef Solo does not support search." @@ -59,14 +60,27 @@ authkey_nodes = search(:node, query) log("nodes with authkey: #{authkey_nodes}") - if authkey_nodes.length == 0 - include_recipe "corosync::authkey_generator" - elsif authkey_nodes.length > 0 + if authkey_nodes.length > 0 authkey_node = authkey_nodes[0] + + if authkey_node[:corosync][:authkey] == nil + authkey_node = nil + end + end +end + +if authkey_node == nil + # If no pre-existing authkey can be found on other nodes, then try to + # check to see if the current node has authkey defined as attribute + # if it has the attribute then we use it + if node["corosync"]["authkey"] != nil + authkey_node = node + else + include_recipe "corosync::authkey_generator" end end -unless authkey_node.nil? +if authkey_node != nil log("Using corosync authkey from node: #{authkey_node.name}") authkey = authkey_node[:corosync][:authkey] From f1ca6ff233c4b6a4b05e8cb03eedb0d11d32e0b6 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:31:53 -0700 Subject: [PATCH 05/19] Use the new subscribes format --- chef/cookbooks/corosync/recipes/authkey_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chef/cookbooks/corosync/recipes/authkey_generator.rb b/chef/cookbooks/corosync/recipes/authkey_generator.rb index a7a06630..19808c87 100644 --- a/chef/cookbooks/corosync/recipes/authkey_generator.rb +++ b/chef/cookbooks/corosync/recipes/authkey_generator.rb @@ -56,6 +56,6 @@ # we didn't run corosync-keygen) unless node[:corosync][:authkey].nil? action :nothing - subscribes :create, resources(execute: "corosync-keygen"), :immediately + subscribes :create, 'execute[corosync-keygen]', :immediately end end From 4b947514727eec92a2c063ad6c0794d578734670 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:33:03 -0700 Subject: [PATCH 06/19] Add error handling to the authkey_writer so that it does not bork during compilation phase when authey is nil --- chef/cookbooks/corosync/recipes/authkey_writer.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/chef/cookbooks/corosync/recipes/authkey_writer.rb b/chef/cookbooks/corosync/recipes/authkey_writer.rb index ca5356d2..5795b298 100644 --- a/chef/cookbooks/corosync/recipes/authkey_writer.rb +++ b/chef/cookbooks/corosync/recipes/authkey_writer.rb @@ -3,6 +3,7 @@ # Recipe:: authkey_writer # # Copyright 2012, Rackspace US, Inc. +# Copyright 2015, Ovais Tariq # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,11 +18,13 @@ # limitations under the License. # -authkey = node[:corosync][:authkey] +require 'base64' + +authkey = node["corosync"]["authkey"] authkey_file = node[:corosync][:authkey_file] # decode so we can write out to file below -corosync_authkey = Base64.decode64(authkey) +corosync_authkey = Base64.decode64(authkey) if authkey != nil file authkey_file do content corosync_authkey From adf77feae70488a8a13d8bae4ea692211e610d7c Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:37:47 -0700 Subject: [PATCH 07/19] The corosync service must be restarted immediately after configuration. Minor code formatting. --- chef/cookbooks/corosync/recipes/config.rb | 27 ++++++++++------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/chef/cookbooks/corosync/recipes/config.rb b/chef/cookbooks/corosync/recipes/config.rb index 3ad05785..43116a5a 100644 --- a/chef/cookbooks/corosync/recipes/config.rb +++ b/chef/cookbooks/corosync/recipes/config.rb @@ -18,16 +18,13 @@ # # chef makes csync2 redundant -if platform_family? "suse" +case node["platform_family"] +when 'suse' service "csync2" do action [:stop, :disable] end -end - -if platform_family? "rhel" - # http://clusterlabs.org/quickstart.html - Chef::Application.fatal! "FIXME: RedHat-based platforms configure corosync via cluster.conf" - return +when 'rhel' + Chef::Log.warn("RedHat-based platforms configure corosync via cluster.conf") end unless %(udp udpu).include?(node[:corosync][:transport]) @@ -39,7 +36,7 @@ end template "/etc/corosync/corosync.conf" do - if node.platform == "suse" && node.platform_version.to_f >= 12.0 + if node["platform_family"] == "suse" && node["platform_version"].to_f >= 12.0 source "corosync.conf.v2.erb" else source "corosync.conf.erb" @@ -48,16 +45,16 @@ group "root" mode 0600 variables( - cluster_name: node[:corosync][:cluster_name], - bind_addr: node[:corosync][:bind_addr], - mcast_addr: node[:corosync][:mcast_addr], - mcast_port: node[:corosync][:mcast_port], - members: node[:corosync][:members], - transport: node[:corosync][:transport] + :cluster_name => node[:corosync][:cluster_name], + :bind_addr => node[:corosync][:bind_addr], + :mcast_addr => node[:corosync][:mcast_addr], + :mcast_port => node[:corosync][:mcast_port], + :members => node[:corosync][:members], + :transport => node[:corosync][:transport] ) service_name = node[:pacemaker][:platform][:service_name] rescue nil if service_name - notifies :restart, "service[#{service_name}]" + notifies :restart, "service[#{service_name}]", :immediately end end From d490ab289a569d588795cff06d7b8ee1caca3a41 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:39:03 -0700 Subject: [PATCH 08/19] Use new chef dsl syntax --- chef/cookbooks/corosync/recipes/firewall.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chef/cookbooks/corosync/recipes/firewall.rb b/chef/cookbooks/corosync/recipes/firewall.rb index 4bada854..74849d9f 100644 --- a/chef/cookbooks/corosync/recipes/firewall.rb +++ b/chef/cookbooks/corosync/recipes/firewall.rb @@ -17,14 +17,14 @@ # limitations under the License. # -case node.platform -when "suse" +case node["platform_family"] +when 'suse' template "/etc/sysconfig/SuSEfirewall2.d/services/cluster" do source "firewall.erb" mode "0640" owner "root" variables( - mcast_port: node[:corosync][:mcast_port] + :mcast_port => node[:corosync][:mcast_port] ) # FIXME: where do I get the name for this from? From 9eaab493fb4f636bf825fa198574a78ee471352f Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:41:12 -0700 Subject: [PATCH 09/19] Setup the yum EPEL repository on RHEL-based platforms as that has the required packages --- chef/cookbooks/corosync/recipes/install.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/chef/cookbooks/corosync/recipes/install.rb b/chef/cookbooks/corosync/recipes/install.rb index 041d7b40..96f7dda7 100644 --- a/chef/cookbooks/corosync/recipes/install.rb +++ b/chef/cookbooks/corosync/recipes/install.rb @@ -3,6 +3,7 @@ # Recipe:: client # # Copyright 2012, Rackspace US, Inc. +# Copyright 2015, Ovais Tariq # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,6 +18,13 @@ # limitations under the License. # +# Configure the necessary yum repositories for RHEL platform +case node["platform_family"] +when 'rhel' + include_recipe 'yum-epel' +end + +# Install the required pacakges node[:corosync][:platform][:packages].each do |pkg| package pkg do action :install From 5d37a071d8e1fb0bddaf2a521607cc28a0c7d4d4 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 18:57:38 -0700 Subject: [PATCH 10/19] The corosync user was being modified without being created first. The corosync init script that was being setup for non-suse platforms only needs to be setup for debian based distros --- chef/cookbooks/corosync/recipes/service.rb | 29 +++++++++++----------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/chef/cookbooks/corosync/recipes/service.rb b/chef/cookbooks/corosync/recipes/service.rb index 732e1fd5..5212edd1 100644 --- a/chef/cookbooks/corosync/recipes/service.rb +++ b/chef/cookbooks/corosync/recipes/service.rb @@ -21,25 +21,24 @@ include_recipe "corosync::config" include_recipe "corosync::authkey" -case node.platform -when %w(debian ubuntu) +case node['platform_family'] +when 'debian' template "/etc/default/corosync" do source "corosync.default.upstart.erb" owner "root" group "root" mode 0600 - variables(enable_openais_service: node["corosync"]["enable_openais_service"]) + variables(:enable_openais_service => node['corosync']['enable_openais_service']) end -end -unless node.platform == "suse" # This block is not really necessary because chef would automatically backup the file. # However, it's good to have the backup file in the same directory. (Easier to find later.) + # This block is only needed in case of debian based distributions ruby_block "backup corosync init script" do block do original_pathname = "/etc/init.d/corosync" backup_pathname = original_pathname + ".old" - FileUtils.cp(original_pathname, backup_pathname, preserve: true) + FileUtils.cp(original_pathname, backup_pathname, :preserve => true) end action :create notifies :create, "cookbook_file[/etc/init.d/corosync]", :immediately @@ -64,7 +63,7 @@ pkg = package rubygem_ruby_shadow do action :nothing end -pkg.run_action(:install) if node.platform == "suse" +pkg.run_action(:install) if node["platform_family"] == 'suse' # After installation of ruby-shadow, we have a new path for the new gem, so we # need to reset the paths if we can't load ruby-shadow @@ -75,7 +74,7 @@ end user node[:corosync][:user] do - action :modify + action :create # requires ruby-shadow gem password node[:corosync][:password] end @@ -111,7 +110,7 @@ "#{block_corosync_file} and run chef-client." end - if node.platform_family != "suse" || node.platform_version.to_f < 12.0 + if node["platform_family"] != "suse" || node["platform_version"].to_f < 12.0 # this service will remove the blocking file on proper shutdown template "/etc/init.d/#{corosync_shutdown}" do source "corosync-shutdown.init.erb" @@ -119,8 +118,8 @@ group "root" mode 0755 variables( - service_name: node[:corosync][:platform][:service_name], - block_corosync_file: block_corosync_file + :service_name => node[:corosync][:platform][:service_name], + :block_corosync_file => block_corosync_file ) end @@ -128,7 +127,7 @@ bash "insserv #{corosync_shutdown} service" do code "insserv #{corosync_shutdown}" action :nothing - subscribes :run, resources(template: "/etc/init.d/#{corosync_shutdown}"), :delayed + subscribes :run, resources(:template=> "/etc/init.d/#{corosync_shutdown}"), :delayed end else template "/etc/systemd/system/#{corosync_shutdown}.service" do @@ -161,7 +160,7 @@ action :disable end - if node.platform_family != "suse" || node.platform_version.to_f < 12.0 + if node["platform_family"] != "suse" || node["platform_version"]to_f < 12.0 file "/etc/init.d/#{corosync_shutdown}" do action :delete end @@ -185,8 +184,8 @@ end service node[:corosync][:platform][:service_name] do - supports restart: true, status: :true - if node.platform_family != "suse" || node.platform_version.to_f < 12.0 + supports :restart => true, :status => :true + if node["platform_family"] != "suse" || node["platform_version"].to_f < 12.0 action [enable_or_disable, :start] end end From 353a6d327b557e543fc18354cd7c0018f734da36 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 19:06:52 -0700 Subject: [PATCH 11/19] Update the README to reflect how the cookbook currently works --- chef/cookbooks/corosync/README.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/chef/cookbooks/corosync/README.md b/chef/cookbooks/corosync/README.md index 18ba0d06..7dd5bafa 100644 --- a/chef/cookbooks/corosync/README.md +++ b/chef/cookbooks/corosync/README.md @@ -1,10 +1,16 @@ -Description +Corosync =========== -This recipe provides a bare bones framework for Corosync. To use, -assign the `corosync::master` recipe to a single server and the -`corosync::client` recipe to the cluster members. +This cookbook configures and sets up Corosync. To use, assign +the `corosync::default` recipe to the cluster members. -The master node will generate the authkey for the cluster and store it -as a node attribute. Clients will search for this attribute and use -it for cluster communication. +The authkey is generated based on the following conditions: +- Is the node a founder node, this is checked by looking at +the attribute `node[:pacemaker][:founder]` +- Is there another founder node within the same cluster and +whether that particular node has already generated the authkey +- Does the current node have the authkey set as the attribute +`node[:corosync][:authkey]` + +Clients then use the `node[:corosync][:authkey]` attribute for +for cluster communication. From 8780bef4e502905880c455b584d9888419003f5e Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 19:09:52 -0700 Subject: [PATCH 12/19] Add testing doc --- chef/cookbooks/corosync/TESTING.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 chef/cookbooks/corosync/TESTING.md diff --git a/chef/cookbooks/corosync/TESTING.md b/chef/cookbooks/corosync/TESTING.md new file mode 100644 index 00000000..10b33dae --- /dev/null +++ b/chef/cookbooks/corosync/TESTING.md @@ -0,0 +1,29 @@ +TESTING doc +======================== + +Bundler +------- +A ruby environment with Bundler installed is a prerequisite for using +the testing harness shipped with this cookbook. At the time of this +writing, it works with Ruby 2.0 and Bundler 1.5.3. All programs +involved, with the exception of Vagrant, can be installed by cd'ing +into the parent directory of this cookbook and running "bundle install" + +Integration Testing +------------------- +Integration testing is performed by Test Kitchen. Test Kitchen will +use the Vagrant driver to instantiate machines and apply cookbooks. +After a successful converge, tests are uploaded and ran out of band of +Chef. Tests should be designed to ensure that a recipe has +accomplished its goal. + +Integration Testing using Vagrant +--------------------------------- +Integration tests can be performed on a local workstation using +Virtualbox or VMWare. Detailed instructions for setting this up can be +found at the [Bento](https://github.com/chef/bento) project web site. + +Integration tests using Vagrant can be performed with either +``` +bundle exec kitchen test +``` From b80201559b394dacc3ee0274bb35e75b75638cd8 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 19:10:45 -0700 Subject: [PATCH 13/19] Add Gemfile with the list of necessary gems --- chef/cookbooks/corosync/Gemfile | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 chef/cookbooks/corosync/Gemfile diff --git a/chef/cookbooks/corosync/Gemfile b/chef/cookbooks/corosync/Gemfile new file mode 100644 index 00000000..36e16e9d --- /dev/null +++ b/chef/cookbooks/corosync/Gemfile @@ -0,0 +1,20 @@ +source 'https://rubygems.org' + +group :common do + gem 'rspec' + gem 'rake' + gem 'berkshelf' +end + +group :kitchen_common do + gem 'test-kitchen', '~> 1.4' +end + +group :kitchen_vagrant do + gem 'kitchen-vagrant', '~> 0.16' +end + +group :kitchen_cloud do + gem 'kitchen-digitalocean' + gem 'kitchen-ec2' +end From d6978c6ea140e595c4030ba9a6892e5e35f4e0dd Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 19:52:27 -0700 Subject: [PATCH 14/19] Update the test platform from centos 6.4 to centos 6.6 --- chef/cookbooks/corosync/.kitchen.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chef/cookbooks/corosync/.kitchen.yml b/chef/cookbooks/corosync/.kitchen.yml index 940c1654..d1f87fc7 100644 --- a/chef/cookbooks/corosync/.kitchen.yml +++ b/chef/cookbooks/corosync/.kitchen.yml @@ -6,7 +6,7 @@ provisioner: name: chef_zero platforms: -- name: centos-6.4 +- name: centos-6.6 suites: - name: node-1 From 2016047a84af81007141aaf8b9a2f35a4a21efeb Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 19:53:01 -0700 Subject: [PATCH 15/19] Fix a typo in services recipe --- chef/cookbooks/corosync/recipes/service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chef/cookbooks/corosync/recipes/service.rb b/chef/cookbooks/corosync/recipes/service.rb index 5212edd1..2acccb8c 100644 --- a/chef/cookbooks/corosync/recipes/service.rb +++ b/chef/cookbooks/corosync/recipes/service.rb @@ -160,7 +160,7 @@ action :disable end - if node["platform_family"] != "suse" || node["platform_version"]to_f < 12.0 + if node["platform_family"] != "suse" || node["platform_version"].to_f < 12.0 file "/etc/init.d/#{corosync_shutdown}" do action :delete end From e9d815937aa913997cf104f41ea955d71689acba Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 20:01:14 -0700 Subject: [PATCH 16/19] Add Rakefile to do the integration tests as they involve converging more than 1 instances so that they can communicate with each other --- chef/cookbooks/corosync/Rakefile | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 chef/cookbooks/corosync/Rakefile diff --git a/chef/cookbooks/corosync/Rakefile b/chef/cookbooks/corosync/Rakefile new file mode 100644 index 00000000..86c19ba9 --- /dev/null +++ b/chef/cookbooks/corosync/Rakefile @@ -0,0 +1,53 @@ +require 'rspec/core/rake_task' +require 'rubocop/rake_task' +require 'foodcritic' +require 'kitchen' +require 'mixlib/shellout' +require 'kitchen/rake_tasks' + +# Integration tests. Kitchen.ci +namespace :integration do + desc 'Setup the test-kitchen vagrant instances' + task :vagrant_setup do + Kitchen.logger = Kitchen.default_file_logger + Kitchen::Config.new.instances.each do |instance| + # this happens serially because virualbox/vagrant can't handle + # parallel vm creation + instance.create() + + # Initial converge + instance.converge() + end + end + + desc 'Verify the test-kitchen vagrant instances' + task :vagrant_verify do + Kitchen.logger = Kitchen.default_file_logger + Kitchen::Config.new.instances.each do |instance| + # Run the integration tests now + instance.verify() + end + end +end + +# Clean up +namespace :cleanup do + desc 'Destroy test-kitchen instances' + task :kitchen_destroy do + destroy = Kitchen::RakeTasks.new do |obj| + def obj.destroy + config.instances.each(&:destroy) + end + end + destroy.destroy + end +end + +desc 'Clean up generated files' +task cleanup: ['cleanup:kitchen_destroy'] + +desc 'Run full integration' +task integration: ['integration:vagrant_setup', 'integration:vagrant_verify'] + +# Default +task default: ['integration', 'cleanup'] From 4b105ed7038a85a05e778688604ea6dc21a23bad Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 20:01:47 -0700 Subject: [PATCH 17/19] Update TESTING doc to use rake for testing --- chef/cookbooks/corosync/TESTING.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/chef/cookbooks/corosync/TESTING.md b/chef/cookbooks/corosync/TESTING.md index 10b33dae..964e32af 100644 --- a/chef/cookbooks/corosync/TESTING.md +++ b/chef/cookbooks/corosync/TESTING.md @@ -9,6 +9,24 @@ writing, it works with Ruby 2.0 and Bundler 1.5.3. All programs involved, with the exception of Vagrant, can be installed by cd'ing into the parent directory of this cookbook and running "bundle install" +Rakefile +-------- +The Rakefile ships with a number of tasks, each of which can be ran +individually, or in groups. Typing "rake" by itself will perform style +checks with Rubocop and Foodcritic, ChefSpec with rspec, and +integration with Test Kitchen using the Vagrant driver by +default.Alternatively, integration tests can be ran with Test Kitchen +cloud drivers. + +``` +$ rake -T +rake cleanup # Clean up generated files +rake cleanup:kitchen_destroy # Destroy test-kitchen instances +rake integration # Run full integration +rake integration:vagrant_setup # Setup the test-kitchen vagrant instances +rake integration:vagrant_verify # Verify the test-kitchen vagrant instances +``` + Integration Testing ------------------- Integration testing is performed by Test Kitchen. Test Kitchen will @@ -23,7 +41,7 @@ Integration tests can be performed on a local workstation using Virtualbox or VMWare. Detailed instructions for setting this up can be found at the [Bento](https://github.com/chef/bento) project web site. -Integration tests using Vagrant can be performed with either +Integration tests using Vagrant can be performed with ``` -bundle exec kitchen test +bundle exec rake integration ``` From 29e9426949f851cf961bbe97f5b1ce740a515c40 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Tue, 1 Sep 2015 20:05:16 -0700 Subject: [PATCH 18/19] Fixes #9 --- chef/cookbooks/corosync/metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chef/cookbooks/corosync/metadata.rb b/chef/cookbooks/corosync/metadata.rb index 8fe74bfd..88de9641 100644 --- a/chef/cookbooks/corosync/metadata.rb +++ b/chef/cookbooks/corosync/metadata.rb @@ -3,7 +3,7 @@ license "Apache 2.0" description "Installs and configures a base corosync installation" long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "1.1.1" +version "1.1.2" depends "yum" depends "yum-epel", '<= 0.6.0' From a7b605b45026f5c45d6e722dc00e0ac3a45ed259 Mon Sep 17 00:00:00 2001 From: Ovais Tariq Date: Thu, 3 Sep 2015 18:30:44 -0700 Subject: [PATCH 19/19] Fix style issues reported by houndci --- chef/cookbooks/corosync/recipes/config.rb | 16 ++++++++-------- chef/cookbooks/corosync/recipes/firewall.rb | 4 ++-- chef/cookbooks/corosync/recipes/install.rb | 6 +++--- chef/cookbooks/corosync/recipes/service.rb | 18 +++++++++--------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/chef/cookbooks/corosync/recipes/config.rb b/chef/cookbooks/corosync/recipes/config.rb index 43116a5a..5f1da6b9 100644 --- a/chef/cookbooks/corosync/recipes/config.rb +++ b/chef/cookbooks/corosync/recipes/config.rb @@ -19,11 +19,11 @@ # chef makes csync2 redundant case node["platform_family"] -when 'suse' +when "suse" service "csync2" do action [:stop, :disable] end -when 'rhel' +when "rhel" Chef::Log.warn("RedHat-based platforms configure corosync via cluster.conf") end @@ -45,12 +45,12 @@ group "root" mode 0600 variables( - :cluster_name => node[:corosync][:cluster_name], - :bind_addr => node[:corosync][:bind_addr], - :mcast_addr => node[:corosync][:mcast_addr], - :mcast_port => node[:corosync][:mcast_port], - :members => node[:corosync][:members], - :transport => node[:corosync][:transport] + cluster_name: node[:corosync][:cluster_name], + bind_addr: node[:corosync][:bind_addr], + mcast_addr: node[:corosync][:mcast_addr], + mcast_port: node[:corosync][:mcast_port], + members: node[:corosync][:members], + transport: node[:corosync][:transport] ) service_name = node[:pacemaker][:platform][:service_name] rescue nil diff --git a/chef/cookbooks/corosync/recipes/firewall.rb b/chef/cookbooks/corosync/recipes/firewall.rb index 74849d9f..5884d56a 100644 --- a/chef/cookbooks/corosync/recipes/firewall.rb +++ b/chef/cookbooks/corosync/recipes/firewall.rb @@ -18,13 +18,13 @@ # case node["platform_family"] -when 'suse' +when "suse" template "/etc/sysconfig/SuSEfirewall2.d/services/cluster" do source "firewall.erb" mode "0640" owner "root" variables( - :mcast_port => node[:corosync][:mcast_port] + mcast_port: node["corosync"]["mcast_port"] ) # FIXME: where do I get the name for this from? diff --git a/chef/cookbooks/corosync/recipes/install.rb b/chef/cookbooks/corosync/recipes/install.rb index 96f7dda7..8151811f 100644 --- a/chef/cookbooks/corosync/recipes/install.rb +++ b/chef/cookbooks/corosync/recipes/install.rb @@ -20,12 +20,12 @@ # Configure the necessary yum repositories for RHEL platform case node["platform_family"] -when 'rhel' - include_recipe 'yum-epel' +when "rhel" + include_recipe "yum-epel" end # Install the required pacakges -node[:corosync][:platform][:packages].each do |pkg| +node["corosync"]["platform"]["packages"].each do |pkg| package pkg do action :install end diff --git a/chef/cookbooks/corosync/recipes/service.rb b/chef/cookbooks/corosync/recipes/service.rb index 2acccb8c..5a3d666a 100644 --- a/chef/cookbooks/corosync/recipes/service.rb +++ b/chef/cookbooks/corosync/recipes/service.rb @@ -21,14 +21,14 @@ include_recipe "corosync::config" include_recipe "corosync::authkey" -case node['platform_family'] -when 'debian' +case node["platform_family"] +when "debian" template "/etc/default/corosync" do source "corosync.default.upstart.erb" owner "root" group "root" mode 0600 - variables(:enable_openais_service => node['corosync']['enable_openais_service']) + variables(enable_openais_service: node['corosync']['enable_openais_service']) end # This block is not really necessary because chef would automatically backup the file. @@ -38,7 +38,7 @@ block do original_pathname = "/etc/init.d/corosync" backup_pathname = original_pathname + ".old" - FileUtils.cp(original_pathname, backup_pathname, :preserve => true) + FileUtils.cp(original_pathname, backup_pathname, preserve: true) end action :create notifies :create, "cookbook_file[/etc/init.d/corosync]", :immediately @@ -63,7 +63,7 @@ pkg = package rubygem_ruby_shadow do action :nothing end -pkg.run_action(:install) if node["platform_family"] == 'suse' +pkg.run_action(:install) if node["platform_family"] == "suse" # After installation of ruby-shadow, we have a new path for the new gem, so we # need to reset the paths if we can't load ruby-shadow @@ -118,8 +118,8 @@ group "root" mode 0755 variables( - :service_name => node[:corosync][:platform][:service_name], - :block_corosync_file => block_corosync_file + service_name: node["corosync"]["platform"]["service_name"], + block_corosync_file: block_corosync_file ) end @@ -127,7 +127,7 @@ bash "insserv #{corosync_shutdown} service" do code "insserv #{corosync_shutdown}" action :nothing - subscribes :run, resources(:template=> "/etc/init.d/#{corosync_shutdown}"), :delayed + subscribes :run, resources(template: "/etc/init.d/#{corosync_shutdown}"), :delayed end else template "/etc/systemd/system/#{corosync_shutdown}.service" do @@ -184,7 +184,7 @@ end service node[:corosync][:platform][:service_name] do - supports :restart => true, :status => :true + supports restart: true, status: true if node["platform_family"] != "suse" || node["platform_version"].to_f < 12.0 action [enable_or_disable, :start] end