cluster: RHEL55 - fencing: Support for 'metadata' option for fencing agents / show_docs
Marek Grác
marx at fedoraproject.org
Mon Oct 12 12:07:17 UTC 2009
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=39fd1b540bb06be1607d4fcd044b5e37abb2daba
Commit: 39fd1b540bb06be1607d4fcd044b5e37abb2daba
Parent: 6db69b1cdc99f4037672c902464d6ee11aec1e20
Author: Marek 'marx' Grac <mgrac at redhat.com>
AuthorDate: Mon Oct 12 14:04:20 2009 +0200
Committer: Marek 'marx' Grac <mgrac at redhat.com>
CommitterDate: Mon Oct 12 14:04:20 2009 +0200
fencing: Support for 'metadata' option for fencing agents / show_docs
New function for showing documentation that accepts default values. Better
XML output for metadata and man-page creation.
Part of solution for bz#488959
---
fence/agents/apc/fence_apc.py | 2 +
fence/agents/bladecenter/fence_bladecenter.py | 2 +
fence/agents/cisco_mds/fence_cisco_mds.py | 2 +
fence/agents/drac/fence_drac5.py | 2 +
fence/agents/eps/fence_eps.py | 2 +
fence/agents/ilo/fence_ilo.py | 2 +
fence/agents/lib/fencing.py.py | 146 +++++++++++++++++++------
fence/agents/lpar/fence_lpar.py | 2 +
fence/agents/rsa/fence_rsa.py | 2 +
fence/agents/sanbox2/fence_sanbox2.py | 2 +
fence/agents/virsh/fence_virsh.py | 2 +
fence/agents/vmware/fence_vmware.py | 2 +
fence/agents/wti/fence_wti.py | 2 +
13 files changed, 138 insertions(+), 32 deletions(-)
diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py
index 20efb49..ced7d39 100755
--- a/fence/agents/apc/fence_apc.py
+++ b/fence/agents/apc/fence_apc.py
@@ -201,6 +201,8 @@ def main():
if 0 == options.has_key("-c"):
options["-c"] = "\n>"
+ show_docs(options)
+
## Support for -n [switch]:[plug] notation that was used before
if (options.has_key("-n") == 1) and (-1 != options["-n"].find(":")):
(switch, plug) = options["-n"].split(":", 1)
diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py
index 83f255c..ef7ed53 100755
--- a/fence/agents/bladecenter/fence_bladecenter.py
+++ b/fence/agents/bladecenter/fence_bladecenter.py
@@ -102,6 +102,8 @@ def main():
options = check_input(device_opt, process_input(device_opt))
+ show_docs(options)
+
##
## Operate the fencing device
######
diff --git a/fence/agents/cisco_mds/fence_cisco_mds.py b/fence/agents/cisco_mds/fence_cisco_mds.py
index 989ec5c..1237ec8 100644
--- a/fence/agents/cisco_mds/fence_cisco_mds.py
+++ b/fence/agents/cisco_mds/fence_cisco_mds.py
@@ -106,6 +106,8 @@ def main():
options = check_input(device_opt, options)
+ show_docs(options)
+
if (not (options["-o"] in ["list","monitor"])):
port_oid=cisco_port2oid(options["-n"])
diff --git a/fence/agents/drac/fence_drac5.py b/fence/agents/drac/fence_drac5.py
index c3e1045..d93501a 100755
--- a/fence/agents/drac/fence_drac5.py
+++ b/fence/agents/drac/fence_drac5.py
@@ -97,6 +97,8 @@ def main():
if 0 == options.has_key("-c"):
options["-c"] = "\$"
+ show_docs(options)
+
##
## Operate the fencing device
######
diff --git a/fence/agents/eps/fence_eps.py b/fence/agents/eps/fence_eps.py
index 0d2a63a..1660931 100644
--- a/fence/agents/eps/fence_eps.py
+++ b/fence/agents/eps/fence_eps.py
@@ -107,6 +107,8 @@ def main():
if (not options.has_key("-c")):
options["-c"]="hidden.htm"
+ show_docs(options)
+
#Run fence action. Conn is None, beacause we always need open new http connection
fence_action(None, options, set_power_status, get_power_status,get_power_status)
diff --git a/fence/agents/ilo/fence_ilo.py b/fence/agents/ilo/fence_ilo.py
index e67f645..ae94017 100755
--- a/fence/agents/ilo/fence_ilo.py
+++ b/fence/agents/ilo/fence_ilo.py
@@ -70,6 +70,8 @@ def main():
LOGIN_TIMEOUT = 10
+ show_docs(options)
+
##
## Login and get version number
####
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 3cd1818..19644c2 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -19,6 +19,7 @@ BUILD_DATE=""
LOG_MODE_VERBOSE = 100
LOG_MODE_QUIET = 0
+EC_GENERIC_ERROR = 1
EC_BAD_ARGS = 2
EC_LOGIN_DENIED = 3
EC_CONNECTION_LOST = 4
@@ -37,11 +38,15 @@ all_opt = {
"getopt" : "h",
"longopt" : "help",
"help" : "-h, --help Display this help and exit",
+ "required" : "0",
+ "shortdesc" : "Display help and exit",
"order" : 54 },
"version" : {
"getopt" : "V",
"longopt" : "version",
"help" : "-V, --version Output version information and exit",
+ "required" : "0",
+ "shortdesc" : "Display version information and exit",
"order" : 53 },
"quiet" : {
"getopt" : "q",
@@ -58,6 +63,8 @@ all_opt = {
"getopt" : "D:",
"longopt" : "debug-file",
"help" : "-D, --debug-file=<debugfile> Debugging to output file",
+ "required" : "0",
+ "shortdesc" : "Write debug information to given file",
"order" : 52 },
"agent" : {
"getopt" : "",
@@ -133,21 +140,30 @@ all_opt = {
"getopt" : "m:",
"longopt" : "module-name",
"help" : "-m, --module-name=<module> DRAC/MC module name",
+ "required" : "0",
+ "shortdesc" : "DRAC/MC module name",
"order" : 1 },
"drac_version" : {
"getopt" : "d:",
"longopt" : "drac-version",
"help" : "-d, --drac-version=<version> Force DRAC version to use",
+ "required" : "0",
+ "shortdesc" : "Force DRAC version to use",
"order" : 1 },
"hmc_version" : {
"getopt" : "H:",
"longopt" : "hmc-version",
- "help" : "-H, --hmc-version=<version> Force HMC version to use: 3, 4 (default)",
+ "help" : "-H, --hmc-version=<version> Force HMC version to use: 3, 4 (default)",
+ "required" : "0",
+ "shortdesc" : "Force HMC version to use (3 or 4)",
+ "default" : "4",
"order" : 1 },
"ribcl" : {
"getopt" : "r:",
"longopt" : "ribcl-version",
"help" : "-r, --ribcl-version=<version> Force ribcl version to use",
+ "required" : "0",
+ "shortdesc" : "Force ribcl version to use",
"order" : 1 },
"login_eol_lf" : {
"getopt" : "",
@@ -158,13 +174,15 @@ all_opt = {
"getopt" : "c:",
"longopt" : "command-prompt",
"help" : "-c, --command-prompt=<prompt> Force command prompt",
+ "shortdesc" : "Force command prompt",
+ "required" : "0",
"order" : 1 },
"secure" : {
"getopt" : "x",
"longopt" : "ssh",
"help" : "-x, --ssh Use ssh connection",
- "required" : "0",
"shortdesc" : "SSH connection",
+ "required" : "0",
"order" : 1 },
"ssl" : {
"getopt" : "z",
@@ -223,31 +241,53 @@ all_opt = {
"order" : 2 },
"snmp_version" : {
"getopt" : "d:",
- "help" : "-d <ver> Specifies SNMP version to use",
+ "longopt" : "snmp-version",
+ "help" : "-d, --snmp-version=<ver> Specifies SNMP version to use",
+ "required" : "0",
+ "shortdesc" : "Specifies SNMP version to use (1,2c,3)",
"order" : 1 },
"community" : {
"getopt" : "c:",
- "help" : "-c <community> Set the community string",
+ "longopt" : "community",
+ "help" : "-c, --community=<community> Set the community string",
+ "required" : "0",
+ "shortdesc" : "Set the community string",
"order" : 1},
"snmp_auth_prot" : {
"getopt" : "b:",
- "help" : "-b <prot> Set authentication protocol (MD5|SHA)",
+ "longopt" : "snmp-auth-prot",
+ "help" : "-b, --snmp-auth-prot=<prot> Set authentication protocol (MD5|SHA)",
+ "required" : "0",
+ "shortdesc" : "Set authentication protocol (MD5|SHA)",
"order" : 1},
"snmp_sec_level" : {
"getopt" : "E:",
- "help" : "-E <level> Set security level (noAuthNoPriv|authNoPriv|authPriv)",
+ "longopt" : "snmp-sec-level",
+ "help" : "-E, --snmp-sec-level=<level> Set security level\n"+
+ " (noAuthNoPriv|authNoPriv|authPriv)",
+ "required" : "0",
+ "shortdesc" : "Set security level (noAuthNoPriv|authNoPriv|authPriv)",
"order" : 1},
"snmp_priv_prot" : {
"getopt" : "B:",
- "help" : "-B <prot> Set privacy protocol (DES|AES)",
+ "longopt" : "snmp-priv-prot",
+ "help" : "-B, --snmp-priv-prot=<prot> Set privacy protocol (DES|AES)",
+ "required" : "0",
+ "shortdesc" : "Set privacy protocol (DES|AES)",
"order" : 1},
"snmp_priv_passwd" : {
"getopt" : "P:",
- "help" : "-P <pass> Set privacy protocol password",
+ "longopt" : "snmp-priv-passwd",
+ "help" : "-P, --snmp-priv-passwd=<pass> Set privacy protocol password",
+ "required" : "0",
+ "shortdesc" : "Set privacy protocol password",
"order" : 1},
"snmp_priv_passwd_script" : {
"getopt" : "R:",
- "help" : "-R <script> Script to run to retrieve privacy password",
+ "longopt" : "snmp-priv-passwd-script",
+ "help" : "-R, --snmp-priv-passwd-script Script to run to retrieve privacy password",
+ "required" : "0",
+ "shortdesc" : "Script to run to retrieve privacy password",
"order" : 1},
"inet4_only" : {
"getopt" : "4",
@@ -265,7 +305,10 @@ all_opt = {
"order" : 1 },
"udpport" : {
"getopt" : "u:",
- "help" : "-u <port> UDP/TCP port to use",
+ "longopt" : "udpport",
+ "help" : "-u, --udpport UDP/TCP port to use",
+ "required" : "0",
+ "shortdesc" : "UDP/TCP port to use for connection with device",
"order" : 1},
"separator" : {
"getopt" : "C:",
@@ -354,12 +397,15 @@ def usage(avail_opt):
if len(value["help"]) != 0:
print " " + value["help"]
-def metadata(avail_opt):
+def metadata(avail_opt, options, docs):
global all_opt
sorted_list = [ (key, all_opt[key]) for key in avail_opt ]
sorted_list.sort(lambda x, y: cmp(x[1]["order"], y[1]["order"]))
+ print "<?xml version=\"1.0\" ?>"
+ print "<resource-agent name=\"" + os.path.basename(sys.argv[0])[:-3] + "\" shortdesc=\"" + docs["shortdesc"] + "\" >"
+ print "<longdesc>" + docs["longdesc"] + "</longdesc>"
print "<parameters>"
for option, value in sorted_list:
if all_opt[option].has_key("shortdesc"):
@@ -368,14 +414,43 @@ def metadata(avail_opt):
default = ""
if all_opt[option].has_key("default"):
default = "default=\""+all_opt[option]["default"]+"\""
+ elif options.has_key("-" + all_opt[option]["getopt"][:-1]):
+ if options["-" + all_opt[option]["getopt"][:-1]]:
+ try:
+ default = "default=\"" + options["-" + all_opt[option]["getopt"][:-1]] + "\""
+ except TypeError:
+ ## @todo/@note: Currently there is no clean way how to handle lists
+ ## we can create a string from it but we can't set it on command line
+ default = "default=\"list of values\""
+ elif options.has_key("-" + all_opt[option]["getopt"]):
+ default = "default=\"true\" "
+
+ mixed = all_opt[option]["help"]
+ ## split it between option and help text
+ res = re.compile("^(.*--\S+)\s+", re.IGNORECASE | re.S).search(mixed)
+ if (None != res):
+ mixed = res.group(1)
+ mixed = mixed.replace("<", "<").replace(">", ">")
+ print "\t\t<getopt mixed=\"" + mixed + "\" />"
if all_opt[option]["getopt"].count(":") > 0:
print "\t\t<content type=\"string\" "+default+" />"
else:
print "\t\t<content type=\"boolean\" "+default+" />"
+
print "\t\t<shortdesc lang=\"en\">" + all_opt[option]["shortdesc"] + "</shortdesc>"
print "\t</parameter>"
print "</parameters>"
+ print "<actions>"
+ print "\t<action name=\"on\" />"
+ print "\t<action name=\"off\" />"
+ print "\t<action name=\"reboot\" />"
+ print "\t<action name=\"status\" />"
+ print "\t<action name=\"list\" />"
+ print "\t<action name=\"monitor\" />"
+ print "\t<action name=\"meta-data\" />"
+ print "</actions>"
+ print "</resource-agent>"
def process_input(avail_opt):
global all_opt
@@ -488,20 +563,10 @@ def check_input(device_opt, opt):
else:
all_opt["login"]["required"] = "0"
- ## Process special options (and exit)
+ ## In special cases (show help, metadata or version) we don't need to check anything
#####
- if options.has_key("-h"):
- usage(device_opt)
- sys.exit(0)
-
- if options.has_key("-o") and options["-o"].lower() == "metadata":
- metadata(device_opt)
- sys.exit(0)
-
- if options.has_key("-V"):
- print FENCE_RELEASE_NAME, BUILD_DATE
- print REDHAT_COPYRIGHT
- sys.exit(0)
+ if options.has_key("-h") or options.has_key("-V") or (options.has_key("-o") and options["-o"].lower() == "metadata"):
+ return options;
## Set default values
#####
@@ -518,17 +583,10 @@ def check_input(device_opt, opt):
else:
options["log"] = LOG_MODE_QUIET
- # Convert action to lowercase
- options["-o"]=options["-o"].lower()
-
if 0 == device_opt.count("io_fencing"):
- if 0 == options.has_key("-o"):
- options["-o"] = "reboot"
if 0 == ["on", "off", "reboot", "status", "list", "monitor"].count(options["-o"].lower()):
fail_usage("Failed: Unrecognised action '" + options["-o"] + "'")
else:
- if 0 == options.has_key("-o"):
- options["-o"] = "disable"
if 0 == ["enable", "disable", "status", "list", "monitor"].count(options["-o"].lower()):
fail_usage("Failed: Unrecognised action '" + options["-o"] + "'")
@@ -603,7 +661,32 @@ def wait_power_status(tn, options, get_power_fn):
return 1
return 0
+def show_docs(options, docs = None):
+ device_opt = options["device_opt"]
+
+ if docs == None:
+ docs = { }
+ docs["shortdesc"] = "Fence agent"
+ docs["longdesc"] = ""
+
+ ## Process special options (and exit)
+ #####
+ if options.has_key("-h"):
+ usage(device_opt)
+ sys.exit(0)
+
+ if options.has_key("-o") and options["-o"].lower() == "metadata":
+ metadata(device_opt, options, docs)
+ sys.exit(0)
+
+ if options.has_key("-V"):
+ print RELEASE_VERSION, BUILD_DATE
+ print REDHAT_COPYRIGHT
+ sys.exit(0)
+
def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None):
+ ## Process options that manipulate fencing device
+ #####
if (options["-o"] == "list") and (0 == options["device_opt"].count("port")) and (0 == options["device_opt"].count("partition")):
print "N/A"
return
@@ -696,7 +779,6 @@ def fence_login(options):
command = '%s %s %s@%s -p %s' % (SSH_PATH, force_ipvx, options["-l"], options["-a"], options["-u"])
if options.has_key("ssh_options"):
command += ' ' + options["ssh_options"]
-
try:
conn = fspawn(command)
except pexpect.ExceptionPexpect, ex:
diff --git a/fence/agents/lpar/fence_lpar.py b/fence/agents/lpar/fence_lpar.py
index 97241d3..cfb78b0 100755
--- a/fence/agents/lpar/fence_lpar.py
+++ b/fence/agents/lpar/fence_lpar.py
@@ -155,6 +155,8 @@ def main():
if 0 == options.has_key("-x"):
fail_usage("Failed: You have to use ssh connection (-x) to fence device")
+ show_docs(options)
+
if 0 == options.has_key("-s"):
fail_usage("Failed: You have to enter name of managed system")
diff --git a/fence/agents/rsa/fence_rsa.py b/fence/agents/rsa/fence_rsa.py
index 0a614a6..9237f67 100755
--- a/fence/agents/rsa/fence_rsa.py
+++ b/fence/agents/rsa/fence_rsa.py
@@ -56,6 +56,8 @@ def main():
# This device will not allow us to login even with LANG=C
options["ssh_options"] = "-F /dev/null"
+
+ show_docs(options)
##
## Operate the fencing device
diff --git a/fence/agents/sanbox2/fence_sanbox2.py b/fence/agents/sanbox2/fence_sanbox2.py
index c792fc5..d1e65cf 100644
--- a/fence/agents/sanbox2/fence_sanbox2.py
+++ b/fence/agents/sanbox2/fence_sanbox2.py
@@ -123,6 +123,8 @@ def main():
if 0 == options.has_key("-c"):
options["-c"] = [ " #> " ]
+ show_docs(options)
+
##
## Operate the fencing device
##
diff --git a/fence/agents/virsh/fence_virsh.py b/fence/agents/virsh/fence_virsh.py
index ea2e06b..9174ac6 100644
--- a/fence/agents/virsh/fence_virsh.py
+++ b/fence/agents/virsh/fence_virsh.py
@@ -79,6 +79,8 @@ def main():
options["ssh_options"]="-t '/bin/bash -c \"PS1=\[EXPECT\]#\ /bin/bash --noprofile --norc\"'"
+ show_docs(options)
+
## Operate the fencing device
conn = fence_login(options)
fence_action(conn, options, set_power_status, get_power_status, get_outlets_status)
diff --git a/fence/agents/vmware/fence_vmware.py b/fence/agents/vmware/fence_vmware.py
index 1ae7398..a6ce9ef 100755
--- a/fence/agents/vmware/fence_vmware.py
+++ b/fence/agents/vmware/fence_vmware.py
@@ -130,6 +130,8 @@ def main():
options["-A"] = "localhost"
options["-x"] = 1
+
+ show_docs(options)
##
## Operate the fencing device
####
diff --git a/fence/agents/wti/fence_wti.py b/fence/agents/wti/fence_wti.py
index 181a4b5..f0f02b3 100755
--- a/fence/agents/wti/fence_wti.py
+++ b/fence/agents/wti/fence_wti.py
@@ -90,6 +90,8 @@ def main():
if 0 == options.has_key("-c"):
options["-c"] = [ "RSM>", "MPC>", "IPS>", "TPS>", "NBB>", "NPS>" ]
+ show_docs(options)
+
##
## Operate the fencing device
##
More information about the cluster-commits
mailing list