Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py
index d0ed9b65..fa1c3a65 100644
--- a/fence/agents/apc/fence_apc.py
+++ b/fence/agents/apc/fence_apc.py
@@ -1,236 +1,237 @@
#!/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
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 = {}
try:
conn.send_eol("1")
conn.log_expect(options, options["-c"], int(options["-Y"]))
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("-s")):
fail_usage("Failed: You have to enter physical switch number")
else:
if (0 == options.has_key("-s")):
options["-s"] = "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["-c"], int(options["-Y"]))
conn.send_eol("1")
else:
conn.send_eol(options["-s"])
while True:
exp_result = conn.log_expect(options, [ options["-c"], "Press <ENTER>" ], int(options["-Y"]))
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["-Y"]))
conn.log_expect(options, options["-c"], int(options["-Y"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
if ["list", "monitor"].count(options["-o"]) == 1:
return outlets
else:
try:
(_, status) = outlets[options["-n"]]
return status.lower().strip()
except KeyError:
fail(EC_STATUS)
def set_power_status(conn, options):
action = {
'on' : "1",
'off': "2"
}[options["-o"]]
try:
conn.send_eol("1")
conn.log_expect(options, options["-c"], int(options["-Y"]))
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["-o"]]
if (None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before)):
if (0 == options.has_key("-s")):
fail_usage("Failed: You have to enter physical switch number")
else:
if (0 == options.has_key("-s")):
options["-s"] = 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["-c"], int(options["-Y"]))
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["-s"])
while 1 == conn.log_expect(options, [ options["-c"], "Press <ENTER>" ], int(options["-Y"])):
conn.send_eol("")
+
conn.send_eol(options["-n"]+"")
conn.log_expect(options, options["-c"], int(options["-Y"]))
if switch == 0:
if admin2 == 1:
conn.send_eol("1")
conn.log_expect(options, options["-c"], int(options["-Y"]))
if admin3 == 1:
conn.send_eol("1")
conn.log_expect(options, options["-c"], int(options["-Y"]))
else:
conn.send_eol("1")
conn.log_expect(options, options["-c"], int(options["-Y"]))
conn.send_eol(action)
conn.log_expect(options, "Enter 'YES' to continue or <ENTER> to cancel :", int(options["-Y"]))
conn.send_eol("YES")
conn.log_expect(options, "Press <ENTER> to continue...", int(options["-Y"]))
conn.send_eol("")
conn.log_expect(options, options["-c"], int(options["-Y"]))
conn.send(chr(03))
conn.log_expect(options, "- Logout", int(options["-Y"]))
conn.log_expect(options, options["-c"], int(options["-Y"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script", "cmd_prompt",
"secure", "port", "identity_file", "switch", "test", "separator",
"inet4_only", "inet6_only", "ipport" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = "\n>"
options = check_input(device_opt, process_input(device_opt))
options["ssh_options"] = "-1 -c blowfish"
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 -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)
options["-s"] = switch
options["-n"] = plug
##
## Operate the fencing device
####
conn = fence_login(options)
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 exceptions.OSError:
pass
except pexpect.ExceptionPexpect:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/apc_snmp/fence_apc_snmp.py b/fence/agents/apc_snmp/fence_apc_snmp.py
index cc624a10..6f95f378 100644
--- a/fence/agents/apc_snmp/fence_apc_snmp.py
+++ b/fence/agents/apc_snmp/fence_apc_snmp.py
@@ -1,204 +1,198 @@
#!/usr/bin/python
# The Following agent has been tested on:
# - APC Switched Rack PDU (MB:v3.7.0 PF:v2.7.0 PN:apc_hw02_aos_270.bin AF1:v2.7.3 AN1:apc_hw02_aos_270.bin
# AF1:v2.7.3 AN1:apc_hw02_rpdu_273.bin MN:AP7930 HR:B2) - SNMP v1
# - APC Web/SNMP Management Card (MB:v3.8.6 PF:v3.5.8 PN:apc_hw02_aos_358.bin AF1:v3.5.7 AN1:apc_hw02_aos_358.bin
# AF1:v3.5.7 AN1:apc_hw02_rpdu_357.bin MN:AP7900 HR:B2) - SNMP v1 and v3 (noAuthNoPrivacy,authNoPrivacy, authPrivacy)
# - APC Switched Rack PDU (MB:v3.7.0 PF:v2.7.0 PN:apc_hw02_aos_270.bin AF1:v2.7.3 AN1:apc_hw02_rpdu_273.bin
# MN:AP7951 HR:B2) - SNMP v1
import sys
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="APC SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# oid defining fence device
OID_SYS_OBJECT_ID = '.1.3.6.1.2.1.1.2.0'
### GLOBAL VARIABLES ###
# Device - see ApcRPDU, ApcMSP, ApcMS
device = None
# Port ID
port_id = None
# Switch ID
switch_id = None
# Classes describing Device params
class ApcRPDU:
# Rack PDU
status_oid = '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.4.%d'
control_oid = '.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4.%d'
outlet_table_oid = '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.2'
ident_str = "APC rPDU"
state_on = 1
state_off = 2
turn_on = 1
turn_off = 2
has_switches = False
class ApcMSP:
# Master Switch+
status_oid = '.1.3.6.1.4.1.318.1.1.6.7.1.1.5.%d.1.%d'
control_oid = '.1.3.6.1.4.1.318.1.1.6.5.1.1.5.%d.1.%d'
outlet_table_oid = '.1.3.6.1.4.1.318.1.1.6.7.1.1.4'
ident_str = "APC Master Switch+"
state_on = 1
state_off = 2
turn_on = 1
turn_off = 3
has_switches = True
class ApcMS:
# Master Switch - seems oldest, but supported on every APC PDU
status_oid = '.1.3.6.1.4.1.318.1.1.4.4.2.1.3.%d'
control_oid = '.1.3.6.1.4.1.318.1.1.4.4.2.1.3.%d'
outlet_table_oid = '.1.3.6.1.4.1.318.1.1.4.4.2.1.4'
ident_str = "APC Master Switch (fallback)"
state_on = 1
state_off = 2
turn_on = 1
turn_off = 2
has_switches = False
### FUNCTIONS ###
def apc_set_device(conn, options):
global device
agents_dir = {'.1.3.6.1.4.1.318.1.3.4.5':ApcRPDU,
'.1.3.6.1.4.1.318.1.3.4.4':ApcMSP,
None:ApcMS}
# First resolve type of APC
apc_type = conn.walk(OID_SYS_OBJECT_ID)
if (not ((len(apc_type)==1) and (agents_dir.has_key(apc_type[0][1])))):
apc_type = [[None, None]]
device = agents_dir[apc_type[0][1]]
conn.log_command("Trying %s"%(device.ident_str))
def apc_resolv_port_id(conn, options):
- global port_id, switch_id, device
+ global port_id, switch_id
if (device == None):
apc_set_device(conn, options)
# Now we resolv port_id/switch_id
if ((options["-n"].isdigit()) and ((not device.has_switches) or (options["-s"].isdigit()))):
port_id = int(options["-n"])
if (device.has_switches):
switch_id = int(options["-s"])
else:
table = conn.walk(device.outlet_table_oid, 30)
for x in table:
if (x[1].strip('"') == options["-n"]):
t = x[0].split('.')
if (device.has_switches):
port_id = int(t[len(t)-1])
switch_id = int(t[len(t)-3])
else:
port_id = int(t[len(t)-1])
if (port_id == None):
fail_usage("Can't find port with name %s!"%(options["-n"]))
def get_power_status(conn, options):
- global port_id, switch_id, device
-
if (port_id == None):
apc_resolv_port_id(conn, options)
oid = ((device.has_switches) and device.status_oid%(switch_id, port_id) or device.status_oid%(port_id))
(oid, status) = conn.get(oid)
return (status==str(device.state_on) and "on" or "off")
def set_power_status(conn, options):
- global port_id, switch_id, device
-
if (port_id == None):
apc_resolv_port_id(conn, options)
oid = ((device.has_switches) and device.control_oid%(switch_id, port_id) or device.control_oid%(port_id))
conn.set(oid, (options["-o"]=="on" and device.turn_on or device.turn_off))
def get_outlets_status(conn, options):
- global device
-
result = {}
if (device == None):
apc_set_device(conn, options)
res_ports = conn.walk(device.outlet_table_oid, 30)
for x in res_ports:
t = x[0].split('.')
port_num = ((device.has_switches) and "%s:%s"%(t[len(t)-3], t[len(t)-1]) or "%s"%(t[len(t)-1]))
port_name = x[1].strip('"')
port_status = ""
result[port_num] = (port_name, port_status)
return result
# Define new options
def apc_snmp_define_defaults():
all_opt["snmp_version"]["default"] = "1"
all_opt["community"]["default"] = "private"
# Main agent method
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"test", "port", "separator", "no_login", "no_password",
"snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
"snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
"udpport", "inet4_only", "inet6_only" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
apc_snmp_define_defaults()
options = check_input(device_opt, process_input(device_opt))
## Support for -n [switch]:[plug] notation that was used before
if ((options.has_key("-n")) and (-1 != options["-n"].find(":"))):
(switch, plug) = options["-n"].split(":", 1)
if ((switch.isdigit()) and (plug.isdigit())):
options["-s"] = switch
options["-n"] = plug
if (not (options.has_key("-s"))):
options["-s"] = "1"
docs = { }
docs["shortdesc"] = "Fence agent for APC over SNMP"
docs["longdesc"] = "fence_apc_snmp is an I/O Fencing agent \
which can be used with the APC network power switch. It logs \
into a device via SNMP and reboots a specified outlet. It supports \
SNMP v1 and v3 with all combinations of authenticity/privacy settings."
docs["vendorurl"] = "http://www.apc.com"
show_docs(options, docs)
# Operate the fencing device
result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py
index 49a3b5be..2825dbec 100644
--- a/fence/agents/bladecenter/fence_bladecenter.py
+++ b/fence/agents/bladecenter/fence_bladecenter.py
@@ -1,136 +1,136 @@
#!/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
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):
try:
node_cmd = "system:blade\[" + options["-n"] + "\]>"
conn.send_eol("env -T system:blade[" + options["-n"] + "]")
i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["-Y"]))
if i == 1:
## Given blade number does not exist
if options.has_key("-M"):
return "off"
else:
fail(EC_STATUS)
conn.send_eol("power -state")
conn.log_expect(options, node_cmd, int(options["-Y"]))
status = conn.before.splitlines()[-1]
conn.send_eol("env -T system")
conn.log_expect(options, options["-c"], int(options["-Y"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
return status.lower().strip()
def set_power_status(conn, options):
try:
node_cmd = "system:blade\[" + options["-n"] + "\]>"
conn.send_eol("env -T system:blade[" + options["-n"] + "]")
i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["-Y"]))
if i == 1:
## Given blade number does not exist
if options.has_key("-M"):
return
else:
fail(EC_GENERIC_ERROR)
conn.send_eol("power -"+options["-o"])
conn.log_expect(options, node_cmd, int(options["-Y"]))
conn.send_eol("env -T system")
conn.log_expect(options, options["-c"], int(options["-Y"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
def get_blades_list(conn, options):
outlets = { }
try:
node_cmd = "system>"
conn.send_eol("env -T system")
conn.log_expect(options, node_cmd, int(options["-Y"]))
conn.send_eol("list -l 2")
conn.log_expect(options, node_cmd, int(options["-Y"]))
lines = conn.before.split("\r\n")
filter_re = re.compile("^\s*blade\[(\d+)\]\s+(.*?)\s*$")
- for x in lines:
- res = filter_re.search(x)
+ for blade_line in lines:
+ res = filter_re.search(blade_line)
if res != None:
outlets[res.group(1)] = (res.group(2), "")
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
return outlets
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"cmd_prompt", "secure", "port", "identity_file", "separator",
"inet4_only", "inet6_only", "ipport", "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)
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 exceptions.OSError:
pass
except pexpect.ExceptionPexpect:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/cisco_mds/fence_cisco_mds.py b/fence/agents/cisco_mds/fence_cisco_mds.py
index 8f3ef9df..8ebce8ac 100644
--- a/fence/agents/cisco_mds/fence_cisco_mds.py
+++ b/fence/agents/cisco_mds/fence_cisco_mds.py
@@ -1,112 +1,108 @@
#!/usr/bin/python
# The Following agent has been tested on:
# - Cisco MDS UROS 9134 FC (1 Slot) Chassis ("1/2/4 10 Gbps FC/Supervisor-2") Motorola, e500v2
# with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
# - Cisco MDS 9124 (1 Slot) Chassis ("1/2/4 Gbps FC/Supervisor-2") Motorola, e500
# with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
import sys, re
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Cisco MDS 9xxx SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# Cisco admin status
PORT_ADMIN_STATUS_OID = ".1.3.6.1.2.1.75.1.2.2.1.1"
# IF-MIB trees for alias, status and port
ALIASES_OID = ".1.3.6.1.2.1.31.1.1.1.18"
PORTS_OID = ".1.3.6.1.2.1.2.2.1.2"
### GLOBAL VARIABLES ###
# OID converted from fc port name (fc(x)/(y))
-port_oid = ""
+PORT_OID = ""
### FUNCTIONS ###
# Convert cisco port name (fc(x)/(y)) to OID
def cisco_port2oid(port):
port = port.lower()
nums = re.match('^fc(\d+)/(\d+)$', port)
if ((nums) and (len(nums.groups()))==2):
return "%s.%d.%d"% (PORT_ADMIN_STATUS_OID, int(nums.group(1))+21, int(nums.group(2))-1)
else:
fail_usage("Mangled port number: %s"%(port))
def get_power_status(conn, options):
- global port_oid
-
- (oid, status) = conn.get(port_oid)
+ (oid, status) = conn.get(PORT_OID)
return (status=="1" and "on" or "off")
def set_power_status(conn, options):
- global port_oid
-
- conn.set(port_oid,(options["-o"]=="on" and 1 or 2))
+ conn.set(PORT_OID, (options["-o"]=="on" and 1 or 2))
# Convert array of format [[key1, value1], [key2, value2], ... [keyN, valueN]] to dict, where key is
# in format a.b.c.d...z and returned dict has key only z
def array_to_dict(ar):
return dict(map(lambda y:[y[0].split('.')[-1], y[1]], ar))
def get_outlets_status(conn, options):
result = {}
res_fc = conn.walk(PORTS_OID, 30)
res_aliases = array_to_dict(conn.walk(ALIASES_OID, 30))
fc_re = re.compile('^"fc\d+/\d+"$')
for x in res_fc:
if fc_re.match(x[1]):
port_num = x[0].split('.')[-1]
port_name = x[1].strip('"')
port_alias = (res_aliases.has_key(port_num) and res_aliases[port_num].strip('"') or "")
port_status = ""
result[port_name] = (port_alias, port_status)
return result
# Main agent method
def main():
- global port_oid
+ global PORT_OID
device_opt = [ "fabric_fencing", "ipaddr", "login", "passwd", "passwd_script",
"test", "port", "separator", "no_login", "no_password",
"snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
"snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
"udpport", "inet4_only", "inet6_only" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for Cisco MDS"
docs["longdesc"] = "fence_cisco_mds is an I/O Fencing agent \
which can be used with any Cisco MDS 9000 series with SNMP enabled device."
docs["vendorurl"] = "http://www.cisco.com"
show_docs(options, docs)
if (not (options["-o"] in ["list","monitor"])):
- port_oid = cisco_port2oid(options["-n"])
+ PORT_OID = cisco_port2oid(options["-n"])
# Operate the fencing device
result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py
index a34a5805..d1d5f2bd 100644
--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py
+++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py
@@ -1,145 +1,155 @@
#!/usr/bin/python
import sys, re
import pycurl, StringIO
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Cisco UCS Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
-re_cookie = re.compile("<aaaLogin .* outCookie=\"(.*?)\"", re.IGNORECASE)
-re_status = re.compile("<lsPower .*? state=\"(.*?)\"", re.IGNORECASE)
-re_get_dn = re.compile(" dn=\"(.*?)\"", re.IGNORECASE)
-re_get_desc = re.compile(" descr=\"(.*?)\"", re.IGNORECASE)
+RE_COOKIE = re.compile("<aaaLogin .* outCookie=\"(.*?)\"", re.IGNORECASE)
+RE_STATUS = re.compile("<lsPower .*? state=\"(.*?)\"", re.IGNORECASE)
+RE_GET_DN = re.compile(" dn=\"(.*?)\"", re.IGNORECASE)
+RE_GET_DESC = re.compile(" descr=\"(.*?)\"", re.IGNORECASE)
def get_power_status(conn, options):
try:
- res = send_command(options, "<configResolveDn cookie=\"" + options["cookie"] + "\" inHierarchical=\"false\" dn=\"org-root" + options["-s"] + "/ls-" + options["-n"] + "/power\"/>", int(options["-Y"]))
+ res = send_command(options, \
+ "<configResolveDn cookie=\"" + options["cookie"] + "\" inHierarchical=\"false\" dn=\"org-root" + options["-s"] + \
+ "/ls-" + options["-n"] + "/power\"/>", \
+ int(options["-Y"]))
except pycurl.error, e:
sys.stderr.write(e[1] + "\n")
fail(EC_TIMED_OUT)
- result = re_status.search(res)
+ result = RE_STATUS.search(res)
if (result == None):
fail(EC_STATUS)
else:
status = result.group(1)
if (status == "up"):
return "on"
else:
return "off"
def set_power_status(conn, options):
action = {
'on' : "up",
'off' : "down"
}[options["-o"]]
try:
- res = send_command(options, "<configConfMos cookie=\"" + options["cookie"] + "\" inHierarchical=\"no\"><inConfigs><pair key=\"org-root" + options["-s"] + "/ls-" + options["-n"] + "/power\"><lsPower dn=\"org-root/ls-" + options["-n"] + "/power\" state=\"" + action + "\" status=\"modified\" /></pair></inConfigs></configConfMos>", int(options["-Y"]))
+ res = send_command(options, \
+ "<configConfMos cookie=\"" + options["cookie"] + "\" inHierarchical=\"no\">" + \
+ "<inConfigs><pair key=\"org-root" + options["-s"] + "/ls-" + options["-n"] + "/power\">" + \
+ "<lsPower dn=\"org-root/ls-" + options["-n"] + "/power\" state=\"" + action + "\" status=\"modified\" />" + \
+ "</pair></inConfigs></configConfMos>", \
+ int(options["-Y"]))
except pycurl.error, e:
sys.stderr.write(e[1] + "\n")
fail(EC_TIMED_OUT)
return
def get_list(conn, options):
outlets = { }
try:
try:
- res = send_command(options, "<configResolveClass cookie=\"" + options["cookie"] + "\" inHierarchical=\"false\" classId=\"lsServer\"/>", int(options["-Y"]))
+ res = send_command(options, \
+ "<configResolveClass cookie=\"" + options["cookie"] + "\" inHierarchical=\"false\" classId=\"lsServer\"/>", \
+ int(options["-Y"]))
except pycurl.error, e:
sys.stderr.write(e[1] + "\n")
fail(EC_TIMED_OUT)
lines = res.split("<lsServer ")
for i in range(1, len(lines)):
- dn = re_get_dn.search(lines[i]).group(1)
- desc = re_get_desc.search(lines[i]).group(1)
+ dn = RE_GET_DN.search(lines[i]).group(1)
+ desc = RE_GET_DESC.search(lines[i]).group(1)
outlets[dn] = (desc, None)
except AttributeError:
return { }
except IndexError:
return { }
return outlets
def send_command(opt, command, timeout):
## setup correct URL
if opt.has_key("-z"):
url = "https:"
else:
url = "http:"
url += "//" + opt["-a"] + ":" + str(opt["-u"]) + "/nuova"
## send command through pycurl
c = pycurl.Curl()
b = StringIO.StringIO()
c.setopt(pycurl.URL, url)
c.setopt(pycurl.HTTPHEADER, [ "Content-type: text/xml" ])
c.setopt(pycurl.POSTFIELDS, command)
c.setopt(pycurl.WRITEFUNCTION, b.write)
c.setopt(pycurl.TIMEOUT, timeout)
c.setopt(pycurl.SSL_VERIFYPEER, 0)
c.setopt(pycurl.SSL_VERIFYHOST, 0)
c.perform()
result = b.getvalue()
if opt["log"] >= LOG_MODE_VERBOSE:
opt["debug_fh"].write(command + "\n")
opt["debug_fh"].write(result + "\n")
return result
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"ssl", "inet4_only", "inet6_only", "ipport", "port",
"web", "separator", "suborg" ]
atexit.register(atexit_handler)
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for Cisco UCS"
docs["longdesc"] = "fence_cisco_ucs is an I/O Fencing agent which can be \
used with Cisco UCS to fence machines."
docs["vendorurl"] = "http://www.cisco.com"
show_docs(options, docs)
### Login
res = send_command(options, "<aaaLogin inName=\"" + options["-l"] + "\" inPassword=\"" + options["-p"] + "\" />", int(options["-y"]))
- result = re_cookie.search(res)
+ result = RE_COOKIE.search(res)
if (result == None):
## Cookie is absenting in response
fail(EC_LOGIN_DENIED)
options["cookie"] = result.group(1)
##
## Modify suborg to format /suborg
if options["-s"] != "":
if options["-s"].startswith("/") == False:
options["-s"] = "/" + options["-s"]
if options["-s"].endswith("/") == True:
options["-s"] = options["-s"][0:-1]
##
## Fence operations
####
result = fence_action(None, options, set_power_status, get_power_status, get_list)
### Logout; we do not care about result as we will end in any case
send_command(options, "<aaaLogout inCookie=\"" + options["cookie"] + "\" />", int(options["-Y"]))
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/eaton_snmp/fence_eaton_snmp.py b/fence/agents/eaton_snmp/fence_eaton_snmp.py
index 24e29fe2..2c5017b0 100644
--- a/fence/agents/eaton_snmp/fence_eaton_snmp.py
+++ b/fence/agents/eaton_snmp/fence_eaton_snmp.py
@@ -1,238 +1,236 @@
#!/usr/bin/python
# The Following agent has been tested on:
# - Eaton ePDU Managed - SNMP v1
# EATON | Powerware ePDU model: Managed ePDU (PW104MA0UB99), firmware: 01.01.01
# - Eaton ePDU Switched - SNMP v1
# EATON | Powerware ePDU model: Switched ePDU (IPV3600), firmware: 2.0.K
import sys
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Eaton SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# oid defining fence device
OID_SYS_OBJECT_ID = '.1.3.6.1.2.1.1.2.0'
### GLOBAL VARIABLES ###
# Device - see EatonManagedePDU, EatonSwitchedePDU
device = None
# Port ID
port_id = None
# Switch ID
switch_id = None
# Did we issue a set before get (to adjust OID with Switched ePDU)
after_set = False
# Classes describing Device params
# Managed ePDU
class EatonManagedePDU:
status_oid = '.1.3.6.1.4.1.534.6.6.6.1.2.2.1.3.%d'
control_oid = '.1.3.6.1.4.1.534.6.6.6.1.2.2.1.3.%d'
outlet_table_oid = '.1.3.6.1.4.1.534.6.6.6.1.2.2.1.1'
ident_str = "Eaton Managed ePDU"
state_off = 0
state_on = 1
state_cycling = 2 # FIXME: not usable with fence-agents
turn_off = 0
turn_on = 1
turn_cycle = 2 # FIXME: not usable with fence-agents
has_switches = False
# Switched ePDU (Pulizzi 2)
# NOTE: sysOID reports "20677.1", while data are actually at "20677.2"
class EatonSwitchedePDU:
status_oid = '.1.3.6.1.4.1.20677.2.6.3.%d.0'
control_oid = '.1.3.6.1.4.1.20677.2.6.2.%d.0'
outlet_table_oid = '.1.3.6.1.4.1.20677.2.6.3'
ident_str = "Eaton Switched ePDU"
state_off = 2
state_on = 1
state_cycling = 0 # Note: this status doesn't exist on this device
turn_off = 2
turn_on = 1
turn_cycle = 3 # FIXME: not usable with fence-agents
has_switches = False
### FUNCTIONS ###
def eaton_set_device(conn, options):
global device
agents_dir = {'.1.3.6.1.4.1.534.6.6.6':EatonManagedePDU,
'.1.3.6.1.4.1.20677.1':EatonSwitchedePDU,
'.1.3.6.1.4.1.20677.2':EatonSwitchedePDU }
# First resolve type of Eaton
eaton_type = conn.walk(OID_SYS_OBJECT_ID)
if (not ((len(eaton_type)==1) and (agents_dir.has_key(eaton_type[0][1])))):
eaton_type = [[None, None]]
device = agents_dir[eaton_type[0][1]]
conn.log_command("Trying %s"%(device.ident_str))
def eaton_resolv_port_id(conn, options):
- global port_id, switch_id, device
+ global port_id, switch_id
if (device==None):
eaton_set_device(conn, options)
# Restore the increment, that was removed in main for ePDU Managed
if (device.ident_str == "Eaton Switched ePDU"):
options["-n"] = str(int(options["-n"]) + 1)
# Now we resolv port_id/switch_id
if ((options["-n"].isdigit()) and ((not device.has_switches) or (options["-s"].isdigit()))):
port_id = int(options["-n"])
if (device.has_switches):
switch_id = int(options["-s"])
else:
table = conn.walk(device.outlet_table_oid, 30)
for x in table:
if (x[1].strip('"')==options["-n"]):
t = x[0].split('.')
if (device.has_switches):
port_id = int(t[len(t)-1])
switch_id = int(t[len(t)-3])
else:
if (device.ident_str == "Eaton Switched ePDU"):
port_id = int(t[len(t)-3])
else:
port_id = int(t[len(t)-1])
if (port_id==None):
# Restore index offset, to provide a valid error output on Managed ePDU
if (device.ident_str != "Eaton Switched ePDU"):
options["-n"] = str(int(options["-n"]) + 1)
fail_usage("Can't find port with name %s!"%(options["-n"]))
def get_power_status(conn, options):
- global port_id, switch_id, device, after_set
+ global port_id, after_set
if (port_id==None):
eaton_resolv_port_id(conn, options)
# Ajust OID for Switched ePDU when the get is after a set
if ((after_set == True) and (device.ident_str == "Eaton Switched ePDU")):
port_id -= 1
after_set = False
oid = ((device.has_switches) and device.status_oid%(switch_id, port_id) or device.status_oid%(port_id))
try:
(oid, status)=conn.get(oid)
if (status==str(device.state_on)):
return "on"
elif (status==str(device.state_off)):
return "off"
else:
return None
except:
return None
def set_power_status(conn, options):
- global port_id, switch_id, device, after_set
+ global port_id, after_set
after_set = True
if (port_id==None):
eaton_resolv_port_id(conn, options)
# Controls start at #2 on Switched ePDU, since #1 is the global command
if (device.ident_str == "Eaton Switched ePDU"):
port_id = int(port_id)+1
oid = ((device.has_switches) and device.control_oid%(switch_id, port_id) or device.control_oid%(port_id))
conn.set(oid,(options["-o"]=="on" and device.turn_on or device.turn_off))
def get_outlets_status(conn, options):
- global device
-
outletCount = 0
result = {}
if (device==None):
eaton_set_device(conn, options)
res_ports = conn.walk(device.outlet_table_oid, 30)
for x in res_ports:
outletCount += 1
status = x[1]
t = x[0].split('.')
# Plug indexing start from zero, so we substract '1' from the
# user's given plug number
if (device.ident_str == "Eaton Managed ePDU"):
port_num = str(int(((device.has_switches) and "%s:%s"%(t[len(t)-3], t[len(t)-1]) or "%s"%(t[len(t)-1]))) + 1)
# Plug indexing start from zero, so we add '1'
# for the user's exposed plug number
port_name = str(int(x[1].strip('"')) + 1)
port_status = ""
result[port_num] = (port_name, port_status)
else:
# Switched ePDU do not propose an outletCount OID!
# Invalid status (ie value == '0'), retrieved via the walk,
# means the outlet is absent
port_num = str(outletCount)
port_name = str(outletCount)
port_status = ""
if (status != '0'):
result[port_num] = (port_name, port_status)
return result
# Main agent method
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"test", "port", "separator", "no_login", "no_password",
"snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
"snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
"udpport", "inet4_only", "inet6_only" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
all_opt["switch"]["default"] = 1
all_opt["power_wait"]["default"] = 2
all_opt["snmp_version"]["default"] = "1"
all_opt["community"]["default"] = "private"
options = check_input(device_opt, process_input(device_opt))
# Plug indexing start from zero on ePDU Managed, so we substract '1' from
# the user's given plug number.
# For Switched ePDU, we will add this back again later.
if ((options.has_key("-n")) and (options["-n"].isdigit())):
options["-n"] = str(int(options["-n"]) - 1)
docs = { }
docs["shortdesc"] = "Fence agent for Eaton over SNMP"
docs["longdesc"] = "fence_eaton_snmp is an I/O Fencing agent \
which can be used with the Eaton network power switch. It logs \
into a device via SNMP and reboots a specified outlet. It supports \
SNMP v1 and v3 with all combinations of authenticity/privacy settings."
docs["vendorurl"] = "http://powerquality.eaton.com"
show_docs(options, docs)
# Operate the fencing device
result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/hpblade/fence_hpblade.py b/fence/agents/hpblade/fence_hpblade.py
index 2953ddc5..c7ceb194 100644
--- a/fence/agents/hpblade/fence_hpblade.py
+++ b/fence/agents/hpblade/fence_hpblade.py
@@ -1,113 +1,113 @@
#!/usr/bin/python
#####
##
## The Following Agent Has Been Tested On:
## * BladeSystem c7000 Enclosure
#####
import sys, re, pexpect, exceptions
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):
try:
conn.send_eol("show server status " + options["-n"])
conn.log_expect(options, options["-c"] , int(options["-Y"]))
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("-M"):
return "off"
else:
fail(EC_STATUS)
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
return status.lower().strip()
def set_power_status(conn, options):
try:
if options["-o"] == "on":
conn.send_eol("poweron server " + options["-n"])
elif options["-o"] == "off":
conn.send_eol("poweroff server " + options["-n"] + " force")
conn.log_expect(options, options["-c"], int(options["-Y"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
def get_blades_list(conn, options):
outlets = { }
try:
conn.send_eol("show server list" )
conn.log_expect(options, options["-c"], int(options["-Y"]))
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())
+ res = list_re.search(line)
+ if res != None:
+ outlets[res.group(1)] = (res.group(2), res.group(4).lower())
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
return outlets
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"cmd_prompt", "secure", "port", "identity_file", "separator",
"inet4_only", "inet6_only", "ipport", "missing_as_off" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = "c7000oa>"
options = check_input(device_opt, process_input(device_opt))
- docs = { }
+ 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 exceptions.OSError:
pass
except pexpect.ExceptionPexpect:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/ibmblade/fence_ibmblade.py b/fence/agents/ibmblade/fence_ibmblade.py
index f9ee9552..ceb747d6 100644
--- a/fence/agents/ibmblade/fence_ibmblade.py
+++ b/fence/agents/ibmblade/fence_ibmblade.py
@@ -1,80 +1,80 @@
#!/usr/bin/python
import sys
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="IBM Blade SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# From fence_ibmblade.pl
STATUSES_OID = ".1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.4" # remoteControlBladePowerState
CONTROL_OID = ".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.7" # powerOnOffBlade
# Status constants returned as value from SNMP
STATUS_DOWN = 0
STATUS_UP = 1
# Status constants to set as value to SNMP
STATUS_SET_OFF = 0
STATUS_SET_ON = 1
### FUNCTIONS ###
def get_power_status(conn, options):
- (oid,status) = conn.get("%s.%s"%(STATUSES_OID, options["-n"]))
- return (status==str(STATUS_UP) and "on" or "off")
+ (_, status) = conn.get("%s.%s"% (STATUSES_OID, options["-n"]))
+ return (status == str(STATUS_UP) and "on" or "off")
def set_power_status(conn, options):
conn.set("%s.%s"%(CONTROL_OID, options["-n"]), (options["-o"]=="on" and STATUS_SET_ON or STATUS_SET_OFF))
-def get_outlets_status(conn, options):
+def get_outlets_status(conn, _):
result = {}
res_blades = conn.walk(STATUSES_OID, 30)
- for x in res_blades:
- port_num = x[0].split('.')[-1]
+ for blade_info in res_blades:
+ port_num = blade_info[0].split('.')[-1]
port_alias = ""
- port_status = (x[1]==str(STATUS_UP) and "on" or "off")
+ port_status = (blade_info[1]==str(STATUS_UP) and "on" or "off")
result[port_num] = (port_alias, port_status)
return result
# Main agent method
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"test", "port", "separator", "no_login", "no_password",
"snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
"snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
"udpport", "inet4_only", "inet6_only" ]
atexit.register(atexit_handler)
snmp_define_defaults()
all_opt["snmp_version"]["default"] = "1"
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for IBM BladeCenter over SNMP"
docs["longdesc"] = "fence_ibmblade is an I/O Fencing agent \
which can be used with IBM BladeCenter chassis. It issues SNMP Set \
request to BladeCenter chassis, rebooting, powering up or down \
the specified Blade Server."
docs["vendorurl"] = "http://www.ibm.com"
show_docs(options, docs)
# Operate the fencing device
result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/ifmib/fence_ifmib.py b/fence/agents/ifmib/fence_ifmib.py
index fc96fb3a..170134e8 100644
--- a/fence/agents/ifmib/fence_ifmib.py
+++ b/fence/agents/ifmib/fence_ifmib.py
@@ -1,131 +1,129 @@
#!/usr/bin/python
# The Following agent has been tested on:
# - Cisco MDS UROS 9134 FC (1 Slot) Chassis ("1/2/4 10 Gbps FC/Supervisor-2") Motorola, e500v2
# with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
# - Cisco MDS 9124 (1 Slot) Chassis ("1/2/4 Gbps FC/Supervisor-2") Motorola, e500
# with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
# - Partially with APC PDU (Network Management Card AOS v2.7.0, Rack PDU APP v2.7.3)
# Only lance if is visible
import sys
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="IF:MIB SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# IF-MIB trees for alias, status and port
ALIASES_OID = ".1.3.6.1.2.1.31.1.1.1.18"
PORTS_OID = ".1.3.6.1.2.1.2.2.1.2"
STATUSES_OID = ".1.3.6.1.2.1.2.2.1.7"
# Status constants returned as value from SNMP
STATUS_UP = 1
STATUS_DOWN = 2
STATUS_TESTING = 3
### GLOBAL VARIABLES ###
# Port number converted from port name or index
port_num = None
### FUNCTIONS ###
# Convert port index or name to port index
def port2index(conn, port):
res = None
if (port.isdigit()):
res = int(port)
else:
ports = conn.walk(PORTS_OID, 30)
for x in ports:
if (x[1].strip('"')==port):
res = int(x[0].split('.')[-1])
break
if (res==None):
fail_usage("Can't find port with name %s!"%(port))
return res
def get_power_status(conn, options):
global port_num
if (port_num==None):
port_num = port2index(conn, options["-n"])
(oid, status) = conn.get("%s.%d"%(STATUSES_OID, port_num))
return (status==str(STATUS_UP) and "on" or "off")
def set_power_status(conn, options):
global port_num
if (port_num==None):
port_num = port2index(conn, options["-n"])
conn.set("%s.%d"%(STATUSES_OID, port_num), (options["-o"]=="on" and STATUS_UP or STATUS_DOWN))
# Convert array of format [[key1, value1], [key2, value2], ... [keyN, valueN]] to dict, where key is
# in format a.b.c.d...z and returned dict has key only z
def array_to_dict(ar):
return dict(map(lambda y:[y[0].split('.')[-1], y[1]], ar))
def get_outlets_status(conn, options):
result = {}
res_fc = conn.walk(PORTS_OID, 30)
res_aliases = array_to_dict(conn.walk(ALIASES_OID, 30))
for x in res_fc:
port_num = x[0].split('.')[-1]
port_name = x[1].strip('"')
port_alias = (res_aliases.has_key(port_num) and res_aliases[port_num].strip('"') or "")
port_status = ""
result[port_name] = (port_alias, port_status)
return result
# Main agent method
def main():
- global port_oid
-
device_opt = [ "fabric_fencing", "ipaddr", "login", "passwd", "passwd_script",
"test", "port", "separator", "no_login", "no_password",
"snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
"snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
"udpport", "inet4_only", "inet6_only" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
all_opt["snmp_version"]["default"] = "2c"
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for IF MIB"
docs["longdesc"] = "fence_ifmib is an I/O Fencing agent \
which can be used with any SNMP IF-MIB capable device. \
\n.P\n\
It was written with managed ethernet switches in mind, in order to \
fence iSCSI SAN connections. However, there are many devices that \
support the IF-MIB interface. The agent uses IF-MIB::ifAdminStatus \
to control the state of an interface."
docs["vendorurl"] = "http://www.ietf.org/wg/concluded/ifmib.html"
show_docs(options, docs)
# Operate the fencing device
result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/intelmodular/fence_intelmodular.py b/fence/agents/intelmodular/fence_intelmodular.py
index 32d8449e..3fd98220 100644
--- a/fence/agents/intelmodular/fence_intelmodular.py
+++ b/fence/agents/intelmodular/fence_intelmodular.py
@@ -1,97 +1,95 @@
#!/usr/bin/python
# Tested with an Intel MFSYS25 using firmware package 2.6 Should work with an
# MFSYS35 as well.
#
# Notes:
#
# The manual and firmware release notes says SNMP is read only. This is not
# true, as per the MIBs that ship with the firmware you can write to
# the bladePowerLed oid to control the servers.
#
# Thanks Matthew Kent for original agent and testing.
import sys
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Intel Modular SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# From INTELCORPORATION-MULTI-FLEX-SERVER-BLADES-MIB.my that ships with
# firmware updates
STATUSES_OID = ".1.3.6.1.4.1.343.2.19.1.2.10.202.1.1.6"
# Status constants returned as value from SNMP
STATUS_UP = 2
STATUS_DOWN = 0
# Status constants to set as value to SNMP
STATUS_SET_ON = 2
STATUS_SET_OFF = 3
### FUNCTIONS ###
def get_power_status(conn, options):
(oid, status) = conn.get("%s.%s"% (STATUSES_OID, options["-n"]))
return (status==str(STATUS_UP) and "on" or "off")
def set_power_status(conn, options):
conn.set("%s.%s"%(STATUSES_OID, options["-n"]), (options["-o"]=="on" and STATUS_SET_ON or STATUS_SET_OFF))
def get_outlets_status(conn, options):
result = {}
res_blades = conn.walk(STATUSES_OID, 30)
for x in res_blades:
port_num = x[0].split('.')[-1]
port_alias = ""
port_status = (x[1]==str(STATUS_UP) and "on" or "off")
result[port_num] = (port_alias, port_status)
return result
# Main agent method
def main():
- global port_oid
-
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"test", "port", "separator", "no_login", "no_password",
"snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
"snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
"udpport", "inet4_only", "inet6_only" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for Intel Modular"
docs["longdesc"] = "fence_intelmodular is an I/O Fencing agent \
which can be used with Intel Modular device (tested on Intel MFSYS25, should \
work with MFSYS35 as well). \
\n.P\n\
Note: Since firmware update version 2.7, SNMP v2 write support is \
removed, and replaced by SNMP v3 support. So agent now has default \
SNMP version 3. If you are using older firmware, please supply -d \
for command line and snmp_version option for your cluster.conf."
docs["vendorurl"] = "http://www.intel.com"
show_docs(options, docs)
# Operate the fencing device
result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/ipdu/fence_ipdu.py b/fence/agents/ipdu/fence_ipdu.py
index 354a0370..da7f1920 100644
--- a/fence/agents/ipdu/fence_ipdu.py
+++ b/fence/agents/ipdu/fence_ipdu.py
@@ -1,164 +1,158 @@
#!/usr/bin/python
# The Following agent has been tested on:
# IBM iPDU model 46M4002
# Firmware release OPDP_sIBM_v01.2_1
#
import sys
sys.path.append("/usr/share/fence")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="IBM iPDU SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# oid defining fence device
OID_SYS_OBJECT_ID = '.1.3.6.1.2.1.1.2.0'
### GLOBAL VARIABLES ###
# Device - see IBM iPDU
device = None
# Port ID
port_id = None
# Switch ID
switch_id = None
# Classes describing Device params
class IBMiPDU:
# iPDU
status_oid = '.1.3.6.1.4.1.2.6.223.8.2.2.1.11.%d'
control_oid = '.1.3.6.1.4.1.2.6.223.8.2.2.1.11.%d'
outlet_table_oid = '.1.3.6.1.4.1.2.6.223.8.2.2.1.2'
ident_str = "IBM iPDU"
state_on = 1
state_off = 0
turn_on = 1
turn_off = 0
has_switches = False
### FUNCTIONS ###
def ipdu_set_device(conn, options):
global device
agents_dir = {'.1.3.6.1.4.1.2.6.223':IBMiPDU,
None:IBMiPDU}
# First resolve type of PDU device
pdu_type = conn.walk(OID_SYS_OBJECT_ID)
if (not ((len(pdu_type)==1) and (agents_dir.has_key(pdu_type[0][1])))):
pdu_type = [[None, None]]
device = agents_dir[pdu_type[0][1]]
conn.log_command("Trying %s"%(device.ident_str))
def ipdu_resolv_port_id(conn, options):
- global port_id, switch_id, device
+ global port_id, switch_id
if (device==None):
ipdu_set_device(conn, options)
# Now we resolv port_id/switch_id
if ((options["-n"].isdigit()) and ((not device.has_switches) or (options["-s"].isdigit()))):
port_id = int(options["-n"])
if (device.has_switches):
switch_id = int(options["-s"])
else:
table = conn.walk(device.outlet_table_oid, 30)
for x in table:
if (x[1].strip('"')==options["-n"]):
t = x[0].split('.')
if (device.has_switches):
port_id = int(t[len(t)-1])
switch_id = int(t[len(t)-3])
else:
port_id = int(t[len(t)-1])
if (port_id==None):
fail_usage("Can't find port with name %s!"%(options["-n"]))
def get_power_status(conn, options):
- global port_id, switch_id, device
-
if (port_id==None):
ipdu_resolv_port_id(conn, options)
oid = ((device.has_switches) and device.status_oid%(switch_id, port_id) or device.status_oid%(port_id))
(oid, status) = conn.get(oid)
return (status==str(device.state_on) and "on" or "off")
def set_power_status(conn, options):
- global port_id, switch_id, device
-
if (port_id==None):
ipdu_resolv_port_id(conn, options)
oid = ((device.has_switches) and device.control_oid%(switch_id, port_id) or device.control_oid%(port_id))
conn.set(oid,(options["-o"]=="on" and device.turn_on or device.turn_off))
def get_outlets_status(conn, options):
- global device
-
result = {}
- if (device==None):
+ if (device == None):
ipdu_set_device(conn, options)
res_ports = conn.walk(device.outlet_table_oid, 30)
for x in res_ports:
t = x[0].split('.')
port_num = ((device.has_switches) and "%s:%s"%(t[len(t)-3], t[len(t)-1]) or "%s"%(t[len(t)-1]))
port_name = x[1].strip('"')
port_status = ""
result[port_num] = (port_name, port_status)
return result
# Main agent method
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"test", "port", "separator", "no_login", "no_password",
"snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
"snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
"udpport", "inet4_only", "inet6_only" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
all_opt["snmp_version"]["default"] = "3"
all_opt["community"]["default"] = "private"
all_opt["switch"]["default"] = "1"
device = IBMiPDU
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for iPDU over SNMP"
docs["longdesc"] = "fence_ipdu is an I/O Fencing agent \
which can be used with the IBM iPDU network power switch. It logs \
into a device via SNMP and reboots a specified outlet. It supports \
SNMP v3 with all combinations of authenticity/privacy settings."
docs["vendorurl"] = "http://www.ibm.com"
show_docs(options, docs)
# Operate the fencing device
result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index ea0ca09a..af216962 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1,983 +1,977 @@
#!/usr/bin/python
import sys, getopt, time, os
-import pexpect, re
-import telnetlib
-import atexit
+import pexpect, re, atexit
import __main__
## do not add code here.
#BEGIN_VERSION_GENERATION
RELEASE_VERSION = "New fence lib agent - test release on steroids"
REDHAT_COPYRIGHT = ""
BUILD_DATE = "March, 2008"
#END_VERSION_GENERATION
LOG_MODE_VERBOSE = 100
LOG_MODE_QUIET = 0
EC_GENERIC_ERROR = 1
EC_BAD_ARGS = 2
EC_LOGIN_DENIED = 3
EC_CONNECTION_LOST = 4
EC_TIMED_OUT = 5
EC_WAITING_ON = 6
EC_WAITING_OFF = 7
EC_STATUS = 8
EC_STATUS_HMC = 9
EC_PASSWORD_MISSING = 10
TELNET_PATH = "/usr/bin/telnet"
SSH_PATH = "/usr/bin/ssh"
SSL_PATH = "@SBINDIR@/fence_nss_wrapper"
SUDO_PATH = "/usr/bin/sudo"
all_opt = {
"help" : {
"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",
"help" : "",
"order" : 50 },
"verbose" : {
"getopt" : "v",
"longopt" : "verbose",
"help" : "-v, --verbose Verbose mode",
"required" : "0",
"shortdesc" : "Verbose mode",
"order" : 51 },
"debug" : {
"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 },
"delay" : {
"getopt" : "f:",
"longopt" : "delay",
"help" : "--delay <seconds> Wait X seconds before fencing is started",
"required" : "0",
"shortdesc" : "Wait X seconds before fencing is started",
"default" : "0",
"order" : 200 },
"agent" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"web" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"action" : {
"getopt" : "o:",
"longopt" : "action",
"help" : "-o, --action=<action> Action: status, reboot (default), off or on",
"required" : "1",
"shortdesc" : "Fencing Action",
"default" : "reboot",
"order" : 1 },
"fabric_fencing" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"ipaddr" : {
"getopt" : "a:",
"longopt" : "ip",
"help" : "-a, --ip=<ip> IP address or hostname of fencing device",
"required" : "1",
"shortdesc" : "IP Address or Hostname",
"order" : 1 },
"ipport" : {
"getopt" : "u:",
"longopt" : "ipport",
"help" : "-u, --ipport=<port> TCP port to use",
"required" : "0",
"shortdesc" : "TCP port to use for connection with device",
"order" : 1 },
"login" : {
"getopt" : "l:",
"longopt" : "username",
"help" : "-l, --username=<name> Login name",
"required" : "?",
"shortdesc" : "Login Name",
"order" : 1 },
"no_login" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"no_password" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"passwd" : {
"getopt" : "p:",
"longopt" : "password",
"help" : "-p, --password=<password> Login password or passphrase",
"required" : "0",
"shortdesc" : "Login password or passphrase",
"order" : 1 },
"passwd_script" : {
"getopt" : "S:",
"longopt" : "password-script=",
"help" : "-S, --password-script=<script> Script to run to retrieve password",
"required" : "0",
"shortdesc" : "Script to retrieve password",
"order" : 1 },
"identity_file" : {
"getopt" : "k:",
"longopt" : "identity-file",
"help" : "-k, --identity-file=<filename> Identity file (private key) for ssh ",
"required" : "0",
"shortdesc" : "Identity file for ssh",
"order" : 1 },
"module_name" : {
"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)",
"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 },
"cmd_prompt" : {
"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",
"shortdesc" : "SSH connection",
"required" : "0",
"order" : 1 },
"ssl" : {
"getopt" : "z",
"longopt" : "ssl",
"help" : "-z, --ssl Use ssl connection",
"required" : "0",
"shortdesc" : "SSL connection",
"order" : 1 },
"port" : {
"getopt" : "n:",
"longopt" : "plug",
"help" : "-n, --plug=<id> Physical plug number on device or\n" +
" name of virtual machine",
"required" : "1",
"shortdesc" : "Physical plug number or name of virtual machine",
"order" : 1 },
"switch" : {
"getopt" : "s:",
"longopt" : "switch",
"help" : "-s, --switch=<id> Physical switch number on device",
"required" : "0",
"shortdesc" : "Physical switch number on device",
"order" : 1 },
"suborg" : {
"getopt" : "s:",
"longopt" : "suborg",
"help" : "--suborg=<path> Additional path needed to access suborganization",
"required" : "0",
"shortdesc" : "Additional path needed to access suborganization",
"default" : "",
"order" : 1 },
"partition" : {
"getopt" : "n:",
"help" : "-n <id> Name of the partition",
"required" : "0",
"shortdesc" : "Partition name",
"order" : 1 },
"managed" : {
"getopt" : "s:",
"help" : "-s <id> Name of the managed system",
"required" : "0",
"shortdesc" : "Managed system name",
"order" : 1 },
"test" : {
"getopt" : "T",
"help" : "",
"order" : 1,
"obsolete" : "use -o status instead" },
"exec" : {
"getopt" : "e:",
"longopt" : "exec",
"help" : "-e, --exec=<command> Command to execute",
"required" : "0",
"shortdesc" : "Command to execute",
"order" : 1 },
"vmware_type" : {
"getopt" : "d:",
"longopt" : "vmware_type",
"help" : "-d, --vmware_type=<type> Type of VMware to connect",
"required" : "0",
"shortdesc" : "Type of VMware to connect",
"order" : 1 },
"vmware_datacenter" : {
"getopt" : "s:",
"longopt" : "vmware-datacenter",
"help" : "-s, --vmware-datacenter=<dc> VMWare datacenter filter",
"required" : "0",
"shortdesc" : "Show only machines in specified datacenter",
"order" : 2 },
"snmp_version" : {
"getopt" : "d:",
"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:",
"longopt" : "community",
"help" : "-c, --community=<community> Set the community string",
"required" : "0",
"shortdesc" : "Set the community string",
"order" : 1},
"snmp_auth_prot" : {
"getopt" : "b:",
"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:",
"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:",
"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:",
"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:",
"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",
"longopt" : "inet4-only",
"help" : "-4, --inet4-only Forces agent to use IPv4 addresses only",
"required" : "0",
"shortdesc" : "Forces agent to use IPv4 addresses only",
"order" : 1 },
"inet6_only" : {
"getopt" : "6",
"longopt" : "inet6-only",
"help" : "-6, --inet6-only Forces agent to use IPv6 addresses only",
"required" : "0",
"shortdesc" : "Forces agent to use IPv6 addresses only",
"order" : 1 },
"udpport" : {
"getopt" : "u:",
"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:",
"longopt" : "separator",
"help" : "-C, --separator=<char> Separator for CSV created by 'list' operation",
"default" : ",",
"required" : "0",
"shortdesc" : "Separator for CSV created by operation list",
"order" : 100 },
"login_timeout" : {
"getopt" : "y:",
"longopt" : "login-timeout",
"help" : "--login-timeout <seconds> Wait X seconds for cmd prompt after login",
"default" : "5",
"required" : "0",
"shortdesc" : "Wait X seconds for cmd prompt after login",
"order" : 200 },
"shell_timeout" : {
"getopt" : "Y:",
"longopt" : "shell-timeout",
"help" : "--shell-timeout <seconds> Wait X seconds for cmd prompt after issuing command",
"default" : "3",
"required" : "0",
"shortdesc" : "Wait X seconds for cmd prompt after issuing command",
"order" : 200 },
"power_timeout" : {
"getopt" : "g:",
"longopt" : "power-timeout",
"help" : "--power-timeout <seconds> Test X seconds for status change after ON/OFF",
"default" : "20",
"required" : "0",
"shortdesc" : "Test X seconds for status change after ON/OFF",
"order" : 200 },
"power_wait" : {
"getopt" : "G:",
"longopt" : "power-wait",
"help" : "--power-wait <seconds> Wait X seconds after issuing ON/OFF",
"default" : "0",
"required" : "0",
"shortdesc" : "Wait X seconds after issuing ON/OFF",
"order" : 200 },
"missing_as_off" : {
"getopt" : "M",
"longopt" : "missing-as-off",
"help" : "--missing-as-off Missing port returns OFF instead of failure",
"required" : "0",
"shortdesc" : "Missing port returns OFF instead of failure",
"order" : 200 },
"retry_on" : {
"getopt" : "F:",
"longopt" : "retry-on",
"help" : "--retry-on <attempts> Count of attempts to retry power on",
"default" : "1",
"required" : "0",
"shortdesc" : "Count of attempts to retry power on",
"order" : 201 },
"session_url" : {
"getopt" : "s:",
"longopt" : "session-url",
"help" : "-s, --session-url URL to connect to XenServer on",
"required" : "1",
"shortdesc" : "The URL of the XenServer host.",
"order" : 1},
"uuid" : {
"getopt" : "U:",
"longopt" : "uuid",
"help" : "-U, --uuid UUID of the VM to fence",
"required" : "0",
"shortdesc" : "The UUID of the virtual machine to fence.",
"order" : 1},
"sudo" : {
"getopt" : "d",
"longopt" : "use-sudo",
"help" : "--use-sudo Use sudo (without password) when calling 3rd party software",
"required" : "0",
"shortdesc" : "Use sudo (without password) when calling 3rd party sotfware.",
"order" : 205}
}
-common_opt = [ "help", "debug", "verbose", "quiet", "version", "action", "agent",
+COMMON_OPT = [ "help", "debug", "verbose", "quiet", "version", "action", "agent",
"power_timeout", "shell_timeout", "login_timeout", "power_wait", "retry_on", "delay" ]
class fspawn(pexpect.spawn):
def __init__(self, options, command):
pexpect.spawn.__init__(self, command)
self.opt = options
def log_expect(self, options, pattern, timeout):
result = self.expect(pattern, timeout)
if options["log"] >= LOG_MODE_VERBOSE:
options["debug_fh"].write(self.before + self.after)
return result
# send EOL according to what was detected in login process (telnet)
def send_eol(self, message):
self.send(message + self.opt["eol"])
def atexit_handler():
try:
sys.stdout.close()
os.close(1)
except IOError:
sys.stderr.write("%s failed to close standard output\n"%(sys.argv[0]))
sys.exit(EC_GENERIC_ERROR)
def version(command, release, build_date, copyright_notice):
print command, " ", release, " ", build_date
if len(copyright_notice) > 0:
print copyright_notice
def fail_usage(message = ""):
if len(message) > 0:
sys.stderr.write(message+"\n")
sys.stderr.write("Please use '-h' for usage\n")
sys.exit(EC_GENERIC_ERROR)
def fail(error_code):
message = {
EC_LOGIN_DENIED : "Unable to connect/login to fencing device",
EC_CONNECTION_LOST : "Connection lost",
EC_TIMED_OUT : "Connection timed out",
EC_WAITING_ON : "Failed: Timed out waiting to power ON",
EC_WAITING_OFF : "Failed: Timed out waiting to power OFF",
EC_STATUS : "Failed: Unable to obtain correct plug status or plug is not available",
- EC_STATUS_HMC : "Failed: Either unable to obtaion correct plug status, partition is not available or incorrect HMC version used",
+ EC_STATUS_HMC :
+ "Failed: Either unable to obtain correct plug status, partition is not available or incorrect HMC version used",
EC_PASSWORD_MISSING : "Failed: You have to set login password"
}[error_code] + "\n"
sys.stderr.write(message)
sys.exit(EC_GENERIC_ERROR)
def usage(avail_opt):
- global all_opt
-
print "Usage:"
print "\t" + os.path.basename(sys.argv[0]) + " [options]"
print "Options:"
sorted_list = [ (key, all_opt[key]) for key in avail_opt ]
sorted_list.sort(lambda x, y: cmp(x[1]["order"], y[1]["order"]))
for key, value in sorted_list:
if len(value["help"]) != 0:
print " " + value["help"]
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]) + "\" shortdesc=\"" + docs["shortdesc"] + "\" >"
if "symlink" in docs:
for (symlink, desc) in docs["symlink"]:
print "<symlink name=\"" + symlink + "\" shortdesc=\"" + desc + "\"/>"
print "<longdesc>" + docs["longdesc"] + "</longdesc>"
if docs.has_key("vendorurl"):
print "<vendor-url>" + docs["vendorurl"] + "</vendor-url>"
print "<parameters>"
- for option, value in sorted_list:
+ for option, _value in sorted_list:
if all_opt[option].has_key("shortdesc"):
print "\t<parameter name=\"" + option + "\" unique=\"0\" required=\"" + all_opt[option]["required"] + "\">"
default = ""
if all_opt[option].has_key("default"):
default = "default=\""+str(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=\"" + str(options["-" + all_opt[option]["getopt"][:-1]]) +"\""
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("<", "&lt;").replace(">", "&gt;")
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\" />"
if avail_opt.count("fabric_fencing") == 0:
print "\t<action name=\"reboot\" />"
print "\t<action name=\"status\" />"
print "\t<action name=\"list\" />"
print "\t<action name=\"monitor\" />"
print "\t<action name=\"metadata\" />"
print "</actions>"
print "</resource-agent>"
def process_input(avail_opt):
- global all_opt
- global common_opt
-
##
## Add options which are available for every fence agent
#####
- avail_opt.extend(common_opt)
+ avail_opt.extend(COMMON_OPT)
##
## Set standard environment
#####
os.putenv("LANG", "C")
os.putenv("LC_ALL", "C")
##
## Prepare list of options for getopt
#####
getopt_string = ""
longopt_list = [ ]
for k in avail_opt:
if all_opt.has_key(k):
getopt_string += all_opt[k]["getopt"]
else:
fail_usage("Parse error: unknown option '"+k+"'")
if all_opt.has_key(k) and all_opt[k].has_key("longopt"):
if all_opt[k]["getopt"].endswith(":"):
longopt_list.append(all_opt[k]["longopt"] + "=")
else:
longopt_list.append(all_opt[k]["longopt"])
## Compatibility layer
if avail_opt.count("module_name") == 1:
getopt_string += "n:"
longopt_list.append("plug=")
##
## Read options from command line or standard input
#####
if len(sys.argv) > 1:
try:
- opt, args = getopt.gnu_getopt(sys.argv[1:], getopt_string, longopt_list)
+ opt, _args = getopt.gnu_getopt(sys.argv[1:], getopt_string, longopt_list)
except getopt.GetoptError, error:
fail_usage("Parse error: " + error.msg)
## Transform longopt to short one which are used in fencing agents
#####
old_opt = opt
opt = { }
for o in dict(old_opt).keys():
if o.startswith("--"):
for x in all_opt.keys():
if all_opt[x].has_key("longopt") and "--" + all_opt[x]["longopt"] == o:
opt["-" + all_opt[x]["getopt"].rstrip(":")] = dict(old_opt)[o]
else:
opt[o] = dict(old_opt)[o]
## Compatibility Layer
#####
z = dict(opt)
if z.has_key("-T") == 1:
z["-o"] = "status"
if z.has_key("-n") == 1:
z["-m"] = z["-n"]
opt = z
##
#####
else:
opt = { }
name = ""
for line in sys.stdin.readlines():
line = line.strip()
if ((line.startswith("#")) or (len(line) == 0)):
continue
(name, value) = (line + "=").split("=", 1)
value = value[:-1]
## Compatibility Layer
######
if name == "blade":
name = "port"
elif name == "option":
name = "action"
elif name == "fm":
name = "port"
elif name == "hostname":
name = "ipaddr"
elif name == "modulename":
name = "module_name"
elif name == "port" and 1 == avail_opt.count("drac_version"):
name = "module_name"
##
######
if avail_opt.count(name) == 0:
sys.stderr.write("Parse error: Ignoring unknown option '"+line+"'\n")
continue
if all_opt[name]["getopt"].endswith(":"):
opt["-"+all_opt[name]["getopt"].rstrip(":")] = value
elif ((value == "1") or (value.lower() == "yes") or (value.lower() == "on") or (value.lower() == "true")):
opt["-"+all_opt[name]["getopt"]] = "1"
return opt
##
## This function checks input and answers if we want to have same answers
## in each of the fencing agents. It looks for possible errors and run
## password script to set a correct password
######
def check_input(device_opt, opt):
- global all_opt
- global common_opt
-
##
## Add options which are available for every fence agent
#####
- device_opt.extend([x for x in common_opt if device_opt.count(x) == 0])
+ device_opt.extend([x for x in COMMON_OPT if device_opt.count(x) == 0])
options = dict(opt)
options["device_opt"] = device_opt
## Set requirements that should be included in metadata
#####
if device_opt.count("login") and device_opt.count("no_login") == 0:
all_opt["login"]["required"] = "1"
else:
all_opt["login"]["required"] = "0"
## In special cases (show help, metadata or version) we don't need to check anything
#####
if options.has_key("-h") or options.has_key("-V") or (options.has_key("-o") and options["-o"].lower() == "metadata"):
- return options;
+ return options
## Set default values
#####
for opt in device_opt:
if all_opt[opt].has_key("default"):
- getopt = "-" + all_opt[opt]["getopt"].rstrip(":")
- if 0 == options.has_key(getopt):
- options[getopt] = all_opt[opt]["default"]
+ getopt_short = "-" + all_opt[opt]["getopt"].rstrip(":")
+ if 0 == options.has_key(getopt_short):
+ options[getopt_short] = all_opt[opt]["default"]
options["-o"] = options["-o"].lower()
if options.has_key("-v"):
options["log"] = LOG_MODE_VERBOSE
else:
options["log"] = LOG_MODE_QUIET
acceptable_actions = [ "on", "off", "status", "list", "monitor" ]
if 0 == device_opt.count("fabric_fencing"):
## Compatibility layer
#####
acceptable_actions.extend(["enable", "disable"])
else:
acceptable_actions.extend(["reboot"])
if 0 == acceptable_actions.count(options["-o"]):
fail_usage("Failed: Unrecognised action '" + options["-o"] + "'")
## Compatibility layer
#####
if options["-o"] == "enable":
options["-o"] = "on"
if options["-o"] == "disable":
options["-o"] = "off"
if (0 == options.has_key("-l")) and device_opt.count("login") and (device_opt.count("no_login") == 0):
fail_usage("Failed: You have to set login name")
if 0 == options.has_key("-a") and 0 == options.has_key("-s"):
fail_usage("Failed: You have to enter fence address")
if (device_opt.count("no_password") == 0):
if 0 == device_opt.count("identity_file"):
if 0 == (options.has_key("-p") or options.has_key("-S")):
fail_usage("Failed: You have to enter password or password script")
else:
if 0 == (options.has_key("-p") or options.has_key("-S") or options.has_key("-k")):
fail_usage("Failed: You have to enter password, password script or identity file")
if 0 == options.has_key("-x") and 1 == options.has_key("-k"):
fail_usage("Failed: You have to use identity file together with ssh connection (-x)")
if 1 == options.has_key("-k"):
if 0 == os.path.isfile(options["-k"]):
fail_usage("Failed: Identity file " + options["-k"] + " does not exist")
- if (0 == ["list", "monitor"].count(options["-o"].lower())) and (0 == options.has_key("-n") and 0 == options.has_key("-U")) and (device_opt.count("port")):
+ if (0 == ["list", "monitor"].count(options["-o"].lower())) and \
+ (0 == options.has_key("-n") and 0 == options.has_key("-U")) and (device_opt.count("port")):
fail_usage("Failed: You have to enter plug number")
if options.has_key("-S"):
options["-p"] = os.popen(options["-S"]).read().rstrip()
if options.has_key("-D"):
try:
options["debug_fh"] = file (options["-D"], "w")
except IOError:
fail_usage("Failed: Unable to create file "+options["-D"])
if options.has_key("-v") and options.has_key("debug_fh") == 0:
options["debug_fh"] = sys.stderr
if options.has_key("-R"):
options["-P"] = os.popen(options["-R"]).read().rstrip()
if options.has_key("-u") == False:
if options.has_key("-x"):
options["-u"] = 22
elif options.has_key("-z"):
options["-u"] = 443
elif device_opt.count("web"):
options["-u"] = 80
else:
options["-u"] = 23
return options
def wait_power_status(tn, options, get_power_fn):
for dummy in xrange(int(options["-g"])):
if get_power_fn(tn, options) != options["-o"]:
time.sleep(1)
else:
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 __main__.RELEASE_VERSION, __main__.BUILD_DATE
print __main__.REDHAT_COPYRIGHT
sys.exit(0)
def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None):
result = 0
## Process options that manipulate fencing device
#####
- if (options["-o"] == "list") and (0 == options["device_opt"].count("port")) and (0 == options["device_opt"].count("partition") and 0 == options["device_opt"].count("uuid") and 0 == options["device_opt"].count("module_name")):
+ if (options["-o"] == "list") and \
+ 0 == options["device_opt"].count("port") and 0 == options["device_opt"].count("partition") and \
+ 0 == options["device_opt"].count("uuid") and 0 == options["device_opt"].count("module_name"):
print "N/A"
return
elif (options["-o"] == "list" and get_outlet_list == None):
## @todo: exception?
## This is just temporal solution, we will remove default value
## None as soon as all existing agent will support this operation
print "NOTICE: List option is not working on this device yet"
return
elif (options["-o"] == "list") or ((options["-o"] == "monitor") and 1 == options["device_opt"].count("port")):
outlets = get_outlet_list(tn, options)
## keys can be numbers (port numbers) or strings (names of VM)
for o in outlets.keys():
(alias, status) = outlets[o]
if options["-o"] != "monitor":
print o + options["-C"] + alias
return
status = get_power_fn(tn, options)
if status != "on" and status != "off":
fail(EC_STATUS)
if options["-o"] == "on":
if status == "on":
print "Success: Already ON"
else:
power_on = False
- for i in range(1, 1 + int(options["-F"])):
+ for _ in range(1, 1 + int(options["-F"])):
set_power_fn(tn, options)
time.sleep(int(options["-G"]))
if wait_power_status(tn, options, get_power_fn):
power_on = True
break
if power_on:
print "Success: Powered ON"
else:
fail(EC_WAITING_ON)
elif options["-o"] == "off":
if status == "off":
print "Success: Already OFF"
else:
set_power_fn(tn, options)
time.sleep(int(options["-G"]))
if wait_power_status(tn, options, get_power_fn):
print "Success: Powered OFF"
else:
fail(EC_WAITING_OFF)
elif options["-o"] == "reboot":
if status != "off":
options["-o"] = "off"
set_power_fn(tn, options)
time.sleep(int(options["-G"]))
if wait_power_status(tn, options, get_power_fn) == 0:
fail(EC_WAITING_OFF)
options["-o"] = "on"
power_on = False
- for i in range(1, 1 + int(options["-F"])):
+ for _ in range(1, 1 + int(options["-F"])):
set_power_fn(tn, options)
time.sleep(int(options["-G"]))
if wait_power_status(tn, options, get_power_fn) == 1:
power_on = True
break
if power_on == False:
- # this should not fail as not was fenced succesfully
+ # this should not fail as node was fenced succesfully
sys.stderr.write('Timed out waiting to power ON\n')
print "Success: Rebooted"
elif options["-o"] == "status":
print "Status: " + status.upper()
if status.upper() == "OFF":
result = 2
elif options["-o"] == "monitor":
- 1
+ pass
return result
def fence_login(options):
force_ipvx = ""
if (options.has_key("-6")):
force_ipvx = "-6 "
if (options.has_key("-4")):
force_ipvx = "-4 "
if (options.has_key("eol") == False):
options["eol"] = "\r\n"
## Do the delay of the fence device before logging in
## Delay is important for two-node clusters fencing but we do not need to delay 'status' operations
if options["-o"] in ["off", "reboot"]:
time.sleep(int(options["-f"]))
try:
re_login = re.compile("(login\s*: )|(Login Name: )|(username: )|(User Name :)", re.IGNORECASE)
re_pass = re.compile("(password)|(pass phrase)", re.IGNORECASE)
if options.has_key("-z"):
command = '%s %s %s %s' % (SSL_PATH, force_ipvx, options["-a"], options["-u"])
try:
conn = fspawn(options, command)
except pexpect.ExceptionPexpect, ex:
## SSL telnet is part of the fencing package
- sys.stderr.write(str(ex) + "\n")
- sys.exit(EC_GENERIC_ERROR)
+ sys.stderr.write(str(ex) + "\n")
+ sys.exit(EC_GENERIC_ERROR)
elif options.has_key("-x") and 0 == options.has_key("-k"):
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(options, command)
except pexpect.ExceptionPexpect, ex:
sys.stderr.write(str(ex) + "\n")
sys.stderr.write("Due to limitations, binary dependencies on fence agents "
"are not in the spec file and must be installed separately." + "\n")
sys.exit(EC_GENERIC_ERROR)
if options.has_key("telnet_over_ssh"):
#This is for stupid ssh servers (like ALOM) which behave more like telnet (ignore name and display login prompt)
result = conn.log_expect(options, [ re_login, "Are you sure you want to continue connecting (yes/no)?" ], int(options["-y"]))
if result == 1:
conn.sendline("yes") # Host identity confirm
conn.log_expect(options, re_login, int(options["-y"]))
conn.sendline(options["-l"])
conn.log_expect(options, re_pass, int(options["-y"]))
else:
result = conn.log_expect(options, [ "ssword:", "Are you sure you want to continue connecting (yes/no)?" ], int(options["-y"]))
if result == 1:
conn.sendline("yes")
conn.log_expect(options, "ssword:", int(options["-y"]))
conn.sendline(options["-p"])
conn.log_expect(options, options["-c"], int(options["-y"]))
elif options.has_key("-x") and 1 == options.has_key("-k"):
command = '%s %s %s@%s -i %s -p %s' % (SSH_PATH, force_ipvx, options["-l"], options["-a"], options["-k"], options["-u"])
if options.has_key("ssh_options"):
command += ' ' + options["ssh_options"]
try:
conn = fspawn(options, command)
except pexpect.ExceptionPexpect, ex:
sys.stderr.write(str(ex) + "\n")
sys.stderr.write("Due to limitations, binary dependencies on fence agents "
"are not in the spec file and must be installed separately." + "\n")
sys.exit(EC_GENERIC_ERROR)
- result = conn.log_expect(options, [ options["-c"], "Are you sure you want to continue connecting (yes/no)?", "Enter passphrase for key '"+options["-k"]+"':" ], int(options["-y"]))
+ result = conn.log_expect(options, [ options["-c"], \
+ "Are you sure you want to continue connecting (yes/no)?", \
+ "Enter passphrase for key '" + options["-k"] + "':" ], int(options["-y"]))
if result == 1:
conn.sendline("yes")
conn.log_expect(options, [ options["-c"], "Enter passphrase for key '"+options["-k"]+"':"] , int(options["-y"]))
if result != 0:
if options.has_key("-p"):
conn.sendline(options["-p"])
conn.log_expect(options, options["-c"], int(options["-y"]))
else:
fail_usage("Failed: You have to enter passphrase (-p) for identity file")
else:
try:
conn = fspawn(options, TELNET_PATH)
conn.send("set binary\n")
conn.send("open %s -%s\n"%(options["-a"], options["-u"]))
except pexpect.ExceptionPexpect, ex:
sys.stderr.write(str(ex) + "\n")
sys.stderr.write("Due to limitations, binary dependencies on fence agents "
"are not in the spec file and must be installed separately." + "\n")
sys.exit(EC_GENERIC_ERROR)
result = conn.log_expect(options, re_login, int(options["-y"]))
conn.send_eol(options["-l"])
## automatically change end of line separator
screen = conn.read_nonblocking(size=100, timeout=int(options["-Y"]))
if (re_login.search(screen) != None):
options["eol"] = "\n"
conn.send_eol(options["-l"])
result = conn.log_expect(options, re_pass, int(options["-y"]))
elif (re_pass.search(screen) == None):
conn.log_expect(options, re_pass, int(options["-Y"]))
try:
conn.send_eol(options["-p"])
conn.log_expect(options, options["-c"], int(options["-Y"]))
except KeyError:
fail(EC_PASSWORD_MISSING)
except pexpect.EOF:
fail(EC_LOGIN_DENIED)
except pexpect.TIMEOUT:
fail(EC_LOGIN_DENIED)
return conn
diff --git a/fence/agents/lpar/fence_lpar.py b/fence/agents/lpar/fence_lpar.py
index df4f1ef9..5a14d56b 100644
--- a/fence/agents/lpar/fence_lpar.py
+++ b/fence/agents/lpar/fence_lpar.py
@@ -1,178 +1,178 @@
#!/usr/bin/python
#####
##
## The Following Agent Has Been Tested On:
##
## Version
## +---------------------------------------------+
## Tested on HMC
##
#####
import sys, re, pexpect, exceptions
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["-H"] == "3":
try:
conn.send("lssyscfg -r lpar -m " + options["-s"] + " -n " + options["-n"] + " -F name,state\n")
conn.log_expect(options, options["-c"], int(options["-g"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
try:
status = re.compile("^" + options["-n"] + ",(.*?),.*$", re.IGNORECASE | re.MULTILINE).search(conn.before).group(1)
except AttributeError:
fail(EC_STATUS_HMC)
elif options["-H"] == "4":
try:
conn.send("lssyscfg -r lpar -m "+ options["-s"] +" --filter 'lpar_names=" + options["-n"] + "'\n")
conn.log_expect(options, options["-c"], int(options["-g"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
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["-H"] == "3":
try:
conn.send("chsysstate -o " + options["-o"] + " -r lpar -m " + options["-s"]
+ " -n " + options["-n"] + "\n")
conn.log_expect(options, options["-c"], int(options["-g"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
elif options["-H"] == "4":
try:
if options["-o"] == "on":
conn.send("chsysstate -o on -r lpar -m " + options["-s"] +
" -n " + options["-n"] +
" -f `lssyscfg -r lpar -F curr_profile " +
" -m " + options["-s"] +
" --filter \"lpar_names="+ options["-n"] +"\"`\n" )
else:
conn.send("chsysstate -o shutdown -r lpar --immed" +
" -m " + options["-s"] + " -n " + options["-n"] + "\n")
conn.log_expect(options, options["-c"], int(options["-g"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
def get_lpar_list(conn, options):
outlets = { }
if options["-H"] == "3":
try:
conn.send("query_partition_names -m " + options["-s"] + "\n")
conn.log_expect(options, options["-c"], int(options["-g"]))
## 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 x in lines:
- outlets[x.rstrip()] = ("", "")
+ for outlet_line in lines:
+ outlets[outlet_line.rstrip()] = ("", "")
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
elif options["-H"] == "4":
try:
conn.send("lssyscfg -r lpar -m " + options["-s"] +
" -F name:state\n")
conn.log_expect(options, options["-c"], int(options["-g"]))
## 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 x in lines:
- s = x.split(":")
- outlets[s[0]] = ("", s[1])
+ for outlet_line in lines:
+ (port, status) = outlet_line.split(":")
+ outlets[port] = ("", status)
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
return outlets
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script", "secure",
"identity_file", "partition", "managed", "hmc_version", "cmd_prompt",
"separator", "inet4_only", "inet6_only", "ipport" ]
atexit.register(atexit_handler)
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"] = ""
show_docs(options, docs)
if 0 == options.has_key("-s"):
fail_usage("Failed: You have to enter name of managed system")
if (0 == ["list", "monitor"].count(options["-o"].lower())) and (0 == options.has_key("-n")):
fail_usage("Failed: You have to enter name of the partition")
if 1 == options.has_key("-H") and (options["-H"] != "3" and options["-H"] != "4"):
fail_usage("Failed: You have to enter valid version number: 3 or 4")
##
## 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 exceptions.OSError:
pass
except pexpect.ExceptionPexpect:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py
index 78eb3005..e1de315f 100644
--- a/fence/agents/rhevm/fence_rhevm.py
+++ b/fence/agents/rhevm/fence_rhevm.py
@@ -1,143 +1,142 @@
#!/usr/bin/python
import sys, re
import pycurl, StringIO
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New RHEV-M Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
-re_get_id = re.compile("<vm( .*)? id=\"(.*?)\"", re.IGNORECASE)
-re_status = re.compile("<state>(.*?)</state>", re.IGNORECASE)
-re_get_name = re.compile("<name>(.*?)</name>", re.IGNORECASE)
+RE_GET_ID = re.compile("<vm( .*)? id=\"(.*?)\"", re.IGNORECASE)
+RE_STATUS = re.compile("<state>(.*?)</state>", re.IGNORECASE)
+RE_GET_NAME = re.compile("<name>(.*?)</name>", re.IGNORECASE)
def get_power_status(conn, options):
### Obtain real ID from name
try:
res = send_command(options, "vms/?search=name%3D" + options["-n"])
except pycurl.error, e:
sys.stderr.write(e[1] + "\n")
fail(EC_TIMED_OUT)
- result = re_get_id.search(res)
+ result = RE_GET_ID.search(res)
if (result == None):
# Unable to obtain ID needed to access virtual machine
fail(EC_STATUS)
options["id"] = result.group(2)
- re_status.search(res)
- result = re_status.search(res)
+ result = RE_STATUS.search(res)
if (result == None):
# We were able to parse ID so output is correct
# in some cases it is possible that RHEV-M output does not
# contain <status> line. We can assume machine is OFF then
return "off"
else:
status = result.group(1)
if (status.lower() == "down"):
return "off"
else:
return "on"
def set_power_status(conn, options):
action = {
'on' : "start",
'off' : "stop"
}[options["-o"]]
url = "vms/" + options["id"] + "/" + action
try:
res = send_command(options, url, "POST")
except pycurl.error, e:
sys.stderr.write(e[1] + "\n")
fail(EC_TIMED_OUT)
return
def get_list(conn, options):
outlets = { }
try:
try:
res = send_command(options, "vms")
except pycurl.error, e:
sys.stderr.write(e[1] + "\n")
fail(EC_TIMED_OUT)
lines = res.split("<vm ")
for i in range(1, len(lines)):
- name = re_get_name.search(lines[i]).group(1)
+ name = RE_GET_NAME.search(lines[i]).group(1)
outlets[name] = ("", None)
except AttributeError:
return { }
except IndexError:
return { }
return outlets
def send_command(opt, command, method = "GET"):
## setup correct URL
if opt.has_key("-z"):
url = "https:"
else:
url = "http:"
url += "//" + opt["-a"] + ":" + str(opt["-u"]) + "/api/" + command
## send command through pycurl
c = pycurl.Curl()
b = StringIO.StringIO()
c.setopt(pycurl.URL, url)
c.setopt(pycurl.HTTPHEADER, [ "Content-type: application/xml", "Accept: application/xml" ])
c.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC)
c.setopt(pycurl.USERPWD, opt["-l"] + ":" + opt["-p"])
c.setopt(pycurl.TIMEOUT, int(opt["-Y"]))
c.setopt(pycurl.SSL_VERIFYPEER, 0)
c.setopt(pycurl.SSL_VERIFYHOST, 0)
if (method == "POST"):
c.setopt(pycurl.POSTFIELDS, "<action />")
c.setopt(pycurl.WRITEFUNCTION, b.write)
c.perform()
result = b.getvalue()
if opt["log"] >= LOG_MODE_VERBOSE:
opt["debug_fh"].write(command + "\n")
opt["debug_fh"].write(result + "\n")
return result
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script", "ssl",
"inet4_only", "inet6_only", "ipport", "port", "web", "separator" ]
atexit.register(atexit_handler)
all_opt["power_wait"]["default"] = "1"
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for RHEV-M REST API"
docs["longdesc"] = "fence_rhevm is an I/O Fencing agent which can be \
used with RHEV-M REST API to fence virtual machines."
docs["vendorurl"] = "http://www.redhat.com"
show_docs(options, docs)
##
## Fence operations
####
result = fence_action(None, options, set_power_status, get_power_status, get_list)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/vmware/fence_vmware.py b/fence/agents/vmware/fence_vmware.py
index 2ec2c3c5..6e3f3943 100644
--- a/fence/agents/vmware/fence_vmware.py
+++ b/fence/agents/vmware/fence_vmware.py
@@ -1,334 +1,334 @@
#!/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
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["-e"]
if (add_login_params):
if (vmware_internal_type==VMWARE_TYPE_ESX):
res += " --server '%s' --username '%s' --password '%s' "% (quote_for_run(options["-a"]),
quote_for_run(options["-l"]),
quote_for_run(options["-p"]))
elif (vmware_internal_type==VMWARE_TYPE_SERVER2):
res += " -h 'https://%s/sdk' -u '%s' -p '%s' -T server "% (quote_for_run(options["-a"]),
quote_for_run(options["-l"]),
quote_for_run(options["-p"]))
elif (vmware_internal_type==VMWARE_TYPE_SERVER1):
host_name_array = options["-a"].split(':')
res += " -h '%s' -u '%s' -p '%s' -T server1 "% (quote_for_run(host_name_array[0]),
quote_for_run(options["-l"]),
quote_for_run(options["-p"]))
if (len(host_name_array)>1):
res += "-P '%s' "% (quote_for_run(host_name_array[1]))
if ((options.has_key("-s")) and (vmware_internal_type==VMWARE_TYPE_ESX)):
res += "--datacenter '%s' "% (quote_for_run(options["-s"]))
if (additional_params != ""):
res += additional_params
return res
# Log message if user set verbose option
def vmware_log(options, message):
if options["log"] >= LOG_MODE_VERBOSE:
options["debug_fh"].write(message+"\n")
# 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["-Y"])+int(options["-y"])+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["-e"], res_output))
else:
vmware_log(options, res_output)
except pexpect.ExceptionPexpect:
fail_usage("Cannot run command %s"% (options["-e"]))
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["-n"]))), 0)
else:
all_machines = vmware_run_command(options, True, "--operation list", int(options["-g"]))
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["-n"] in outlets)):
fail_usage("Failed: You have to enter existing name of virtual machine!")
else:
return outlets[options["-n"]][1]
elif (vmware_internal_type==VMWARE_TYPE_SERVER1):
return ((options["-n"] 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["-o"]=="on" and "on" or "off"), quote_for_run(options["-n"]))
elif ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)):
additional_params = "%s '%s'"% ((options["-o"]=="on" and "start" or "stop"), quote_for_run(options["-n"]))
if (options["-o"]=="off"):
additional_params += " hard"
vmware_run_command(options, True, additional_params, int(options["-g"]))
# 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
+ 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["-e"] to path (if not specified)
def vmware_check_vmware_type(options):
global vmware_internal_type
options["-d"] = options["-d"].lower()
if (options["-d"]=="esx"):
vmware_internal_type = VMWARE_TYPE_ESX
if (not options.has_key("-e")):
options["-e"] = VMHELPER_COMMAND
elif (options["-d"]=="server2"):
vmware_internal_type = VMWARE_TYPE_SERVER2
if (not options.has_key("-e")):
options["-e"] = VMRUN_COMMAND
elif (options["-d"]=="server1"):
vmware_internal_type = VMWARE_TYPE_SERVER1
if (not options.has_key("-e")):
options["-e"] = VMRUN_COMMAND
else:
fail_usage("vmware_type can be esx,server2 or server1!")
# Main agent method
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"test", "port", "separator", "exec", "vmware_type",
"vmware_datacenter", "secure", "identity_file" ]
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/wti/fence_wti.py b/fence/agents/wti/fence_wti.py
index 1f353bee..b1fdd051 100644
--- a/fence/agents/wti/fence_wti.py
+++ b/fence/agents/wti/fence_wti.py
@@ -1,174 +1,173 @@
#!/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
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_power_status(conn, options):
listing = ""
try:
conn.send("/S"+"\r\n")
if isinstance(options["-c"], list):
re_all = list(options["-c"])
else:
re_all = [options["-c"]]
re_next = re.compile("Enter: ", re.IGNORECASE)
re_all.append(re_next)
result = conn.log_expect(options, re_all, int(options["-Y"]))
listing = conn.before
if result == (len(re_all) - 1):
conn.send("\r\n")
conn.log_expect(options, options["-c"], int(options["-Y"]))
listing += conn.before
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
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
- pass
if ["list", "monitor"].count(options["-o"]) == 0 and options["-n"].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["-o"]) == 1:
return outlets
else:
return "PROBLEM"
def set_power_status(conn, options):
action = {
'on' : "/on",
'off': "/off"
}[options["-o"]]
try:
conn.send(action + " " + options["-n"] + ",y\r\n")
conn.log_expect(options, options["-c"], int(options["-g"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
def main():
device_opt = [ "ipaddr", "login", "passwd", "passwd_script",
"cmd_prompt", "secure", "identity_file", "port", "no_login", "no_password",
"test", "separator", "inet4_only", "inet6_only", "ipport" ]
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("-x"):
try:
try:
conn = fspawn(options, TELNET_PATH)
conn.send("set binary\n")
conn.send("open %s -%s\n"%(options["-a"], options["-u"]))
except pexpect.ExceptionPexpect, ex:
sys.stderr.write(str(ex) + "\n")
sys.stderr.write("Due to limitations, binary dependencies on fence agents "
"are not in the spec file and must be installed separately." + "\n")
sys.exit(EC_GENERIC_ERROR)
re_login = re.compile("(login: )|(Login Name: )|(username: )|(User Name :)", re.IGNORECASE)
re_prompt = re.compile("|".join(map (lambda x: "(" + x + ")", options["-c"])), re.IGNORECASE)
result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], int(options["-Y"]))
if result == 0:
if options.has_key("-l"):
conn.send(options["-l"]+"\r\n")
result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], int(options["-Y"]))
else:
fail_usage("Failed: You have to set login name")
if result == 1:
if options.has_key("-p"):
conn.send(options["-p"]+"\r\n")
conn.log_expect(options, options["-c"], int(options["-Y"]))
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 exceptions.OSError:
pass
except pexpect.ExceptionPexpect:
pass
sys.exit(result)
if __name__ == "__main__":
main()

File Metadata

Mime Type
text/x-diff
Expires
Wed, Feb 26, 2:28 PM (12 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1465442
Default Alt Text
(112 KB)

Event Timeline