diff --git a/fence/agents/alom/fence_alom.py b/fence/agents/alom/fence_alom.py index ae484a48..28449049 100644 --- a/fence/agents/alom/fence_alom.py +++ b/fence/agents/alom/fence_alom.py @@ -1,66 +1,66 @@ #!/usr/bin/python # The Following Agent Has Been Tested On: # # Sun(tm) Advanced Lights Out Manager CMT v1.6.1 # as found on SUN T2000 Niagara -import sys, re, pexpect, time, exceptions +import sys, re, time import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="Sun Advanced Lights Out Manager (ALOM)" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_power_status(conn, options): conn.send_eol("showplatform") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) status = re.search("standby", conn.before.lower()) result = (status != None and "off" or "on") return result def set_power_status(conn, options): cmd_line = (options["--action"] == "on" and "poweron" or "poweroff -f -y") conn.send_eol(cmd_line) conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) # Get the machine some time between poweron and poweroff time.sleep(int(options["--power-timeout"])) def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure" ] atexit.register(atexit_handler) all_opt["secure"]["default"] = "1" all_opt["cmd_prompt"]["default"] = [ "sc\>\ " ] options = check_input(device_opt, process_input(device_opt)) options["telnet_over_ssh"] = 1 docs = { } docs["shortdesc"] = "Fence agent for Sun ALOM" docs["longdesc"] = "fence_alom is an I/O Fencing \ agent which can be used with ALOM connected machines." docs["vendorurl"] = "http://www.sun.com" show_docs(options, docs) # Operate the fencing device conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, None) # Logout from system try: conn.send_eol("logout") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/amt/fence_amt.py b/fence/agents/amt/fence_amt.py index 5d84045a..100a384d 100644 --- a/fence/agents/amt/fence_amt.py +++ b/fence/agents/amt/fence_amt.py @@ -1,155 +1,155 @@ #!/usr/bin/python -import sys, subprocess, re, os, stat +import sys, subprocess, re import logging import atexit from pipes import quote sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="Fence agent for Intel AMT" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_power_status(_, options): cmd = create_command(options, "status") try: logging.debug("Running: %s" % cmd) process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except OSError: fail_usage("Amttool not found or not accessible") process.wait() out = process.communicate() process.stdout.close() process.stderr.close() logging.debug("%s\n" % str(out)) match = re.search('Powerstate:[\\s]*(..)', str(output)) status = match.group(1) if match else None if (status == None): return "fail" elif (status == "S0"): # SO = on; S3 = sleep; S5 = off return "on" else: return "off" def set_power_status(_, options): cmd = create_command(options, options["--action"]) try: logging.debug("Running: %s" % cmd) process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except OSError: fail_usage("Amttool not found or not accessible") process.wait() out = process.communicate() process.stdout.close() process.stderr.close() logging.debug("%s\n" % str(out)) return def reboot_cycle(_, options): cmd = create_command(options, "cycle") try: logging.debug("Running: %s" % cmd) process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except OSError: fail_usage("Amttool not found or not accessible") status = process.wait() out = process.communicate() process.stdout.close() process.stderr.close() logging.debug("%s\n" % str(out)) return not bool(status) def create_command(options, action): # --password / -p cmd = "AMT_PASSWORD=" + quote(options["--password"]) cmd += " " + options["--amttool-path"] # --ip / -a cmd += " " + options["--ip"] # --action / -o if action == "status": cmd += " info" elif action == "on": cmd = "echo \"y\"|" + cmd cmd += " powerup" elif action == "off": cmd = "echo \"y\"|" + cmd cmd += " powerdown" elif action == "cycle": cmd = "echo \"y\"|" + cmd cmd += " powercycle" if action in ["on", "off", "cycle"] and options.has_key("--boot-option"): cmd += options["--boot-option"] # --use-sudo / -d if options.has_key("--use-sudo"): cmd = SUDO_PATH + " " + cmd return cmd def define_new_opts(): all_opt["boot_option"] = { "getopt" : "b:", "longopt" : "boot-option", "help" : "-b, --boot-option=[option] " "Change the default boot behavior of the machine. (pxe|hd|hdsafe|cd|diag)", "required" : "0", "shortdesc" : "Change the default boot behavior of the machine.", "choices" : ["pxe", "hd", "hdsafe", "cd", "diag"], "order" : 1 } all_opt["amttool_path"] = { "getopt" : "i:", "longopt" : "amttool-path", "help" : "--amttool-path=[path] Path to amttool binary", "required" : "0", "shortdesc" : "Path to amttool binary", "default" : "@AMTTOOL_PATH@", "order": 200 } def main(): atexit.register(atexit_handler) device_opt = [ "ipaddr", "no_login", "passwd", "boot_option", "no_port", "sudo", "amttool_path", "method" ] define_new_opts() options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for AMT" docs["longdesc"] = "fence_amt is an I/O Fencing agent \ which can be used with Intel AMT. This agent calls support software amttool\ (http://www.kraxel.org/cgit/amtterm/)." docs["vendorurl"] = "http://www.intel.com/" show_docs(options, docs) if not is_executable(options["--amttool-path"]): fail_usage("Amttool not found or not accessible") result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle) sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py index b97bbffa..d976be68 100644 --- a/fence/agents/apc/fence_apc.py +++ b/fence/agents/apc/fence_apc.py @@ -1,270 +1,270 @@ #!/usr/bin/python ##### ## ## The Following Agent Has Been Tested On: ## ## Model Firmware ## +---------------------------------------------+ ## AP7951 AOS v2.7.0, PDU APP v2.7.3 ## AP7941 AOS v3.5.7, PDU APP v3.5.6 ## AP9606 AOS v2.5.4, PDU APP v2.7.3 ## ## @note: ssh is very slow on AP79XX devices protocol (1) and ## cipher (des/blowfish) have to be defined ##### -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New APC Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="March, 2008" #END_VERSION_GENERATION def get_power_status(conn, options): exp_result = 0 outlets = {} conn.send_eol("1") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) version = 0 admin = 0 switch = 0 if (None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before)): switch = 1 if (None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before)): if (0 == options.has_key("--switch")): fail_usage("Failed: You have to enter physical switch number") else: if (0 == options.has_key("--switch")): options["--switch"] = "1" if (None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before)): version = 2 else: version = 3 if (None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before)): admin = 0 else: admin = 1 if switch == 0: if version == 2: if admin == 0: conn.send_eol("2") else: conn.send_eol("3") else: conn.send_eol("2") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.send_eol("1") else: conn.send_eol(options["--switch"]) while True: exp_result = conn.log_expect(options, ["Press " ] + options["--command-prompt"], int(options["--shell-timeout"])) lines = conn.before.split("\n") show_re = re.compile('(^|\x0D)\s*(\d+)- (.*?)\s+(ON|OFF)\s*') for x in lines: res = show_re.search(x) if (res != None): outlets[res.group(2)] = (res.group(3), res.group(4)) conn.send_eol("") if exp_result != 0: break conn.send(chr(03)) conn.log_expect(options, "- Logout", int(options["--shell-timeout"])) conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) if ["list", "monitor"].count(options["--action"]) == 1: return outlets else: try: (_, status) = outlets[options["--plug"]] return status.lower().strip() except KeyError: fail(EC_STATUS) def set_power_status(conn, options): action = { 'on' : "1", 'off': "2" }[options["--action"]] conn.send_eol("1") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) version = 0 admin2 = 0 admin3 = 0 switch = 0 if (None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before)): switch = 1 ## MasterSwitch has different schema for on/off actions action = { 'on' : "1", 'off': "3" }[options["--action"]] if (None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before)): if (0 == options.has_key("--switch")): fail_usage("Failed: You have to enter physical switch number") else: if (0 == options.has_key("--switch")): options["--switch"] = 1 if (None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before)): version = 2 else: version = 3 if (None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before)): admin2 = 0 else: admin2 = 1 if switch == 0: if version == 2: if admin2 == 0: conn.send_eol("2") else: conn.send_eol("3") else: conn.send_eol("2") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) if (None == re.compile('.*2- Outlet Restriction.*', re.IGNORECASE | re.S).match(conn.before)): admin3 = 0 else: admin3 = 1 conn.send_eol("1") else: conn.send_eol(options["--switch"]) while 0 == conn.log_expect(options, [ "Press " ] + options["--command-prompt"], int(options["--shell-timeout"])): conn.send_eol("") conn.send_eol(options["--plug"]+"") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) if switch == 0: if admin2 == 1: conn.send_eol("1") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) if admin3 == 1: conn.send_eol("1") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) else: conn.send_eol("1") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.send_eol(action) conn.log_expect(options, "Enter 'YES' to continue or to cancel :", int(options["--shell-timeout"])) conn.send_eol("YES") conn.log_expect(options, "Press to continue...", int(options["--shell-timeout"])) conn.send_eol("") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.send(chr(03)) conn.log_expect(options, "- Logout", int(options["--shell-timeout"])) conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) def get_power_status5(conn, options): outlets = {} conn.send_eol("olStatus all") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) lines = conn.before.split("\n") show_re = re.compile('^\s*(\d+): (.*): (On|Off)\s*$', re.IGNORECASE) for x in lines: res = show_re.search(x) if (res != None): outlets[res.group(1)] = (res.group(2), res.group(3)) if ["list", "monitor"].count(options["--action"]) == 1: return outlets else: try: (_, status) = outlets[options["--plug"]] return status.lower().strip() except KeyError: fail(EC_STATUS) def set_power_status5(conn, options): action = { 'on' : "olOn", 'off': "olOff" }[options["--action"]] conn.send_eol(action + " " + options["--plug"]) conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \ "port", "switch" ] atexit.register(atexit_handler) all_opt["cmd_prompt"]["default"] = [ "\n>", "\napc>" ] all_opt["ssh_options"]["default"] = "-1 -c blowfish" options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for APC over telnet/ssh" docs["longdesc"] = "fence_apc is an I/O Fencing agent \ which can be used with the APC network power switch. It logs into device \ via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh connections \ should be avoided while a GFS cluster is running because the connection \ will block any necessary fencing actions." docs["vendorurl"] = "http://www.apc.com" show_docs(options, docs) ## Support for --plug [switch]:[plug] notation that was used before if (options.has_key("--plug") == 1) and (-1 != options["--plug"].find(":")): (switch, plug) = options["--plug"].split(":", 1) options["--switch"] = switch options["--plug"] = plug ## ## Operate the fencing device #### conn = fence_login(options) ## Detect firmware version (ASCII menu vs command-line interface) ## and continue with proper action #### result = -1 firmware_version = re.compile('\s*v(\d)*\.').search(conn.before) if (firmware_version != None) and (firmware_version.group(1) == "5"): result = fence_action(conn, options, set_power_status5, get_power_status5, get_power_status5) else: result = fence_action(conn, options, set_power_status, get_power_status, get_power_status) ## ## Logout from system ## ## In some special unspecified cases it is possible that ## connection will be closed before we run close(). This is not ## a problem because everything is checked before. ###### try: conn.send_eol("4") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py index d3a03011..e94fd7de 100644 --- a/fence/agents/bladecenter/fence_bladecenter.py +++ b/fence/agents/bladecenter/fence_bladecenter.py @@ -1,119 +1,119 @@ #!/usr/bin/python ##### ## ## The Following Agent Has Been Tested On: ## ## Model Firmware ## +--------------------+---------------------------+ ## (1) Main application BRET85K, rev 16 ## Boot ROM BRBR67D, rev 16 ## Remote Control BRRG67D, rev 16 ## ##### -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New Bladecenter Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="March, 2008" #END_VERSION_GENERATION def get_power_status(conn, options): node_cmd = "system:blade\[" + options["--plug"] + "\]>" conn.send_eol("env -T system:blade[" + options["--plug"] + "]") i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["--shell-timeout"])) if i == 1: ## Given blade number does not exist if options.has_key("--missing-as-off"): return "off" else: fail(EC_STATUS) conn.send_eol("power -state") conn.log_expect(options, node_cmd, int(options["--shell-timeout"])) status = conn.before.splitlines()[-1] conn.send_eol("env -T system") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) return status.lower().strip() def set_power_status(conn, options): node_cmd = "system:blade\[" + options["--plug"] + "\]>" conn.send_eol("env -T system:blade[" + options["--plug"] + "]") i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["--shell-timeout"])) if i == 1: ## Given blade number does not exist if options.has_key("--missing-as-off"): return else: fail(EC_GENERIC_ERROR) conn.send_eol("power -"+options["--action"]) conn.log_expect(options, node_cmd, int(options["--shell-timeout"])) conn.send_eol("env -T system") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) def get_blades_list(conn, options): outlets = { } node_cmd = "system>" conn.send_eol("env -T system") conn.log_expect(options, node_cmd, int(options["--shell-timeout"])) conn.send_eol("list -l 2") conn.log_expect(options, node_cmd, int(options["--shell-timeout"])) lines = conn.before.split("\r\n") filter_re = re.compile("^\s*blade\[(\d+)\]\s+(.*?)\s*$") for blade_line in lines: res = filter_re.search(blade_line) if res != None: outlets[res.group(1)] = (res.group(2), "") return outlets def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \ "port", "missing_as_off" ] atexit.register(atexit_handler) all_opt["power_wait"]["default"] = "10" all_opt["cmd_prompt"]["default"] = [ "system>" ] options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for IBM BladeCenter" docs["longdesc"] = "fence_bladecenter is an I/O Fencing agent \ which can be used with IBM Bladecenters with recent enough firmware that \ includes telnet support. It logs into a Brocade chasis via telnet or ssh \ and uses the command line interface to power on and off blades." docs["vendorurl"] = "http://www.ibm.com" show_docs(options, docs) ## ## Operate the fencing device ###### conn = fence_login(options, "(username: )") result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list) ## ## Logout from system ###### try: conn.send_eol("exit") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/brocade/fence_brocade.py b/fence/agents/brocade/fence_brocade.py index 018f3c09..9e37e49e 100644 --- a/fence/agents/brocade/fence_brocade.py +++ b/fence/agents/brocade/fence_brocade.py @@ -1,87 +1,87 @@ #!/usr/bin/python -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New Brocade Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="March, 20013" #END_VERSION_GENERATION def get_power_status(conn, options): conn.send_eol("portCfgShow " + options["--plug"]) conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) show_re = re.compile('^\s*Persistent Disable\s*(ON|OFF)\s*$', re.IGNORECASE) lines = conn.before.split("\n") for x in lines: res = show_re.search(x) if (res != None): # We queried if it is disabled, so we have to negate answer if res.group(1) == "ON": return "off" else: return "on" fail(EC_STATUS) def set_power_status(conn, options): action = { 'on' : "portCfgPersistentEnable", 'off': "portCfgPersistentDisable" }[options["--action"]] conn.send_eol(action + " " + options["--plug"]) conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "fabric_fencing" ] atexit.register(atexit_handler) all_opt["cmd_prompt"]["default"] = [ "> " ] options = check_input(device_opt, process_input(device_opt)) options["eol"] = "\n" docs = { } docs["shortdesc"] = "Fence agent for HP Brocade over telnet/ssh" docs["longdesc"] = "fence_brocade is an I/O Fencing agent which can be used with Brocade FC switches. \ It logs into a Brocade switch via telnet and disables a specified port. Disabling the port which a machine is \ connected to effectively fences that machine. Lengthy telnet connections to the switch should be avoided while \ a GFS cluster is running because the connection will block any necessary fencing actions. \ \ After a fence operation has taken place the fenced machine can no longer connect to the Brocade FC switch. \ When the fenced machine is ready to be brought back into the GFS cluster (after reboot) the port on the Brocade \ FC switch needs to be enabled. This can be done by running fence_brocade and specifying the enable action" docs["vendorurl"] = "http://www.brocade.com" show_docs(options, docs) ## ## Operate the fencing device #### conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, None) ## ## Logout from system ## ## In some special unspecified cases it is possible that ## connection will be closed before we run close(). This is not ## a problem because everything is checked before. ###### try: conn.send_eol("exit") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/drac/fence_drac.py b/fence/agents/drac/fence_drac.py index 90314f4a..ba08ee76 100644 --- a/fence/agents/drac/fence_drac.py +++ b/fence/agents/drac/fence_drac.py @@ -1,81 +1,81 @@ #!/usr/bin/python -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_power_status(conn, options): conn.send_eol("getmodinfo") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) status = re.compile("\s+(on|off)\s+", re.IGNORECASE).search(conn.before).group(1) return (status.lower().strip()) def set_power_status(conn, options): action = { 'on' : "powerup", 'off': "powerdown" }[options["--action"]] conn.send_eol("serveraction -d 0 " + action) conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt" ] atexit.register(atexit_handler) opt = process_input(device_opt) if "--username" in opt: all_opt["cmd_prompt"]["default"] = [ "\\[" + opt["--username"] + "\\]# " ] else: all_opt["cmd_prompt"]["default"] = [ "\\[" "username" + "\\]# " ] options = check_input(device_opt, opt) docs = { } docs["shortdesc"] = "I/O Fencing agent for Dell DRAC IV" docs["longdesc"] = "fence_drac is an I/O Fencing agent which can be used with \ the Dell Remote Access Card (DRAC). This card provides remote access to controlling \ power to a server. It logs into the DRAC through the telnet interface of the card. By \ default, the telnet interface is not enabled. To enable the interface, you will need \ to use the racadm command in the racser-devel rpm available from Dell. \ \ To enable telnet on the DRAC: \ \ [root]# racadm config -g cfgSerial -o cfgSerialTelnetEnable 1 \ \ [root]# racadm racreset \ " docs["vendorurl"] = "http://www.dell.com" show_docs(options, docs) ## ## Operate the fencing device #### conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, None) ## ## Logout from system ## ## In some special unspecified cases it is possible that ## connection will be closed before we run close(). This is not ## a problem because everything is checked before. ###### try: conn.send_eol("exit") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/drac5/fence_drac5.py b/fence/agents/drac5/fence_drac5.py index 036f2943..b95b1c7f 100644 --- a/fence/agents/drac5/fence_drac5.py +++ b/fence/agents/drac5/fence_drac5.py @@ -1,162 +1,162 @@ #!/usr/bin/python ##### ## ## The Following Agent Has Been Tested On: ## ## DRAC Version Firmware ## +-----------------+---------------------------+ ## DRAC 5 1.0 (Build 06.05.12) ## DRAC 5 1.21 (Build 07.05.04) ## ## @note: drac_version was removed ##### -import sys, re, pexpect, exceptions, time +import sys, re, time import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New Drac5 Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="March, 2008" #END_VERSION_GENERATION def get_power_status(conn, options): if options["--drac-version"] == "DRAC MC": (_, status) = get_list_devices(conn, options)[options["--plug"]] else: if options["--drac-version"] == "DRAC CMC": conn.send_eol("racadm serveraction powerstatus -m " + options["--plug"]) elif options["--drac-version"] == "DRAC 5": conn.send_eol("racadm serveraction powerstatus") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) status = re.compile("(^|: )(ON|OFF|Powering ON|Powering OFF)\s*$", re.IGNORECASE | re.MULTILINE).search(conn.before).group(2) if status.lower().strip() in ["on", "powering on", "powering off"]: return "on" else: return "off" def set_power_status(conn, options): action = { 'on' : "powerup", 'off': "powerdown" }[options["--action"]] if options["--drac-version"] == "DRAC CMC": conn.send_eol("racadm serveraction " + action + " -m " + options["--plug"]) elif options["--drac-version"] == "DRAC 5": conn.send_eol("racadm serveraction " + action) elif options["--drac-version"] == "DRAC MC": conn.send_eol("racadm serveraction -s " + options["--plug"] + " " + action) ## Fix issue with double-enter [CR/LF] ## We need to read two additional command prompts (one from get + one from set command) conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) if len(conn.before.strip()) == 0: options["eol"] = options["eol"][:-1] conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) def get_list_devices(conn, options): outlets = { } if options["--drac-version"] == "DRAC CMC": conn.send_eol("getmodinfo") list_re = re.compile("^([^\s]*?)\s+Present\s*(ON|OFF)\s*.*$") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) for line in conn.before.splitlines(): if (list_re.search(line)): outlets[list_re.search(line).group(1)] = ("", list_re.search(line).group(2)) elif options["--drac-version"] == "DRAC MC": conn.send_eol("getmodinfo") list_re = re.compile("^\s*([^\s]*)\s*---->\s*(.*?)\s+Present\s*(ON|OFF)\s*.*$") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) for line in conn.before.splitlines(): if (list_re.search(line)): outlets[list_re.search(line).group(2)] = ("", list_re.search(line).group(3)) elif options["--drac-version"] == "DRAC 5": ## DRAC 5 can be used only for one computer ## standard fence library can't handle correctly situation ## when some fence devices supported by fence agent ## works with 'list' and other should returns 'N/A' print "N/A" return outlets def define_new_opts(): all_opt["drac_version"] = { "getopt" : "d:", "longopt" : "drac-version", "help" : "-d, --drac-version=[version] Force DRAC version to use (DRAC 5, DRAC CMC, DRAC MC)", "required" : "0", "shortdesc" : "Force DRAC version to use (DRAC 5, DRAC CMC, DRAC MC)", "choices" : [ "DRAC CMC", "DRAC MC", "DRAC 5" ], "order" : 1 } def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \ "drac_version", "port", "no_port" ] atexit.register(atexit_handler) define_new_opts() all_opt["cmd_prompt"]["default"] = [ "\$", "DRAC\/MC:" ] options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for Dell DRAC CMC/5" docs["longdesc"] = "fence_drac5 is an I/O Fencing agent \ which can be used with the Dell Remote Access Card v5 or CMC (DRAC). \ This device provides remote access to controlling power to a server. \ It logs into the DRAC through the telnet/ssh interface of the card. \ By default, the telnet interface is not enabled." docs["vendorurl"] = "http://www.dell.com" show_docs(options, docs) ## ## Operate the fencing device ###### conn = fence_login(options) if options.has_key("--drac-version") == False: ## autodetect from text issued by fence device if conn.before.find("CMC") >= 0: options["--drac-version"] = "DRAC CMC" elif conn.before.find("DRAC 5") >= 0: options["--drac-version"] = "DRAC 5" elif conn.after.find("DRAC/MC") >= 0: options["--drac-version"] = "DRAC MC" else: ## Assume this is DRAC 5 by default as we don't want to break anything options["--drac-version"] = "DRAC 5" if options["--drac-version"] in ["DRAC MC", "DRAC CMC"]: if 0 == options.has_key("--plug") and 0 == ["monitor", "list"].count(options["--action"].lower()): fail_usage("Failed: You have to enter module name (-n)") result = fence_action(conn, options, set_power_status, get_power_status, get_list_devices) ## ## Logout from system ###### try: conn.send_eol("exit") time.sleep(1) conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/dummy/fence_dummy.py b/fence/agents/dummy/fence_dummy.py index 800b11dd..2de240bd 100644 --- a/fence/agents/dummy/fence_dummy.py +++ b/fence/agents/dummy/fence_dummy.py @@ -1,133 +1,133 @@ #!/usr/bin/python -import sys, re, pexpect, exceptions, random +import sys, random import logging import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New Dummy Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION plug_status = "on" def get_power_status_file(conn, options): try: status_file = open(options["--status-file"], 'r') except: return "off" status = status_file.read() status_file.close() return status.lower() def set_power_status_file(conn, options): if not (options["--action"] in [ "on", "off" ]): return status_file = open(options["--status-file"], 'w') status_file.write(options["--action"]) status_file.close() def get_power_status_fail(conn, options): outlets = get_outlets_fail(conn, options) if len(outlets) == 0 or options.has_key("--plug") == 0: fail_usage("Failed: You have to enter existing machine!") else: return outlets[options["--plug"]][0] def set_power_status_fail(conn, options): global plug_status plug_status = "unknown" if options["--action"] == "on": plug_status = "off" def get_outlets_fail(conn, options): result = {} global plug_status if options["--action"] == "on": plug_status = "off" # This fake agent has no port data to list, so we have to make # something up for the list action. if options.has_key("--action") and options["--action"] == "list": result["fake_port_1"] = [plug_status, "fake"] result["fake_port_2"] = [plug_status, "fake"] elif (options.has_key("--plug") == 0): fail_usage("Failed: You have to enter existing machine!") else: port = options["--plug"] result[port] = [plug_status, "fake"] return result def main(): device_opt = [ "no_password", "status_file", "random_sleep_range", "type", "port" ] atexit.register(atexit_handler) all_opt["status_file"] = { "getopt" : "s:", "longopt" : "status-file", "help":"--status-file=[file] Name of file that holds current status", "required" : "0", "shortdesc" : "File with status", "default" : "/tmp/fence_dummy.status", "order": 1 } all_opt["random_sleep_range"] = { "getopt" : "r:", "longopt" : "random_sleep_range", "help":"--random_sleep_range=[seconds] Issue a sleep between 1 and [seconds]", "required" : "0", "shortdesc" : "Issue a sleep between 1 and X seconds. Used for testing.", "order": 1 } all_opt["type"] = { "getopt" : "t:", "longopt" : "type", "help":"--type=[type] Possible types are: file and fail", "required" : "0", "shortdesc" : "Type of the dummy fence agent", "default" : "file", "order": 1 } pinput = process_input(device_opt) if (pinput.has_key("--type") and pinput["--type"] == "file") or (pinput.has_key("--type") == False): # hack to have fence agents that require ports 'fail' and one that do not 'file' device_opt.remove("port") options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Dummy fence agent" docs["longdesc"] = "fence_dummy" docs["vendorurl"] = "http://www.example.com" show_docs(options, docs) # random sleep for testing if options.has_key("--random_sleep_range"): val = int(options["--random_sleep_range"]) ran = random.randint(1, val) logging.info("Random sleep for %d seconds\n" % ran) time.sleep(ran) if options["--type"] == "fail": result = fence_action(None, options, set_power_status_fail, get_power_status_fail, get_outlets_fail) else: result = fence_action(None, options, set_power_status_file, get_power_status_file, None) sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/hds_cb/fence_hds_cb.py b/fence/agents/hds_cb/fence_hds_cb.py index d8046b14..78754fc5 100755 --- a/fence/agents/hds_cb/fence_hds_cb.py +++ b/fence/agents/hds_cb/fence_hds_cb.py @@ -1,146 +1,146 @@ #!/usr/bin/python ##### ## ## The Following Agent Has Been Tested On: ## ## Model Modle/Firmware ## +--------------------+---------------------------+ ## (1) Main application CB2000/A0300-E-6617 ## ##### -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New Compute Blade 2000 Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="November, 2012" #END_VERSION_GENERATION RE_STATUS_LINE = "^([0-9]+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*$" def get_power_status(conn, options): #### Maybe should put a conn.log_expect here to make sure #### we have properly entered into the main menu conn.sendline("S") # Enter System Command Mode conn.log_expect(options, "SVP>", int(options["--shell-timeout"])) conn.sendline("PC") # Enter partition control conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) result = {} # Status can now be obtained from the output of the PC # command. Line looks like the following: # "P Power Condition LID lamp Mode Auto power on" # "0 On Normal Off Basic Synchronized" # "1 On Normal Off Basic Synchronized" for line in conn.before.splitlines(): # populate the relevant fields based on regex partition = re.search(RE_STATUS_LINE, line) if( partition != None): # find the blade number defined in args if( partition.group(1) == options["--plug"] ): result = partition.group(2).lower() # We must make sure we go back to the main menu as the # status is checked before any fencing operations are # executed. We could in theory save some time by staying in # the partition control, but the logic is a little cleaner # this way. conn.sendline("Q") # Back to system command mode conn.log_expect(options, "SVP>", int(options["--shell-timeout"])) conn.sendline("EX") # Back to system console main menu conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) return result def set_power_status(conn, options): action = { 'on' : "P", 'off': "F", 'reboot' : "H", }[options["--action"]] conn.sendline("S") # Enter System Command Mode conn.log_expect(options, "SVP>", int(options["--shell-timeout"])) conn.sendline("PC") # Enter partition control conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.sendline("P") # Enter power control menu conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.sendline(action) # Execute action from array above conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.sendline(options["--plug"]) # Select blade number from args conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.sendline("Y") # Confirm action conn.log_expect(options, "Hit enter key.", int(options["--shell-timeout"])) conn.sendline("") # Press the any key conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.sendline("Q") # Quit back to partition control conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.sendline("Q") # Quit back to system command mode conn.log_expect(options, "SVP>", int(options["--shell-timeout"])) conn.sendline("EX") # Quit back to system console menu conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) def get_blades_list(conn, options): outlets = { } conn.sendline("S") # Enter System Command Mode conn.log_expect(options, "SVP>", int(options["--shell-timeout"])) conn.sendline("PC") # Enter partition control conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) # Status can now be obtained from the output of the PC # command. Line looks like the following: # "P Power Condition LID lamp Mode Auto power on" # "0 On Normal Off Basic Synchronized" # "1 On Normal Off Basic Synchronized" for line in conn.before.splitlines(): partition = re.search(RE_STATUS_LINE, line) if( partition != None): outlets[partition.group(1)] = (partition.group(2), "") conn.sendline("Q") # Quit back to system command mode conn.log_expect(options, "SVP>", int(options["--shell-timeout"])) conn.sendline("EX") # Quit back to system console menu conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) return outlets def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \ "port", "missing_as_off" ] atexit.register(atexit_handler) all_opt["power_wait"]["default"] = "5" all_opt["cmd_prompt"]["default"] = [ "\) :" ] options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for Hitachi Compute Blade systems" docs["longdesc"] = "fence_hds_cb is an I/O Fencing agent \ which can be used with Hitachi Compute Blades with recent enough firmware that \ includes telnet support." docs["vendorurl"] = "http://www.hds.com" show_docs(options, docs) ## ## Operate the fencing device ###### conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list) ## ## Logout from system ###### try: conn.sendline("X") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/hpblade/fence_hpblade.py b/fence/agents/hpblade/fence_hpblade.py index e2de1481..84e0b0b9 100644 --- a/fence/agents/hpblade/fence_hpblade.py +++ b/fence/agents/hpblade/fence_hpblade.py @@ -1,96 +1,96 @@ #!/usr/bin/python ##### ## ## The Following Agent Has Been Tested On: ## * BladeSystem c7000 Enclosure ##### -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New Bladecenter Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="March, 2008" #END_VERSION_GENERATION def get_power_status(conn, options): conn.send_eol("show server status " + options["--plug"]) conn.log_expect(options, options["--command-prompt"] , int(options["--shell-timeout"])) power_re = re.compile("^\s*Power: (.*?)\s*$") status = "unknown" for line in conn.before.splitlines(): res = power_re.search(line) if res != None: status = res.group(1) if status == "unknown": if options.has_key("--missing-as-off"): return "off" else: fail(EC_STATUS) return status.lower().strip() def set_power_status(conn, options): if options["--action"] == "on": conn.send_eol("poweron server " + options["--plug"]) elif options["--action"] == "off": conn.send_eol("poweroff server " + options["--plug"] + " force") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) def get_blades_list(conn, options): outlets = { } conn.send_eol("show server list" ) conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) list_re = re.compile("^\s*(.*?)\s+(.*?)\s+(.*?)\s+OK\s+(.*?)\s+(.*?)\s*$") for line in conn.before.splitlines(): res = list_re.search(line) if res != None: outlets[res.group(1)] = (res.group(2), res.group(4).lower()) return outlets def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "missing_as_off" ] atexit.register(atexit_handler) all_opt["cmd_prompt"]["default"] = [ "c7000oa>" ] options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for HP BladeSystem" docs["longdesc"] = "fence_hpblade is an I/O Fencing agent \ which can be used with HP BladeSystem. It logs into an enclosure via telnet or ssh \ and uses the command line interface to power on and off blades." docs["vendorurl"] = "http://www.hp.com" show_docs(options, docs) ## ## Operate the fencing device ###### options["eol"] = "\n" conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list) ## ## Logout from system ###### try: conn.send_eol("exit") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/ilo_mp/fence_ilo_mp.py b/fence/agents/ilo_mp/fence_ilo_mp.py index 5bb234b7..c76c281b 100644 --- a/fence/agents/ilo_mp/fence_ilo_mp.py +++ b/fence/agents/ilo_mp/fence_ilo_mp.py @@ -1,69 +1,69 @@ #!/usr/bin/python -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_power_status(conn, options): conn.send_eol("show /system1") re_state = re.compile('EnabledState=(.*)', re.IGNORECASE) conn.log_expect(options, re_state, int(options["--shell-timeout"])) status = conn.match.group(1).lower() if status.startswith("enabled"): return "on" else: return "off" def set_power_status(conn, options): if options["--action"] == "on": conn.send_eol("start /system1") else: conn.send_eol("stop -f /system1") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) return def main(): device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt" ] atexit.register(atexit_handler) all_opt["cmd_prompt"]["default"] = [ "MP>", "hpiLO->" ] all_opt["power_wait"]["default"] = 5 options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for HP iLO MP" docs["longdesc"] = "" docs["vendorurl"] = "http://www.hp.com" show_docs(options, docs) conn = fence_login(options) conn.send_eol("SMCLP") ## ## Fence operations #### result = fence_action(conn, options, set_power_status, get_power_status) try: conn.send_eol("exit") except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py index d224c590..37df6cbe 100644 --- a/fence/agents/ipmilan/fence_ipmilan.py +++ b/fence/agents/ipmilan/fence_ipmilan.py @@ -1,201 +1,201 @@ #!/usr/bin/python -import sys, shlex, stat, subprocess, re, os +import sys, shlex, subprocess, re, os import logging import atexit from pipes import quote sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_power_status(_, options): cmd = create_command(options, "status") try: logging.info("Executing: %s\n" % cmd) process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: fail_usage("Ipmitool not found or not accessible") process.wait() out = process.communicate() process.stdout.close() process.stderr.close() logging.debug("%s\n" % str(out)) match = re.search('[Cc]hassis [Pp]ower is [\\s]*([a-zA-Z]{2,3})', str(out)) status = match.group(1) if match else None return status def set_power_status(_, options): cmd = create_command(options, options["--action"]) try: logging.debug("Executing: %s\n" % cmd) process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: fail_usage("Ipmitool not found or not accessible") process.wait() out = process.communicate() process.stdout.close() process.stderr.close() logging.debug("%s\n" % str(out)) return def reboot_cycle(_, options): cmd = create_command(options, "cycle") try: logging.debug("Executing: %s\n" % cmd) process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: fail_usage("Ipmitool not found or not accessible") process.wait() out = process.communicate() process.stdout.close() process.stderr.close() logging.debug("%s\n" % str(out)) return bool(re.search('chassis power control: cycle', str(out).lower())) def create_command(options, action): cmd = options["--ipmitool-path"] # --lanplus / -L if options.has_key("--lanplus") and options["--lanplus"] in ["", "1"]: cmd += " -I lanplus" else: cmd += " -I lan" # --ip / -a cmd += " -H " + options["--ip"] # --username / -l if options.has_key("--username") and len(options["--username"]) != 0: cmd += " -U " + quote(options["--username"]) # --auth / -A if options.has_key("--auth"): cmd += " -A " + options["--auth"] # --password / -p if options.has_key("--password"): cmd += " -P " + quote(options["--password"]) # --cipher / -C cmd += " -C " + options["--cipher"] # --port / -n if options.has_key("--ipport"): cmd += " -p " + options["--ipport"] if options.has_key("--privlvl"): cmd += " -L " + options["--privlvl"] # --action / -o cmd += " chassis power " + action # --use-sudo / -d if options.has_key("--use-sudo"): cmd = SUDO_PATH + " " + cmd return cmd def define_new_opts(): all_opt["lanplus"] = { "getopt" : "P", "longopt" : "lanplus", "help" : "-P, --lanplus Use Lanplus to improve security of connection", "required" : "0", "default" : "0", "shortdesc" : "Use Lanplus to improve security of connection", "order": 1 } all_opt["auth"] = { "getopt" : "A:", "longopt" : "auth", "help" : "-A, --auth=[auth] IPMI Lan Auth type (md5|password|none)", "required" : "0", "shortdesc" : "IPMI Lan Auth type.", "choices" : ["md5", "password", "none"], "order": 1 } all_opt["cipher"] = { "getopt" : "C:", "longopt" : "cipher", "help" : "-C, --cipher=[cipher] Ciphersuite to use (same as ipmitool -C parameter)", "required" : "0", "shortdesc" : "Ciphersuite to use (same as ipmitool -C parameter)", "default" : "0", "order": 1 } all_opt["privlvl"] = { "getopt" : "L:", "longopt" : "privlvl", "help" : "-L, --privlvl=[level] " "Privilege level on IPMI device (callback|user|operator|administrator)", "required" : "0", "shortdesc" : "Privilege level on IPMI device", "default" : "administrator", "choices" : ["callback", "user", "operator", "administrator"], "order": 1 } all_opt["ipmitool_path"] = { "getopt" : "i:", "longopt" : "ipmitool-path", "help" : "--ipmitool-path=[path] Path to ipmitool binary", "required" : "0", "shortdesc" : "Path to ipmitool binary", "default" : "@IPMITOOL_PATH@", "order": 200 } def main(): atexit.register(atexit_handler) device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd", "lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method"] define_new_opts() if os.path.basename(sys.argv[0]) == "fence_ilo3": all_opt["power_wait"]["default"] = "4" all_opt["method"]["default"] = "cycle" all_opt["lanplus"]["default"] = "1" elif os.path.basename(sys.argv[0]) == "fence_ilo4": all_opt["lanplus"]["default"] = "1" all_opt["ipport"]["default"] = "623" options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for IPMI" docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent\ which can be used with machines controlled by IPMI.\ This agent calls support software ipmitool (http://ipmitool.sf.net/)." docs["vendorurl"] = "" docs["symlink"] = [("fence_ilo3", "Fence agent for HP iLO3"), ("fence_ilo4", "Fence agent for HP iLO4"), ("fence_imm", "Fence agent for IBM Integrated Management Module"), ("fence_idrac", "Fence agent for Dell iDRAC")] show_docs(options, docs) if not is_executable(options["--ipmitool-path"]): fail_usage("Ipmitool not found or not accessible") result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle) sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/lpar/fence_lpar.py b/fence/agents/lpar/fence_lpar.py index 438acaeb..05e9b283 100644 --- a/fence/agents/lpar/fence_lpar.py +++ b/fence/agents/lpar/fence_lpar.py @@ -1,163 +1,163 @@ #!/usr/bin/python ##### ## ## The Following Agent Has Been Tested On: ## ## Version ## +---------------------------------------------+ ## Tested on HMC ## ##### -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_power_status(conn, options): if options["--hmc-version"] == "3": conn.send("lssyscfg -r lpar -m " + options["--managed"] + " -n " + options["--plug"] + " -F name,state\n") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) try: status = re.compile("^" + options["--plug"] + ",(.*?),.*$", re.IGNORECASE | re.MULTILINE).search(conn.before).group(1) except AttributeError: fail(EC_STATUS_HMC) elif options["--hmc-version"] == "4": conn.send("lssyscfg -r lpar -m "+ options["--managed"] + " --filter 'lpar_names=" + options["--plug"] + "'\n") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) try: status = re.compile(",state=(.*?),", re.IGNORECASE).search(conn.before).group(1) except AttributeError: fail(EC_STATUS_HMC) ## ## Transformation to standard ON/OFF status if possible if status in ["Running", "Open Firmware", "Shutting Down", "Starting"]: status = "on" else: status = "off" return status def set_power_status(conn, options): if options["--hmc-version"] == "3": conn.send("chsysstate -o " + options["--action"] + " -r lpar -m " + options["--managed"] + " -n " + options["--plug"] + "\n") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) elif options["--hmc-version"] == "4": if options["--action"] == "on": conn.send("chsysstate -o on -r lpar -m " + options["--managed"] + " -n " + options["--plug"] + " -f `lssyscfg -r lpar -F curr_profile " + " -m " + options["--managed"] + " --filter \"lpar_names="+ options["--plug"] +"\"`\n" ) else: conn.send("chsysstate -o shutdown -r lpar --immed" + " -m " + options["--managed"] + " -n " + options["--plug"] + "\n") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) def get_lpar_list(conn, options): outlets = { } if options["--hmc-version"] == "3": conn.send("query_partition_names -m " + options["--managed"] + "\n") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) ## We have to remove first 3 lines (command + header) and last line (part of new prompt) #### res = re.search("^.+?\n(.+?\n){2}(.*)\n.*$", conn.before, re.S) if res == None: fail_usage("Unable to parse output of list command") lines = res.group(2).split("\n") for outlet_line in lines: outlets[outlet_line.rstrip()] = ("", "") elif options["--hmc-version"] == "4": conn.send("lssyscfg -r lpar -m " + options["--managed"] + " -F name:state\n") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) ## We have to remove first line (command) and last line (part of new prompt) #### res = re.search("^.+?\n(.*)\n.*$", conn.before, re.S) if res == None: fail_usage("Unable to parse output of list command") lines = res.group(1).split("\n") for outlet_line in lines: (port, status) = outlet_line.split(":") outlets[port] = ("", status) return outlets def define_new_opts(): all_opt["managed"] = { "getopt" : "s:", "longopt" : "managed", "help" : "-s, --managed=[id] Name of the managed system", "required" : "0", "shortdesc" : "Managed system name", "order" : 1 } all_opt["hmc_version"] = { "getopt" : "H:", "longopt" : "hmc-version", "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", "choices" : [ "3", "4" ], "order" : 1 } def main(): device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt", \ "port", "managed", "hmc_version" ] atexit.register(atexit_handler) define_new_opts() all_opt["login_timeout"]["default"] = "15" all_opt["secure"]["default"] = "1" all_opt["cmd_prompt"]["default"] = [ ":~>", "]\$", "\$ " ] options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for IBM LPAR" docs["longdesc"] = "" docs["vendorurl"] = "http://www.ibm.com" show_docs(options, docs) if 0 == options.has_key("--managed"): fail_usage("Failed: You have to enter name of managed system") ## ## Operate the fencing device #### conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, get_lpar_list) ## ## Logout from system ###### try: conn.send("quit\r\n") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/netio/fence_netio.py b/fence/agents/netio/fence_netio.py index 5902e2e0..e483470d 100755 --- a/fence/agents/netio/fence_netio.py +++ b/fence/agents/netio/fence_netio.py @@ -1,114 +1,114 @@ #!/usr/bin/python -import sys, re, pexpect, exceptions +import sys, re, pexpect import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_power_status(conn, options): conn.send_eol("port %s" % options["--plug"]) re_status = re.compile("250 [01imt]") conn.log_expect(options, re_status, int(options["--shell-timeout"])) status = { "0" : "off", "1" : "on", "i" : "reboot", "m" : "manual", "t" : "timer" }[conn.after.split()[1]] return status def set_power_status(conn, options): action = { "on" : "1", "off" : "0", "reboot" : "i" }[options["--action"]] conn.send_eol("port %s %s" % (options["--plug"], action)) conn.log_expect(options, "250 OK", int(options["--shell-timeout"])) def get_outlet_list(conn, options): result = {} try: # the NETIO-230B has 4 ports, counting start at 1 for plug in ["1", "2", "3", "4"]: conn.send_eol("port setup %s" % plug) conn.log_expect(options, "250 .+", int(options["--shell-timeout"])) # the name is enclosed in "", drop those with [1:-1] name = conn.after.split()[1][1:-1] result[plug] = (name, "unknown") except Exception, exn: print str(exn) return result def main(): device_opt = [ "ipaddr", "login", "passwd", "port" ] atexit.register(atexit_handler) opt = process_input(device_opt) # set default port for telnet only if 0 == opt.has_key("--ipport"): opt["--ipport"] = "1234" opt["eol"] = "\r\n" options = check_input(device_opt, opt) docs = { } docs["shortdesc"] = "I/O Fencing agent for Koukaam NETIO-230B" docs["longdesc"] = "fence_netio is an I/O Fencing agent which can be \ used with the Koukaam NETIO-230B Power Distribution Unit. It logs into \ device via telnet and reboots a specified outlet. Lengthy telnet connections \ should be avoided while a GFS cluster is running because the connection will \ block any necessary fencing actions." docs["vendorurl"] = "http://www.koukaam.se/" show_docs(options, docs) ## ## Operate the fencing device ## We can not use fence_login(), username and passwd are sent on one line #### try: conn = fspawn(options, TELNET_PATH) conn.send("set binary\n") conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"])) conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"])) conn.log_expect(options, "100 HELLO .*", int(options["--shell-timeout"])) conn.send_eol("login %s %s" % (options["--username"], options["--password"])) conn.log_expect(options, "250 OK", int(options["--shell-timeout"])) except pexpect.EOF: fail(EC_LOGIN_DENIED) except pexpect.TIMEOUT: fail(EC_LOGIN_DENIED) result = fence_action(conn, options, set_power_status, get_power_status, get_outlet_list) ## ## Logout from system ## ## In some special unspecified cases it is possible that ## connection will be closed before we run close(). This is not ## a problem because everything is checked before. ###### try: conn.send("quit\n") conn.log_expect(options, "110 BYE", int(options["--shell-timeout"])) conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/rsa/fence_rsa.py b/fence/agents/rsa/fence_rsa.py index 992c5e6b..4e855a24 100644 --- a/fence/agents/rsa/fence_rsa.py +++ b/fence/agents/rsa/fence_rsa.py @@ -1,78 +1,78 @@ #!/usr/bin/python ##### ## ## The Following Agent Has Been Tested On: ## Main GFEP25A & Boot GFBP25A ## ##### -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New RSA2 Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_power_status(conn, options): conn.send_eol("power state") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) match = re.compile("Power: (.*)", re.IGNORECASE).search(conn.before) if (match != None): status = match.group(1) else: status = "undefined" return status.lower().strip() def set_power_status(conn, options): conn.send_eol("power " + options["--action"]) conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure" ] atexit.register(atexit_handler) all_opt["login_timeout"]["default"] = 10 all_opt["cmd_prompt"]["default"] = [ ">" ] # This device will not allow us to login even with LANG=C all_opt["ssh_options"]["default"] = "-F /dev/null" options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for IBM RSA" docs["longdesc"] = "fence_rsa is an I/O Fencing agent \ which can be used with the IBM RSA II management interface. It \ logs into an RSA II device via telnet and reboots the associated \ machine. Lengthy telnet connections to the RSA II device should \ be avoided while a GFS cluster is running because the connection \ will block any necessary fencing actions." docs["vendorurl"] = "http://www.ibm.com" show_docs(options, docs) ## ## Operate the fencing device ###### conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, None) ## ## Logout from system ###### try: conn.send_eol("exit") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py index 6c5e1193..89fb304d 100755 --- a/fence/agents/rsb/fence_rsb.py +++ b/fence/agents/rsb/fence_rsb.py @@ -1,87 +1,87 @@ #!/usr/bin/python -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_power_status(conn, options): conn.send("2") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) status = re.compile("Power Status[\s]*: (on|off)", re.IGNORECASE).search(conn.before).group(1) conn.send("0") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) return (status.lower().strip()) def set_power_status(conn, options): action = { 'on' : "4", 'off': "1" }[options["--action"]] conn.send("2") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.send_eol(action) conn.log_expect(options, ["want to power off", "'yes' or 'no'"], int(options["--shell-timeout"])) conn.send_eol("yes") conn.log_expect(options, "any key to continue", int(options["--power-timeout"])) conn.send_eol("") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) conn.send_eol("0") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) def main(): device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt" ] atexit.register(atexit_handler) all_opt["cmd_prompt"]["default"] = [ "to quit:" ] opt = process_input(device_opt) # set default port for telnet only if 0 == opt.has_key("--ssh") and 0 == opt.has_key("--ipport"): opt["--ipport"] = "3172" options = check_input(device_opt, opt) docs = { } docs["shortdesc"] = "I/O Fencing agent for Fujitsu-Siemens RSB" docs["longdesc"] = "fence_rsb is an I/O Fencing agent \ which can be used with the Fujitsu-Siemens RSB management interface. It logs \ into device via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh \ connections should be avoided while a GFS cluster is running because the connection \ will block any necessary fencing actions." docs["vendorurl"] = "http://www.fujitsu.com" show_docs(options, docs) ## ## Operate the fencing device #### conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, None) ## ## Logout from system ## ## In some special unspecified cases it is possible that ## connection will be closed before we run close(). This is not ## a problem because everything is checked before. ###### try: conn.send_eol("0") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/virsh/fence_virsh.py b/fence/agents/virsh/fence_virsh.py index 29d3e58e..170c0894 100644 --- a/fence/agents/virsh/fence_virsh.py +++ b/fence/agents/virsh/fence_virsh.py @@ -1,104 +1,104 @@ #!/usr/bin/python # The Following Agent Has Been Tested On: # # Virsh 0.3.3 on RHEL 5.2 with xen-3.0.3-51 # -import sys, re, pexpect, exceptions +import sys, re import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="Virsh fence agent" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION def get_name_or_uuid(options): return options["--uuid"] if options.has_key("--uuid") else options["--plug"] def get_outlets_status(conn, options): if options.has_key("--use-sudo"): prefix = SUDO_PATH + " " else: prefix = "" conn.sendline(prefix + "virsh list --all") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) result = {} #This is status of mini finite automata. 0 = we didn't found Id and Name, 1 = we did fa_status = 0 for line in conn.before.splitlines(): domain = re.search("^\s*(\S+)\s+(\S+)\s+(\S+).*$", line) if (domain!=None): if ((fa_status==0) and (domain.group(1).lower()=="id") and (domain.group(2).lower()=="name")): fa_status = 1 elif (fa_status==1): result[domain.group(2)] = ("", (domain.group(3).lower() in ["running", "blocked", "idle", "no state", "paused"] and "on" or "off")) return result def get_power_status(conn, options): prefix = SUDO_PATH + " " if options.has_key("--use-sudo") else "" conn.sendline(prefix + "virsh domstate %s" % (get_name_or_uuid(options))) conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) for line in conn.before.splitlines(): if line.strip() in ["running", "blocked", "idle", "no state", "paused"]: return "on" if "error:" in line.strip(): fail_usage("Failed: You have to enter existing name/UUID of virtual machine!") return "off" def set_power_status(conn, options): prefix = SUDO_PATH + " " if options.has_key("--use-sudo") else "" conn.sendline(prefix + "virsh %s " % (options["--action"] == "on" and "start" or "destroy") + get_name_or_uuid(options)) conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) time.sleep(int(options["--power-wait"])) def main(): device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "sudo" ] atexit.register(atexit_handler) all_opt["secure"]["default"] = "1" all_opt["cmd_prompt"]["default"] = [ "\[EXPECT\]#\ " ] all_opt["ssh_options"]["default"] = "-t '/bin/bash -c \"PS1=\[EXPECT\]#\ /bin/bash --noprofile --norc\"'" options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for virsh" docs["longdesc"] = "fence_virsh is an I/O Fencing agent \ which can be used with the virtual machines managed by libvirt. \ It logs via ssh to a dom0 and there run virsh command, which does \ all work. \ \n.P\n\ By default, virsh needs root account to do properly work. So you \ must allow ssh login in your sshd_config." docs["vendorurl"] = "http://libvirt.org" show_docs(options, docs) ## Operate the fencing device conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, get_outlets_status) ## Logout from system try: conn.sendline("quit") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/vmware/fence_vmware.py b/fence/agents/vmware/fence_vmware.py index 3cd2efa6..703ecdd7 100644 --- a/fence/agents/vmware/fence_vmware.py +++ b/fence/agents/vmware/fence_vmware.py @@ -1,339 +1,339 @@ #!/usr/bin/python # # The Following agent has been tested on: # vmrun 2.0.0 build-116503 (from VMware Server 2.0) against: # VMware ESX 4.0.0 # VMware vCenter 4.0.0 # VMware ESX 3.5 # VMware Server 2.0.0 # VMware ESXi 3.5 update 2 # VMware Server 1.0.7 (works but list/status show only running VMs) # # VI Perl API 1.6 against: # VMware ESX 4.0.0 # VMware vCenter 4.0.0 # VMware ESX 3.5 # VMware ESXi 3.5 update 2 # VMware Virtual Center 2.5 # # VMware vSphere SDK for Perl 4.0.0 against: # VMware ESX 4.0.0 # VMware vCenter 4.0.0 # -import sys, re, pexpect, exceptions +import sys, re, pexpect import logging import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="VMware Agent using VI Perl API and/or VIX vmrun command" REDHAT_COPYRIGHT="" BUILD_DATE="" #END_VERSION_GENERATION ### CONSTANTS #### # VMware type is ESX/ESXi/VC VMWARE_TYPE_ESX = 0 # VMware type is Server 1.x VMWARE_TYPE_SERVER1 = 1 # VMware type is Server 2.x and/or ESX 3.5 up2, ESXi 3.5 up2, VC 2.5 up2 VMWARE_TYPE_SERVER2 = 2 # Minimum required version of vmrun command VMRUN_MINIMUM_REQUIRED_VERSION = 2 # Default path to vmhelper command VMHELPER_COMMAND = "fence_vmware_helper" # Default path to vmrun command VMRUN_COMMAND = "/usr/bin/vmrun" # Default type of vmware VMWARE_DEFAULT_TYPE = "esx" #### GLOBAL VARIABLES #### # Internal type. One of VMWARE_TYPE_, set by #vmware_check_vmware_type vmware_internal_type = VMWARE_TYPE_ESX # If ESX is disconnected, say, that VM is off (don't return previous state) vmware_disconnected_hack = False ### FUNCTIONS #### #Split string in simplified DSV format to array of items def dsv_split(dsv_str): delimiter_c = ':' escape_c = '\\' res = [] status = 0 tmp_str = "" for x in dsv_str: if (status==0): if (x==delimiter_c): res.append(tmp_str) tmp_str = "" elif (x==escape_c): status = 1 else: tmp_str += x elif (status==1): if (x==delimiter_c): tmp_str += delimiter_c elif (x==escape_c): tmp_str += escape_c else: tmp_str += escape_c+x status = 0 if (tmp_str != ""): res.append(tmp_str) return res # Quote string for proper existence in quoted string used for pexpect.run function # Ex. test'this will return test'\''this. So pexpect run will really pass ' to argument def quote_for_run(str): dstr = '' for c in str: if c == r"'": dstr += "'\\''" else: dstr += c return dstr # Return string with command and additional parameters (something like vmrun -h 'host' def vmware_prepare_command(options, add_login_params, additional_params): res = options["--exec"] if (add_login_params): if (vmware_internal_type==VMWARE_TYPE_ESX): res += " --server '%s' --username '%s' --password '%s' "% (quote_for_run(options["--ip"]), quote_for_run(options["--username"]), quote_for_run(options["--password"])) elif (vmware_internal_type==VMWARE_TYPE_SERVER2): res += " -h 'https://%s/sdk' -u '%s' -p '%s' -T server "% (quote_for_run(options["--ip"]), quote_for_run(options["--username"]), quote_for_run(options["--password"])) elif (vmware_internal_type==VMWARE_TYPE_SERVER1): host_name_array = options["--ip"].split(':') res += " -h '%s' -u '%s' -p '%s' -T server1 "% (quote_for_run(host_name_array[0]), quote_for_run(options["--username"]), quote_for_run(options["--password"])) if (len(host_name_array)>1): res += "-P '%s' "% (quote_for_run(host_name_array[1])) if ((options.has_key("--vmware-datacenter")) and (vmware_internal_type==VMWARE_TYPE_ESX)): res += "--datacenter '%s' "% (quote_for_run(options["--vmware-datacenter"])) if (additional_params != ""): res += additional_params return res # Log message if user set verbose option def vmware_log(options, message): logging.debug("%s\n" % message) # Run command with timeout and parameters. Internaly uses vmware_prepare_command. Returns string # with output from vmrun command. If something fails (command not found, exit code is not 0), fail_usage # function is called (and never return). def vmware_run_command(options, add_login_params, additional_params, additional_timeout): command = vmware_prepare_command(options, add_login_params, additional_params) try: vmware_log(options, command) (res_output, res_code) = pexpect.run(command, int(options["--shell-timeout"]) + int(options["--login-timeout"]) + additional_timeout, True) if (res_code==None): fail(EC_TIMED_OUT) if ((res_code!=0) and (add_login_params)): vmware_log(options, res_output) fail_usage("%s returned %s"% (options["--exec"], res_output)) else: vmware_log(options, res_output) except pexpect.ExceptionPexpect: fail_usage("Cannot run command %s"% (options["--exec"])) return res_output # Get outlet list with status as hash table. If you will use add_vm_name, only VM with vmname is # returned. This is used in get_status function def vmware_get_outlets_vi(conn, options, add_vm_name): outlets = {} if (add_vm_name): all_machines = vmware_run_command(options, True, ("--operation status --vmname '%s'"% (quote_for_run(options["--plug"]))), 0) else: all_machines = vmware_run_command(options, True, "--operation list", int(options["--power-timeout"])) all_machines_array = all_machines.splitlines() for machine in all_machines_array: machine_array = dsv_split(machine) if (len(machine_array) == 4): if (machine_array[0] in outlets): fail_usage("Failed. More machines with same name %s found!"%(machine_array[0])) if (vmware_disconnected_hack): outlets[machine_array[0]] = ("", ( ((machine_array[2].lower() in ["poweredon"]) and (machine_array[3].lower()=="connected")) and "on" or "off")) else: outlets[machine_array[0]] = ("", ((machine_array[2].lower() in ["poweredon"]) and "on" or "off")) return outlets # Get outlet list with status as hash table. def vmware_get_outlets_vix(conn, options): outlets = {} running_machines = vmware_run_command(options, True, "list", 0) running_machines_array = running_machines.splitlines()[1:] if (vmware_internal_type==VMWARE_TYPE_SERVER2): all_machines = vmware_run_command(options, True, "listRegisteredVM", 0) all_machines_array = all_machines.splitlines()[1:] elif (vmware_internal_type==VMWARE_TYPE_SERVER1): all_machines_array = running_machines_array for machine in all_machines_array: if (machine!=""): outlets[machine] = ("", ((machine in running_machines_array) and "on" or "off")) return outlets def get_outlets_status(conn, options): if (vmware_internal_type==VMWARE_TYPE_ESX): return vmware_get_outlets_vi(conn, options, False) if ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)): return vmware_get_outlets_vix(conn, options) def get_power_status(conn, options): if (vmware_internal_type==VMWARE_TYPE_ESX): outlets = vmware_get_outlets_vi(conn, options, True) else: outlets = get_outlets_status(conn, options) if ((vmware_internal_type==VMWARE_TYPE_SERVER2) or (vmware_internal_type==VMWARE_TYPE_ESX)): if (not (options["--plug"] in outlets)): fail_usage("Failed: You have to enter existing name of virtual machine!") else: return outlets[options["--plug"]][1] elif (vmware_internal_type==VMWARE_TYPE_SERVER1): return ((options["--plug"] in outlets) and "on" or "off") def set_power_status(conn, options): if (vmware_internal_type==VMWARE_TYPE_ESX): additional_params = "--operation %s --vmname '%s'" % \ ((options["--action"]=="on" and "on" or "off"), quote_for_run(options["--plug"])) elif ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)): additional_params = "%s '%s'" % \ ((options["--action"]=="on" and "start" or "stop"), quote_for_run(options["--plug"])) if (options["--action"]=="off"): additional_params += " hard" vmware_run_command(options, True, additional_params, int(options["--power-timeout"])) # Returns True, if user uses supported vmrun version (currently >=2.0.0) otherwise False. def vmware_is_supported_vmrun_version(options): vmware_help_str = vmware_run_command(options, False, "", 0) version_re = re.search("vmrun version (\d\.(\d[\.]*)*)", vmware_help_str.lower()) if (version_re==None): return False # Looks like this "vmrun" is not real vmrun version_array = version_re.group(1).split(".") try: if (int(version_array[0]) < VMRUN_MINIMUM_REQUIRED_VERSION): return False except Exception: return False return True # Check vmware type, set vmware_internal_type to one of VMWARE_TYPE_ value and # options["--exec"] to path (if not specified) def vmware_check_vmware_type(options): global vmware_internal_type options["--vmware_type"] = options["--vmware_type"].lower() if (options["--vmware_type"]=="esx"): vmware_internal_type = VMWARE_TYPE_ESX if (not options.has_key("--exec")): options["--exec"] = VMHELPER_COMMAND elif (options["--vmware_type"]=="server2"): vmware_internal_type = VMWARE_TYPE_SERVER2 if (not options.has_key("--exec")): options["--exec"] = VMRUN_COMMAND elif (options["--vmware_type"]=="server1"): vmware_internal_type = VMWARE_TYPE_SERVER1 if (not options.has_key("--exec")): options["--exec"] = VMRUN_COMMAND else: fail_usage("vmware_type can be esx,server2 or server1!") # Main agent method def main(): device_opt = [ "ipaddr", "login", "passwd", "secure", "exec", "vmware_type", "vmware_datacenter"] atexit.register(atexit_handler) all_opt["secure"]["default"] = "1" all_opt["vmware_type"]["default"] = VMWARE_DEFAULT_TYPE options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for VMWare" docs["longdesc"] = "fence_vmware is an I/O Fencing agent \ which can be used with the VMware ESX, VMware ESXi or VMware Server \ to fence virtual machines.\ \n.P\n\ Before you can use this agent, it must be installed VI Perl Toolkit or \ vmrun command on every node you want to make fencing.\ \n.P\n\ VI Perl Toolkit is preferred for VMware ESX/ESXi and Virtual Center. Vmrun \ command is only solution for VMware Server 1/2 (this command will works against \ ESX/ESXi 3.5 up2 and VC up2 too, but not cluster aware!) and is available as part \ of VMware VIX API SDK package. VI Perl and VIX API SDK are both available from \ VMware web pages (not int RHEL repository!). \ \n.P\n\ You can specify type of VMware you are connecting to with \\fB-d\\fP switch \ (or \\fIvmware_type\\fR for stdin). Possible values are esx, server2 and server1.\ Default value is esx, which will use VI Perl. With server1 and server2, vmrun \ command is used.\ \n.P\n\ After you have successfully installed VI Perl Toolkit or VIX API, you should \ be able to run fence_vmware_helper (part of this agent) or vmrun command. \ This agent supports only vmrun from version 2.0.0 (VIX API 1.6.0)." docs["vendorurl"] = "http://www.vmware.com" show_docs(options, docs) # Check vmware type and set path vmware_check_vmware_type(options) # Test user vmrun command version if ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)): if (not (vmware_is_supported_vmrun_version(options))): fail_usage("Unsupported version of vmrun command! You must use at least version %d!" % (VMRUN_MINIMUM_REQUIRED_VERSION)) # Operate the fencing device result = fence_action(None, options, set_power_status, get_power_status, get_outlets_status) sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py index 6fa3cd66..b55b56ce 100644 --- a/fence/agents/vmware_soap/fence_vmware_soap.py +++ b/fence/agents/vmware_soap/fence_vmware_soap.py @@ -1,226 +1,226 @@ #!/usr/bin/python -import sys, exceptions, time +import sys, time import shutil, tempfile, suds import logging import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from suds.client import Client from suds.sudsobject import Property from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New VMWare Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="April, 2011" #END_VERSION_GENERATION def soap_login(options): if options["--action"] in ["off", "reboot"]: time.sleep(int(options["--delay"])) if options.has_key("--ssl"): url = "https://" else: url = "http://" url += options["--ip"] + ":" + str(options["--ipport"]) + "/sdk" tmp_dir = tempfile.mkdtemp() tempfile.tempdir = tmp_dir atexit.register(remove_tmp_dir, tmp_dir) try: conn = Client(url + "/vimService.wsdl") conn.set_options(location = url) mo_ServiceInstance = Property('ServiceInstance') mo_ServiceInstance._type = 'ServiceInstance' ServiceContent = conn.service.RetrieveServiceContent(mo_ServiceInstance) mo_SessionManager = Property(ServiceContent.sessionManager.value) mo_SessionManager._type = 'SessionManager' conn.service.Login(mo_SessionManager, options["--username"], options["--password"]) except Exception: fail(EC_LOGIN_DENIED) options["ServiceContent"] = ServiceContent options["mo_SessionManager"] = mo_SessionManager return conn def process_results(results, machines, uuid, mappingToUUID): for m in results.objects: info = {} for i in m.propSet: info[i.name] = i.val # Prevent error KeyError: 'config.uuid' when reaching systems which P2V failed, # since these systems don't have a valid UUID if info.has_key("config.uuid"): machines[info["name"]] = (info["config.uuid"], info["summary.runtime.powerState"]) uuid[info["config.uuid"]] = info["summary.runtime.powerState"] mappingToUUID[m.obj.value] = info["config.uuid"] return (machines, uuid, mappingToUUID) def get_power_status(conn, options): mo_ViewManager = Property(options["ServiceContent"].viewManager.value) mo_ViewManager._type = "ViewManager" mo_RootFolder = Property(options["ServiceContent"].rootFolder.value) mo_RootFolder._type = "Folder" mo_PropertyCollector = Property(options["ServiceContent"].propertyCollector.value) mo_PropertyCollector._type = 'PropertyCollector' ContainerView = conn.service.CreateContainerView(mo_ViewManager, recursive = 1, container = mo_RootFolder, type = ['VirtualMachine']) mo_ContainerView = Property(ContainerView.value) mo_ContainerView._type = "ContainerView" FolderTraversalSpec = conn.factory.create('ns0:TraversalSpec') FolderTraversalSpec.name = "traverseEntities" FolderTraversalSpec.path = "view" FolderTraversalSpec.skip = False FolderTraversalSpec.type = "ContainerView" objSpec = conn.factory.create('ns0:ObjectSpec') objSpec.obj = mo_ContainerView objSpec.selectSet = [ FolderTraversalSpec ] objSpec.skip = True propSpec = conn.factory.create('ns0:PropertySpec') propSpec.all = False propSpec.pathSet = ["name", "summary.runtime.powerState", "config.uuid"] propSpec.type = "VirtualMachine" propFilterSpec = conn.factory.create('ns0:PropertyFilterSpec') propFilterSpec.propSet = [ propSpec ] propFilterSpec.objectSet = [ objSpec ] try: raw_machines = conn.service.RetrievePropertiesEx(mo_PropertyCollector, propFilterSpec) except Exception: fail(EC_STATUS) (machines, uuid, mappingToUUID) = process_results(raw_machines, {}, {}, {}) # Probably need to loop over the ContinueRetreive if there are more results after 1 iteration. while (hasattr(raw_machines, 'token') == True): try: raw_machines = conn.service.ContinueRetrievePropertiesEx(mo_PropertyCollector, raw_machines.token) except Exception: fail(EC_STATUS) (more_machines, more_uuid, more_mappingToUUID) = process_results(raw_machines, {}, {}, {}) machines.update(more_machines) uuid.update(more_uuid) mappingToUUID.update(more_mappingToUUID) # Do not run unnecessary SOAP requests if options.has_key("--uuid") and options["--uuid"] in uuid: break if ["list", "monitor"].count(options["--action"]) == 1: return machines else: if options.has_key("--uuid") == False: if options["--plug"].startswith('/'): ## Transform InventoryPath to UUID mo_SearchIndex = Property(options["ServiceContent"].searchIndex.value) mo_SearchIndex._type = "SearchIndex" vm = conn.service.FindByInventoryPath(mo_SearchIndex, options["--plug"]) try: options["--uuid"] = mappingToUUID[vm.value] except KeyError: fail(EC_STATUS) except AttributeError: fail(EC_STATUS) else: ## Name of virtual machine instead of path ## warning: if you have same names of machines this won't work correctly try: (options["--uuid"], _) = machines[options["--plug"]] except KeyError: fail(EC_STATUS) except AttributeError: fail(EC_STATUS) try: if uuid[options["--uuid"]] == "poweredOn": return "on" else: return "off" except KeyError: fail(EC_STATUS) def set_power_status(conn, options): mo_SearchIndex = Property(options["ServiceContent"].searchIndex.value) mo_SearchIndex._type = "SearchIndex" vm = conn.service.FindByUuid(mo_SearchIndex, vmSearch = 1, uuid = options["--uuid"]) mo_machine = Property(vm.value) mo_machine._type = "VirtualMachine" try: if options["--action"] == "on": conn.service.PowerOnVM_Task(mo_machine) else: conn.service.PowerOffVM_Task(mo_machine) except suds.WebFault, ex: if ((str(ex).find("Permission to perform this operation was denied")) >= 0): fail(EC_INVALID_PRIVILEGES) else: if options["--action"] == "on": fail(EC_WAITING_ON) else: fail(EC_WAITING_OFF) def remove_tmp_dir(tmp_dir): shutil.rmtree(tmp_dir) def main(): device_opt = [ "ipaddr", "login", "passwd", "web", "ssl", "notls", "port" ] atexit.register(atexit_handler) options = check_input(device_opt, process_input(device_opt)) ## ## Fence agent specific defaults ##### docs = { } docs["shortdesc"] = "Fence agent for VMWare over SOAP API" docs["longdesc"] = "fence_vmware_soap is an I/O Fencing agent \ which can be used with the virtual machines managed by VMWare products \ that have SOAP API v4.1+. \ \n.P\n\ Name of virtual machine (-n / port) has to be used in inventory path \ format (e.g. /datacenter/vm/Discovered virtual machine/myMachine). \ In the cases when name of yours VM is unique you can use it instead. \ Alternatively you can always use UUID to access virtual machine." docs["vendorurl"] = "http://www.vmware.com" show_docs(options, docs) logging.basicConfig(level=logging.INFO) logging.getLogger('suds.client').setLevel(logging.CRITICAL) ## ## Operate the fencing device #### conn = soap_login(options) result = fence_action(conn, options, set_power_status, get_power_status, get_power_status) ## ## Logout from system ##### try: conn.service.Logout(options["mo_SessionManager"]) except Exception: pass sys.exit(result) if __name__ == "__main__": main() diff --git a/fence/agents/wti/fence_wti.py b/fence/agents/wti/fence_wti.py index 1cb3356a..bcb287bd 100644 --- a/fence/agents/wti/fence_wti.py +++ b/fence/agents/wti/fence_wti.py @@ -1,241 +1,241 @@ #!/usr/bin/python ##### ## ## The Following Agent Has Been Tested On: ## ## Version Firmware ## +-----------------+---------------------------+ ## WTI RSM-8R4 ?? unable to find out ?? ## WTI MPC-??? ?? unable to find out ?? ## WTI IPS-800-CE v1.40h (no username) ('list' tested) ##### -import sys, re, pexpect, exceptions +import sys, re, pexpect import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * #BEGIN_VERSION_GENERATION RELEASE_VERSION="New WTI Agent - test release on steroids" REDHAT_COPYRIGHT="" BUILD_DATE="March, 2008" #END_VERSION_GENERATION def get_listing(conn, options, listing_command): listing = "" conn.send(listing_command + "\r\n") if isinstance(options["--command-prompt"], list): re_all = list(options["--command-prompt"]) else: re_all = [options["--command-prompt"]] re_next = re.compile("Enter: ", re.IGNORECASE) re_all.append(re_next) result = conn.log_expect(options, re_all, int(options["--shell-timeout"])) listing = conn.before if result == (len(re_all) - 1): conn.send("\r\n") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) listing += conn.before return listing def get_plug_status(conn, options): listing = get_listing(conn, options, "/S") plug_section = 0 plug_index = -1 name_index = -1 status_index = -1 plug_header = list() outlets = {} for line in listing.splitlines(): if (plug_section == 2) and line.find("|") >= 0 and line.startswith("PLUG") == False: plug_line = [x.strip().lower() for x in line.split("|")] if len(plug_line) < len(plug_header): plug_section = -1 if ["list", "monitor"].count(options["--action"]) == 0 and \ options["--plug"].lower() == plug_line[plug_index]: return plug_line[status_index] else: ## We already believe that first column contains plug number if len(plug_line[0]) != 0: outlets[plug_line[0]] = (plug_line[name_index], plug_line[status_index]) elif (plug_section == 1): plug_section = 2 elif (line.upper().startswith("PLUG")): plug_section = 1 plug_header = [x.strip().lower() for x in line.split("|")] plug_index = plug_header.index("plug") name_index = plug_header.index("name") status_index = plug_header.index("status") if ["list", "monitor"].count(options["--action"]) == 1: return outlets else: return "PROBLEM" def get_plug_group_status_from_list(status_list): for status in status_list: if status == "on": return status return "off" def get_plug_group_status(conn, options): listing = get_listing(conn, options, "/SG") outlets = {} line_index = 0 lines = listing.splitlines() while line_index < len(lines) and line_index >= 0: line = lines[line_index] if (line.find("|") >= 0 and line.lstrip().startswith("GROUP NAME") == False): plug_line = [x.strip().lower() for x in line.split("|")] if ["list", "monitor"].count(options["--action"]) == 0 and \ options["--plug"].lower() == plug_line[name_index]: plug_status = [] while line_index < len(lines) and line_index >= 0: plug_line = [x.strip().lower() for x in lines[line_index].split("|")] if len(plug_line) >= max(name_index, status_index) and \ len(plug_line[plug_index]) > 0 and \ (len(plug_line[name_index]) == 0 or options["--plug"].lower() == plug_line[name_index]): ## Firmware 1.43 does not have a valid value of plug on first line as only name is defined on that line if not "---" in plug_line[status_index]: plug_status.append(plug_line[status_index]) line_index += 1 else: line_index = -1 return get_plug_group_status_from_list(plug_status) else: ## We already believe that first column contains plug number if len(plug_line[0]) != 0: group_name = plug_line[0] plug_line_index = line_index + 1 plug_status = [] while plug_line_index < len(lines) and plug_line_index >= 0: plug_line = [x.strip().lower() for x in lines[plug_line_index].split("|")] if len(plug_line[name_index]) > 0: plug_line_index = -1 break if len(plug_line[plug_index]) > 0: plug_status.append(plug_line[status_index]) plug_line_index += 1 else: plug_line_index = -1 outlets[group_name] = (group_name, get_plug_group_status_from_list(plug_status)) line_index += 1 elif (line.upper().lstrip().startswith("GROUP NAME")): plug_header = [x.strip().lower() for x in line.split("|")] name_index = plug_header.index("group name") plug_index = plug_header.index("plug") status_index = plug_header.index("status") line_index += 2 else: line_index += 1 if ["list", "monitor"].count(options["--action"]) == 1: for group, status in outlet_groups: outlets[group] = (group, status[0]) return outlets else: return "PROBLEM" def get_power_status(conn, options): ret = get_plug_status(conn, options) if ret == "PROBLEM": ret = get_plug_group_status(conn, options) return ret def set_power_status(conn, options): action = { 'on' : "/on", 'off': "/off" }[options["--action"]] conn.send(action + " " + options["--plug"] + ",y\r\n") conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) def main(): device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \ "cmd_prompt", "secure", "port" ] atexit.register(atexit_handler) all_opt["cmd_prompt"]["default"] = [ "RSM>", "MPC>", "IPS>", "TPS>", "NBB>", "NPS>", "VMR>" ] options = check_input(device_opt, process_input(device_opt)) docs = { } docs["shortdesc"] = "Fence agent for WTI" docs["longdesc"] = "fence_wti is an I/O Fencing agent \ which can be used with the WTI Network Power Switch (NPS). It logs \ into an NPS via telnet or ssh and boots a specified plug. \ Lengthy telnet connections to the NPS should be avoided while a GFS cluster \ is running because the connection will block any necessary fencing actions." docs["vendorurl"] = "http://www.wti.com" show_docs(options, docs) ## ## Operate the fencing device ## ## @note: if it possible that this device does not need either login, password or both of them ##### if 0 == options.has_key("--ssh"): try: if options["--action"] in ["off", "reboot"]: time.sleep(int(options["--delay"])) conn = fspawn(options, TELNET_PATH) conn.send("set binary\n") conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"])) re_login = re.compile("(login: )|(Login Name: )|(username: )|(User Name :)", re.IGNORECASE) re_prompt = re.compile("|".join(map (lambda x: "(" + x + ")", options["--command-prompt"])), re.IGNORECASE) result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], int(options["--shell-timeout"])) if result == 0: if options.has_key("--username"): conn.send(options["--username"]+"\r\n") result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], int(options["--shell-timeout"])) else: fail_usage("Failed: You have to set login name") if result == 1: if options.has_key("--password"): conn.send(options["--password"]+"\r\n") conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) else: fail_usage("Failed: You have to enter password or password script") except pexpect.EOF: fail(EC_LOGIN_DENIED) except pexpect.TIMEOUT: fail(EC_LOGIN_DENIED) else: conn = fence_login(options) result = fence_action(conn, options, set_power_status, get_power_status, get_power_status) ## ## Logout from system ###### try: conn.send("/X"+"\r\n") conn.close() except: pass sys.exit(result) if __name__ == "__main__": main()