Relax requires when creating resources on remote nodes

In the composable HA architecture we must be able to create
properties and resources from a pacemaker remote node (which
does not have neither corosync nor pacemaker running).
In order to be able to do that we need to relax the requires
and remove the "Exec['wait-for-settle']" which only exists
in the corosync class, which does not exist on a pacemaker remote
node.

The onus is on the user to make sure that the cluster is functional
before trying to create a resource from a pacemaker remote node.
In TripleO we do this by creating the resources only on step2.

The pacemaker_remote configuration for the remote node itself was
never really designed in to the current module, so tweaking the
existing corosync class to cater for remote nodes would mean rewriting
most of the class and is not worth it when we are actually trying
to merge with the "new" puppet pacemaker module in the future.

Currently the pacemaker_remote node configuration happens in a tripleo
profile: I92953afcc7d536d387381f08164cae8b52f41605

Note: Creating resources on a pacemaker remote node only works
with pcs-0.9.152 or later (CentOS/RHEL 7.3 and later)

Change-Id: I5379b804757d23cae694943b54e7d9256f3ca669
This commit is contained in:
Michele Baldessari
2016-12-07 22:09:47 +01:00
parent 9eb4361b6a
commit b4e3b88ba9
12 changed files with 61 additions and 22 deletions

View File

@@ -0,0 +1,8 @@
require 'facter'
Facter.add('pcmk_is_remote') do
setcode do
systemd_pcmk_remote = `/usr/bin/systemctl is-active pacemaker_remote`
systemd_pcmk_remote.downcase.chomp == 'active'
end
end

View File

