Merge "Scale up logic with extra IP addresses for pcs 0.10"

This commit is contained in:
Zuul 2019-07-19 12:44:57 +00:00 committed by Gerrit Code Review
commit 4c06196391
3 changed files with 135 additions and 30 deletions

View File

@ -5,7 +5,10 @@ module Puppet::Parser::Functions
arity: -1,
doc: <<-eof
Input data cluster_members string separated by a space:
* String 'n1 n2 n3'
* String A space-separated string containing a list of node names
* String A list containing either a single string (single ip) or a list of strings
(multiple ipaddresses) associated to each cluster node
* String the version of pcs used
* Output of `crm_node -l` (only used to ease unit testing) (optional)
Output forms:
@ -17,13 +20,20 @@ Output forms:
# no point in doing this if the crm_node executable does not exist
return [] if Facter::Util::Resolution.which('crm_node') == nil
nodes = args[0]
crm_node_list = args[1]
addr_list = args[1]
pcs_version = args[2]
crm_node_list = args[3]
unless nodes.is_a? String
fail "Got unsupported nodes input data: #{nodes.inspect}"
end
unless addr_list.is_a? Array
fail "Got unsupported addr_list input data: #{addr_list.inspect}"
end
if crm_node_list && !crm_node_list.kind_of?(String) then
fail "Got unsupported crm_node_list #{crm_node_list.inspect}"
end
node_list = nodes.split()
fail "pcmk_cluster_setup: node list and addr list should be of the same size when defined and not empty" if addr_list.size > 0 and addr_list.size != node_list.size
if crm_node_list && crm_node_list.kind_of?(String) then
return [] if crm_node_list.empty?
@ -46,9 +56,45 @@ Output forms:
state.downcase! if state
crm_nodes.push(node.strip) if valid_states.include? state
}
cluster_nodes = nodes.split(" ")
nodes_added = cluster_nodes - crm_nodes
Puppet.debug("pcmk_nodes_added: #{nodes_added}")
nodes_added
nodes_added = node_list - crm_nodes
if pcs_version =~ /0.10/
# If the addr_list was specified we need to return a list in the form of
# ['node1 addr=1.2.3.4', 'node2 addr=1.2.3.5 addr=1.2.3.6', 'node3 addr=1.2.3.7']
if addr_list.size > 0
ret = []
nodes_addrs_added = node_list.zip(addr_list)
.select { |node_addr| nodes_added.include?(node_addr[0]) }
nodes_addrs_added.each do |node_addr|
node = node_addr[0]
ip = node_addr[1]
# addr can be '1.2.3.4' or ['1.2.3.4', '1.2.3.5'] or
if ip.is_a? String
addr = "addr=#{ip}"
elsif ip.is_a? Array
addr = ''
ip.each do |i|
addr += "addr=#{i}"
addr += " " if not i.equal?(ip.last)
end
else
fail "pcmk_nodes_added: One of the addresses in addr_list is neither a String nor an Array"
end
ret << "#{node} #{addr}"
end
# only node_added is specified so we just return the original string
else
ret = nodes_added
end
elsif pcs_version =~ /0.9/
# With pcs 0.9 only non-knet clusters are supported, aka only one address can be used
# so we take the node name as we always did
ret = nodes_added
else
fail("pcmk_nodes_added: pcs #{pcs_version} is unsupported")
end
Puppet.debug("pcmk_nodes_added: #{ret}")
ret
end
end

View File

