From a10a3ad46145c19343adb3ed4ba3f649c0a529ed Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Thu, 12 Dec 2013 22:59:32 +0000 Subject: [PATCH] merge pacemaker cookbooks Preliminary merge of git://github.com/ktc-itsnotbutter/pacemaker.git (in the chef/cookbooks/pacemaker/ directory) with the cookbook from the pacemaker_service branch of: https://github.com/mattray/barclamp_ha_service.git (in the chef/cookbooks/pacemaker2/ directory) since both forks had some nice stuff. This merge is not complete yet. --- README.md | 2 +- attributes/default.rb | 15 ++++++ examples/roles/pacemaker-active.rb | 22 +++++++++ examples/roles/pacemaker.rb | 14 ++++++ files/default/corosync | 3 ++ metadata.rb | 6 +-- providers/service.rb | 68 +++++++++++++++++++++++++ recipes/client.rb | 29 +++++++++++ recipes/master.rb | 43 ++++++++++++++++ recipes/services.rb | 34 +++++++++++++ resources/service.rb | 26 ++++++++++ templates/default/corosync.conf.erb | 77 +++++++++++++++++++++++++++++ templates/default/ha.cf.erb | 20 ++++++++ 13 files changed, 355 insertions(+), 4 deletions(-) create mode 100644 examples/roles/pacemaker-active.rb create mode 100644 examples/roles/pacemaker.rb create mode 100644 files/default/corosync create mode 100644 providers/service.rb create mode 100644 recipes/client.rb create mode 100644 recipes/master.rb create mode 100644 recipes/services.rb create mode 100644 resources/service.rb create mode 100644 templates/default/corosync.conf.erb create mode 100644 templates/default/ha.cf.erb diff --git a/README.md b/README.md index e7c5175..195023d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Description +DESCRIPTION =========== This is a cookbook for installing and configuring pacemaker. diff --git a/attributes/default.rb b/attributes/default.rb index 1f8a6a7..3881562 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -1,3 +1,17 @@ +# Copyright 2011, Dell, Inc. +# +# 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. +# # Only use short hostname (not FQDN) default['pacemaker']['nodes'] = ['node1', 'node2'] @@ -79,3 +93,4 @@ default['pacemaker']['order']['o-lvm']['resources'] = ['drbd-cluster', 'clvm-clo default['pacemaker']['order']['o-lvm']['active'] = "#{pacemaker['nodes']}" default['pacemaker']['property']['no-quorum-policy'] = "ignore" +default['pacemaker']['services'] = {} diff --git a/examples/roles/pacemaker-active.rb b/examples/roles/pacemaker-active.rb new file mode 100644 index 0000000..664452d --- /dev/null +++ b/examples/roles/pacemaker-active.rb @@ -0,0 +1,22 @@ +name "pacemaker-active" +description "pacemaker active." + +override_attributes( + "pacemaker" => { + "services" => { + "apache2" => { + "vip" => "10.0.111.5", + "active" => "ubuntu1-1004.vm" + }, + "mysql" => { + "vip" => "10.0.111.7", + "passive" => ["ubuntu1-1004.vm"] + } + } + } + ) + +run_list( + "recipe[pacemaker::master]", + "recipe[pacemaker::services]" + ) diff --git a/examples/roles/pacemaker.rb b/examples/roles/pacemaker.rb new file mode 100644 index 0000000..cd42c0a --- /dev/null +++ b/examples/roles/pacemaker.rb @@ -0,0 +1,14 @@ +name "pacemaker-passive" +description "pacemaker passive." + +override_attributes( + "pacemaker" => { + "services" => { + } + } + ) + +run_list( + "recipe[pacemaker::client]", + "recipe[pacemaker::services]" + ) diff --git a/files/default/corosync b/files/default/corosync new file mode 100644 index 0000000..d397f9e --- /dev/null +++ b/files/default/corosync @@ -0,0 +1,3 @@ +# managed by Chef +# start corosync at boot [yes|no] +START=yes diff --git a/metadata.rb b/metadata.rb index f22b9fe..da2e096 100644 --- a/metadata.rb +++ b/metadata.rb @@ -1,7 +1,7 @@ name "pacemaker" -maintainer "Robert Choi" -maintainer_email "taeilchoi1@gmail.com" +maintainer "Crowbar Project" +maintainer_email "crowbar@dell.com" license "Apache 2.0" -description "Installs/Configures Pacemaker" +description "Installs/configures Pacemaker" long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version "0.1" diff --git a/providers/service.rb b/providers/service.rb new file mode 100644 index 0000000..b63b67c --- /dev/null +++ b/providers/service.rb @@ -0,0 +1,68 @@ +# +# Author:: Matt Ray () +# Cookbook Name:: pacemaker +# Provider:: service +# +# Copyright:: 2011, Opscode, Inc +# +# 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. +# + +# actions :create, :remove + +# attribute :service, :kind_of => String, :name_attribute => true +# attribute :vip, :kind_of => String +# attribute :active, :default => false +# attribute :path, :kind_of => String + +action :create do + service = new_resource.service + vip = new_resource.vip + active = new_resource.active + path = new_resource.path + Chef::Log.info "pacemaker_service #{service} #{vip} #{active} #{path}" + oldservice = node['pacemaker']['services'][service] + newservice = {} + newservice['vip'] = vip + if active + newservice['active'] = node.name + else + #search for active? + #newservice['active'] = + if oldservice + newservice['active'] = oldservice['active'] + newservice['passive'] = oldservice['passive'] + newservice['passive'].push(node.name) + newservice['passive'].uniq!.sort! + else + newservice['passive'] = [node.name] + end + end + #compare with previous state + if newservice != oldservice + #put the service into the attributes of the node + node['pacemaker']['services'][service] = newservice + #figure out how pacemaker handles services + new_resource.updated_by_last_action(true) + end +end + +action :remove do + service = new_resource.service + if node['pacemaker']['services'][service] + #remove the parameters into the attributes of the node + node['pacemaker']['services'].delete(service) + #figure out how to restore services from pacemaker control + new_resource.updated_by_last_action(true) + end +end diff --git a/recipes/client.rb b/recipes/client.rb new file mode 100644 index 0000000..0803a64 --- /dev/null +++ b/recipes/client.rb @@ -0,0 +1,29 @@ +require 'base64' + +# Install haveged to create entropy so keygen doesn't take an hour +%w{ corosync pacemaker }.each do |pkg| + package pkg +end + +authkey = "" + +# Find the master node: +if !File.exists?("/etc/corosync/authkey") + master = search(:node, "corosync:authkey") + if master.nil? or (master.length > 1) + Chef::Application.fatal! "You must have one node with the pacemaker::master recipe in their run list to be a client." + end + Chef::Log.info "Found pacemaker::master node: #{master[0].name}" + authkey = Base64.decode64(master[0]['corosync']['authkey']) +end + +file "/etc/corosync/authkey" do + not_if {File.exists?("/etc/corosync/authkey")} + content authkey + owner "root" + mode "0400" + action :create +end + +#manage the corosync services +include_recipe "pacemaker::default" diff --git a/recipes/master.rb b/recipes/master.rb new file mode 100644 index 0000000..09684dc --- /dev/null +++ b/recipes/master.rb @@ -0,0 +1,43 @@ +require 'base64' + +# Install haveged to create entropy so keygen doesn't take an hour +# odd errors coming out of automated installation, gets restarted next +package "haveged" do + ignore_failure true +end + +%w{ corosync pacemaker }.each do |pkg| + package pkg +end + +service "haveged" do + supports :restart => true, :status => :true + action [:enable, :start] +end + +#create authkey +execute "corosync-keygen" do + creates "/etc/corosync/authkey" + user "root" + umask "0400" + action :run +end + +# Read authkey (it's binary) into encoded format and save to chef server +ruby_block "Store authkey" do + block do + file = File.new('/etc/corosync/authkey', 'r') + contents = "" + file.each do |f| + contents << f + end + packed = Base64.encode64(contents) + node.set_unless['corosync']['authkey'] = packed + node.save + end + action :nothing + subscribes :create, resources(:execute => "corosync-keygen"), :immediately +end + +#manage the corosync services +include_recipe "pacemaker::default" diff --git a/recipes/services.rb b/recipes/services.rb new file mode 100644 index 0000000..34fe4ae --- /dev/null +++ b/recipes/services.rb @@ -0,0 +1,34 @@ +# +# Author:: Matt Ray () +# Cookbook Name:: pacemaker +# Recipe:: services +# +# Copyright 2011, Opscode, Inc. +# +# 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. +# + +node['pacemaker']['services'].keys.each do |svc| + Chef::Log.debug "Pacemaker::services #{svc}" + Chef::Log.debug node['pacemaker']['services'][svc] + isactive = false + if node['pacemaker']['services'][svc]['active'].eql?(node.name) + isactive = true + end + pacemaker_service svc do + vip node['pacemaker']['services'][svc]['vip'] + active isactive + path node['pacemaker']['services'][svc]['path'] + action :create + end +end diff --git a/resources/service.rb b/resources/service.rb new file mode 100644 index 0000000..354919d --- /dev/null +++ b/resources/service.rb @@ -0,0 +1,26 @@ +# +# Author:: Matt Ray () +# Cookbook Name:: pacemaker +# Resource:: service +# +# Copyright:: 2011, Opscode, Inc +# +# 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. +# + +actions :create, :remove + +attribute :service, :kind_of => String, :name_attribute => true +attribute :vip, :kind_of => String +attribute :active, :default => false +attribute :path, :kind_of => String diff --git a/templates/default/corosync.conf.erb b/templates/default/corosync.conf.erb new file mode 100644 index 0000000..8d2d52d --- /dev/null +++ b/templates/default/corosync.conf.erb @@ -0,0 +1,77 @@ +# Dynamically generated by Chef on <%= node["fqdn"] %> +# Please read the openais.conf.5 manual page + +totem { + version: 2 + + # How long before declaring a token lost (ms) + token: 3000 + + # 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 consensus to be achieved before starting a new round of membership configuration (ms) + consensus: 5000 + + # 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 + + # Limit generated nodeids to 31-bits (positive signed integers) + clear_node_high_bit: yes + + # Disable encryption + secauth: off + + # How many threads to use for encryption/decryption + threads: 0 + + # Optionally assign a fixed node id (integer) + # nodeid: 1234 + + # This specifies the mode of redundant ring, which may be none, active, or passive. + rrp_mode: none + + interface { + # The following values need to be set based on your environment + ringnumber: 0 + bindnetaddr: <%= @bindnetaddr %> + mcastaddr: 226.94.1.1 + mcastport: 5405 + } +} + +amf { + mode: disabled +} + +service { + # Load the Pacemaker Cluster Resource Manager + ver: 0 + name: pacemaker +} + +aisexec { + user: root + group: root +} + +logging { + fileline: off + to_stderr: yes + to_logfile: no + to_syslog: yes + syslog_facility: daemon + debug: off + timestamp: on + logger_subsys { + subsys: AMF + debug: off + tags: enter|leave|trace1|trace2|trace3|trace4|trace6 + } +} diff --git a/templates/default/ha.cf.erb b/templates/default/ha.cf.erb new file mode 100644 index 0000000..92038d1 --- /dev/null +++ b/templates/default/ha.cf.erb @@ -0,0 +1,20 @@ +# Logging +debug 1 +use_logd false +logfacility daemon + +# Misc Options +traditional_compression off +compression bz2 +coredumps true + +# Communications +udpport 691 +bcast eth0 +autojoin any + +# Thresholds (in seconds) +keepalive 1 +warntime 6 +deadtime 10 +initdead 15 \ No newline at end of file