Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F2824989
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
124 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/fence/agents/alom/fence_alom.py b/fence/agents/alom/fence_alom.py
index c2af527c..d64838e7 100644
--- a/fence/agents/alom/fence_alom.py
+++ b/fence/agents/alom/fence_alom.py
@@ -1,66 +1,66 @@
#!/usr/bin/python -tt
# The Following Agent Has Been Tested On:
#
# Sun(tm) Advanced Lights Out Manager CMT v1.6.1
# as found on SUN T2000 Niagara
import sys, re, time
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Sun Advanced Lights Out Manager (ALOM)"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("showplatform")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
status = re.search("standby", conn.before.lower())
result = (status != None and "off" or "on")
return result
def set_power_status(conn, options):
cmd_line = (options["--action"] == "on" and "poweron" or "poweroff -f -y")
conn.send_eol(cmd_line)
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
# Get the machine some time between poweron and poweroff
time.sleep(int(options["--power-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure" ]
atexit.register(atexit_handler)
all_opt["secure"]["default"] = "1"
all_opt["cmd_prompt"]["default"] = [ r"sc\>\ " ]
options = check_input(device_opt, process_input(device_opt))
options["telnet_over_ssh"] = 1
docs = { }
docs["shortdesc"] = "Fence agent for Sun ALOM"
docs["longdesc"] = "fence_alom is an I/O Fencing \
agent which can be used with ALOM connected machines."
docs["vendorurl"] = "http://www.sun.com"
show_docs(options, docs)
# Operate the fencing device
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, None)
# Logout from system
try:
conn.send_eol("logout")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py
index 4b4c2bc1..c6a9aaf2 100644
--- a/fence/agents/apc/fence_apc.py
+++ b/fence/agents/apc/fence_apc.py
@@ -1,271 +1,271 @@
#!/usr/bin/python -tt
#####
##
## 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
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, fail_usage, EC_STATUS
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New APC Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
exp_result = 0
outlets = {}
conn.send_eol("1")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
version = 0
admin = 0
switch = 0
if None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before):
switch = 1
if None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before):
if 0 == options.has_key("--switch"):
fail_usage("Failed: You have to enter physical switch number")
else:
if 0 == options.has_key("--switch"):
options["--switch"] = "1"
if None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before):
version = 2
else:
version = 3
if None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before):
admin = 0
else:
admin = 1
if switch == 0:
if version == 2:
if admin == 0:
conn.send_eol("2")
else:
conn.send_eol("3")
else:
conn.send_eol("2")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.send_eol("1")
else:
conn.send_eol(options["--switch"])
while True:
exp_result = conn.log_expect(options,
["Press <ENTER>" ] + options["--command-prompt"], int(options["--shell-timeout"]))
lines = conn.before.split("\n")
show_re = re.compile(r'(^|\x0D)\s*(\d+)- (.*?)\s+(ON|OFF)\s*')
for line in lines:
res = show_re.search(line)
if res != None:
outlets[res.group(2)] = (res.group(3), res.group(4))
conn.send_eol("")
if exp_result != 0:
break
conn.send(chr(03))
conn.log_expect(options, "- Logout", int(options["--shell-timeout"]))
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
if ["list", "monitor"].count(options["--action"]) == 1:
return outlets
else:
try:
(_, status) = outlets[options["--plug"]]
return status.lower().strip()
except KeyError:
fail(EC_STATUS)
def set_power_status(conn, options):
action = {
'on' : "1",
'off': "2"
}[options["--action"]]
conn.send_eol("1")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
version = 0
admin2 = 0
admin3 = 0
switch = 0
if None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before):
switch = 1
## MasterSwitch has different schema for on/off actions
action = {
'on' : "1",
'off': "3"
}[options["--action"]]
if None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before):
if 0 == options.has_key("--switch"):
fail_usage("Failed: You have to enter physical switch number")
else:
if 0 == options.has_key("--switch"):
options["--switch"] = 1
if None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before):
version = 2
else:
version = 3
if None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before):
admin2 = 0
else:
admin2 = 1
if switch == 0:
if version == 2:
if admin2 == 0:
conn.send_eol("2")
else:
conn.send_eol("3")
else:
conn.send_eol("2")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
if None == re.compile('.*2- Outlet Restriction.*', re.IGNORECASE | re.S).match(conn.before):
admin3 = 0
else:
admin3 = 1
conn.send_eol("1")
else:
conn.send_eol(options["--switch"])
while 0 == conn.log_expect(options,
[ "Press <ENTER>" ] + options["--command-prompt"], int(options["--shell-timeout"])):
conn.send_eol("")
conn.send_eol(options["--plug"]+"")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
if switch == 0:
if admin2 == 1:
conn.send_eol("1")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
if admin3 == 1:
conn.send_eol("1")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
else:
conn.send_eol("1")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.send_eol(action)
conn.log_expect(options, "Enter 'YES' to continue or <ENTER> to cancel :", int(options["--shell-timeout"]))
conn.send_eol("YES")
conn.log_expect(options, "Press <ENTER> to continue...", int(options["--shell-timeout"]))
conn.send_eol("")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.send(chr(03))
conn.log_expect(options, "- Logout", int(options["--shell-timeout"]))
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def get_power_status5(conn, options):
outlets = {}
conn.send_eol("olStatus all")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
lines = conn.before.split("\n")
show_re = re.compile(r'^\s*(\d+): (.*): (On|Off)\s*$', re.IGNORECASE)
for line in lines:
res = show_re.search(line)
if res != None:
outlets[res.group(1)] = (res.group(2), res.group(3))
if ["list", "monitor"].count(options["--action"]) == 1:
return outlets
else:
try:
(_, status) = outlets[options["--plug"]]
return status.lower().strip()
except KeyError:
fail(EC_STATUS)
def set_power_status5(conn, options):
action = {
'on' : "olOn",
'off': "olOff"
}[options["--action"]]
conn.send_eol(action + " " + options["--plug"])
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
"port", "switch" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "\n>", "\napc>" ]
all_opt["ssh_options"]["default"] = "-1 -c blowfish"
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for APC over telnet/ssh"
docs["longdesc"] = "fence_apc is an I/O Fencing agent \
which can be used with the APC network power switch. It logs into device \
via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh connections \
should be avoided while a GFS cluster is running because the connection \
will block any necessary fencing actions."
docs["vendorurl"] = "http://www.apc.com"
show_docs(options, docs)
## Support for --plug [switch]:[plug] notation that was used before
if (options.has_key("--plug") == 1) and (-1 != options["--plug"].find(":")):
(switch, plug) = options["--plug"].split(":", 1)
options["--switch"] = switch
options["--plug"] = plug
##
## Operate the fencing device
####
conn = fence_login(options)
## Detect firmware version (ASCII menu vs command-line interface)
## and continue with proper action
####
result = -1
firmware_version = re.compile(r'\s*v(\d)*\.').search(conn.before)
if (firmware_version != None) and (firmware_version.group(1) == "5"):
result = fence_action(conn, options, set_power_status5, get_power_status5, get_power_status5)
else:
result = fence_action(conn, options, set_power_status, get_power_status, get_power_status)
##
## Logout from system
##
## In some special unspecified cases it is possible that
## connection will be closed before we run close(). This is not
## a problem because everything is checked before.
######
try:
conn.send_eol("4")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py
index 0f59f558..b6cd0051 100644
--- a/fence/agents/bladecenter/fence_bladecenter.py
+++ b/fence/agents/bladecenter/fence_bladecenter.py
@@ -1,120 +1,120 @@
#!/usr/bin/python -tt
#####
##
## 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
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, EC_STATUS, EC_GENERIC_ERROR
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Bladecenter Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
node_cmd = r"system:blade\[" + options["--plug"] + r"\]>"
conn.send_eol("env -T system:blade[" + options["--plug"] + "]")
i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["--shell-timeout"]))
if i == 1:
## Given blade number does not exist
if options.has_key("--missing-as-off"):
return "off"
else:
fail(EC_STATUS)
conn.send_eol("power -state")
conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
status = conn.before.splitlines()[-1]
conn.send_eol("env -T system")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
return status.lower().strip()
def set_power_status(conn, options):
node_cmd = r"system:blade\[" + options["--plug"] + r"\]>"
conn.send_eol("env -T system:blade[" + options["--plug"] + "]")
i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["--shell-timeout"]))
if i == 1:
## Given blade number does not exist
if options.has_key("--missing-as-off"):
return
else:
fail(EC_GENERIC_ERROR)
conn.send_eol("power -"+options["--action"])
conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
conn.send_eol("env -T system")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def get_blades_list(conn, options):
outlets = { }
node_cmd = "system>"
conn.send_eol("env -T system")
conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
conn.send_eol("list -l 2")
conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
lines = conn.before.split("\r\n")
filter_re = re.compile(r"^\s*blade\[(\d+)\]\s+(.*?)\s*$")
for blade_line in lines:
res = filter_re.search(blade_line)
if res != None:
outlets[res.group(1)] = (res.group(2), "")
return outlets
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
"port", "missing_as_off" ]
atexit.register(atexit_handler)
all_opt["power_wait"]["default"] = "10"
all_opt["cmd_prompt"]["default"] = [ "system>" ]
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for IBM BladeCenter"
docs["longdesc"] = "fence_bladecenter is an I/O Fencing agent \
which can be used with IBM Bladecenters with recent enough firmware that \
includes telnet support. It logs into a Brocade chasis via telnet or ssh \
and uses the command line interface to power on and off blades."
docs["vendorurl"] = "http://www.ibm.com"
show_docs(options, docs)
##
## Operate the fencing device
######
conn = fence_login(options, "(username: )")
result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list)
##
## Logout from system
######
try:
conn.send_eol("exit")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/brocade/fence_brocade.py b/fence/agents/brocade/fence_brocade.py
index 3bbb74c0..716bad1c 100644
--- a/fence/agents/brocade/fence_brocade.py
+++ b/fence/agents/brocade/fence_brocade.py
@@ -1,88 +1,88 @@
#!/usr/bin/python -tt
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, EC_STATUS
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Brocade Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 20013"
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("portCfgShow " + options["--plug"])
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
show_re = re.compile(r'^\s*Persistent Disable\s*(ON|OFF)\s*$', re.IGNORECASE)
lines = conn.before.split("\n")
for line in lines:
res = show_re.search(line)
if res != None:
# We queried if it is disabled, so we have to negate answer
if res.group(1) == "ON":
return "off"
else:
return "on"
fail(EC_STATUS)
def set_power_status(conn, options):
action = {
'on' : "portCfgPersistentEnable",
'off': "portCfgPersistentDisable"
}[options["--action"]]
conn.send_eol(action + " " + options["--plug"])
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "fabric_fencing" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "> " ]
options = check_input(device_opt, process_input(device_opt))
options["eol"] = "\n"
docs = { }
docs["shortdesc"] = "Fence agent for HP Brocade over telnet/ssh"
docs["longdesc"] = "fence_brocade is an I/O Fencing agent which can be used with Brocade FC switches. \
It logs into a Brocade switch via telnet and disables a specified port. Disabling the port which a machine is \
connected to effectively fences that machine. Lengthy telnet connections to the switch should be avoided while \
a GFS cluster is running because the connection will block any necessary fencing actions. \
\
After a fence operation has taken place the fenced machine can no longer connect to the Brocade FC switch. \
When the fenced machine is ready to be brought back into the GFS cluster (after reboot) the port on the Brocade \
FC switch needs to be enabled. This can be done by running fence_brocade and specifying the enable action"
docs["vendorurl"] = "http://www.brocade.com"
show_docs(options, docs)
##
## Operate the fencing device
####
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, None)
##
## Logout from system
##
## In some special unspecified cases it is possible that
## connection will be closed before we run close(). This is not
## a problem because everything is checked before.
######
try:
conn.send_eol("exit")
conn.close()
- except:
+ except Exception:
pass
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 57c8d4ef..fd4fa6c8 100644
--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py
+++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py
@@ -1,161 +1,161 @@
#!/usr/bin/python -tt
import sys, re
import pycurl, StringIO
import logging
import time
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, EC_STATUS, EC_LOGIN_DENIED, run_delay
#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)
def get_power_status(conn, options):
del conn
res = send_command(options, "<configResolveDn cookie=\"" + options["cookie"] +
"\" inHierarchical=\"false\" dn=\"org-root" + options["--suborg"] + "/ls-" +
options["--plug"] + "/power\"/>", int(options["--shell-timeout"]))
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):
del conn
action = {
'on' : "up",
'off' : "down"
}[options["--action"]]
send_command(options, "<configConfMos cookie=\"" + options["cookie"] + "\" inHierarchical=\"no\">" +
"<inConfigs><pair key=\"org-root" + options["--suborg"] + "/ls-" + options["--plug"] +
"/power\">" + "<lsPower dn=\"org-root/ls-" + options["--plug"] + "/power\" state=\"" +
action + "\" status=\"modified\" />" + "</pair></inConfigs></configConfMos>",
int(options["--shell-timeout"]))
return
def get_list(conn, options):
del conn
outlets = { }
try:
res = send_command(options, "<configResolveClass cookie=\"" + options["cookie"] +
"\" inHierarchical=\"false\" classId=\"lsServer\"/>", int(options["--shell-timeout"]))
lines = res.split("<lsServer ")
for i in range(1, len(lines)):
node_name = RE_GET_DN.search(lines[i]).group(1)
desc = RE_GET_DESC.search(lines[i]).group(1)
outlets[node_name] = (desc, None)
except AttributeError:
return { }
except IndexError:
return { }
return outlets
def send_command(opt, command, timeout):
## setup correct URL
if opt.has_key("--ssl"):
url = "https:"
else:
url = "http:"
url += "//" + opt["--ip"] + ":" + str(opt["--ipport"]) + "/nuova"
## send command through pycurl
conn = pycurl.Curl()
web_buffer = StringIO.StringIO()
conn.setopt(pycurl.URL, url)
conn.setopt(pycurl.HTTPHEADER, [ "Content-type: text/xml" ])
conn.setopt(pycurl.POSTFIELDS, command)
conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write)
conn.setopt(pycurl.TIMEOUT, timeout)
conn.setopt(pycurl.SSL_VERIFYPEER, 0)
conn.setopt(pycurl.SSL_VERIFYHOST, 0)
conn.perform()
result = web_buffer.getvalue()
logging.debug("%s\n", command)
logging.debug("%s\n", result)
return result
def define_new_opts():
all_opt["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 }
def main():
device_opt = [ "ipaddr", "login", "passwd", "ssl", "notls", "port", "web", "suborg" ]
atexit.register(atexit_handler)
define_new_opts()
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)
run_delay(options)
### Login
try:
res = send_command(options, "<aaaLogin inName=\"" + options["--username"] +
"\" inPassword=\"" + options["--password"] + "\" />", int(options["--login-timeout"]))
result = RE_COOKIE.search(res)
if result == None:
## Cookie is absenting in response
fail(EC_LOGIN_DENIED)
- except:
+ except Exception:
fail(EC_LOGIN_DENIED)
options["cookie"] = result.group(1)
##
## Modify suborg to format /suborg
if options["--suborg"] != "":
options["--suborg"] = "/" + options["--suborg"].lstrip("/").rstrip("/")
##
## 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["--shell-timeout"]))
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/drac/fence_drac.py b/fence/agents/drac/fence_drac.py
index 3cd7653f..4c0dea8b 100644
--- a/fence/agents/drac/fence_drac.py
+++ b/fence/agents/drac/fence_drac.py
@@ -1,81 +1,81 @@
#!/usr/bin/python -tt
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("getmodinfo")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
status = re.compile(r"\s+(on|off)\s+", re.IGNORECASE).search(conn.before).group(1)
return status.lower().strip()
def set_power_status(conn, options):
action = {
'on' : "powerup",
'off': "powerdown"
}[options["--action"]]
conn.send_eol("serveraction -d 0 " + action)
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt" ]
atexit.register(atexit_handler)
opt = process_input(device_opt)
if "--username" in opt:
all_opt["cmd_prompt"]["default"] = [ "\\[" + opt["--username"] + "\\]# " ]
else:
all_opt["cmd_prompt"]["default"] = [ "\\[" "username" + "\\]# " ]
options = check_input(device_opt, opt)
docs = { }
docs["shortdesc"] = "I/O Fencing agent for Dell DRAC IV"
docs["longdesc"] = "fence_drac is an I/O Fencing agent which can be used with \
the Dell Remote Access Card (DRAC). This card provides remote access to controlling \
power to a server. It logs into the DRAC through the telnet interface of the card. By \
default, the telnet interface is not enabled. To enable the interface, you will need \
to use the racadm command in the racser-devel rpm available from Dell. \
\
To enable telnet on the DRAC: \
\
[root]# racadm config -g cfgSerial -o cfgSerialTelnetEnable 1 \
\
[root]# racadm racreset \
"
docs["vendorurl"] = "http://www.dell.com"
show_docs(options, docs)
##
## Operate the fencing device
####
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, None)
##
## Logout from system
##
## In some special unspecified cases it is possible that
## connection will be closed before we run close(). This is not
## a problem because everything is checked before.
######
try:
conn.send_eol("exit")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/drac5/fence_drac5.py b/fence/agents/drac5/fence_drac5.py
index 6f70dad9..ade299e4 100644
--- a/fence/agents/drac5/fence_drac5.py
+++ b/fence/agents/drac5/fence_drac5.py
@@ -1,163 +1,163 @@
#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## DRAC Version Firmware
## +-----------------+---------------------------+
## DRAC 5 1.0 (Build 06.05.12)
## DRAC 5 1.21 (Build 07.05.04)
##
## @note: drac_version was removed
#####
import sys, re, time
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Drac5 Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
if options["--drac-version"] == "DRAC MC":
(_, status) = get_list_devices(conn, options)[options["--plug"]]
else:
if options["--drac-version"] == "DRAC CMC":
conn.send_eol("racadm serveraction powerstatus -m " + options["--plug"])
elif options["--drac-version"] == "DRAC 5":
conn.send_eol("racadm serveraction powerstatus")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
status = re.compile(r"(^|: )(ON|OFF|Powering ON|Powering OFF)\s*$",
re.IGNORECASE | re.MULTILINE).search(conn.before).group(2)
if status.lower().strip() in ["on", "powering on", "powering off"]:
return "on"
else:
return "off"
def set_power_status(conn, options):
action = {
'on' : "powerup",
'off': "powerdown"
}[options["--action"]]
if options["--drac-version"] == "DRAC CMC":
conn.send_eol("racadm serveraction " + action + " -m " + options["--plug"])
elif options["--drac-version"] == "DRAC 5":
conn.send_eol("racadm serveraction " + action)
elif options["--drac-version"] == "DRAC MC":
conn.send_eol("racadm serveraction -s " + options["--plug"] + " " + action)
## Fix issue with double-enter [CR/LF]
## We need to read two additional command prompts (one from get + one from set command)
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
if len(conn.before.strip()) == 0:
options["eol"] = options["eol"][:-1]
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def get_list_devices(conn, options):
outlets = { }
if options["--drac-version"] == "DRAC CMC":
conn.send_eol("getmodinfo")
list_re = re.compile(r"^([^\s]*?)\s+Present\s*(ON|OFF)\s*.*$")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
for line in conn.before.splitlines():
if list_re.search(line):
outlets[list_re.search(line).group(1)] = ("", list_re.search(line).group(2))
elif options["--drac-version"] == "DRAC MC":
conn.send_eol("getmodinfo")
list_re = re.compile(r"^\s*([^\s]*)\s*---->\s*(.*?)\s+Present\s*(ON|OFF)\s*.*$")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
for line in conn.before.splitlines():
if list_re.search(line):
outlets[list_re.search(line).group(2)] = ("", list_re.search(line).group(3))
elif options["--drac-version"] == "DRAC 5":
## DRAC 5 can be used only for one computer
## standard fence library can't handle correctly situation
## when some fence devices supported by fence agent
## works with 'list' and other should returns 'N/A'
print "N/A"
return outlets
def define_new_opts():
all_opt["drac_version"] = {
"getopt" : "d:",
"longopt" : "drac-version",
"help" : "-d, --drac-version=[version] Force DRAC version to use (DRAC 5, DRAC CMC, DRAC MC)",
"required" : "0",
"shortdesc" : "Force DRAC version to use (DRAC 5, DRAC CMC, DRAC MC)",
"choices" : [ "DRAC CMC", "DRAC MC", "DRAC 5" ],
"order" : 1 }
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
"drac_version", "port", "no_port" ]
atexit.register(atexit_handler)
define_new_opts()
all_opt["cmd_prompt"]["default"] = [ r"\$", r"DRAC\/MC:" ]
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for Dell DRAC CMC/5"
docs["longdesc"] = "fence_drac5 is an I/O Fencing agent \
which can be used with the Dell Remote Access Card v5 or CMC (DRAC). \
This device provides remote access to controlling power to a server. \
It logs into the DRAC through the telnet/ssh interface of the card. \
By default, the telnet interface is not enabled."
docs["vendorurl"] = "http://www.dell.com"
show_docs(options, docs)
##
## Operate the fencing device
######
conn = fence_login(options)
if options.has_key("--drac-version") == False:
## autodetect from text issued by fence device
if conn.before.find("CMC") >= 0:
options["--drac-version"] = "DRAC CMC"
elif conn.before.find("DRAC 5") >= 0:
options["--drac-version"] = "DRAC 5"
elif conn.after.find("DRAC/MC") >= 0:
options["--drac-version"] = "DRAC MC"
else:
## Assume this is DRAC 5 by default as we don't want to break anything
options["--drac-version"] = "DRAC 5"
if options["--drac-version"] in ["DRAC MC", "DRAC CMC"]:
if 0 == options.has_key("--plug") and 0 == ["monitor", "list"].count(options["--action"].lower()):
fail_usage("Failed: You have to enter module name (-n)")
result = fence_action(conn, options, set_power_status, get_power_status, get_list_devices)
##
## Logout from system
######
try:
conn.send_eol("exit")
time.sleep(1)
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/dummy/fence_dummy.py b/fence/agents/dummy/fence_dummy.py
index f460746a..5256aa8b 100644
--- a/fence/agents/dummy/fence_dummy.py
+++ b/fence/agents/dummy/fence_dummy.py
@@ -1,142 +1,142 @@
#!/usr/bin/python -tt
import sys, random
import logging
import time
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Dummy Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
plug_status = "on"
def get_power_status_file(conn, options):
del conn
try:
status_file = open(options["--status-file"], 'r')
- except:
+ except Exception:
return "off"
status = status_file.read()
status_file.close()
return status.lower()
def set_power_status_file(conn, options):
del conn
if not (options["--action"] in [ "on", "off" ]):
return
status_file = open(options["--status-file"], 'w')
status_file.write(options["--action"])
status_file.close()
def get_power_status_fail(conn, options):
outlets = get_outlets_fail(conn, options)
if len(outlets) == 0 or options.has_key("--plug") == 0:
fail_usage("Failed: You have to enter existing machine!")
else:
return outlets[options["--plug"]][0]
def set_power_status_fail(conn, options):
global plug_status
del conn
plug_status = "unknown"
if options["--action"] == "on":
plug_status = "off"
def get_outlets_fail(conn, options):
del conn
result = {}
global plug_status
if options["--action"] == "on":
plug_status = "off"
# This fake agent has no port data to list, so we have to make
# something up for the list action.
if options.has_key("--action") and options["--action"] == "list":
result["fake_port_1"] = [plug_status, "fake"]
result["fake_port_2"] = [plug_status, "fake"]
elif options.has_key("--plug") == 0:
fail_usage("Failed: You have to enter existing machine!")
else:
port = options["--plug"]
result[port] = [plug_status, "fake"]
return result
def main():
device_opt = [ "no_password", "status_file", "random_sleep_range", "type", "port" ]
atexit.register(atexit_handler)
all_opt["status_file"] = {
"getopt" : "s:",
"longopt" : "status-file",
"help":"--status-file=[file] Name of file that holds current status",
"required" : "0",
"shortdesc" : "File with status",
"default" : "/tmp/fence_dummy.status",
"order": 1
}
all_opt["random_sleep_range"] = {
"getopt" : "r:",
"longopt" : "random_sleep_range",
"help":"--random_sleep_range=[seconds] Issue a sleep between 1 and [seconds]",
"required" : "0",
"shortdesc" : "Issue a sleep between 1 and X seconds. Used for testing.",
"order": 1
}
all_opt["type"] = {
"getopt" : "t:",
"longopt" : "type",
"help":"--type=[type] Possible types are: file and fail",
"required" : "0",
"shortdesc" : "Type of the dummy fence agent",
"default" : "file",
"order": 1
}
pinput = process_input(device_opt)
if (pinput.has_key("--type") and pinput["--type"] == "file") or (pinput.has_key("--type") == False):
# hack to have fence agents that require ports 'fail' and one that do not 'file'
device_opt.remove("port")
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Dummy fence agent"
docs["longdesc"] = "fence_dummy"
docs["vendorurl"] = "http://www.example.com"
show_docs(options, docs)
# random sleep for testing
if options.has_key("--random_sleep_range"):
val = int(options["--random_sleep_range"])
ran = random.randint(1, val)
logging.info("Random sleep for %d seconds\n", ran)
time.sleep(ran)
if options["--type"] == "fail":
result = fence_action(None, options, set_power_status_fail, get_power_status_fail, get_outlets_fail)
else:
result = fence_action(None, options, set_power_status_file, get_power_status_file, None)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/eaton_snmp/fence_eaton_snmp.py b/fence/agents/eaton_snmp/fence_eaton_snmp.py
index 884fd6dd..59a61470 100644
--- a/fence/agents/eaton_snmp/fence_eaton_snmp.py
+++ b/fence/agents/eaton_snmp/fence_eaton_snmp.py
@@ -1,234 +1,234 @@
#!/usr/bin/python -tt
# 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
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage
from fencing_snmp import FencingSnmp
#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(object):
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(object):
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):
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
if device == None:
eaton_set_device(conn)
# Restore the increment, that was removed in main for ePDU Managed
if device.ident_str == "Eaton Switched ePDU":
options["--plug"] = str(int(options["--plug"]) + 1)
# Now we resolv port_id/switch_id
if options["--plug"].isdigit() and ((not device.has_switches) or (options["--switch"].isdigit())):
port_id = int(options["--plug"])
if device.has_switches:
switch_id = int(options["--switch"])
else:
table = conn.walk(device.outlet_table_oid, 30)
for x in table:
if x[1].strip('"') == options["--plug"]:
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["--plug"] = str(int(options["--plug"]) + 1)
fail_usage("Can't find port with name %s!"%(options["--plug"]))
def get_power_status(conn, options):
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 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:
+ except Exception:
return None
def set_power_status(conn, options):
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["--action"]=="on" and device.turn_on or device.turn_off))
def get_outlets_status(conn, options):
outletCount = 0
result = {}
if device == None:
eaton_set_device(conn)
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", "no_login", "no_password", \
"port", "snmp_version", "community" ]
atexit.register(atexit_handler)
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("--plug") and options["--plug"].isdigit():
options["--plug"] = str(int(options["--plug"]) - 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/hds_cb/fence_hds_cb.py b/fence/agents/hds_cb/fence_hds_cb.py
index 6caee7f3..8092de19 100755
--- a/fence/agents/hds_cb/fence_hds_cb.py
+++ b/fence/agents/hds_cb/fence_hds_cb.py
@@ -1,146 +1,146 @@
#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## Model Modle/Firmware
## +--------------------+---------------------------+
## (1) Main application CB2000/A0300-E-6617
##
#####
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Compute Blade 2000 Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="November, 2012"
#END_VERSION_GENERATION
RE_STATUS_LINE = r"^([0-9]+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*$"
def get_power_status(conn, options):
#### Maybe should put a conn.log_expect here to make sure
#### we have properly entered into the main menu
conn.sendline("S") # Enter System Command Mode
conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
conn.sendline("PC") # Enter partition control
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
result = {}
# Status can now be obtained from the output of the PC
# command. Line looks like the following:
# "P Power Condition LID lamp Mode Auto power on"
# "0 On Normal Off Basic Synchronized"
# "1 On Normal Off Basic Synchronized"
for line in conn.before.splitlines():
# populate the relevant fields based on regex
partition = re.search(RE_STATUS_LINE, line)
if partition != None:
# find the blade number defined in args
if partition.group(1) == options["--plug"]:
result = partition.group(2).lower()
# We must make sure we go back to the main menu as the
# status is checked before any fencing operations are
# executed. We could in theory save some time by staying in
# the partition control, but the logic is a little cleaner
# this way.
conn.sendline("Q") # Back to system command mode
conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
conn.sendline("EX") # Back to system console main menu
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
return result
def set_power_status(conn, options):
action = {
'on' : "P",
'off': "F",
'reboot' : "H",
}[options["--action"]]
conn.sendline("S") # Enter System Command Mode
conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
conn.sendline("PC") # Enter partition control
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.sendline("P") # Enter power control menu
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.sendline(action) # Execute action from array above
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.sendline(options["--plug"]) # Select blade number from args
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.sendline("Y") # Confirm action
conn.log_expect(options, "Hit enter key.", int(options["--shell-timeout"]))
conn.sendline("") # Press the any key
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.sendline("Q") # Quit back to partition control
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.sendline("Q") # Quit back to system command mode
conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
conn.sendline("EX") # Quit back to system console menu
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def get_blades_list(conn, options):
outlets = { }
conn.sendline("S") # Enter System Command Mode
conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
conn.sendline("PC") # Enter partition control
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
# Status can now be obtained from the output of the PC
# command. Line looks like the following:
# "P Power Condition LID lamp Mode Auto power on"
# "0 On Normal Off Basic Synchronized"
# "1 On Normal Off Basic Synchronized"
for line in conn.before.splitlines():
partition = re.search(RE_STATUS_LINE, line)
if partition != None:
outlets[partition.group(1)] = (partition.group(2), "")
conn.sendline("Q") # Quit back to system command mode
conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
conn.sendline("EX") # Quit back to system console menu
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
return outlets
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
"port", "missing_as_off" ]
atexit.register(atexit_handler)
all_opt["power_wait"]["default"] = "5"
all_opt["cmd_prompt"]["default"] = [ r"\) :" ]
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for Hitachi Compute Blade systems"
docs["longdesc"] = "fence_hds_cb is an I/O Fencing agent \
which can be used with Hitachi Compute Blades with recent enough firmware that \
includes telnet support."
docs["vendorurl"] = "http://www.hds.com"
show_docs(options, docs)
##
## Operate the fencing device
######
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list)
##
## Logout from system
######
try:
conn.sendline("X")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/hpblade/fence_hpblade.py b/fence/agents/hpblade/fence_hpblade.py
index 636c77d3..ee59d5f2 100644
--- a/fence/agents/hpblade/fence_hpblade.py
+++ b/fence/agents/hpblade/fence_hpblade.py
@@ -1,97 +1,97 @@
#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
## * BladeSystem c7000 Enclosure
#####
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, EC_STATUS
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Bladecenter Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("show server status " + options["--plug"])
conn.log_expect(options, options["--command-prompt"] , int(options["--shell-timeout"]))
power_re = re.compile(r"^\s*Power: (.*?)\s*$")
status = "unknown"
for line in conn.before.splitlines():
res = power_re.search(line)
if res != None:
status = res.group(1)
if status == "unknown":
if options.has_key("--missing-as-off"):
return "off"
else:
fail(EC_STATUS)
return status.lower().strip()
def set_power_status(conn, options):
if options["--action"] == "on":
conn.send_eol("poweron server " + options["--plug"])
elif options["--action"] == "off":
conn.send_eol("poweroff server " + options["--plug"] + " force")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def get_blades_list(conn, options):
outlets = { }
conn.send_eol("show server list" )
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
list_re = re.compile(r"^\s*(.*?)\s+(.*?)\s+(.*?)\s+OK\s+(.*?)\s+(.*?)\s*$")
for line in conn.before.splitlines():
res = list_re.search(line)
if res != None:
outlets[res.group(1)] = (res.group(2), res.group(4).lower())
return outlets
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "missing_as_off" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "c7000oa>" ]
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for HP BladeSystem"
docs["longdesc"] = "fence_hpblade is an I/O Fencing agent \
which can be used with HP BladeSystem. It logs into an enclosure via telnet or ssh \
and uses the command line interface to power on and off blades."
docs["vendorurl"] = "http://www.hp.com"
show_docs(options, docs)
##
## Operate the fencing device
######
options["eol"] = "\n"
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list)
##
## Logout from system
######
try:
conn.send_eol("exit")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/ilo_mp/fence_ilo_mp.py b/fence/agents/ilo_mp/fence_ilo_mp.py
index 1d874c12..6cc2d9f9 100644
--- a/fence/agents/ilo_mp/fence_ilo_mp.py
+++ b/fence/agents/ilo_mp/fence_ilo_mp.py
@@ -1,69 +1,69 @@
#!/usr/bin/python -tt
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("show /system1")
re_state = re.compile('EnabledState=(.*)', re.IGNORECASE)
conn.log_expect(options, re_state, int(options["--shell-timeout"]))
status = conn.match.group(1).lower()
if status.startswith("enabled"):
return "on"
else:
return "off"
def set_power_status(conn, options):
if options["--action"] == "on":
conn.send_eol("start /system1")
else:
conn.send_eol("stop -f /system1")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
return
def main():
device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "MP>", "hpiLO->" ]
all_opt["power_wait"]["default"] = 5
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for HP iLO MP"
docs["longdesc"] = ""
docs["vendorurl"] = "http://www.hp.com"
show_docs(options, docs)
conn = fence_login(options)
conn.send_eol("SMCLP")
##
## Fence operations
####
result = fence_action(conn, options, set_power_status, get_power_status)
try:
conn.send_eol("exit")
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 845372bb..964e6136 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1,1129 +1,1129 @@
#!/usr/bin/python -tt
import sys, getopt, time, os, uuid, pycurl, stat
import pexpect, re, atexit, syslog
import logging
import subprocess
import threading
import shlex
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
__all__ = [ 'atexit_handler', 'check_input', 'process_input', 'all_opt', 'show_docs',
'fence_login', 'fence_action' ]
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
EC_INVALID_PRIVILEGES = 11
TELNET_PATH = "/usr/bin/telnet"
SSH_PATH = "/usr/bin/ssh"
SSL_PATH = "@GNUTLSCLI_PATH@"
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 },
"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/UDP port to use",
"required" : "0",
"shortdesc" : "TCP/UDP 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 },
"no_port" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"no_status" : {
"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 },
"cmd_prompt" : {
"getopt" : "c:",
"longopt" : "command-prompt",
"help" : "-c, --command-prompt=[prompt] Force Python regex for command prompt",
"shortdesc" : "Force Python regex for command prompt",
"required" : "0",
"order" : 1 },
"secure" : {
"getopt" : "x",
"longopt" : "ssh",
"help" : "-x, --ssh Use ssh connection",
"shortdesc" : "SSH connection",
"required" : "0",
"order" : 1 },
"ssh_options" : {
"getopt" : "X:",
"longopt" : "ssh-options",
"help" : "--ssh-options=[options] SSH options to use",
"shortdesc" : "SSH options to use",
"required" : "0",
"order" : 1 },
"ssl" : {
"getopt" : "z",
"longopt" : "ssl",
"help" : "-z, --ssl Use ssl connection",
"required" : "0",
"shortdesc" : "SSL connection",
"order" : 1 },
"notls" : {
"getopt" : "t",
"longopt" : "notls",
"help" : "-t, --notls "
"Disable TLS negotiation and force SSL3.0.\n"
" "
"This should only be used for devices that do not support TLS1.0 and up.",
"required" : "0",
"shortdesc" : "Disable TLS negotiation",
"order" : 1 },
"port" : {
"getopt" : "n:",
"longopt" : "plug",
"help" : "-n, --plug=[id] Physical plug number on device, UUID or\n" +
" identification of machine",
"required" : "1",
"shortdesc" : "Physical plug number, name of virtual machine or UUID",
"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 },
"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=[version] Specifies SNMP version to use",
"required" : "0",
"shortdesc" : "Specifies SNMP version to use (1,2c,3)",
"choices" : [ "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)",
"choices" : [ "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)",
"choices" : [ "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)",
"choices" : [ "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 },
"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},
"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},
"method" : {
"getopt" : "m:",
"longopt" : "method",
"help" : "-m, --method=[method] Method to fence (onoff|cycle) (Default: onoff)",
"required" : "0",
"shortdesc" : "Method to fence (onoff|cycle)",
"default" : "onoff",
"choices" : [ "onoff", "cycle" ],
"order" : 1}
}
# options which are added automatically if 'key' is encountered ("default" is always added)
DEPENDENCY_OPT = {
"default" : [ "help", "debug", "verbose", "version", "action", "agent", \
"power_timeout", "shell_timeout", "login_timeout", "power_wait", "retry_on", "delay" ],
"passwd" : [ "passwd_script" ],
"secure" : [ "identity_file", "ssh_options" ],
"ipaddr" : [ "ipport", "inet4_only", "inet6_only" ],
"port" : [ "separator" ],
"community" : [ "snmp_auth_prot", "snmp_sec_level", "snmp_priv_prot", \
"snmp_priv_passwd", "snmp_priv_passwd_script" ]
}
class fspawn(pexpect.spawn):
def __init__(self, options, command):
logging.info("Running command: %s", command)
pexpect.spawn.__init__(self, command)
self.opt = options
def log_expect(self, options, pattern, timeout):
result = self.expect(pattern, timeout)
logging.debug("Received: %s", self.before + self.after)
return result
def send(self, message):
logging.debug("Sent: %s", message)
return pexpect.spawn.send(self, message)
# send EOL according to what was detected in login process (telnet)
def send_eol(self, message):
return self.send(message + self.opt["eol"])
def atexit_handler():
try:
sys.stdout.close()
os.close(1)
except IOError:
logging.error("%s failed to close standard output\n", sys.argv[0])
syslog.syslog(syslog.LOG_ERR, "Failed to close standard output")
sys.exit(EC_GENERIC_ERROR)
def add_dependency_options(options):
## Add also options which are available for every fence agent
added_opt = []
for opt in options + ["default"]:
if DEPENDENCY_OPT.has_key(opt):
added_opt.extend([y for y in DEPENDENCY_OPT[opt] if options.count(y) == 0])
return added_opt
def fail_usage(message = ""):
if len(message) > 0:
logging.error("%s\n", message)
logging.error("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 obtain correct plug status, "
"partition is not available or incorrect HMC version used",
EC_PASSWORD_MISSING : "Failed: You have to set login password",
EC_INVALID_PRIVILEGES : "Failed: The user does not have the correct privileges to do the requested action."
}[error_code] + "\n"
logging.error("%s\n", message)
syslog.syslog(syslog.LOG_ERR, message)
sys.exit(EC_GENERIC_ERROR)
def usage(avail_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):
# avail_opt has to be unique, if there are duplicities then they should be removed
sorted_list = [ (key, all_opt[key]) for key in list(set(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, _ 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 = str(all_opt[option]["default"])
elif options.has_key("--" + all_opt[option]["longopt"]) and all_opt[option]["getopt"].endswith(":"):
if options["--" + all_opt[option]["longopt"]]:
try:
default = options["--" + all_opt[option]["longopt"]]
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 = str(options["--" + all_opt[option]["longopt"]])
elif options.has_key("--" + all_opt[option]["longopt"]):
default = "true"
if default:
default = default.replace("&", "&" )
default = default.replace('"', """ )
default = default.replace('<', "<" )
default = default.replace('>', ">" )
default = default.replace("'", "'" )
default = "default=\"" + default + "\" "
mixed = all_opt[option]["help"]
## split it between option and help text
res = re.compile(r"^(.*?--\S+)\s+", re.IGNORECASE | re.S).search(mixed)
if None != res:
mixed = res.group(1)
mixed = mixed.replace("<", "<").replace(">", ">")
print "\t\t<getopt mixed=\"" + mixed + "\" />"
if all_opt[option].has_key("choices"):
print "\t\t<content type=\"select\" "+default+" >"
for choice in all_opt[option]["choices"]:
print "\t\t\t<option value=\"%s\" />" % (choice)
print "\t\t</content>"
elif 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>"
if avail_opt.count("fabric_fencing") == 1:
## do 'unfence' at the start
print "\t<action name=\"on\" automatic=\"1\"/>"
else:
print "\t<action name=\"on\" automatic=\"0\"/>"
print "\t<action name=\"off\" />"
if avail_opt.count("fabric_fencing") == 0:
print "\t<action name=\"reboot\" />"
if avail_opt.count("no_status") == 0:
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):
avail_opt.extend(add_dependency_options(avail_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"])
##
## 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)
except getopt.GetoptError, error:
fail_usage("Parse error: " + error.msg)
## Transform short getopt to long 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]["longopt"]] = dict(old_opt)[o]
else:
for x in all_opt.keys():
if x in avail_opt and all_opt[x].has_key("getopt") and all_opt[x].has_key("longopt") and \
("-" + all_opt[x]["getopt"] == o or "-" + all_opt[x]["getopt"].rstrip(":") == o):
opt["--" + all_opt[x]["longopt"]] = dict(old_opt)[o]
opt[o] = dict(old_opt)[o]
## Compatibility Layer
#####
z = dict(opt)
if z.has_key("--plug") == 1:
z["-m"] = z["--plug"]
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]
if avail_opt.count(name) == 0:
logging.warning("Parse error: Ignoring unknown option '%s'\n", line)
syslog.syslog(syslog.LOG_WARNING, "Parse error: Ignoring unknown option '" + line)
continue
if all_opt[name]["getopt"].endswith(":"):
opt["--"+all_opt[name]["longopt"].rstrip(":")] = value
elif value.lower() in [ "1", "yes", "on", "true" ]:
opt["--"+all_opt[name]["longopt"]] = "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):
device_opt.extend(add_dependency_options(device_opt))
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"
if device_opt.count("fabric_fencing"):
all_opt["action"]["default"] = "off"
all_opt["action"]["help"] = "-o, --action=[action] Action: status, off (default) or on"
if device_opt.count("ipport"):
if options.has_key("--ipport"):
all_opt["ipport"]["help"] = "-u, --ipport=[port] " + \
"TCP/UDP port to use (default " + options["--ipport"] +")"
elif all_opt.has_key("ipport") and all_opt["ipport"].has_key("default"):
all_opt["ipport"]["help"] = "-u, --ipport=[port] " + \
"TCP/UDP port to use (default " + all_opt["ipport"]["default"] +")"
elif device_opt.count("snmp_version"):
all_opt["ipport"]["default"] = "161"
all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 161)"
elif options.has_key("--ssh") or (all_opt["secure"].has_key("default") and all_opt["secure"]["default"] == '1'):
all_opt["ipport"]["default"] = 22
all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 22)"
elif options.has_key("--ssl") or (all_opt["ssl"].has_key("default") and all_opt["ssl"]["default"] == '1'):
all_opt["ipport"]["default"] = 443
all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 443)"
elif device_opt.count("web"):
all_opt["ipport"]["default"] = 80
if device_opt.count("ssl") == 0:
all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 80)"
else:
all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
(default 80, 443 if --ssl option is used)"
else:
all_opt["ipport"]["default"] = 23
if device_opt.count("secure") == 0:
all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 23)"
else:
all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
(default 23, 22 if --ssh option is used)"
## Set default values
#####
for opt in device_opt:
if all_opt[opt].has_key("default"):
getopt_long = "--" + all_opt[opt]["longopt"]
if 0 == options.has_key(getopt_long):
options[getopt_long] = all_opt[opt]["default"]
## In special cases (show help, metadata or version) we don't need to check anything
#####
if options.has_key("--help") or options.has_key("--version") or \
(options.has_key("--action") and options["--action"].lower() == "metadata"):
return options
options["--action"] = options["--action"].lower()
if options.has_key("--verbose"):
logging.getLogger().setLevel(logging.DEBUG)
acceptable_actions = [ "on", "off", "status", "list", "monitor" ]
if 1 == device_opt.count("fabric_fencing"):
## Compatibility layer
#####
acceptable_actions.extend(["enable", "disable"])
else:
acceptable_actions.extend(["reboot"])
if 1 == device_opt.count("no_status"):
acceptable_actions.remove("status")
if 0 == acceptable_actions.count(options["--action"]):
fail_usage("Failed: Unrecognised action '" + options["--action"] + "'")
## Compatibility layer
#####
if options["--action"] == "enable":
options["--action"] = "on"
if options["--action"] == "disable":
options["--action"] = "off"
## automatic detection and set of valid UUID from --plug
if (0 == options.has_key("--username")) and \
device_opt.count("login") and (device_opt.count("no_login") == 0):
fail_usage("Failed: You have to set login name")
if device_opt.count("ipaddr") and 0 == options.has_key("--ip") and 0 == options.has_key("--managed"):
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("--password") or options.has_key("--password-script")):
fail_usage("Failed: You have to enter password or password script")
else:
if 0 == (options.has_key("--password") or \
options.has_key("--password-script") or options.has_key("--identity-file")):
fail_usage("Failed: You have to enter password, password script or identity file")
if 0 == options.has_key("--ssh") and 1 == options.has_key("--identity-file"):
fail_usage("Failed: You have to use identity file together with ssh connection (-x)")
if 1 == options.has_key("--identity-file"):
if 0 == os.path.isfile(options["--identity-file"]):
fail_usage("Failed: Identity file " + options["--identity-file"] + " does not exist")
if (0 == ["list", "monitor"].count(options["--action"].lower())) and \
0 == options.has_key("--plug") and device_opt.count("port") and device_opt.count("no_port") == 0:
fail_usage("Failed: You have to enter plug number or machine identification")
if options.has_key("--password-script"):
options["--password"] = os.popen(options["--password-script"]).read().rstrip()
if options.has_key("--debug-file"):
try:
fh = logging.FileHandler(options["--debug-file"])
fh.setLevel(logging.DEBUG)
logging.getLogger().addHandler(fh)
except IOError:
logging.error("Unable to create file %s", options["--debug-file"])
fail_usage("Failed: Unable to create file " + options["--debug-file"])
if options.has_key("--snmp-priv-passwd-script"):
options["--snmp-priv-passwd"] = os.popen(options["--snmp-priv-passwd-script"]).read().rstrip()
if options.has_key("--plug") and len(options["--plug"].split(",")) > 1 and \
options.has_key("--method") and options["--method"] == "cycle":
fail_usage("Failed: Cannot use --method cycle for more than 1 plug")
for opt in device_opt:
if all_opt[opt].has_key("choices"):
longopt = "--" + all_opt[opt]["longopt"]
possible_values_upper = [y.upper() for y in all_opt[opt]["choices"]]
if options.has_key(longopt):
options[longopt] = options[longopt].upper()
if not options["--" + all_opt[opt]["longopt"]] in possible_values_upper:
fail_usage("Failed: You have to enter a valid choice " + \
"for %s from the valid values: %s" % \
("--" + all_opt[opt]["longopt"] , str(all_opt[opt]["choices"])))
return options
def wait_power_status(tn, options, get_power_fn):
for dummy in xrange(int(options["--power-timeout"])):
if get_multi_power_fn(tn, options, get_power_fn) != options["--action"]:
time.sleep(1)
else:
return 1
return 0
## Obtain a power status from possibly more than one plug
## "on" is returned if at least one plug is ON
######
def get_multi_power_fn(tn, options, get_power_fn):
status = "off"
if options.has_key("--plugs"):
for plug in options["--plugs"]:
try:
options["--uuid"] = str(uuid.UUID(plug))
except ValueError:
pass
except KeyError:
pass
options["--plug"] = plug
plug_status = get_power_fn(tn, options)
if plug_status != "off":
status = plug_status
else:
status = get_power_fn(tn, options)
return status
def set_multi_power_fn(tn, options, set_power_fn):
if options.has_key("--plugs"):
for plug in options["--plugs"]:
try:
options["--uuid"] = str(uuid.UUID(plug))
except ValueError:
pass
except KeyError:
pass
options["--plug"] = plug
set_power_fn(tn, options)
else:
set_power_fn(tn, options)
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("--help"):
usage(device_opt)
sys.exit(0)
if options.has_key("--action") and options["--action"].lower() == "metadata":
metadata(device_opt, options, docs)
sys.exit(0)
if options.has_key("--version"):
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, reboot_cycle_fn = None):
result = 0
try:
if options.has_key("--plug"):
options["--plugs"] = options["--plug"].split(",")
## Process options that manipulate fencing device
#####
if options["--action"] == "list" and 0 == options["device_opt"].count("port"):
print "N/A"
return
elif options["--action"] == "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["--action"] == "list") or \
((options["--action"] == "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 outlet_id in outlets.keys():
(alias, status) = outlets[outlet_id]
if options["--action"] != "monitor":
print outlet_id + options["--separator"] + alias
return
status = get_multi_power_fn(tn, options, get_power_fn)
if status != "on" and status != "off":
fail(EC_STATUS)
if options["--action"] == "on":
if status == "on":
print "Success: Already ON"
else:
power_on = False
for _ in range(1, 1 + int(options["--retry-on"])):
set_multi_power_fn(tn, options, set_power_fn)
time.sleep(int(options["--power-wait"]))
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["--action"] == "off":
if status == "off":
print "Success: Already OFF"
else:
set_multi_power_fn(tn, options, set_power_fn)
time.sleep(int(options["--power-wait"]))
if wait_power_status(tn, options, get_power_fn):
print "Success: Powered OFF"
else:
fail(EC_WAITING_OFF)
elif options["--action"] == "reboot":
power_on = False
if options.has_key("--method") and options["--method"].lower() == "cycle" and reboot_cycle_fn is not None:
for _ in range(1, 1 + int(options["--retry-on"])):
if reboot_cycle_fn(tn, options):
power_on = True
break
if not power_on:
fail(EC_TIMED_OUT)
else:
if status != "off":
options["--action"] = "off"
set_multi_power_fn(tn, options, set_power_fn)
time.sleep(int(options["--power-wait"]))
if wait_power_status(tn, options, get_power_fn) == 0:
fail(EC_WAITING_OFF)
options["--action"] = "on"
try:
for _ in range(1, 1 + int(options["--retry-on"])):
set_multi_power_fn(tn, options, set_power_fn)
time.sleep(int(options["--power-wait"]))
if wait_power_status(tn, options, get_power_fn) == 1:
power_on = True
break
except Exception, ex:
# an error occured during power ON phase in reboot
# fence action was completed succesfully even in that case
logging.error("%s", str(ex))
syslog.syslog(syslog.LOG_NOTICE, str(ex))
if power_on == False:
# this should not fail as node was fenced succesfully
logging.error('Timed out waiting to power ON\n')
syslog.syslog(syslog.LOG_NOTICE, "Timed out waiting to power ON")
print "Success: Rebooted"
elif options["--action"] == "status":
print "Status: " + status.upper()
if status.upper() == "OFF":
result = 2
elif options["--action"] == "monitor":
pass
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
except pycurl.error, ex:
logging.error("%s\n", str(ex))
syslog.syslog(syslog.LOG_ERR, ex[1])
fail(EC_TIMED_OUT)
return result
def fence_login(options, re_login_string = r"(login\s*: )|(Login Name: )|(username: )|(User Name :)"):
force_ipvx = ""
if options.has_key("--inet6-only"):
force_ipvx = "-6 "
if options.has_key("--inet4-only"):
force_ipvx = "-4 "
if not options.has_key("eol"):
options["eol"] = "\r\n"
if options.has_key("--command-prompt") and type(options["--command-prompt"]) is not list:
options["--command-prompt"] = [ options["--command-prompt"] ]
## Do the delay of the fence device before logging in
run_delay(options)
try:
re_login = re.compile(re_login_string, re.IGNORECASE)
re_pass = re.compile("(password)|(pass phrase)", re.IGNORECASE)
if options.has_key("--ssl"):
gnutls_opts = ""
if options.has_key("--notls"):
gnutls_opts = "--priority \"NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:-VERS-TLS1.0:+VERS-SSL3.0\""
command = '%s %s --insecure --crlf -p %s %s' % \
(SSL_PATH, gnutls_opts, options["--ipport"], options["--ip"])
try:
conn = fspawn(options, command)
except pexpect.ExceptionPexpect, ex:
logging.error("%s\n", str(ex))
syslog.syslog(syslog.LOG_ERR, str(ex))
sys.exit(EC_GENERIC_ERROR)
elif options.has_key("--ssh") and 0 == options.has_key("--identity-file"):
command = '%s %s %s@%s -p %s -o PubkeyAuthentication=no' % \
(SSH_PATH, force_ipvx, options["--username"], options["--ip"], options["--ipport"])
if options.has_key("--ssh-options"):
command += ' ' + options["--ssh-options"]
conn = fspawn(options, command)
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["--login-timeout"]))
if result == 1:
conn.sendline("yes") # Host identity confirm
conn.log_expect(options, re_login, int(options["--login-timeout"]))
conn.sendline(options["--username"])
conn.log_expect(options, re_pass, int(options["--login-timeout"]))
else:
result = conn.log_expect(options, \
[ "ssword:", "Are you sure you want to continue connecting (yes/no)?" ],
int(options["--login-timeout"]))
if result == 1:
conn.sendline("yes")
conn.log_expect(options, "ssword:", int(options["--login-timeout"]))
conn.sendline(options["--password"])
conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
elif options.has_key("--ssh") and options.has_key("--identity-file"):
command = '%s %s %s@%s -i %s -p %s' % \
(SSH_PATH, force_ipvx, options["--username"], options["--ip"], \
options["--identity-file"], options["--ipport"])
if options.has_key("--ssh-options"):
command += ' ' + options["--ssh-options"]
conn = fspawn(options, command)
result = conn.log_expect(options, [ "Enter passphrase for key '" + options["--identity-file"] + "':", \
"Are you sure you want to continue connecting (yes/no)?" ] + \
options["--command-prompt"], int(options["--login-timeout"]))
if result == 1:
conn.sendline("yes")
result = conn.log_expect(options,
[ "Enter passphrase for key '" + options["--identity-file"]+"':"] + \
options["--command-prompt"], int(options["--login-timeout"]))
if result == 0:
if options.has_key("--password"):
conn.sendline(options["--password"])
conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
else:
fail_usage("Failed: You have to enter passphrase (-p) for identity file")
else:
conn = fspawn(options, TELNET_PATH)
conn.send("set binary\n")
conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
result = conn.log_expect(options, re_login, int(options["--login-timeout"]))
conn.send_eol(options["--username"])
## automatically change end of line separator
screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
if re_login.search(screen) != None:
options["eol"] = "\n"
conn.send_eol(options["--username"])
result = conn.log_expect(options, re_pass, int(options["--login-timeout"]))
elif re_pass.search(screen) != None:
conn.log_expect(options, re_pass, int(options["--shell-timeout"]))
try:
conn.send_eol(options["--password"])
valid_password = conn.log_expect(options, [ re_login ] + \
options["--command-prompt"], int(options["--shell-timeout"]))
if valid_password == 0:
## password is invalid or we have to change EOL separator
options["eol"] = "\r"
conn.send_eol("")
screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
## after sending EOL the fence device can either show 'Login' or 'Password'
if re_login.search(screen) != None:
conn.send_eol("")
conn.send_eol(options["--username"])
conn.log_expect(options, re_pass, int(options["--login-timeout"]))
conn.send_eol(options["--password"])
conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
except KeyError:
fail(EC_PASSWORD_MISSING)
except pexpect.EOF:
fail(EC_LOGIN_DENIED)
except pexpect.TIMEOUT:
fail(EC_LOGIN_DENIED)
return conn
def is_executable(path):
if os.path.exists(path):
stats = os.stat(path)
if stat.S_ISREG(stats.st_mode) and os.access(path, os.X_OK):
return True
return False
def run_command(options, command, timeout = None, env = None):
if timeout is None and "--power-timeout" in options:
timeout = options["--power-timeout"]
if timeout is not None:
timeout = float(timeout)
logging.info("Executing: %s\n", command)
try:
process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
- except OSError, ex:
+ except OSError:
fail_usage("Unable to run %s\n" % command)
thread = threading.Thread(target = process.wait)
thread.start()
thread.join(timeout)
if thread.is_alive():
process.kill()
fail(EC_TIMED_OUT)
status = process.wait()
(pipe_stdout, pipe_stderr) = process.communicate()
process.stdout.close()
process.stderr.close()
logging.debug("%s %s %s\n", str(status), str(pipe_stdout), str(pipe_stderr))
return (status, pipe_stdout, pipe_stderr)
def run_delay(options):
## Delay is important for two-node clusters fencing but we do not need to delay 'status' operations
if options["--action"] in ["off", "reboot"]:
logging.info("Delay %s second(s) before logging in to the fence device", options["--delay"])
time.sleep(int(options["--delay"]))
diff --git a/fence/agents/lpar/fence_lpar.py b/fence/agents/lpar/fence_lpar.py
index 304ebe41..c4876563 100644
--- a/fence/agents/lpar/fence_lpar.py
+++ b/fence/agents/lpar/fence_lpar.py
@@ -1,164 +1,164 @@
#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## Version
## +---------------------------------------------+
## Tested on HMC
##
#####
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, fail_usage, EC_STATUS_HMC
#BEGIN_VERSION_GENERATION
RELEASE_VERSION=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
if options["--hmc-version"] == "3":
conn.send("lssyscfg -r lpar -m " + options["--managed"] + " -n " + options["--plug"] + " -F name,state\n")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
try:
status = re.compile("^" + options["--plug"] + ",(.*?),.*$",
re.IGNORECASE | re.MULTILINE).search(conn.before).group(1)
except AttributeError:
fail(EC_STATUS_HMC)
elif options["--hmc-version"] == "4":
conn.send("lssyscfg -r lpar -m "+ options["--managed"] +
" --filter 'lpar_names=" + options["--plug"] + "'\n")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
try:
status = re.compile(",state=(.*?),", re.IGNORECASE).search(conn.before).group(1)
except AttributeError:
fail(EC_STATUS_HMC)
##
## Transformation to standard ON/OFF status if possible
if status in ["Running", "Open Firmware", "Shutting Down", "Starting"]:
status = "on"
else:
status = "off"
return status
def set_power_status(conn, options):
if options["--hmc-version"] == "3":
conn.send("chsysstate -o " + options["--action"] + " -r lpar -m " + options["--managed"]
+ " -n " + options["--plug"] + "\n")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
elif options["--hmc-version"] == "4":
if options["--action"] == "on":
conn.send("chsysstate -o on -r lpar -m " + options["--managed"] +
" -n " + options["--plug"] +
" -f `lssyscfg -r lpar -F curr_profile " +
" -m " + options["--managed"] +
" --filter \"lpar_names="+ options["--plug"] +"\"`\n" )
else:
conn.send("chsysstate -o shutdown -r lpar --immed" +
" -m " + options["--managed"] + " -n " + options["--plug"] + "\n")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def get_lpar_list(conn, options):
outlets = { }
if options["--hmc-version"] == "3":
conn.send("query_partition_names -m " + options["--managed"] + "\n")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
## We have to remove first 3 lines (command + header) and last line (part of new prompt)
####
res = re.search("^.+?\n(.+?\n){2}(.*)\n.*$", conn.before, re.S)
if res == None:
fail_usage("Unable to parse output of list command")
lines = res.group(2).split("\n")
for outlet_line in lines:
outlets[outlet_line.rstrip()] = ("", "")
elif options["--hmc-version"] == "4":
conn.send("lssyscfg -r lpar -m " + options["--managed"] +
" -F name:state\n")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
## We have to remove first line (command) and last line (part of new prompt)
####
res = re.search("^.+?\n(.*)\n.*$", conn.before, re.S)
if res == None:
fail_usage("Unable to parse output of list command")
lines = res.group(1).split("\n")
for outlet_line in lines:
(port, status) = outlet_line.split(":")
outlets[port] = ("", status)
return outlets
def define_new_opts():
all_opt["managed"] = {
"getopt" : "s:",
"longopt" : "managed",
"help" : "-s, --managed=[id] Name of the managed system",
"required" : "0",
"shortdesc" : "Managed system name",
"order" : 1 }
all_opt["hmc_version"] = {
"getopt" : "H:",
"longopt" : "hmc-version",
"help" : "-H, --hmc-version=[version] Force HMC version to use: 3, 4 (default)",
"required" : "0",
"shortdesc" : "Force HMC version to use (3 or 4)",
"default" : "4",
"choices" : [ "3", "4" ],
"order" : 1 }
def main():
device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt", \
"port", "managed", "hmc_version" ]
atexit.register(atexit_handler)
define_new_opts()
all_opt["login_timeout"]["default"] = "15"
all_opt["secure"]["default"] = "1"
all_opt["cmd_prompt"]["default"] = [ r":~>", r"]\$", r"\$ " ]
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for IBM LPAR"
docs["longdesc"] = ""
docs["vendorurl"] = "http://www.ibm.com"
show_docs(options, docs)
if 0 == options.has_key("--managed"):
fail_usage("Failed: You have to enter name of managed system")
##
## Operate the fencing device
####
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, get_lpar_list)
##
## Logout from system
######
try:
conn.send("quit\r\n")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/netio/fence_netio.py b/fence/agents/netio/fence_netio.py
index 3b8247b9..4cf3b43c 100755
--- a/fence/agents/netio/fence_netio.py
+++ b/fence/agents/netio/fence_netio.py
@@ -1,116 +1,116 @@
#!/usr/bin/python -tt
import sys, re, pexpect
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fspawn, fail, EC_LOGIN_DENIED, TELNET_PATH, run_delay
#BEGIN_VERSION_GENERATION
RELEASE_VERSION=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("port %s" % options["--plug"])
re_status = re.compile("250 [01imt]")
conn.log_expect(options, re_status, int(options["--shell-timeout"]))
status = {
"0" : "off",
"1" : "on",
"i" : "reboot",
"m" : "manual",
"t" : "timer"
}[conn.after.split()[1]]
return status
def set_power_status(conn, options):
action = {
"on" : "1",
"off" : "0",
"reboot" : "i"
}[options["--action"]]
conn.send_eol("port %s %s" % (options["--plug"], action))
conn.log_expect(options, "250 OK", int(options["--shell-timeout"]))
def get_outlet_list(conn, options):
result = {}
try:
# the NETIO-230B has 4 ports, counting start at 1
for plug in ["1", "2", "3", "4"]:
conn.send_eol("port setup %s" % plug)
conn.log_expect(options, "250 .+", int(options["--shell-timeout"]))
# the name is enclosed in "", drop those with [1:-1]
name = conn.after.split()[1][1:-1]
result[plug] = (name, "unknown")
except Exception, exn:
print str(exn)
return result
def main():
device_opt = [ "ipaddr", "login", "passwd", "port" ]
atexit.register(atexit_handler)
opt = process_input(device_opt)
# set default port for telnet only
if 0 == opt.has_key("--ipport"):
opt["--ipport"] = "1234"
opt["eol"] = "\r\n"
options = check_input(device_opt, opt)
docs = { }
docs["shortdesc"] = "I/O Fencing agent for Koukaam NETIO-230B"
docs["longdesc"] = "fence_netio is an I/O Fencing agent which can be \
used with the Koukaam NETIO-230B Power Distribution Unit. It logs into \
device via telnet and reboots a specified outlet. Lengthy telnet connections \
should be avoided while a GFS cluster is running because the connection will \
block any necessary fencing actions."
docs["vendorurl"] = "http://www.koukaam.se/"
show_docs(options, docs)
##
## Operate the fencing device
## We can not use fence_login(), username and passwd are sent on one line
####
run_delay(options)
try:
conn = fspawn(options, TELNET_PATH)
conn.send("set binary\n")
conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
conn.log_expect(options, "100 HELLO .*", int(options["--shell-timeout"]))
conn.send_eol("login %s %s" % (options["--username"], options["--password"]))
conn.log_expect(options, "250 OK", int(options["--shell-timeout"]))
except pexpect.EOF:
fail(EC_LOGIN_DENIED)
except pexpect.TIMEOUT:
fail(EC_LOGIN_DENIED)
result = fence_action(conn, options, set_power_status, get_power_status, get_outlet_list)
##
## Logout from system
##
## In some special unspecified cases it is possible that
## connection will be closed before we run close(). This is not
## a problem because everything is checked before.
######
try:
conn.send("quit\n")
conn.log_expect(options, "110 BYE", int(options["--shell-timeout"]))
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/raritan/fence_raritan.py b/fence/agents/raritan/fence_raritan.py
index 7704c41b..efd56053 100644
--- a/fence/agents/raritan/fence_raritan.py
+++ b/fence/agents/raritan/fence_raritan.py
@@ -1,99 +1,99 @@
#!/usr/bin/python -tt
import sys, re, pexpect
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fspawn, fail, fail_usage, TELNET_PATH, EC_LOGIN_DENIED, run_delay
#BEGIN_VERSION_GENERATION
RELEASE_VERSION=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
# --plug should include path to the outlet # such as port 1:
# /system1/outlet1
def get_power_status(conn, options):
conn.send_eol("show -d properties=powerState %s" % options["--plug"])
re_status = re.compile(".*powerState is [12].*")
conn.log_expect(options, re_status, int(options["--shell-timeout"]))
status = {
#"0" : "off",
"1" : "on",
"2" : "off",
}[conn.after.split()[2]]
return status
def set_power_status(conn, options):
action = {
"on" : "on",
"off" : "off",
}[options["--action"]]
conn.send_eol("set %s powerState=%s" % (options["--plug"], action))
def main():
device_opt = [ "ipaddr", "login", "passwd", "port" ]
atexit.register(atexit_handler)
opt = process_input(device_opt)
all_opt["ipport"]["default"] = "23"
opt["eol"] = "\r\n"
options = check_input(device_opt, opt)
docs = { }
docs["shortdesc"] = "I/O Fencing agent for Raritan Dominion PX"
docs["longdesc"] = "fence_raritan is an I/O Fencing agent which can be \
used with the Raritan DPXS12-20 Power Distribution Unit. It logs into \
device via telnet and reboots a specified outlet. Lengthy telnet connections \
should be avoided while a GFS cluster is running because the connection will \
block any necessary fencing actions."
docs["vendorurl"] = "http://www.raritan.com/"
show_docs(options, docs)
# add support also for delay before login which is very useful for 2-node clusters
run_delay(options)
##
## Operate the fencing device
## We can not use fence_login(), username and passwd are sent on one line
####
try:
conn = fspawn(options, TELNET_PATH)
conn.send("set binary\n")
conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
conn.log_expect(options, "Login.*", int(options["--shell-timeout"]))
conn.send_eol("%s" % (options["--username"]))
conn.log_expect(options, "Password.*", int(options["--shell-timeout"]))
conn.send_eol("%s" % (options["--password"]))
conn.log_expect(options, "clp.*", int(options["--shell-timeout"]))
except pexpect.EOF:
fail(EC_LOGIN_DENIED)
except pexpect.TIMEOUT:
fail(EC_LOGIN_DENIED)
result = fence_action(conn, options, set_power_status, get_power_status)
##
## 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("exit\n")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/rsa/fence_rsa.py b/fence/agents/rsa/fence_rsa.py
index e1633975..11679078 100644
--- a/fence/agents/rsa/fence_rsa.py
+++ b/fence/agents/rsa/fence_rsa.py
@@ -1,78 +1,78 @@
#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
## Main GFEP25A & Boot GFBP25A
##
#####
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New RSA2 Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("power state")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
match = re.compile("Power: (.*)", re.IGNORECASE).search(conn.before)
if match != None:
status = match.group(1)
else:
status = "undefined"
return status.lower().strip()
def set_power_status(conn, options):
conn.send_eol("power " + options["--action"])
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure" ]
atexit.register(atexit_handler)
all_opt["login_timeout"]["default"] = 10
all_opt["cmd_prompt"]["default"] = [ ">" ]
# This device will not allow us to login even with LANG=C
all_opt["ssh_options"]["default"] = "-F /dev/null"
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for IBM RSA"
docs["longdesc"] = "fence_rsa is an I/O Fencing agent \
which can be used with the IBM RSA II management interface. It \
logs into an RSA II device via telnet and reboots the associated \
machine. Lengthy telnet connections to the RSA II device should \
be avoided while a GFS cluster is running because the connection \
will block any necessary fencing actions."
docs["vendorurl"] = "http://www.ibm.com"
show_docs(options, docs)
##
## Operate the fencing device
######
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, None)
##
## Logout from system
######
try:
conn.send_eol("exit")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py
index e9e37de4..7aab0ae9 100755
--- a/fence/agents/rsb/fence_rsb.py
+++ b/fence/agents/rsb/fence_rsb.py
@@ -1,87 +1,87 @@
#!/usr/bin/python -tt
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send("2")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
status = re.compile(r"Power Status[\s]*: (on|off)", re.IGNORECASE).search(conn.before).group(1)
conn.send("0")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
return status.lower().strip()
def set_power_status(conn, options):
action = {
'on' : "4",
'off': "1"
}[options["--action"]]
conn.send("2")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.send_eol(action)
conn.log_expect(options, ["want to power off", "'yes' or 'no'"], int(options["--shell-timeout"]))
conn.send_eol("yes")
conn.log_expect(options, "any key to continue", int(options["--power-timeout"]))
conn.send_eol("")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.send_eol("0")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "to quit:" ]
opt = process_input(device_opt)
# set default port for telnet only
if 0 == opt.has_key("--ssh") and 0 == opt.has_key("--ipport"):
opt["--ipport"] = "3172"
options = check_input(device_opt, opt)
docs = { }
docs["shortdesc"] = "I/O Fencing agent for Fujitsu-Siemens RSB"
docs["longdesc"] = "fence_rsb is an I/O Fencing agent \
which can be used with the Fujitsu-Siemens RSB management interface. It logs \
into device via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh \
connections should be avoided while a GFS cluster is running because the connection \
will block any necessary fencing actions."
docs["vendorurl"] = "http://www.fujitsu.com"
show_docs(options, docs)
##
## Operate the fencing device
####
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, None)
##
## Logout from system
##
## In some special unspecified cases it is possible that
## connection will be closed before we run close(). This is not
## a problem because everything is checked before.
######
try:
conn.send_eol("0")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/sanbox2/fence_sanbox2.py b/fence/agents/sanbox2/fence_sanbox2.py
index c53f1eff..996a5010 100644
--- a/fence/agents/sanbox2/fence_sanbox2.py
+++ b/fence/agents/sanbox2/fence_sanbox2.py
@@ -1,156 +1,156 @@
#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## Version Firmware
## +-----------------+---------------------------+
#####
import sys, re, pexpect, exceptions
import logging
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, EC_TIMED_OUT, EC_GENERIC_ERROR
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Sanbox2 Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
status_trans = {
'online' : "on",
'offline' : "off"
}
try:
conn.send_eol("show port " + options["--plug"])
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
except pexpect.TIMEOUT:
try:
conn.send_eol("admin end")
conn.send_eol("exit")
conn.close()
- except:
+ except Exception:
pass
fail(EC_TIMED_OUT)
status = re.compile(r".*AdminState\s+(online|offline)\s+",
re.IGNORECASE | re.MULTILINE).search(conn.before).group(1)
try:
return status_trans[status.lower().strip()]
except KeyError:
return "PROBLEM"
def set_power_status(conn, options):
action = {
'on' : "online",
'off' : "offline"
}[options["--action"]]
try:
conn.send_eol("set port " + options["--plug"] + " state " + action)
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
except pexpect.TIMEOUT:
try:
conn.send_eol("admin end")
conn.send_eol("exit")
conn.close()
- except:
+ except Exception:
pass
fail(EC_TIMED_OUT)
try:
conn.send_eol("set port " + options["--plug"] + " state " + action)
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
except pexpect.TIMEOUT:
try:
conn.send_eol("admin end")
conn.send_eol("exit")
conn.close()
- except:
+ except Exception:
pass
fail(EC_TIMED_OUT)
def get_list_devices(conn, options):
outlets = { }
try:
conn.send_eol("show port")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
list_re = re.compile(r"^\s+(\d+?)\s+(Online|Offline)\s+", re.IGNORECASE)
for line in conn.before.splitlines():
if list_re.search(line):
status = {
'online' : "ON",
'offline' : "OFF"
}[list_re.search(line).group(2).lower()]
outlets[list_re.search(line).group(1)] = ("", status)
except pexpect.TIMEOUT:
try:
conn.send_eol("admin end")
conn.send_eol("exit")
conn.close()
- except:
+ except Exception:
pass
fail(EC_TIMED_OUT)
return outlets
def main():
device_opt = [ "fabric_fencing", "ipaddr", "login", "passwd", "cmd_prompt", "port" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ " #> " ]
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for QLogic SANBox2 FC switches"
docs["longdesc"] = "fence_sanbox2 is an I/O Fencing agent which can be used with \
QLogic SANBox2 FC switches. It logs into a SANBox2 switch via telnet and disables a specified \
port. Disabling the port which a machine is connected to effectively fences that machine. \
Lengthy telnet connections to the switch should be avoided while a GFS cluster is running \
because the connection will block any necessary fencing actions."
docs["vendorurl"] = "http://www.qlogic.com"
show_docs(options, docs)
##
## Operate the fencing device
##
conn = fence_login(options)
conn.send_eol("admin start")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
if re.search(r"\(admin\)", conn.before, re.MULTILINE) == None:
## Someone else is in admin section, we can't enable/disable
## ports so we will rather exit
logging.error("Failed: Unable to switch to admin section\n")
sys.exit(EC_GENERIC_ERROR)
result = fence_action(conn, options, set_power_status, get_power_status, get_list_devices)
##
## Logout from system
######
try:
conn.send_eol("admin end")
conn.send_eol("exit\n")
conn.close()
except exceptions.OSError:
pass
except pexpect.ExceptionPexpect:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/virsh/fence_virsh.py b/fence/agents/virsh/fence_virsh.py
index 9f94f58f..b56fec2a 100644
--- a/fence/agents/virsh/fence_virsh.py
+++ b/fence/agents/virsh/fence_virsh.py
@@ -1,106 +1,106 @@
#!/usr/bin/python -tt
# The Following Agent Has Been Tested On:
#
# Virsh 0.3.3 on RHEL 5.2 with xen-3.0.3-51
#
import sys, re
import time
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage, SUDO_PATH
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Virsh fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_name_or_uuid(options):
return options["--uuid"] if options.has_key("--uuid") else options["--plug"]
def get_outlets_status(conn, options):
if options.has_key("--use-sudo"):
prefix = SUDO_PATH + " "
else:
prefix = ""
conn.sendline(prefix + "virsh list --all")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
result = {}
#This is status of mini finite automata. 0 = we didn't found Id and Name, 1 = we did
fa_status = 0
for line in conn.before.splitlines():
domain = re.search(r"^\s*(\S+)\s+(\S+)\s+(\S+).*$", line)
if domain != None:
if fa_status == 0 and domain.group(1).lower() == "id" and domain.group(2).lower() == "name":
fa_status = 1
elif fa_status == 1:
result[domain.group(2)] = ("",
(domain.group(3).lower() in ["running", "blocked", "idle", "no state", "paused"] and "on" or "off"))
return result
def get_power_status(conn, options):
prefix = SUDO_PATH + " " if options.has_key("--use-sudo") else ""
conn.sendline(prefix + "virsh domstate %s" % (get_name_or_uuid(options)))
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
for line in conn.before.splitlines():
if line.strip() in ["running", "blocked", "idle", "no state", "paused"]:
return "on"
if "error:" in line.strip():
fail_usage("Failed: You have to enter existing name/UUID of virtual machine!")
return "off"
def set_power_status(conn, options):
prefix = SUDO_PATH + " " if options.has_key("--use-sudo") else ""
conn.sendline(prefix + "virsh %s " %
(options["--action"] == "on" and "start" or "destroy") + get_name_or_uuid(options))
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
time.sleep(int(options["--power-wait"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "sudo" ]
atexit.register(atexit_handler)
all_opt["secure"]["default"] = "1"
all_opt["cmd_prompt"]["default"] = [ r"\[EXPECT\]#\ " ]
all_opt["ssh_options"]["default"] = "-t '/bin/bash -c \"" + r"PS1=\[EXPECT\]#\ " + "/bin/bash --noprofile --norc\"'"
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for virsh"
docs["longdesc"] = "fence_virsh is an I/O Fencing agent \
which can be used with the virtual machines managed by libvirt. \
It logs via ssh to a dom0 and there run virsh command, which does \
all work. \
\n.P\n\
By default, virsh needs root account to do properly work. So you \
must allow ssh login in your sshd_config."
docs["vendorurl"] = "http://libvirt.org"
show_docs(options, docs)
## Operate the fencing device
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, get_outlets_status)
## Logout from system
try:
conn.sendline("quit")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/wti/fence_wti.py b/fence/agents/wti/fence_wti.py
index a7e1c8f4..290eaaa0 100644
--- a/fence/agents/wti/fence_wti.py
+++ b/fence/agents/wti/fence_wti.py
@@ -1,252 +1,252 @@
#!/usr/bin/python -tt
#####
##
## 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
import atexit
import time
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fspawn, fail, fail_usage, TELNET_PATH, EC_LOGIN_DENIED
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New WTI Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_listing(conn, options, listing_command):
listing = ""
conn.send(listing_command + "\r\n")
if isinstance(options["--command-prompt"], list):
re_all = list(options["--command-prompt"])
else:
re_all = [options["--command-prompt"]]
re_next = re.compile("Enter: ", re.IGNORECASE)
re_all.append(re_next)
result = conn.log_expect(options, re_all, int(options["--shell-timeout"]))
listing = conn.before
if result == (len(re_all) - 1):
conn.send("\r\n")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
listing += conn.before
return listing
def get_plug_status(conn, options):
listing = get_listing(conn, options, "/S")
plug_section = 0
plug_index = -1
name_index = -1
status_index = -1
plug_header = list()
outlets = {}
for line in listing.splitlines():
if (plug_section == 2) and line.find("|") >= 0 and line.startswith("PLUG") == False:
plug_line = [x.strip().lower() for x in line.split("|")]
if len(plug_line) < len(plug_header):
plug_section = -1
if ["list", "monitor"].count(options["--action"]) == 0 and \
options["--plug"].lower() == plug_line[plug_index]:
return plug_line[status_index]
else:
## We already believe that first column contains plug number
if len(plug_line[0]) != 0:
outlets[plug_line[0]] = (plug_line[name_index], plug_line[status_index])
elif plug_section == 1:
plug_section = 2
elif line.upper().startswith("PLUG"):
plug_section = 1
plug_header = [x.strip().lower() for x in line.split("|")]
plug_index = plug_header.index("plug")
name_index = plug_header.index("name")
status_index = plug_header.index("status")
if ["list", "monitor"].count(options["--action"]) == 1:
return outlets
else:
return "PROBLEM"
def get_plug_group_status_from_list(status_list):
for status in status_list:
if status == "on":
return status
return "off"
def get_plug_group_status(conn, options):
listing = get_listing(conn, options, "/SG")
outlets = {}
line_index = 0
status_index = -1
plug_index = -1
name_index = -1
lines = listing.splitlines()
while line_index < len(lines) and line_index >= 0:
line = lines[line_index]
if line.find("|") >= 0 and line.lstrip().startswith("GROUP NAME") == False:
plug_line = [x.strip().lower() for x in line.split("|")]
if ["list", "monitor"].count(options["--action"]) == 0 and \
options["--plug"].lower() == plug_line[name_index]:
plug_status = []
while line_index < len(lines) and line_index >= 0:
plug_line = [x.strip().lower() for x in lines[line_index].split("|")]
if len(plug_line) >= max(name_index, status_index) and \
len(plug_line[plug_index]) > 0 and \
(len(plug_line[name_index]) == 0 or options["--plug"].lower() == plug_line[name_index]):
## Firmware 1.43 does not have a valid value of plug on first line as only name is defined on that line
if not "---" in plug_line[status_index]:
plug_status.append(plug_line[status_index])
line_index += 1
else:
line_index = -1
return get_plug_group_status_from_list(plug_status)
else:
## We already believe that first column contains plug number
if len(plug_line[0]) != 0:
group_name = plug_line[0]
plug_line_index = line_index + 1
plug_status = []
while plug_line_index < len(lines) and plug_line_index >= 0:
plug_line = [x.strip().lower() for x in lines[plug_line_index].split("|")]
if len(plug_line[name_index]) > 0:
plug_line_index = -1
break
if len(plug_line[plug_index]) > 0:
plug_status.append(plug_line[status_index])
plug_line_index += 1
else:
plug_line_index = -1
outlets[group_name] = (group_name, get_plug_group_status_from_list(plug_status))
line_index += 1
elif line.upper().lstrip().startswith("GROUP NAME"):
plug_header = [x.strip().lower() for x in line.split("|")]
name_index = plug_header.index("group name")
plug_index = plug_header.index("plug")
status_index = plug_header.index("status")
line_index += 2
else:
line_index += 1
if ["list", "monitor"].count(options["--action"]) == 1:
results = {}
for group, status in outlets.items():
results[group] = (group, status[0])
return results
else:
return "PROBLEM"
def get_power_status(conn, options):
if ["list"].count(options["--action"]) == 0:
ret = get_plug_status(conn, options)
if ret == "PROBLEM":
ret = get_plug_group_status(conn, options)
else:
ret = dict(get_plug_status(conn, options).items() + \
get_plug_group_status(conn, options).items())
return ret
def set_power_status(conn, options):
action = {
'on' : "/on",
'off': "/off"
}[options["--action"]]
conn.send(action + " " + options["--plug"] + ",y\r\n")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
"cmd_prompt", "secure", "port" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "RSM>", "MPC>", "IPS>", "TPS>", "NBB>", "NPS>", "VMR>" ]
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for WTI"
docs["longdesc"] = "fence_wti is an I/O Fencing agent \
which can be used with the WTI Network Power Switch (NPS). It logs \
into an NPS via telnet or ssh and boots a specified plug. \
Lengthy telnet connections to the NPS should be avoided while a GFS cluster \
is running because the connection will block any necessary fencing actions."
docs["vendorurl"] = "http://www.wti.com"
show_docs(options, docs)
##
## Operate the fencing device
##
## @note: if it possible that this device does not need either login, password or both of them
#####
if 0 == options.has_key("--ssh"):
try:
if options["--action"] in ["off", "reboot"]:
time.sleep(int(options["--delay"]))
conn = fspawn(options, TELNET_PATH)
conn.send("set binary\n")
conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
re_login = re.compile("(login: )|(Login Name: )|(username: )|(User Name :)", re.IGNORECASE)
re_prompt = re.compile("|".join(["(" + x + ")" for x in options["--command-prompt"]]), re.IGNORECASE)
result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], int(options["--shell-timeout"]))
if result == 0:
if options.has_key("--username"):
conn.send(options["--username"]+"\r\n")
result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], int(options["--shell-timeout"]))
else:
fail_usage("Failed: You have to set login name")
if result == 1:
if options.has_key("--password"):
conn.send(options["--password"]+"\r\n")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
else:
fail_usage("Failed: You have to enter password or password script")
except pexpect.EOF:
fail(EC_LOGIN_DENIED)
except pexpect.TIMEOUT:
fail(EC_LOGIN_DENIED)
else:
conn = fence_login(options)
result = fence_action(conn, options, set_power_status, get_power_status, get_power_status)
##
## Logout from system
######
try:
conn.send("/X"+"\r\n")
conn.close()
- except:
+ except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Jan 25, 11:09 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1322283
Default Alt Text
(124 KB)
Attached To
Mode
rF Fence Agents
Attached
Detach File
Event Timeline
Log In to Comment