Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=b5253b0c74175e... Commit: b5253b0c74175ecda233f573fb0afa733b60eda2 Parent: 7d64a32254aac1c4bbeb7d7d684c606893d9fda1 Author: Marek 'marx' Grac mgrac@redhat.com AuthorDate: Mon Jul 23 17:23:39 2012 +0200 Committer: Marek 'marx' Grac mgrac@redhat.com CommitterDate: Mon Jul 23 17:23:39 2012 +0200
fencing: Automatic detection of EOL during login process
Resolves: rhbz#810949 --- fence/agents/apc/fence_apc.py | 44 +++++++++++----------- fence/agents/bladecenter/fence_bladecenter.py | 18 +++++----- fence/agents/drac/fence_drac5.py | 12 +++--- fence/agents/ilo_mp/fence_ilo_mp.py | 12 +++--- fence/agents/lib/fencing.py.py | 48 +++++++++++++++--------- fence/agents/rsa/fence_rsa.py | 6 ++-- fence/agents/sanbox2/fence_sanbox2.py | 32 ++++++++-------- fence/agents/wti/fence_wti.py | 2 +- 8 files changed, 93 insertions(+), 81 deletions(-)
diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py index 0a3ce58..4125d39 100755 --- a/fence/agents/apc/fence_apc.py +++ b/fence/agents/apc/fence_apc.py @@ -29,7 +29,7 @@ def get_power_status(conn, options): exp_result = 0 outlets = {} try: - conn.send("1\r\n") + conn.send_eol("1") conn.log_expect(options, options["-c"], int(options["-Y"]))
version = 0 @@ -58,15 +58,15 @@ def get_power_status(conn, options): if switch == 0: if version == 2: if admin == 0: - conn.send("2\r\n") + conn.send_eol("2") else: - conn.send("3\r\n") + conn.send_eol("3") else: - conn.send("2\r\n") + conn.send_eol("2") conn.log_expect(options, options["-c"], int(options["-Y"])) - conn.send("1\r\n") + conn.send_eol("1") else: - conn.send(options["-s"]+"\r\n") + conn.send_eol(options["-s"]) while True: exp_result = conn.log_expect(options, [ options["-c"], "Press <ENTER>" ], int(options["-Y"])) @@ -76,7 +76,7 @@ def get_power_status(conn, options): res = show_re.search(x) if (res != None): outlets[res.group(2)] = (res.group(3), res.group(4)) - conn.send("\r\n") + conn.send_eol("") if exp_result == 0: break conn.send(chr(03)) @@ -103,7 +103,7 @@ def set_power_status(conn, options): }[options["-o"]]
try: - conn.send("1\r\n") + conn.send_eol("1") conn.log_expect(options, options["-c"], int(options["-Y"]))
version = 0 @@ -138,41 +138,41 @@ def set_power_status(conn, options): if switch == 0: if version == 2: if admin2 == 0: - conn.send("2\r\n") + conn.send_eol("2") else: - conn.send("3\r\n") + conn.send_eol("3") else: - conn.send("2\r\n") + conn.send_eol("2") conn.log_expect(options, options["-c"], int(options["-Y"])) if (None == re.compile('.*2- Outlet Restriction.*', re.IGNORECASE | re.S).match(conn.before)): admin3 = 0 else: admin3 = 1 - conn.send("1\r\n") + conn.send_eol("1") else: - conn.send(options["-s"] + "\r\n") + conn.send_eol(options["-s"])
while 1 == conn.log_expect(options, [ options["-c"], "Press <ENTER>" ], int(options["-Y"])): - conn.send("\r\n") - conn.send(options["-n"]+"\r\n") + conn.send_eol("") + conn.send_eol(options["-n"]+"") conn.log_expect(options, options["-c"], int(options["-Y"]))
if switch == 0: if admin2 == 1: - conn.send("1\r\n") + conn.send_eol("1") conn.log_expect(options, options["-c"], int(options["-Y"])) if admin3 == 1: - conn.send("1\r\n") + conn.send_eol("1") conn.log_expect(options, options["-c"], int(options["-Y"])) else: - conn.send("1\r\n") + conn.send_eol("1") conn.log_expect(options, options["-c"], int(options["-Y"])) - conn.send(action+"\r\n") + conn.send_eol(action) conn.log_expect(options, "Enter 'YES' to continue or <ENTER> to cancel :", int(options["-Y"])) - conn.send("YES\r\n") + conn.send_eol("YES") conn.log_expect(options, "Press <ENTER> to continue...", int(options["-Y"])) - conn.send("\r\n") + conn.send_eol("") conn.log_expect(options, options["-c"], int(options["-Y"])) conn.send(chr(03)) conn.log_expect(options, "- Logout", int(options["-Y"])) @@ -231,7 +231,7 @@ will block any necessary fencing actions." ## a problem because everything is checked before. ###### try: - conn.sendline("4") + conn.send_eol("4") conn.close() except exceptions.OSError: pass diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py index ac65f65..d97b9e4 100755 --- a/fence/agents/bladecenter/fence_bladecenter.py +++ b/fence/agents/bladecenter/fence_bladecenter.py @@ -27,7 +27,7 @@ def get_power_status(conn, options): try: node_cmd = "system:blade[" + options["-n"] + "]>"
- conn.send("env -T system:blade[" + options["-n"] + "]\r\n") + conn.send_eol("env -T system:blade[" + options["-n"] + "]") i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["-Y"])) if i == 1: ## Given blade number does not exist @@ -35,10 +35,10 @@ def get_power_status(conn, options): return "off" else: fail(EC_STATUS) - conn.send("power -state\r\n") + conn.send_eol("power -state") conn.log_expect(options, node_cmd, int(options["-Y"])) status = conn.before.splitlines()[-1] - conn.send("env -T system\r\n") + conn.send_eol("env -T system") conn.log_expect(options, options["-c"], int(options["-Y"])) except pexpect.EOF: fail(EC_CONNECTION_LOST) @@ -56,7 +56,7 @@ def set_power_status(conn, options): try: node_cmd = "system:blade[" + options["-n"] + "]>"
- conn.send("env -T system:blade[" + options["-n"] + "]\r\n") + conn.send_eol("env -T system:blade[" + options["-n"] + "]") i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["-Y"])) if i == 1: ## Given blade number does not exist @@ -65,9 +65,9 @@ def set_power_status(conn, options): else: fail(EC_GENERIC_ERROR)
- conn.send("power -"+options["-o"]+"\r\n") + conn.send_eol("power -"+options["-o"]) conn.log_expect(options, node_cmd, int(options["-Y"])) - conn.send("env -T system\r\n") + conn.send_eol("env -T system") conn.log_expect(options, options["-c"], int(options["-Y"])) except pexpect.EOF: fail(EC_CONNECTION_LOST) @@ -79,9 +79,9 @@ def get_blades_list(conn, options): try: node_cmd = "system>"
- conn.send("env -T system\r\n") + conn.send_eol("env -T system") conn.log_expect(options, node_cmd, int(options["-Y"])) - conn.send("list -l 2\r\n") + conn.send_eol("list -l 2") conn.log_expect(options, node_cmd, int(options["-Y"]))
lines = conn.before.split("\r\n") @@ -131,7 +131,7 @@ and uses the command line interface to power on and off blades." ## Logout from system ###### try: - conn.send("exit\r\n") + conn.send_eol("exit") conn.close() except exceptions.OSError: pass diff --git a/fence/agents/drac/fence_drac5.py b/fence/agents/drac/fence_drac5.py index 23cd7ca..298339f 100755 --- a/fence/agents/drac/fence_drac5.py +++ b/fence/agents/drac/fence_drac5.py @@ -25,9 +25,9 @@ BUILD_DATE="" def get_power_status(conn, options): try: if options["model"] == "DRAC CMC": - conn.sendline("racadm serveraction powerstatus -m " + options["-m"]) + conn.send_eol("racadm serveraction powerstatus -m " + options["-m"]) elif options["model"] == "DRAC 5": - conn.sendline("racadm serveraction powerstatus") + conn.send_eol("racadm serveraction powerstatus") conn.log_expect(options, options["-c"], int(options["-Y"])) except pexpect.EOF: @@ -49,9 +49,9 @@ def set_power_status(conn, options):
try: if options["model"] == "DRAC CMC": - conn.sendline("racadm serveraction " + action + " -m " + options["-m"]) + conn.send_eol("racadm serveraction " + action + " -m " + options["-m"]) elif options["model"] == "DRAC 5": - conn.sendline("racadm serveraction " + action) + conn.send_eol("racadm serveraction " + action) conn.log_expect(options, options["-c"], int(options["-g"])) except pexpect.EOF: fail(EC_CONNECTION_LOST) @@ -63,7 +63,7 @@ def get_list_devices(conn, options):
try: if options["model"] == "DRAC CMC": - conn.sendline("getmodinfo") + conn.send_eol("getmodinfo")
list_re = re.compile("^([^\s]*?)\s+Present\s*(ON|OFF)\s*.*$") conn.log_expect(options, options["-c"], int(options["-g"])) @@ -133,7 +133,7 @@ By default, the telnet interface is not enabled." ## Logout from system ###### try: - conn.sendline("exit") + conn.send_eol("exit") time.sleep(1) conn.close() except exceptions.OSError: diff --git a/fence/agents/ilo_mp/fence_ilo_mp.py b/fence/agents/ilo_mp/fence_ilo_mp.py index 06e1358..40ac597 100644 --- a/fence/agents/ilo_mp/fence_ilo_mp.py +++ b/fence/agents/ilo_mp/fence_ilo_mp.py @@ -12,7 +12,7 @@ BUILD_DATE=""
def get_power_status(conn, options): try: - conn.send("show /system1\r\n") + conn.send_eol("show /system1") re_state = re.compile('EnabledState=(.*)', re.IGNORECASE) conn.log_expect(options, re_state, int(options["-Y"])) @@ -31,9 +31,9 @@ def get_power_status(conn, options): def set_power_status(conn, options): try: if options["-o"] == "on": - conn.send("start /system1\r\n") + conn.send_eol("start /system1") else: - conn.send("stop -f /system1\r\n") + conn.send_eol("stop -f /system1")
conn.log_expect(options, options["-c"], int(options["-g"]))
@@ -46,7 +46,7 @@ def set_power_status(conn, options): def main(): device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", "action", "ipaddr", "login", "passwd", "passwd_script", - "secure", "identity_file", "cmd_prompt", "ipport", "login_eol_lf", + "secure", "identity_file", "cmd_prompt", "ipport", "separator", "inet4_only", "inet6_only", "power_timeout", "shell_timeout", "login_timeout", "power_wait" ]
@@ -64,7 +64,7 @@ def main(): show_docs(options, docs) conn = fence_login(options) - conn.send("SMCLP\r\n") + conn.send_eol("SMCLP")
## ## Fence operations @@ -72,7 +72,7 @@ def main(): result = fence_action(conn, options, set_power_status, get_power_status)
try: - conn.send("exit\r\n") + conn.send_eol("exit") except exceptions.OSError: pass except pexpect.ExceptionPexpect: diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py index c4fe218..25a0f7e 100644 --- a/fence/agents/lib/fencing.py.py +++ b/fence/agents/lib/fencing.py.py @@ -178,11 +178,6 @@ all_opt = { "required" : "0", "shortdesc" : "Force ribcl version to use", "order" : 1 }, - "login_eol_lf" : { - "getopt" : "", - "help" : "", - "order" : 1 - }, "cmd_prompt" : { "getopt" : "c:", "longopt" : "command-prompt", @@ -403,12 +398,20 @@ all_opt = { common_opt = [ "retry_on", "delay" ]
class fspawn(pexpect.spawn): + def __init__(self, options, command): + pexpect.spawn.__init__(self, command) + self.opt = options + def log_expect(self, options, pattern, timeout): result = self.expect(pattern, timeout) if options["log"] >= LOG_MODE_VERBOSE: options["debug_fh"].write(self.before + self.after) return result
+ # send EOL according to what was detected in login process (telnet) + def send_eol(self, message): + self.send(message + self.opt["eol"]) + def atexit_handler(): try: sys.stdout.close() @@ -859,10 +862,7 @@ def fence_login(options): if (options.has_key("-4")): force_ipvx="-4 "
- if (options["device_opt"].count("login_eol_lf")): - login_eol = "\n" - else: - login_eol = "\r\n" + options["eol"] = "\r\n"
## Do the delay of the fence device before logging in ## Delay is important for two-node clusters fencing but we do not need to delay 'status' operations @@ -876,7 +876,7 @@ def fence_login(options): if options.has_key("-z"): command = '%s %s %s %s' % (SSL_PATH, force_ipvx, options["-a"], options["-u"]) try: - conn = fspawn(command) + conn = fspawn(options, command) except pexpect.ExceptionPexpect, ex: ## SSL telnet is part of the fencing package sys.stderr.write(str(ex) + "\n") @@ -886,7 +886,7 @@ def fence_login(options): if options.has_key("ssh_options"): command += ' ' + options["ssh_options"] try: - conn = fspawn(command) + conn = fspawn(options, command) except pexpect.ExceptionPexpect, ex: sys.stderr.write(str(ex) + "\n") sys.stderr.write("Due to limitations, binary dependencies on fence agents " @@ -915,7 +915,7 @@ def fence_login(options): if options.has_key("ssh_options"): command += ' ' + options["ssh_options"] try: - conn = fspawn(command) + conn = fspawn(options, command) except pexpect.ExceptionPexpect, ex: sys.stderr.write(str(ex) + "\n") sys.stderr.write("Due to limitations, binary dependencies on fence agents " @@ -934,7 +934,7 @@ def fence_login(options): fail_usage("Failed: You have to enter passphrase (-p) for identity file") else: try: - conn = fspawn(TELNET_PATH) + conn = fspawn(options, TELNET_PATH) conn.send("set binary\n") conn.send("open %s -%s\n"%(options["-a"], options["-u"])) except pexpect.ExceptionPexpect, ex: @@ -943,11 +943,23 @@ def fence_login(options): "are not in the spec file and must be installed separately." + "\n") sys.exit(EC_GENERIC_ERROR)
- conn.log_expect(options, re_login, int(options["-y"])) - conn.send(options["-l"] + login_eol) - conn.log_expect(options, re_pass, int(options["-Y"])) - conn.send(options["-p"] + login_eol) - conn.log_expect(options, options["-c"], int(options["-Y"])) + result = conn.log_expect(options, re_login, int(options["-y"])) + conn.send_eol(options["-l"]) + + ## automatically change end of line separator + screen = conn.read_nonblocking(size=100, timeout=int(options["-Y"])) + if (re_login.search(screen) != None): + options["eol"] = "\n" + conn.send_eol(options["-l"]) + result = conn.log_expect(options, re_pass, int(options["-y"])) + elif (re_pass.search(screen) == None): + conn.log_expect(options, re_pass, int(options["-Y"])) + + try: + conn.send_eol(options["-p"]) + conn.log_expect(options, options["-c"], int(options["-Y"])) + except KeyError: + fail(EC_PASSWORD_MISSING) except pexpect.EOF: fail(EC_LOGIN_DENIED) except pexpect.TIMEOUT: diff --git a/fence/agents/rsa/fence_rsa.py b/fence/agents/rsa/fence_rsa.py index 33c7fe9..d82c448 100755 --- a/fence/agents/rsa/fence_rsa.py +++ b/fence/agents/rsa/fence_rsa.py @@ -19,7 +19,7 @@ BUILD_DATE="March, 2009"
def get_power_status(conn, options): try: - conn.send("power state\r\n") + conn.send_eol("power state") conn.log_expect(options, options["-c"], int(options["-Y"])) except pexpect.EOF: fail(EC_CONNECTION_LOST) @@ -36,7 +36,7 @@ def get_power_status(conn, options):
def set_power_status(conn, options): try: - conn.send("power " + options["-o"] + "\r\n") + conn.send_eol("power " + options["-o"]) conn.log_expect(options, options["-c"], int(options["-g"])) except pexpect.EOF: fail(EC_CONNECTION_LOST) @@ -84,7 +84,7 @@ will block any necessary fencing actions." ## Logout from system ###### try: - conn.sendline("exit") + conn.send_eol("exit") conn.close() except exceptions.OSError: pass diff --git a/fence/agents/sanbox2/fence_sanbox2.py b/fence/agents/sanbox2/fence_sanbox2.py index c95e602..d20f7e2 100644 --- a/fence/agents/sanbox2/fence_sanbox2.py +++ b/fence/agents/sanbox2/fence_sanbox2.py @@ -24,14 +24,14 @@ def get_power_status(conn, options): 'offline' : "off" } try: - conn.send("show port " + options["-n"] + "\n") + conn.send_eol("show port " + options["-n"]) conn.log_expect(options, options["-c"], int(options["-Y"])) except pexpect.EOF: fail(EC_CONNECTION_LOST) except pexpect.TIMEOUT: try: - conn.send("admin end\n") - conn.send("exit\n") + conn.send_eol("admin end") + conn.send_eol("exit") conn.close() except: pass @@ -51,28 +51,28 @@ def set_power_status(conn, options): }[options["-o"]]
try: - conn.send("set port " + options["-n"] + " state " + action + "\n") + conn.send_eol("set port " + options["-n"] + " state " + action) conn.log_expect(options, options["-c"], int(options["-g"])) except pexpect.EOF: fail(EC_CONNECTION_LOST) except pexpect.TIMEOUT: try: - conn.send("admin end\n") - conn.send("exit\n") + conn.send_eol("admin end") + conn.send_eol("exit") conn.close() except: pass fail(EC_TIMED_OUT)
try: - conn.send("set port " + options["-n"] + " state " + action + "\n") + conn.send_eol("set port " + options["-n"] + " state " + action) conn.log_expect(options, options["-c"], int(options["-g"])) except pexpect.EOF: fail(EC_CONNECTION_LOST) except pexpect.TIMEOUT: try: - conn.send("admin end\n") - conn.send("exit\n") + conn.send_eol("admin end") + conn.send_eol("exit") conn.close() except: pass @@ -82,7 +82,7 @@ def get_list_devices(conn, options): outlets = { }
try: - conn.send("show port" + "\n") + conn.send_eol("show port") conn.log_expect(options, options["-c"], int(options["-Y"]))
list_re = re.compile("^\s+(\d+?)\s+(Online|Offline)\s+", re.IGNORECASE) @@ -98,8 +98,8 @@ def get_list_devices(conn, options): fail(EC_CONNECTION_LOST) except pexpect.TIMEOUT: try: - conn.send("admin end\n") - conn.send("exit\n") + conn.send_eol("admin end") + conn.send_eol("exit") conn.close() except: pass @@ -110,7 +110,7 @@ def get_list_devices(conn, options): def main(): device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", "io_fencing", "ipaddr", "login", "passwd", "passwd_script", - "cmd_prompt", "port", "ipport", "login_eol_lf", "separator", + "cmd_prompt", "port", "ipport", "separator", "power_timeout", "shell_timeout", "login_timeout", "power_wait" ]
atexit.register(atexit_handler) @@ -138,7 +138,7 @@ because the connection will block any necessary fencing actions." ## conn = fence_login(options)
- conn.send("admin start\n") + conn.send_eol("admin start") conn.log_expect(options, options["-c"], int(options["-Y"]))
if (re.search("(admin)", conn.before, re.MULTILINE) == None): @@ -153,8 +153,8 @@ because the connection will block any necessary fencing actions." ## Logout from system ###### try: - conn.send("admin end\n") - conn.send("exit\n") + conn.send_eol("admin end") + conn.send_eol("exit\n") conn.close() except exceptions.OSError: pass diff --git a/fence/agents/wti/fence_wti.py b/fence/agents/wti/fence_wti.py index c742e71..40b97e3 100755 --- a/fence/agents/wti/fence_wti.py +++ b/fence/agents/wti/fence_wti.py @@ -125,7 +125,7 @@ is running because the connection will block any necessary fencing actions." if 0 == options.has_key("-x"): try: try: - conn = fspawn(TELNET_PATH) + conn = fspawn(options, TELNET_PATH) conn.send("set binary\n") conn.send("open %s -%s\n"%(options["-a"], options["-u"])) except pexpect.ExceptionPexpect, ex:
cluster-commits@lists.stg.fedorahosted.org