From 397fbfd47097260ed75bd34d4e23b8cac335a43f Mon Sep 17 00:00:00 2001 From: Luca Miccini Date: Mon, 31 Oct 2022 13:44:43 +0100 Subject: [PATCH] Add fence_watchdog (sbd) stonith agent This commit adds a new stonith agent "fence_watchdog", allowing operators to define a stonith device called "watchdog" (name is hard coded in pacemaker) and eventually add this to the clusters stonith topology. Since this is a special dummy stonith device it is exempted from having a constraint rule preventing it from running on the same cluster nodes that is in charge of monitoring. The "watchdog" resource needs the sbd daemon to be enabled and depends on a valid watchdog timer device - either phisical or virtual - to perform self-fencing when required. Change-Id: Id010a392df0047d53dfab1c21cc78021c8c1aabf --- agent_generator/agent_generator.rb | 52 +++++--- agent_generator/src_xml/fence_watchdog.xml | 40 ++++++ agent_generator/variables.sh | 5 +- lib/puppet/provider/pcmk_stonith/default.rb | 2 +- manifests/stonith/fence_redfish.pp | 6 +- manifests/stonith/fence_rhevm.pp | 77 ++++++------ manifests/stonith/fence_watchdog.pp | 130 ++++++++++++++++++++ 7 files changed, 247 insertions(+), 65 deletions(-) create mode 100644 agent_generator/src_xml/fence_watchdog.xml create mode 100644 manifests/stonith/fence_watchdog.pp diff --git a/agent_generator/agent_generator.rb b/agent_generator/agent_generator.rb index fc182322..46d8cac9 100755 --- a/agent_generator/agent_generator.rb +++ b/agent_generator/agent_generator.rb @@ -126,11 +126,7 @@ define pacemaker::stonith::#{@parser.getAgentName} ( $update_settle_secs = 600, ) { #{getVariableValues} - $pcmk_host_value_chunk = $pcmk_host_list ? { - undef => '$(/usr/sbin/crm_node -n)', - default => $pcmk_host_list, - } - +#{getPcmkHostList} $meta_attr_value_chunk = $meta_attr ? { undef => '', default => "meta ${meta_attr}", @@ -144,26 +140,46 @@ define pacemaker::stonith::#{@parser.getAgentName} ( $param_string = "#{getChunks} op monitor interval=${interval} ${meta_attr_value_chunk}" #{getPackageSnippet} - pcmk_stonith { "stonith-#{@parser.getAgentName}-${safe_title}": - ensure => $ensure, - stonith_type => '#{@parser.getAgentName}', - pcmk_host_list => $pcmk_host_value_chunk, - pcs_param_string => $param_string, - tries => $tries, - try_sleep => $try_sleep, - deep_compare => $deep_compare, - update_settle_secs => $update_settle_secs, - } -} +#{getManifestCreate}} eos end + def getManifestCreate + agent_name = @parser.getAgentName == 'fence_watchdog' ? '\'watchdog\'' : "\"stonith-#{@parser.getAgentName}-${safe_title}\"" + text = '' + text += " pcmk_stonith { #{agent_name}:\n" + text += " ensure => $ensure,\n" + text += " stonith_type => '#{@parser.getAgentName}',\n" + text += " pcmk_host_list => $pcmk_host_value_chunk,\n" + text += " pcs_param_string => $param_string,\n" + text += " tries => $tries,\n" + text += " try_sleep => $try_sleep,\n" + text += " deep_compare => $deep_compare,\n" + text += " update_settle_secs => $update_settle_secs,\n" + text += " }\n" + text + end + + def getPcmkHostList + text = '' + if @parser.getAgentName == 'fence_watchdog' + text += " $pcmk_host_value_chunk = '$(crm_node -l |awk \\'{print $2}\\' |paste -sd, -)'\n" + else + text += " $pcmk_host_value_chunk = $pcmk_host_list ? {\n" + text += " undef => '$(/usr/sbin/crm_node -n)',\n" + text += " default => $pcmk_host_list,\n" + text += " }\n" + end + text + end + def getPackageSnippet + agent_name = @parser.getAgentName == 'fence_watchdog' ? '\'watchdog\'' : "\"stonith-#{@parser.getAgentName}-${safe_title}\"" text = '' if @parser.getPackageName != 'None' text += " if $ensure != 'absent' {\n" - text += " ensure_resource('package', '#{@parser.getPackageName}', { ensure => 'installed' })\n" - text += " Package['#{@parser.getPackageName}'] -> Pcmk_stonith[\"stonith-#{@parser.getAgentName}-${safe_title}\"]\n" + text += " ensure_packages('#{@parser.getPackageName}', { ensure => 'installed' })\n" + text += " Package['#{@parser.getPackageName}'] -> Pcmk_stonith[#{agent_name}]\n" text += " }" end text diff --git a/agent_generator/src_xml/fence_watchdog.xml b/agent_generator/src_xml/fence_watchdog.xml new file mode 100644 index 00000000..503dfeec --- /dev/null +++ b/agent_generator/src_xml/fence_watchdog.xml @@ -0,0 +1,40 @@ + + +fence_watchdog just provides +meta-data - actual fencing is done by the pacemaker internal watchdog agent. + + + + + Fencing Action + + + + + Ignored + + + + + Ignored + + + + + Display version information and exit + + + + + Display help and exit + + + + + + + + + + + diff --git a/agent_generator/variables.sh b/agent_generator/variables.sh index ffb0491c..27d8bb95 100644 --- a/agent_generator/variables.sh +++ b/agent_generator/variables.sh @@ -29,18 +29,17 @@ cmd_pkg_map=( "fence_ironic:None" "fence_kdump:fence-agents-kdump" "fence_kubevirt:None" + "fence_redfish:fence-agents-redfish" "fence_rhevm:fence-agents-rhevm" "fence_rsb:fence-agents-rsb" "fence_scsi:fence-agents-scsi" "fence_virt:fence-virt" "fence_vmware_soap:fence-agents-vmware-soap" + "fence_watchdog:fence-agents-sbd" "fence_wti:fence-agents-wti" # These have manual changes and need to be updated manually: # "fence_xvm:fence-virt" - # Until https://bugzilla.redhat.com/show_bug.cgi?id=1677020 is fixed properly - # we need to manually use deprecated parameters - #"fence_redfish:fence-agents-redfish" # re fence_kubevirt: # change to fence-agents-kubevirt when we have it with diff --git a/lib/puppet/provider/pcmk_stonith/default.rb b/lib/puppet/provider/pcmk_stonith/default.rb index 5a5432de..55d43531 100644 --- a/lib/puppet/provider/pcmk_stonith/default.rb +++ b/lib/puppet/provider/pcmk_stonith/default.rb @@ -132,7 +132,7 @@ Puppet::Type.type(:pcmk_stonith).provide(:default) do def stonith_location_rule_create() pcmk_host_list = @resource[:pcmk_host_list] nodes_count = crm_node_l().lines.size - if not_empty_string(pcmk_host_list) and nodes_count > 1 + if not_empty_string(pcmk_host_list) and nodes_count > 1 and @resource[:name] != 'watchdog' location_cmd = "constraint location #{@resource[:name]} avoids #{pcmk_host_list}=10000" Puppet.debug("stonith_location_rule_create: #{location_cmd}") pcs('create', @resource[:name], location_cmd, @resource[:tries], diff --git a/manifests/stonith/fence_redfish.pp b/manifests/stonith/fence_redfish.pp index ce67dff6..01f8b68d 100644 --- a/manifests/stonith/fence_redfish.pp +++ b/manifests/stonith/fence_redfish.pp @@ -250,10 +250,9 @@ define pacemaker::stonith::fence_redfish ( undef => '', default => "port=\"${port}\"", } - # Manual workaround s/_/-/ needed due to https://bugzilla.redhat.com/show_bug.cgi?id=1677020 $redfish_uri_chunk = $redfish_uri ? { undef => '', - default => "redfish-uri=\"${redfish_uri}\"", + default => "redfish_uri=\"${redfish_uri}\"", } $ssl_chunk = $ssl ? { undef => '', @@ -267,10 +266,9 @@ define pacemaker::stonith::fence_redfish ( undef => '', default => "ssl_secure=\"${ssl_secure}\"", } - # Manual workaround s/_/-/ needed due to https://bugzilla.redhat.com/show_bug.cgi?id=1677020 $systems_uri_chunk = $systems_uri ? { undef => '', - default => "systems-uri=\"${systems_uri}\"", + default => "systems_uri=\"${systems_uri}\"", } $username_chunk = $username ? { undef => '', diff --git a/manifests/stonith/fence_rhevm.pp b/manifests/stonith/fence_rhevm.pp index 3df7d199..944a696a 100644 --- a/manifests/stonith/fence_rhevm.pp +++ b/manifests/stonith/fence_rhevm.pp @@ -58,6 +58,9 @@ # [*power_timeout*] # Test X seconds for status change after ON/OFF # +# [*disable_http_filter*] +# Set HTTP Filter header to false +# # [*shell_timeout*] # Wait X seconds for cmd prompt after issuing command # @@ -88,9 +91,6 @@ # [*pcmk_host_list*] # List of Pacemaker hosts. # -# [*disable_http_filter*] -# (optional) Set HTTP Filter header to false -# # [*meta_attr*] # (optional) String of meta attributes # Defaults to undef @@ -131,38 +131,37 @@ # under the License. # define pacemaker::stonith::fence_rhevm ( - $ipaddr = undef, - $login = undef, - $passwd = undef, - $ssl = undef, - $notls = undef, - $port = undef, - $ipport = undef, - $inet4_only = undef, - $inet6_only = undef, - $passwd_script = undef, - $ssl_secure = undef, - $ssl_insecure = undef, - $action = undef, - $verbose = undef, - $debug = undef, - $separator = undef, - $power_timeout = undef, - $shell_timeout = undef, - $login_timeout = undef, - $power_wait = undef, - $delay = undef, - $retry_on = undef, - - $meta_attr = undef, - $interval = '60s', - $ensure = present, - $pcmk_host_list = undef, - - $tries = undef, - $try_sleep = undef, - + $ipaddr = undef, + $login = undef, + $passwd = undef, + $ssl = undef, + $notls = undef, + $port = undef, + $ipport = undef, + $inet4_only = undef, + $inet6_only = undef, + $passwd_script = undef, + $ssl_secure = undef, + $ssl_insecure = undef, + $action = undef, + $verbose = undef, + $debug = undef, + $separator = undef, + $power_timeout = undef, $disable_http_filter = undef, + $shell_timeout = undef, + $login_timeout = undef, + $power_wait = undef, + $delay = undef, + $retry_on = undef, + + $meta_attr = undef, + $interval = '60s', + $ensure = present, + $pcmk_host_list = undef, + + $tries = undef, + $try_sleep = undef, $deep_compare = false, $update_settle_secs = 600, @@ -235,6 +234,10 @@ define pacemaker::stonith::fence_rhevm ( undef => '', default => "power_timeout=\"${power_timeout}\"", } + $disable_http_filter_chunk = $disable_http_filter ? { + undef => '', + default => "disable_http_filter=\"${disable_http_filter}\"", + } $shell_timeout_chunk = $shell_timeout ? { undef => '', default => "shell_timeout=\"${shell_timeout}\"", @@ -247,10 +250,6 @@ define pacemaker::stonith::fence_rhevm ( undef => '', default => "power_wait=\"${power_wait}\"", } - $disable_http_filter_chunk = $disable_http_filter ? { - undef => '', - default => "disable_http_filter=\"${disable_http_filter}\"", - } $delay_chunk = $delay ? { undef => '', default => "delay=\"${delay}\"", @@ -275,7 +274,7 @@ define pacemaker::stonith::fence_rhevm ( Exec<| title == 'wait-for-settle' |> -> Pcmk_stonith<||> - $param_string = "${ipaddr_chunk} ${login_chunk} ${passwd_chunk} ${ssl_chunk} ${notls_chunk} ${port_chunk} ${ipport_chunk} ${inet4_only_chunk} ${inet6_only_chunk} ${passwd_script_chunk} ${ssl_secure_chunk} ${ssl_insecure_chunk} ${action_chunk} ${verbose_chunk} ${debug_chunk} ${separator_chunk} ${power_timeout_chunk} ${shell_timeout_chunk} ${login_timeout_chunk} ${power_wait_chunk} ${delay_chunk} ${retry_on_chunk} op monitor interval=${interval} ${meta_attr_value_chunk}" + $param_string = "${ipaddr_chunk} ${login_chunk} ${passwd_chunk} ${ssl_chunk} ${notls_chunk} ${port_chunk} ${ipport_chunk} ${inet4_only_chunk} ${inet6_only_chunk} ${passwd_script_chunk} ${ssl_secure_chunk} ${ssl_insecure_chunk} ${action_chunk} ${verbose_chunk} ${debug_chunk} ${separator_chunk} ${power_timeout_chunk} ${disable_http_filter_chunk} ${shell_timeout_chunk} ${login_timeout_chunk} ${power_wait_chunk} ${delay_chunk} ${retry_on_chunk} op monitor interval=${interval} ${meta_attr_value_chunk}" if $ensure != 'absent' { ensure_packages('fence-agents-rhevm', { ensure => 'installed' }) diff --git a/manifests/stonith/fence_watchdog.pp b/manifests/stonith/fence_watchdog.pp new file mode 100644 index 00000000..609a8000 --- /dev/null +++ b/manifests/stonith/fence_watchdog.pp @@ -0,0 +1,130 @@ +# == Define: pacemaker::stonith::fence_watchdog +# +# Module for managing Stonith for fence_watchdog. +# +# WARNING: Generated by "rake generate_stonith", manual changes will +# be lost. +# +# === Parameters +# +# [*action*] +# Fencing Action +# +# [*nodename*] +# Ignored +# +# [*plug*] +# Ignored +# +# [*interval*] +# Interval between tries. +# +# [*ensure*] +# The desired state of the resource. +# +# [*tries*] +# The number of tries. +# +# [*try_sleep*] +# Time to sleep between tries. +# +# [*pcmk_host_list*] +# List of Pacemaker hosts. +# +# [*meta_attr*] +# (optional) String of meta attributes +# Defaults to undef +# +# [*deep_compare*] +# Enable deep comparing of resources and bundles +# When set to true a resource will be compared in full (options, meta parameters,..) +# to the existing one and in case of difference it will be repushed to the CIB +# Defaults to false +# +# [*update_settle_secs*] +# When deep_compare is enabled and puppet updates a resource, this +# parameter represents the number (in seconds) to wait for the cluster to settle +# after the resource update. +# Defaults to 600 (seconds) +# +# === Dependencies +# None +# +# === Authors +# +# Generated by rake generate_stonith task. +# +# === Copyright +# +# Copyright (C) 2016 Red Hat 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. +# +define pacemaker::stonith::fence_watchdog ( + $action = undef, + $nodename = undef, + $plug = undef, + + $meta_attr = undef, + $interval = '60s', + $ensure = present, + $pcmk_host_list = undef, + + $tries = undef, + $try_sleep = undef, + + $deep_compare = false, + $update_settle_secs = 600, +) { + $action_chunk = $action ? { + undef => '', + default => "action=\"${action}\"", + } + $nodename_chunk = $nodename ? { + undef => '', + default => "nodename=\"${nodename}\"", + } + $plug_chunk = $plug ? { + undef => '', + default => "plug=\"${plug}\"", + } + + $pcmk_host_value_chunk = '$(crm_node -l |awk \'{print $2}\' |paste -sd, -)' + + $meta_attr_value_chunk = $meta_attr ? { + undef => '', + default => "meta ${meta_attr}", + } + + # $title can be a mac address, remove the colons for pcmk resource name + $safe_title = regsubst($title, ':', '', 'G') + + Exec<| title == 'wait-for-settle' |> -> Pcmk_stonith<||> + + $param_string = "${action_chunk} ${nodename_chunk} ${plug_chunk} op monitor interval=${interval} ${meta_attr_value_chunk}" + + if $ensure != 'absent' { + ensure_packages('fence-agents-sbd', { ensure => 'installed' }) + Package['fence-agents-sbd'] -> Pcmk_stonith['watchdog'] + } + pcmk_stonith { 'watchdog': + ensure => $ensure, + stonith_type => 'fence_watchdog', + pcmk_host_list => $pcmk_host_value_chunk, + pcs_param_string => $param_string, + tries => $tries, + try_sleep => $try_sleep, + deep_compare => $deep_compare, + update_settle_secs => $update_settle_secs, + } +}