@ -227,23 +227,30 @@ class pacemaker::corosync(
if $setup_cluster {
# Detect if we are trying to add some nodes by comparing
# $cluster_members and the actual running nodes in the cluster
$nodes_added = pcmk_nodes_added($cluster_members)
if $::pacemaker::pcs_010 {
$nodes_added = pcmk_nodes_added($cluster_members, $cluster_members_addr, '0.10')
$node_add_start_part = '--start'
} else {
$nodes_added = pcmk_nodes_added($cluster_members, $cluster_members_addr, '0.9')
$node_add_start_part = ''
}
# If we're rerunning this puppet manifest and $cluster_members
# contains more nodes than the currently running cluster
if count($nodes_added) > 0 {
$nodes_added.each |$node_to_add| {
$node_name = split($node_to_add, ' ')[0]
exec {"Adding Cluster node: ${node_to_add} to Cluster ${cluster_name}":
unless => "${::pacemaker::pcs_bin} status 2>&1 | grep -e \"^Online:.* ${node_to_add} .*\"",
command => "${::pacemaker::pcs_bin} cluster node add ${node_to_add} --wait",
unless => "${::pacemaker::pcs_bin} status 2>&1 | grep -e \"^Online:.* ${node_name} .*\"",
command => "${::pacemaker::pcs_bin} cluster node add ${node_to_add} ${node_add_start_part} --wait",
timeout => $cluster_start_timeout,
tries => $cluster_start_tries,
try_sleep => $cluster_start_try_sleep,
notify => Exec["node-cluster-start-${node_to_add}"],
notify => Exec["node-cluster-start-${node_name}"],
tag => 'pacemaker-scaleup',
}
exec {"node-cluster-start-${node_to_add}":
unless => "${::pacemaker::pcs_bin} status 2>&1 | grep -e \"^Online:.* ${node_to_add} .*\"",
command => "${::pacemaker::pcs_bin} cluster start ${node_to_add} --wait",
exec {"node-cluster-start-${node_name}":
unless => "${::pacemaker::pcs_bin} status 2>&1 | grep -e \"^Online:.* ${node_name} .*\"",
command => "${::pacemaker::pcs_bin} cluster start ${node_name} --wait",
timeout => $cluster_start_timeout,
tries => $cluster_start_tries,
try_sleep => $cluster_start_try_sleep,

View File

@ -1,31 +1,83 @@
require 'spec_helper'
shared_examples_for 'pcmk_nodes_added without addrs' do |pcs_version|
it 'returns no added nodes because cluster is not set up' do
is_expected.to run.with_params('foo', [], pcs_version, '').and_return([])
is_expected.to run.with_params('foo bar', [], pcs_version, '').and_return([])
is_expected.to run.with_params('', [], pcs_version, '').and_return([])
end
it 'returns added nodes when cluster is fully up' do
crm_out = "\n3 ctr-2 member\n2 ctr-1 member\n1 ctr-0 member\n"
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2', [], pcs_version, crm_out).and_return([])
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2 ctr-3', [], pcs_version, crm_out).and_return(['ctr-3'])
is_expected.to run.with_params('ctr-1 ctr-3 ctr-2', [], pcs_version, crm_out).and_return(['ctr-3'])
is_expected.to run.with_params('', [], pcs_version, crm_out).and_return([])
end
it 'returns added nodes when cluster is not fully up' do
crm_out = "\n3 ctr-2 lost\n2 ctr-1 member\n1 ctr-0 member\n"
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2', [], pcs_version, crm_out).and_return([])
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2 ctr-3', [], pcs_version, crm_out).and_return(['ctr-3'])
is_expected.to run.with_params('ctr-1 ctr-3 ctr-2', [], pcs_version, crm_out).and_return(['ctr-3'])
is_expected.to run.with_params('', [], pcs_version, crm_out).and_return([])
end
end
describe 'pcmk_nodes_added' do
context 'interface' do
it { is_expected.not_to eq(nil) }
it { is_expected.to run.with_params(1).and_raise_error(Puppet::Error, /Got unsupported nodes input data/) }
it { is_expected.to run.with_params('foo', []).and_raise_error(Puppet::Error, /Got unsupported crm_node_list/) }
it { is_expected.to run.with_params('foo', 'bar').and_raise_error(Puppet::Error, /Got unsupported addr_list input data/) }
it { is_expected.to run.with_params('foo bar', ['1.2.3.4']).and_raise_error(Puppet::Error, /should be of the same size/) }
it { is_expected.to run.with_params('foo', [], '0.9', []).and_raise_error(Puppet::Error, /Got unsupported crm_node_list/) }
end
it 'returns no added nodes because cluster is not set up' do
is_expected.to run.with_params('foo', '').and_return([])
is_expected.to run.with_params('foo bar', '').and_return([])
is_expected.to run.with_params('', '').and_return([])
context 'with pcs 0.9' do
include_examples 'pcmk_nodes_added without addrs', '0.9'
end
it 'returns added nodes when cluster is fully up' do
crm_out = "\n3 ctr-2 member\n2 ctr-1 member\n1 ctr-0 member\n"
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2', crm_out).and_return([])
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2 ctr-3', crm_out).and_return(['ctr-3'])
is_expected.to run.with_params('ctr-1 ctr-3 ctr-2', crm_out).and_return(['ctr-3'])
is_expected.to run.with_params('', crm_out).and_return([])
context 'with pcs 0.10, without addr list' do
include_examples 'pcmk_nodes_added without addrs', '0.10'
end
it 'returns added nodes when cluster is not fully up' do
crm_out = "\n3 ctr-2 lost\n2 ctr-1 member\n1 ctr-0 member\n"
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2', crm_out).and_return([])
is_expected.to run.with_params('ctr-0 ctr-1 ctr-2 ctr-3', crm_out).and_return(['ctr-3'])
is_expected.to run.with_params('ctr-1 ctr-3 ctr-2', crm_out).and_return(['ctr-3'])
is_expected.to run.with_params('', crm_out).and_return([])
context 'with pcs 0.10 and addr list' do
let (:pcs_version) { '0.10' }
let (:nodes_1) { 'ctr-0' }
let (:nodes_2) { 'ctr-0 ctr-1' }
let (:nodes_3) { 'ctr-0 ctr-1 ctr-2' }
let (:nodes_4) { 'ctr-0 ctr-1 ctr-2 ctr-3' }
let (:nodes_4_alt) { 'ctr-3 ctr-0 ctr-2 ctr-1' }
let (:addrs_1) { ['1.2.3.4'] }
let (:addrs_2) { ['1.2.3.4', ['1.2.3.5', '1.2.3.6']] }
let (:addrs_3) { ['1.2.3.4', ['1.2.3.5', '1.2.3.6'], '1.2.3.7'] }
let (:addrs_4) { ['1.2.3.4', ['1.2.3.5', '1.2.3.6'], '1.2.3.7', ['1.2.3.8', '1.2.3.9']] }
let (:addrs_4_alt) { ['1.2.3.8', '1.2.3.4', '1.2.3.7', ['1.2.3.5', '1.2.3.6']] }
it 'returns no added nodes because cluster is not set up' do
is_expected.to run.with_params(nodes_1, addrs_1, pcs_version, '').and_return([])
is_expected.to run.with_params(nodes_2, addrs_2, pcs_version, '').and_return([])
is_expected.to run.with_params('', [], pcs_version, '').and_return([])
end
it 'returns added nodes when cluster is fully up' do
crm_out = "\n3 ctr-2 member\n2 ctr-1 member\n1 ctr-0 member\n"
is_expected.to run.with_params(nodes_3, addrs_3, pcs_version, crm_out).and_return([])
is_expected.to run.with_params(nodes_4, addrs_4, pcs_version, crm_out).and_return(['ctr-3 addr=1.2.3.8 addr=1.2.3.9'])
is_expected.to run.with_params(nodes_4_alt, addrs_4_alt, pcs_version, crm_out).and_return(['ctr-3 addr=1.2.3.8'])
is_expected.to run.with_params('', [], pcs_version, crm_out).and_return([])
end
it 'returns multiple added nodes' do
crm_out = "\n1 ctr-0 member\n"
is_expected.to run.with_params(nodes_4, addrs_4, pcs_version, crm_out).and_return(['ctr-1 addr=1.2.3.5 addr=1.2.3.6', 'ctr-2 addr=1.2.3.7', 'ctr-3 addr=1.2.3.8 addr=1.2.3.9'])
end
it 'returns added nodes when cluster is not fully up' do
crm_out = "\n3 ctr-2 lost\n2 ctr-1 member\n1 ctr-0 member\n"
is_expected.to run.with_params(nodes_3, addrs_3, pcs_version, crm_out).and_return([])
is_expected.to run.with_params(nodes_4, addrs_4, pcs_version, crm_out).and_return(['ctr-3 addr=1.2.3.8 addr=1.2.3.9'])
is_expected.to run.with_params('', [], pcs_version, crm_out).and_return([])
end
end
end