-
Notifications
You must be signed in to change notification settings - Fork 175
fence_heuristics_resource: add new fence-agent for dynamic delay fencing #308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
c928a80
6e156c0
03ff829
b71797f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| #!/usr/libexec/platform-python -tt | ||
|
|
||
| import io | ||
| import re | ||
| import subprocess | ||
| import shlex | ||
| import sys, stat | ||
| import logging | ||
| import atexit | ||
| import time | ||
| sys.path.append("/usr/share/fence") | ||
| from fencing import fail_usage, run_command, fence_action, all_opt | ||
| from fencing import atexit_handler, check_input, process_input, show_docs | ||
| from fencing import run_delay | ||
|
|
||
| def heuristics_resource(con, options): | ||
| # Search the node where the resource is running and determine | ||
| # the ACT node or not. For SBY node, a delay is generated. | ||
| # Note that this method always returns FALSE. | ||
|
|
||
| if not "--nodename" in options or options["--nodename"] == "": | ||
| logging.error("nodename parameter required") | ||
| return False | ||
|
|
||
| if not "--resource" in options or options["--resource"] == "": | ||
| logging.error("resource parameter required") | ||
| return False | ||
|
|
||
| target = options["--nodename"] | ||
| resource = options["--resource"] | ||
| promotable = options["--promotable"] in ["", "1"] | ||
| standby_wait = int(options["--standby-wait"]) | ||
| crm_resource_path = options["--crm-resource-path"] | ||
| crm_node_path = options["--crm-node-path"] | ||
|
|
||
| (rc, out, err) = run_command(options, "%s --name" % crm_node_path) | ||
| if rc != 0 or out == None: | ||
| logging.error("Can not get my nodename. rc=%s, stderr=%s" % (rc, err)) | ||
| return False | ||
|
|
||
| mynodename = out.strip() | ||
|
|
||
| if mynodename == target: | ||
| logging.info("Skip standby wait due to self-fencing.") | ||
| return False | ||
|
|
||
| (rc, out, err) = run_command(options, "%s -r %s -W" % (crm_resource_path, resource)) | ||
| if rc != 0 or out == None: | ||
| logging.error("Command failed. rc=%s, stderr=%s" % (rc, err)) | ||
| return False | ||
|
|
||
| search_str = re.compile(r"\s%s%s$" % (mynodename, '\sMaster' if promotable else '')) | ||
|
||
| for line in out.splitlines(): | ||
| searchres = search_str.search(line.strip()) | ||
| if searchres: | ||
| logging.info("This node is ACT! Skip standby wait.") | ||
| return False | ||
|
|
||
| logging.info("Resource %s NOT found on this node" % resource) | ||
|
|
||
| if standby_wait > 0: | ||
| # The SBY node waits for fencing from the ACT node, and tries to fence | ||
| # the ACT node on next fencing level waking up from sleep. | ||
| logging.info("Standby wait %s sec" % standby_wait) | ||
| time.sleep(standby_wait) | ||
|
|
||
| return False | ||
|
|
||
|
|
||
| def define_new_opts(): | ||
| all_opt["nodename"] = { | ||
| "getopt" : "n:", | ||
| "longopt" : "nodename", | ||
| "required" : "1", | ||
| "help" : "-n, --nodename=[nodename] Name of node to be fenced", | ||
| "shortdesc" : "Name of node to be fenced", | ||
| "default" : "", | ||
| "order" : 1 | ||
| } | ||
| all_opt["resource"] = { | ||
| "getopt" : "r:", | ||
| "longopt" : "resource", | ||
| "required" : "1", | ||
| "help" : "-r, --resource=[resource-id] ID of the resource that should be running in the ACT node", | ||
|
||
| "shortdesc" : "Resource ID", | ||
| "default" : "", | ||
| "order" : 1 | ||
| } | ||
| all_opt["promotable"] = { | ||
| "getopt" : "p", | ||
| "longopt" : "promotable", | ||
| "required" : "0", | ||
| "help" : "-p, --promotable Specify if resource parameter is promotable (master/slave) resource", | ||
| "shortdesc" : "Handle the promotable resource. The node on which the master resource is running is considered as ACT.", | ||
| "default" : "False", | ||
| "order" : 1 | ||
| } | ||
|
||
| all_opt["standby_wait"] = { | ||
| "getopt" : "w:", | ||
| "longopt" : "standby-wait", | ||
| "required" : "0", | ||
| "help" : "-w, --standby-wait=[seconds] Wait X seconds on SBY node. If a positive number is specified, fencing action of this agent will always succeed after waits.", | ||
| "shortdesc" : "Wait X seconds on SBY node. If a positive number is specified, fencing action of this agent will always succeed after waits.", | ||
|
||
| "default" : "0", | ||
| "order" : 1 | ||
| } | ||
| all_opt["crm_resource_path"] = { | ||
| "getopt" : ":", | ||
| "longopt" : "crm-resource-path", | ||
| "required" : "0", | ||
| "help" : "--crm-resource-path=[path] Path to crm_resource", | ||
| "shortdesc" : "Path to crm_resource command", | ||
| "default" : "@CRM_RESOURCE_PATH@", | ||
| "order" : 1 | ||
| } | ||
| all_opt["crm_node_path"] = { | ||
| "getopt" : ":", | ||
| "longopt" : "crm-node-path", | ||
| "required" : "0", | ||
| "help" : "--crm-node-path=[path] Path to crm_node", | ||
| "shortdesc" : "Path to crm_node command", | ||
| "default" : "@CRM_NODE_PATH@", | ||
| "order" : 1 | ||
| } | ||
|
|
||
|
|
||
| def main(): | ||
| device_opt = ["no_status", "no_password", "nodename", "resource", "promotable", "standby_wait", "crm_resource_path", "crm_node_path", "method"] | ||
| define_new_opts() | ||
| atexit.register(atexit_handler) | ||
|
|
||
| all_opt["method"]["default"] = "cycle" | ||
| all_opt["method"]["help"] = "-m, --method=[method] Method to fence (cycle|onoff) (Default: cycle)" | ||
|
|
||
| options = check_input(device_opt, process_input(device_opt)) | ||
|
|
||
| docs = {} | ||
| docs["shortdesc"] = "Fence agent for resource-heuristic based fencing delay" | ||
| docs["longdesc"] = "fence_heuristics_resource uses resource-heuristics to delay execution of fence agent running on next level.\ | ||
| \n.P\n\ | ||
| This is not a fence agent by itself! \ | ||
| Its only purpose is to delay execution of another fence agent that lives on next fencing level. \ | ||
| Note that this agent always returns FALSE. Therefore, subsequent agents on the same fencing level will not run" | ||
| docs["vendorurl"] = "" | ||
| show_docs(options, docs) | ||
|
|
||
| run_delay(options) | ||
|
|
||
| result = fence_action(\ | ||
| None, \ | ||
| options, \ | ||
| None, \ | ||
| None, \ | ||
| reboot_cycle_fn = heuristics_resource, | ||
| sync_set_power_fn = heuristics_resource) | ||
|
|
||
| sys.exit(result) | ||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| <?xml version="1.0" ?> | ||
| <resource-agent name="fence_heuristics_resource" shortdesc="Fence agent for resource-heuristic based fencing delay" > | ||
| <longdesc>fence_heuristics_resource uses resource-heuristics to delay execution of fence agent running on next level. | ||
|
|
||
| This is not a fence agent by itself! Its only purpose is to delay execution of another fence agent that lives on next fencing level. Note that this agent always returns FALSE. Therefore, subsequent agents on the same fencing level will not run</longdesc> | ||
| <vendor-url></vendor-url> | ||
| <parameters> | ||
| <parameter name="action" unique="0" required="1"> | ||
| <getopt mixed="-o, --action=[action]" /> | ||
| <content type="string" default="reboot" /> | ||
| <shortdesc lang="en">Fencing action</shortdesc> | ||
| </parameter> | ||
| <parameter name="crm_node_path" unique="0" required="0"> | ||
| <getopt mixed="--crm-node-path=[path]" /> | ||
| <shortdesc lang="en">Path to crm_node command</shortdesc> | ||
| </parameter> | ||
| <parameter name="crm_resource_path" unique="0" required="0"> | ||
| <getopt mixed="--crm-resource-path=[path]" /> | ||
| <shortdesc lang="en">Path to crm_resource command</shortdesc> | ||
| </parameter> | ||
| <parameter name="method" unique="0" required="0"> | ||
| <getopt mixed="-m, --method=[method]" /> | ||
| <content type="select" default="cycle" > | ||
| <option value="onoff" /> | ||
| <option value="cycle" /> | ||
| </content> | ||
| <shortdesc lang="en">Method to fence</shortdesc> | ||
| </parameter> | ||
| <parameter name="nodename" unique="0" required="1"> | ||
| <getopt mixed="-n, --nodename=[nodename]" /> | ||
| <content type="string" default="" /> | ||
| <shortdesc lang="en">Name of node to be fenced</shortdesc> | ||
| </parameter> | ||
| <parameter name="promotable" unique="0" required="0"> | ||
| <getopt mixed="-p, --promotable" /> | ||
| <content type="boolean" default="False" /> | ||
| <shortdesc lang="en">Handle the promotable resource. The node on which the master resource is running is considered as ACT.</shortdesc> | ||
| </parameter> | ||
| <parameter name="resource" unique="0" required="1"> | ||
| <getopt mixed="-r, --resource=[resource-id]" /> | ||
| <content type="string" default="" /> | ||
| <shortdesc lang="en">Resource ID</shortdesc> | ||
| </parameter> | ||
| <parameter name="standby_wait" unique="0" required="0"> | ||
| <getopt mixed="-w, --standby-wait=[seconds]" /> | ||
| <content type="string" default="0" /> | ||
| <shortdesc lang="en">Wait X seconds on SBY node. If a positive number is specified, fencing action of this agent will always succeed after waits.</shortdesc> | ||
| </parameter> | ||
| <parameter name="quiet" unique="0" required="0"> | ||
| <getopt mixed="-q, --quiet" /> | ||
| <content type="boolean" /> | ||
| <shortdesc lang="en">Disable logging to stderr. Does not affect --verbose or --debug-file or logging to syslog.</shortdesc> | ||
| </parameter> | ||
| <parameter name="verbose" unique="0" required="0"> | ||
| <getopt mixed="-v, --verbose" /> | ||
| <content type="boolean" /> | ||
| <shortdesc lang="en">Verbose mode</shortdesc> | ||
| </parameter> | ||
| <parameter name="debug" unique="0" required="0" deprecated="1"> | ||
| <getopt mixed="-D, --debug-file=[debugfile]" /> | ||
| <content type="string" /> | ||
| <shortdesc lang="en">Write debug information to given file</shortdesc> | ||
| </parameter> | ||
| <parameter name="debug_file" unique="0" required="0" obsoletes="debug"> | ||
| <getopt mixed="-D, --debug-file=[debugfile]" /> | ||
| <content type="string" /> | ||
| <shortdesc lang="en">Write debug information to given file</shortdesc> | ||
| </parameter> | ||
| <parameter name="version" unique="0" required="0"> | ||
| <getopt mixed="-V, --version" /> | ||
| <content type="boolean" /> | ||
| <shortdesc lang="en">Display version information and exit</shortdesc> | ||
| </parameter> | ||
| <parameter name="help" unique="0" required="0"> | ||
| <getopt mixed="-h, --help" /> | ||
| <content type="boolean" /> | ||
| <shortdesc lang="en">Display help and exit</shortdesc> | ||
| </parameter> | ||
| <parameter name="delay" unique="0" required="0"> | ||
| <getopt mixed="--delay=[seconds]" /> | ||
| <content type="second" default="0" /> | ||
| <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc> | ||
| </parameter> | ||
| <parameter name="login_timeout" unique="0" required="0"> | ||
| <getopt mixed="--login-timeout=[seconds]" /> | ||
| <content type="second" default="5" /> | ||
| <shortdesc lang="en">Wait X seconds for cmd prompt after login</shortdesc> | ||
| </parameter> | ||
| <parameter name="power_timeout" unique="0" required="0"> | ||
| <getopt mixed="--power-timeout=[seconds]" /> | ||
| <content type="second" default="20" /> | ||
| <shortdesc lang="en">Test X seconds for status change after ON/OFF</shortdesc> | ||
| </parameter> | ||
| <parameter name="power_wait" unique="0" required="0"> | ||
| <getopt mixed="--power-wait=[seconds]" /> | ||
| <content type="second" default="0" /> | ||
| <shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc> | ||
| </parameter> | ||
| <parameter name="shell_timeout" unique="0" required="0"> | ||
| <getopt mixed="--shell-timeout=[seconds]" /> | ||
| <content type="second" default="3" /> | ||
| <shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc> | ||
| </parameter> | ||
| <parameter name="retry_on" unique="0" required="0"> | ||
| <getopt mixed="--retry-on=[attempts]" /> | ||
| <content type="integer" default="1" /> | ||
| <shortdesc lang="en">Count of attempts to retry power on</shortdesc> | ||
| </parameter> | ||
| </parameters> | ||
| <actions> | ||
| <action name="on" automatic="0"/> | ||
| <action name="off" /> | ||
| <action name="reboot" /> | ||
| <action name="monitor" /> | ||
| <action name="metadata" /> | ||
| <action name="manpage" /> | ||
| <action name="validate-all" /> | ||
| </actions> | ||
| </resource-agent> |
Uh oh!
There was an error while loading. Please reload this page.