@@ -112,13 +112,16 @@ define pacemaker::constraint::base (
$first_resource_cleaned = regsubst($first_resource, '(:)', '.', 'G')
$second_resource_cleaned = regsubst($second_resource, '(:)', '.', 'G')
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
if($ensure == absent) {
if($constraint_type == 'location') {
$name_cleaned = regsubst($name, '(:)', '.', 'G')
exec { "Removing location constraint ${name}":
command => "/usr/sbin/pcs constraint location remove ${name_cleaned}",
onlyif => "/usr/sbin/pcs constraint location show --full | grep ${name_cleaned}",
require => Exec['wait-for-settle'],
require => $pcmk_require,
tries => $tries,
try_sleep => $try_sleep,
tag => [ 'pacemaker', 'pacemaker_constraint'],
@@ -127,7 +130,7 @@ define pacemaker::constraint::base (
exec { "Removing ${constraint_type} constraint ${name}":
command => "/usr/sbin/pcs constraint ${constraint_type} remove ${first_resource_cleaned} ${second_resource_cleaned}",
onlyif => "/usr/sbin/pcs constraint ${constraint_type} show | grep ${first_resource_cleaned} | grep ${second_resource_cleaned}",
require => Exec['wait-for-settle'],
require => $pcmk_require,
tries => $tries,
try_sleep => $try_sleep,
tag => [ 'pacemaker', 'pacemaker_constraint'],
@@ -140,7 +143,7 @@ define pacemaker::constraint::base (
exec { "Creating colocation constraint ${name}":
command => "/usr/sbin/pcs constraint colocation add ${first_resource_cleaned} ${second_resource_cleaned} ${score}",
unless => "/usr/sbin/pcs constraint colocation show | grep ${first_resource_cleaned} | grep ${second_resource_cleaned} > /dev/null 2>&1",
require => [Exec['wait-for-settle'],Package['pcs']],
require => $pcmk_require,
tries => $tries,
try_sleep => $try_sleep,
tag => [ 'pacemaker', 'pacemaker_constraint'],
@@ -150,7 +153,7 @@ define pacemaker::constraint::base (
exec { "Creating order constraint ${name}":
command => "/usr/sbin/pcs constraint order ${first_action} ${first_resource_cleaned} then ${second_action} ${second_resource_cleaned} ${_constraint_params}",
unless => "/usr/sbin/pcs constraint order show | grep ${first_resource_cleaned} | grep ${second_resource_cleaned} > /dev/null 2>&1",
require => [Exec['wait-for-settle'],Package['pcs']],
require => $pcmk_require,
tries => $tries,
try_sleep => $try_sleep,
tag => [ 'pacemaker', 'pacemaker_constraint'],
@@ -161,7 +164,7 @@ define pacemaker::constraint::base (
exec { "Creating location constraint ${name}":
command => "/usr/sbin/pcs constraint location add ${name} ${first_resource_cleaned} ${location} ${score}",
unless => "/usr/sbin/pcs constraint location show | grep ${first_resource_cleaned} > /dev/null 2>&1",
require => [Exec['wait-for-settle'],Package['pcs']],
require => $pcmk_require,
tries => $tries,
try_sleep => $try_sleep,
tag => [ 'pacemaker', 'pacemaker_constraint'],

View File

@@ -53,6 +53,10 @@ define pacemaker::constraint::colocation (
$master_slave = false,
$ensure = present,
) {
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
pcmk_constraint {"colo-${source}-${target}":
ensure => $ensure,
constraint_type => colocation,
@@ -60,7 +64,7 @@ define pacemaker::constraint::colocation (
location => $target,
score => $score,
master_slave => $master_slave,
require => Exec['wait-for-settle'],
require => $pcmk_require,
}
}

View File

@@ -48,13 +48,16 @@ define pacemaker::constraint::location (
$score,
$ensure='present'
) {
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
pcmk_constraint {"loc-${resource}-${location}":
ensure => $ensure,
constraint_type => location,
resource => $resource,
location => $location,
score => $score,
require => Exec['wait-for-settle'],
require => $pcmk_require,
}
}

View File

@@ -71,6 +71,10 @@ define pacemaker::property (
fail('When present, must provide value')
}
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
# Special-casing node branches due to https://bugzilla.redhat.com/show_bug.cgi?id=1302010
# (Basically pcs property show <property> will show all node properties anyway)
if $node {
@@ -78,8 +82,7 @@ define pacemaker::property (
exec { "Removing node-property ${property} on ${node}":
command => "/usr/sbin/pcs property unset --node ${node} ${property}",
onlyif => "/usr/sbin/pcs property show | grep ${property}= | grep ${node}",
require => [Exec['wait-for-settle'],
Class['::pacemaker::corosync']],
require => $pcmk_require,
tries => $tries,
try_sleep => $try_sleep,
}
@@ -92,8 +95,7 @@ define pacemaker::property (
exec { "Creating node-property ${property} on ${node}":
command => $cmd,
unless => "/usr/sbin/pcs property show ${property} | grep \"${property}=${value}\" | grep ${node}",
require => [Exec['wait-for-settle'],
Class['::pacemaker::corosync']],
require => $pcmk_require,
tries => $tries,
try_sleep => $try_sleep,
}
@@ -103,8 +105,7 @@ define pacemaker::property (
exec { "Removing cluster-wide property ${property}":
command => "/usr/sbin/pcs property unset ${property}",
onlyif => "/usr/sbin/pcs property show | grep ${property}: ",
require => [Exec['wait-for-settle'],
Class['::pacemaker::corosync']],
require => $pcmk_require,
tries => $tries,
try_sleep => $try_sleep,
}
@@ -117,8 +118,7 @@ define pacemaker::property (
exec { "Creating cluster-wide property ${property}":
command => $cmd,
unless => "/usr/sbin/pcs property show ${property} | grep \"${property} *[:=] *${value}\"",
require => [Exec['wait-for-settle'],
Class['::pacemaker::corosync']],
require => $pcmk_require,
tries => $tries,
try_sleep => $try_sleep,
}

View File

@@ -123,6 +123,9 @@ define pacemaker::resource::filesystem(
default => "device=${device} directory=${directory} fstype=${fstype} options=\"${fsoptions}\"",
}
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
pcmk_resource { $resource_id:
ensure => $ensure,
resource_type => 'Filesystem',
@@ -136,6 +139,6 @@ define pacemaker::resource::filesystem(
try_sleep => $try_sleep,
verify_on_create => $verify_on_create,
location_rule => $location_rule,
require => Exec['wait-for-settle'],
require => $pcmk_require,
}
}

View File

@@ -107,6 +107,9 @@ define pacemaker::resource::ip(
# pcs dislikes colons from IPv6 addresses. Replacing them with dots.
$resource_name = regsubst($ip_address, '(:)', '.', 'G')
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
pcmk_resource { "ip-${resource_name}":
ensure => $ensure,
resource_type => 'IPaddr2',
@@ -117,7 +120,7 @@ define pacemaker::resource::ip(
try_sleep => $try_sleep,
verify_on_create => $verify_on_create,
location_rule => $location_rule,
require => Exec['wait-for-settle'],
require => $pcmk_require,
}
}

View File

@@ -105,6 +105,9 @@ define pacemaker::resource::lsb(
$verify_on_create = false,
$location_rule = undef,
) {
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
pcmk_resource { $name:
ensure => $ensure,
resource_type => "lsb:${service_name}",
@@ -118,6 +121,6 @@ define pacemaker::resource::lsb(
try_sleep => $try_sleep,
verify_on_create => $verify_on_create,
location => $location_rule,
require => Exec['wait-for-settle'],
require => $pcmk_require,
}
}

View File

@@ -111,6 +111,9 @@ define pacemaker::resource::ocf(
$verify_on_create = false,
$location_rule = undef,
) {
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
pcmk_resource { $name:
ensure => $ensure,
resource_type => "ocf:${ocf_agent_name}",
@@ -125,6 +128,6 @@ define pacemaker::resource::ocf(
try_sleep => $try_sleep,
verify_on_create => $verify_on_create,
location_rule => $location_rule,
require => Exec['wait-for-settle'],
require => $pcmk_require,
}
}

View File

@@ -125,6 +125,9 @@ define pacemaker::resource::route(
default => " gateway=${gateway}"
}
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
pcmk_resource { "route-${name}":
ensure => $ensure,
resource_type => 'Route',
@@ -136,7 +139,7 @@ define pacemaker::resource::route(
try_sleep => $try_sleep,
verify_on_create => $verify_on_create,
location_rule => $location_rule,
require => Exec['wait-for-settle'],
require => $pcmk_require,
}
}

View File

@@ -107,6 +107,9 @@ define pacemaker::resource::service(
) {
include ::pacemaker::params
$res = "pacemaker::resource::${::pacemaker::params::services_manager}"
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
create_resources($res,
{ "${name}" => {
@@ -124,7 +127,7 @@ define pacemaker::resource::service(
location_rule => $location_rule,
# https://github.com/voxpupuli/puppet-lint-absolute_classname-check/issues/9
# lint:ignore:relative_classname_inclusion
require => Exec['wait-for-settle'],
require => $pcmk_require,
# lint:endignore
}
})

View File

@@ -105,6 +105,9 @@ define pacemaker::resource::systemd(
$verify_on_create = false,
$location_rule = undef,
) {
# We do not want to require Exec['wait-for-settle'] when we run this
# from a pacemaker remote node
$pcmk_require = str2bool($::pcmk_is_remote) ? { true => [], false => Exec['wait-for-settle'] }
pcmk_resource { $name:
ensure => $ensure,
resource_type => "systemd:${service_name}",
@@ -118,6 +121,6 @@ define pacemaker::resource::systemd(
try_sleep => $try_sleep,
verify_on_create => $verify_on_create,
location_rule => $location_rule,
require => Exec['wait-for-settle'],
require => $pcmk_require,
}
}