From b4e3b88ba9a428bc0d691f61e530670a29cdaa0c Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Wed, 7 Dec 2016 22:09:47 +0100 Subject: [PATCH] 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 --- lib/facter/pcmk_is_remote.rb | 8 ++++++++ manifests/constraint/base.pp | 13 ++++++++----- manifests/constraint/colocation.pp | 6 +++++- manifests/constraint/location.pp | 5 ++++- manifests/property.pp | 16 ++++++++-------- manifests/resource/filesystem.pp | 5 ++++- manifests/resource/ip.pp | 5 ++++- manifests/resource/lsb.pp | 5 ++++- manifests/resource/ocf.pp | 5 ++++- manifests/resource/route.pp | 5 ++++- manifests/resource/service.pp | 5 ++++- manifests/resource/systemd.pp | 5 ++++- 12 files changed, 61 insertions(+), 22 deletions(-) create mode 100644 lib/facter/pcmk_is_remote.rb diff --git a/lib/facter/pcmk_is_remote.rb b/lib/facter/pcmk_is_remote.rb new file mode 100644 index 00000000..6ae40986 --- /dev/null +++ b/lib/facter/pcmk_is_remote.rb @@ -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 diff --git a/manifests/constraint/base.pp b/manifests/constraint/base.pp index cffa6e98..0a7a4483 100644 --- a/manifests/constraint/base.pp +++ b/manifests/constraint/base.pp @@ -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'], diff --git a/manifests/constraint/colocation.pp b/manifests/constraint/colocation.pp index 8a6ca227..0d30f09f 100644 --- a/manifests/constraint/colocation.pp +++ b/manifests/constraint/colocation.pp @@ -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, } } diff --git a/manifests/constraint/location.pp b/manifests/constraint/location.pp index f9a7f8fb..bc71f8b1 100644 --- a/manifests/constraint/location.pp +++ b/manifests/constraint/location.pp @@ -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, } } diff --git a/manifests/property.pp b/manifests/property.pp index 16d89382..e43c3902 100644 --- a/manifests/property.pp +++ b/manifests/property.pp @@ -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 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, } diff --git a/manifests/resource/filesystem.pp b/manifests/resource/filesystem.pp index 712ff050..f6d72702 100644 --- a/manifests/resource/filesystem.pp +++ b/manifests/resource/filesystem.pp @@ -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, } } diff --git a/manifests/resource/ip.pp b/manifests/resource/ip.pp index 17dff5f0..d183c044 100644 --- a/manifests/resource/ip.pp +++ b/manifests/resource/ip.pp @@ -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, } } diff --git a/manifests/resource/lsb.pp b/manifests/resource/lsb.pp index c8516310..039ea314 100644 --- a/manifests/resource/lsb.pp +++ b/manifests/resource/lsb.pp @@ -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, } } diff --git a/manifests/resource/ocf.pp b/manifests/resource/ocf.pp index b5858914..9a77e47d 100644 --- a/manifests/resource/ocf.pp +++ b/manifests/resource/ocf.pp @@ -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, } } diff --git a/manifests/resource/route.pp b/manifests/resource/route.pp index 3a010e89..734d01f5 100644 --- a/manifests/resource/route.pp +++ b/manifests/resource/route.pp @@ -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, } } diff --git a/manifests/resource/service.pp b/manifests/resource/service.pp index e4ef5d3c..db8b2e35 100644 --- a/manifests/resource/service.pp +++ b/manifests/resource/service.pp @@ -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 } }) diff --git a/manifests/resource/systemd.pp b/manifests/resource/systemd.pp index ab0e6a9d..63a3a848 100644 --- a/manifests/resource/systemd.pp +++ b/manifests/resource/systemd.pp @@ -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, } }