From mboxrd@z Thu Jan 1 00:00:00 1970 From: fabbione@sourceware.org Date: 16 Jul 2008 06:04:57 -0000 Subject: [Cluster-devel] Cluster Project branch, RHEL4, updated. gfs-kernel_2_6_9_76-109-g231cd16 Message-ID: <20080716060457.23073.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Cluster Project". http://sources.redhat.com/git/gitweb.cgi?p=cluster.git;a=commitdiff;h=231cd16350113d8aea47200c0d92a31d0691af7c The branch, RHEL4 has been updated via 231cd16350113d8aea47200c0d92a31d0691af7c (commit) via a21058eaa8f4290fab8c3bd8e53e90068d70b878 (commit) via cd45c4414fcf0c78c9f1d746008b10e747bcbe85 (commit) via f731c0474eaba0374518076a56cf3d1377427d6f (commit) via 96d24e6747156aa8dbeb9977e14a72c46a68aa98 (commit) via 15faca66f4ae5c14f50598f6ab250b9d964fce0f (commit) via 39172ebe93b39b5fa3f4525d67cdc78a9e904725 (commit) via 4f7070d58d3d7bd67f6985b30608aad2c3bf1223 (commit) via 390c1f7048fbfd3443f1d8c8a73781c089933edb (commit) via 7274ca8f1f8bc43b4d3183edf5d89ecd1d594778 (commit) via 54091dbea767a4e6d067bfb1a98edf1298d53365 (commit) via 14df64185852b8dbbb48016a683305c92810269d (commit) via 4344e2e0714ab5f5627c332f1640e23221f6186f (commit) via 945fb63d22af346849e6bfa2708bd385084ec6b6 (commit) via 680f7426e15836ae952452e82892dcac52356479 (commit) via 83e0a46d114eb71dc1b3649ea1cbb4e7542ba04c (commit) via d136af691a96b218dc79df947cf5a5a7ab5293d8 (commit) via af9098eb7d6f13c990b4df5cb462e6ad3279a078 (commit) via 0dda6d1cb413d5a464b307ef39920fe6fcfdd828 (commit) via 3500f29631ada488bb881fe7cbd7f1202d7defc6 (commit) via 8af5ef32d6066a463bc894a8eebb77e44ab2fcf1 (commit) via e390f6fc77af4e1c262151ef76454a74eadac882 (commit) from 3ab00427e3eaf45e99d5f40fed6f3b459faccb14 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 231cd16350113d8aea47200c0d92a31d0691af7c Author: Fabio M. Di Nitto Date: Mon May 26 10:22:35 2008 +0200 [BUILD] Add fence_lpar fencing agent to the build system Signed-off-by: Fabio M. Di Nitto commit a21058eaa8f4290fab8c3bd8e53e90068d70b878 Author: Fabio M. Di Nitto Date: Wed Jul 16 07:56:34 2008 +0200 [BUILD] Fix install of telnet_ssl Signed-off-by: Fabio M. Di Nitto commit cd45c4414fcf0c78c9f1d746008b10e747bcbe85 Author: Fabio M. Di Nitto Date: Thu Jul 3 06:01:04 2008 +0200 [BUILD] Fix telnet_ssl build Signed-off-by: Fabio M. Di Nitto commit f731c0474eaba0374518076a56cf3d1377427d6f Author: Fabio M. Di Nitto Date: Thu Jul 3 05:46:11 2008 +0200 [BUILD] Fix install of telnet_ssl Signed-off-by: Fabio M. Di Nitto commit 96d24e6747156aa8dbeb9977e14a72c46a68aa98 Author: Marek 'marx' Grac Date: Wed Jul 2 15:55:48 2008 +0200 [FENCE] Bug #448822: fence_ilo doesn't work with iLO New fencing agent for iLO used ssh/telnet to connect, but unfortutely there is a problem with power off. This is why we need to use SSL connection and RIBCL commands. As there is no (?) telnet with ssl connection in RHEL we need one to be able to use same infrastructure as in other agents. This agent was not tested with RIBCL version < 2.0 (these part where just ported from the old perl fencing agent) @todo: we have to put telnet_ssl.py somewhere, I'm not sure where commit 15faca66f4ae5c14f50598f6ab250b9d964fce0f Author: Marek 'marx' Grac Date: Wed Jun 4 15:54:49 2008 +0200 [FENCE] Fix: 447378: fence_apc unable to connect via ssh to APC 7900 Increased timeout from SHELL_TIMEOUT to LOGIN_TIMEOUT in login function. commit 39172ebe93b39b5fa3f4525d67cdc78a9e904725 Author: Ryan McCabe Date: Wed May 28 16:28:34 2008 -0400 fence: fixes and cleanups to fencing.py library - Do not report failure if a node is successfully powered off, but fails to power on. - Change 'pass' to 'continue' so that comments and blank lines from stdin are ignored. - Use the full path to ssh and telnet when executing the binaries. commit 4f7070d58d3d7bd67f6985b30608aad2c3bf1223 Author: Marek 'marx' Grac Date: Mon Jun 2 16:15:50 2008 +0200 [FENCE] Fix #446995: Unknown option Previous patch worked just for command line and there was a problem with stdin argument. Typo fixed. commit 390c1f7048fbfd3443f1d8c8a73781c089933edb Author: Marek 'marx' Grac Date: Fri May 23 19:01:06 2008 +0200 [FENCE]: Fix #237266: New fence agent for HMC/LPAR commit 7274ca8f1f8bc43b4d3183edf5d89ecd1d594778 Author: Marek 'marx' Grac Date: Wed May 21 17:26:03 2008 +0200 [FENCE] Fix #447378 - fence_apc unable to connect via ssh to APC 7900 Problem was that even with ssh itself it was really painfull to log into this device (15 - 40 seconds). After specifying cipher and protocol we can login and check status in time comparable to others. commit 54091dbea767a4e6d067bfb1a98edf1298d53365 Author: Fabio M. Di Nitto Date: Tue May 20 12:41:22 2008 +0200 [BUILD] Fix fence agents generation When switching from perl to python implementations we forgot to modify the version/copyright generators in the Makefile snippets. This fixes BZ: #447432, #447434, #447437 Signed-off-by: Fabio M. Di Nitto commit 14df64185852b8dbbb48016a683305c92810269d Author: Marek 'marx' Grac Date: Tue May 20 11:11:23 2008 +0200 [FENCE] Fix #446995: Parse error: Unknown option 'switch=3' Support for APC MasterSwitch was added (it worked in original fencing agent). Option 'switch' on STDIN didn't have a getopt alternative, so '-s ' was added. Plug number notation : works as before. Original behaviour for missing switch number does not change. If there is just one MasterSwitch then we will set it up otherwise error is returned. commit 4344e2e0714ab5f5627c332f1640e23221f6186f Author: Marek 'marx' Grac Date: Mon May 19 17:28:39 2008 +0200 [FENCE] Fix #248609: SSH support in Bladecenter fencing (ssh) Complete ssh support for Bladecenter. You can use password or private key (identity_file on STDIN; -k in getopt) to login to system. This patch contains complete infrastructure (usable also by other agents). commit 945fb63d22af346849e6bfa2708bd385084ec6b6 Author: Fabio M. Di Nitto Date: Fri May 16 07:24:37 2008 +0200 [BUILD] Fix drac5 generation Signed-off-by: Fabio M. Di Nitto commit 680f7426e15836ae952452e82892dcac52356479 Author: Marek 'marx' Grac Date: Tue May 13 18:21:44 2008 +0200 [FENCE] Fix typo in name of the exceptions in fencing agents Exceptions should be pexpect.EOF, pexpect.TIMEOUT (not pexcept.*). This problem only occured in set_status(). Function get_status() contains correct exceptions. commit 83e0a46d114eb71dc1b3649ea1cbb4e7542ba04c Author: Marek 'marx' Grac Date: Tue May 13 17:26:56 2008 +0200 [FENCE] Fix problem with different menu for admin/user for APC In APC user/admin can see a different menu and they have to use different sequence of keystrokes to access Outlet Controls. Previously only support for user was provided. commit d136af691a96b218dc79df947cf5a5a7ab5293d8 Author: Marek 'marx' Grac Date: Tue May 13 17:00:57 2008 +0200 [FENCE] Fix name of the option in fencing library We were testing for option 'plug_no' but in every other file we have 'port'. commit af9098eb7d6f13c990b4df5cb462e6ad3279a078 Author: Marek 'marx' Grac Date: Tue May 6 16:50:00 2008 +0200 [FENCE] Fix #444615: Support for 24 port APC fencing device Fixed in the new version of python fencing agent. But there was still a problem because there is major change of interface between firmware v2.7.x and v3.5.x. After this patch both types of firmware version should work. commit 0dda6d1cb413d5a464b307ef39920fe6fcfdd828 Author: Marek 'marx' Grac Date: Wed Apr 30 15:30:24 2008 +0200 [FENCE] SSH support using stdin options STDIN options have to be name=value even if they are just boolean. These options are taken from cluster.conf so they have to be XML-like. (cherry picked from commit ec62ff54c098e4942db8d74a33fddf5a18a2a03d) commit 3500f29631ada488bb881fe7cbd7f1202d7defc6 Author: Fabio M. Di Nitto Date: Mon Apr 28 13:13:45 2008 +0200 [BUILD] Fix fence/lib install target Signed-off-by: Fabio M. Di Nitto commit 8af5ef32d6066a463bc894a8eebb77e44ab2fcf1 Author: Fabio M. Di Nitto Date: Fri Apr 25 15:28:18 2008 +0200 [FENCE] Enable new fence agents by default agents/Makefile: - enable lib target. agents/apc/fence_apc.py, bladecenter/fence_bladecenter.py, agents/drac/fence_drac5.py, agents/ilo/fence_ilo.py, agents/lib/fencing.py.py, agents/wti/fence_wti.py: - add version, build and copyright information. - fix path to fence agents lib. agents/bladecenter/Makefile, fence/agents/drac/Makefile, agents/ilo/Makefile, agents/wti/Makefile: - enable new agents. bin/Makefile: - install fence_drac5 - install/uninstall fence library Signed-off-by: Fabio M. Di Nitto commit e390f6fc77af4e1c262151ef76454a74eadac882 Author: Marek 'marx' Grac Date: Tue Apr 22 17:52:01 2008 +0200 fence/agents: New fencings agents There are new fencing agents based on a new library. They need a 'pexpect' package. If it is possible there is support for both telnet and ssh. In this patch there are agents for: APC, BladeCenter, Drac 5, ILo and WTI. Fence agents that support ssh in 4.7 are iLO, DRAC5, WTI, APC, and BladeCenter ----------------------------------------------------------------------- Summary of changes: fence/agents/Makefile | 6 + fence/agents/apc/fence_apc.py | 1002 +++++-------------------- fence/agents/bladecenter/Makefile | 10 +- fence/agents/bladecenter/fence_bladecenter.py | 90 +++ fence/agents/drac/Makefile | 39 +- fence/agents/drac/fence_drac5.py | 79 ++ fence/agents/ilo/Makefile | 8 +- fence/agents/ilo/fence_ilo.py | 102 +++ fence/agents/lib/Makefile | 48 ++ fence/agents/lib/fencing.py.py | 399 ++++++++++ fence/agents/lib/telnet_ssl.py | 72 ++ fence/agents/lpar/Makefile | 35 + fence/agents/lpar/fence_lpar.py | 97 +++ fence/agents/wti/Makefile | 8 +- fence/agents/wti/fence_wti.py | 109 +++ fence/bin/Makefile | 13 +- 16 files changed, 1273 insertions(+), 844 deletions(-) mode change 100644 => 100755 fence/agents/apc/fence_apc.py create mode 100755 fence/agents/bladecenter/fence_bladecenter.py create mode 100755 fence/agents/drac/fence_drac5.py create mode 100755 fence/agents/ilo/fence_ilo.py create mode 100644 fence/agents/lib/Makefile create mode 100644 fence/agents/lib/fencing.py.py create mode 100755 fence/agents/lib/telnet_ssl.py create mode 100644 fence/agents/lpar/Makefile create mode 100755 fence/agents/lpar/fence_lpar.py create mode 100755 fence/agents/wti/fence_wti.py diff --git a/fence/agents/Makefile b/fence/agents/Makefile index 8418016..940da98 100644 --- a/fence/agents/Makefile +++ b/fence/agents/Makefile @@ -13,6 +13,7 @@ all: + cd lib && ${MAKE} all cd apc && ${MAKE} all cd apc_snmp && ${MAKE} all cd rsa && ${MAKE} all @@ -27,6 +28,7 @@ all: # cd ibmblade && ${MAKE} all cd ilo && ${MAKE} all cd ipmilan && ${MAKE} all + cd lpar && ${MAKE} all cd manual && ${MAKE} all cd mcdata && ${MAKE} all # cd rackswitch && ${MAKE} all @@ -40,6 +42,7 @@ all: # cd zvm && ${MAKE} all copytobin: + cd lib && ${MAKE} copytobin cd apc && ${MAKE} copytobin cd apc_snmp && ${MAKE} copytobin cd rsa && ${MAKE} copytobin @@ -54,6 +57,7 @@ copytobin: # cd ibmblade && ${MAKE} copytobin cd ilo && ${MAKE} copytobin cd ipmilan && ${MAKE} copytobin + cd lpar && ${MAKE} copytobin cd manual && ${MAKE} copytobin cd mcdata && ${MAKE} copytobin # cd rackswitch && ${MAKE} copytobin @@ -67,6 +71,7 @@ copytobin: # cd zvm && ${MAKE} copytobin clean: + cd lib && ${MAKE} clean cd apc && ${MAKE} clean cd apc_snmp && ${MAKE} clean cd rsa && ${MAKE} clean @@ -81,6 +86,7 @@ clean: # cd ibmblade && ${MAKE} clean cd ilo && ${MAKE} clean cd ipmilan && ${MAKE} clean + cd lpar && ${MAKE} clean cd manual && ${MAKE} clean cd mcdata && ${MAKE} clean # cd rackswitch && ${MAKE} clean diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py old mode 100644 new mode 100755 index e28d6e2..4ac8be9 --- a/fence/agents/apc/fence_apc.py +++ b/fence/agents/apc/fence_apc.py @@ -1,832 +1,200 @@ #!/usr/bin/python -############################################################################### -############################################################################### ## -## Copyright (C) 2006 Red Hat, Inc. All rights reserved. +## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. ## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. +## The Following Agent Has Been Tested On: ## -############################################################################### -############################################################################### - -import getopt, sys -import os -import socket -import time - -from telnetlib import Telnet - -TELNET_TIMEOUT=5 #How long to wait for a response from a telnet try +## 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 +##### -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile +import sys, re, pexpect +sys.path.append("/usr/lib/fence") +from fencing import * #BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="New APC Agent - test release" +FENCE_RELEASE_NAME="" REDHAT_COPYRIGHT="" -BUILD_DATE="September 21, 2006" +BUILD_DATE="" #END_VERSION_GENERATION -POWER_OFF = 0 -POWER_ON = 1 -POWER_STATUS = 2 -POWER_REBOOT = 3 - -COMPLETE = 0 -NOT_COMPLETE = 1 - -ON = "ON" -OFF = "OFF" - -SUCCESS = "success" -FAIL = "fail" - -address = "" -login = "" -passwd = "" -passwd_script = "" -port = "" -switchnum = "" -action = POWER_REBOOT #default action -verbose = False - -logfile = None - -#set up regex list -CONTROL_CONSOLE = "Control Console -----" -DEVICE_MANAGER = "Device Manager -----" -OUTLET_CONTROL = "- Outlet Control/Configuration -----" -OUTLET_MANAGE = "- Outlet Management -----" -CONTROL_OUTLET = "- Control Outlet -----" -CONTROL_OUTLET_2 = "- Outlet Control " -COMMAND_SUCCESS = "Command successfully issued." -COMMAND_SUCCESS_2 = " Success" -CONFIRM = "Enter 'YES' to continue or to cancel :" -CONTINUE = "Press to continue..." -SCREEN_END = "- Main Menu, - Refresh, - Event Log" -SCREEN_END_2 = "- Back, - Refresh, - Event Log" -USERNAME = "User Name :" -PASSWORD = "Password :" -MASTER = "------- MasterSwitch" -FIRMWARE_STR = "Rack PDU APP" - -CONTINUE_INDEX = 0 - -FIRMWARE_REV = 2 - -regex_list = list() -regex_list.append(CONTINUE) -regex_list.append(SCREEN_END) -regex_list.append(SCREEN_END_2) -regex_list.append(USERNAME) -regex_list.append(PASSWORD) - -def usage(): - print "Usage:\n" - print "fence_apc [options]" - print "Options:" - print " -a ip or hostname of APC switch" - print " -h print out help" - print " -l [login] login name" - print " -n [port] switch port" - print " -p [password] password" - print " -S [path] script to run to retrieve password" - print " -o [action] Reboot (default), Off, On, or Status" - print " -v Verbose Verbose mode - writes file to /tmp/apclog" - print " -V Print Version, then exit" - - sys.exit (0) - -def version(): - print "fence_apc %s %s\n" % (FENCE_RELEASE_NAME, BUILD_DATE) - print "%s\n" % REDHAT_COPYRIGHT - sys.exit(0) +def get_power_status(conn, options): + result = "" + try: + conn.send("1\r\n") + conn.log_expect(options, options["-c"], 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("-s")): + fail_usage("Failed: You have to enter physical switch number") + else: + if (0 == options.has_key("-s")): + options["-s"] = 1 + + if (None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before)): + version = 2 + else: + version = 3 + + if (None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before)): + admin = 0 + else: + admin = 1 + + if switch == 0: + if version == 2: + if admin == 0: + conn.send("2\r\n") + else: + conn.send("3\r\n") + else: + conn.send("2\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + conn.send("1\r\n") + else: + conn.send(options["-s"]+"\r\n") + + while 1 == conn.log_expect(options, [ options["-c"], "Press " ], SHELL_TIMEOUT): + result += conn.before + conn.send("\r\n") + result += conn.before + conn.send(chr(03)) + conn.log_expect(options, "- Logout", SHELL_TIMEOUT) + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + except pexpect.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + fail(EC_TIMED_OUT) + + status = re.compile("\s*"+options["-n"]+"-.*(ON|OFF)", re.IGNORECASE).search(result).group(1) + return status.lower().strip() + +def set_power_status(conn, options): + action = { + 'on' : "1", + 'off': "2" + }[options["-o"]] + + try: + conn.send("1\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + + version = 0 + admin = 0 + switch = 0 + + if (None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before)): + switch = 1; + ## MasterSwitch has different schema for on/off actions + action = { + 'on' : "1", + 'off': "3" + }[options["-o"]] + if (None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before)): + if (0 == options.has_key("-s")): + fail_usage("Failed: You have to enter physical switch number") + else: + if (0 == options.has_key("-s")): + options["-s"] = 1 + + if (None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before)): + version = 2 + else: + version = 3 + + if (None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before)): + admin = 0 + else: + admin = 1 + + if switch == 0: + if version == 2: + if admin == 0: + conn.send("2\r\n") + else: + conn.send("3\r\n") + else: + conn.send("2\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + conn.send("1\r\n") + else: + conn.send(options["-s"] + "\r\n") + + while 1 == conn.log_expect(options, [ options["-c"], "Press " ], SHELL_TIMEOUT): + conn.send("\r\n") + conn.send(options["-n"]+"\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + + if switch == 0: + if admin == 1: + conn.send("1\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + if version == 3: + conn.send("1\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + else: + conn.send("1\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + + conn.send(action+"\r\n") + conn.log_expect(options, "Enter 'YES' to continue or to cancel :", SHELL_TIMEOUT) + conn.send("YES\r\n") + conn.log_expect(options, "Press to continue...", SHELL_TIMEOUT) + conn.send("\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + conn.send(chr(03)) + conn.log_expect(options, "- Logout", SHELL_TIMEOUT) + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + except pexpect.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + fail(EC_TIMED_OUT) def main(): - - global address, login, passwd, passwd_script, port, action, verbose, logfile, switchnum - - if len(sys.argv) > 1: - try: - opts, args = getopt.getopt(sys.argv[1:], "a:hl:o:n:p:S:vV", ["help", "output="]) - except getopt.GetoptError: - #print help info and quit - usage() - sys.exit(2) - - for o, a in opts: - if o == "-v": - verbose = True - if o == "-V": - version() - if o in ("-h", "--help"): - usage() - sys.exit() - if o == "-l": - login = a - if o == "-p": - passwd = a - if o == "-S": - passwd_script = a - if o == "-n": - dex = a.find(":") - if dex == (-1): - port = a - else: - switchnum = a[:dex] - port = a[(dex+1):] - if o == "-o": - if a == "Off" or a == "OFF" or a == "off": - action = POWER_OFF - elif a == "On" or a == "ON" or a == "on": - action = POWER_ON - elif a == "Status" or a == "STATUS" or a == "status": - action = POWER_STATUS - elif a == "Reboot" or a == "REBOOT" or a == "reboot": - action = POWER_REBOOT - else: - usage() - sys.exit() - if o == "-a": - address = a - if address == "" or login == "" or (passwd == "" and passwd_script == "") or port == "": - usage() - sys.exit() - - else: #Take args from stdin... - params = {} - #place params in dict - for line in sys.stdin: - val = line.split("=") - if len(val) == 2: - params[val[0].strip()] = val[1].strip() - - try: - address = params["ipaddr"] - except KeyError, e: - sys.stderr.write("FENCE: Missing ipaddr param for fence_apc...exiting") - sys.exit(1) - try: - login = params["login"] - except KeyError, e: - sys.stderr.write("FENCE: Missing login param for fence_apc...exiting") - sys.exit(1) - try: - if 'passwd' in params: - passwd = params["passwd"] - if 'passwd_script' in params: - passwd_script = params['passwd_script'] - if passwd == "" and passwd_script == "": - raise "missing password" - except: - sys.stderr.write("FENCE: Missing passwd for fence_apc...exiting") - sys.exit(1) - try: - port = params["port"] - except KeyError, e: - sys.stderr.write("FENCE: Missing port param for fence_apc...exiting") - sys.exit(1) - try: - switchnum = params["switch"] - except KeyError, e: - pass - try: - verbose = params["verbose"] - verbose = (verbose == 'True' or verbose == 'true' or verbose == 'TRUE') - except KeyError, e: - pass - - try: - a = params["option"] - if a == "Off" or a == "OFF" or a == "off": - action = POWER_OFF - elif a == "On" or a == "ON" or a == "on": - action = POWER_ON - elif a == "Reboot" or a == "REBOOT" or a == "reboot": - action = POWER_REBOOT - except KeyError, e: - action = POWER_REBOOT - - #### End of stdin section - - - # retrieve passwd from passwd_script (if specified) - passwd_scr = '' - if len(passwd_script): - try: - if not os.access(passwd_script, os.X_OK): - raise 'script not executable' - p = os.popen(passwd_script, 'r', 1024) - passwd_scr = p.readline().strip() - if p.close() != None: - raise 'script failed' - except: - sys.stderr.write('password-script "%s" failed\n' % passwd_script) - passwd_scr = '' - - if passwd == "" and passwd_scr == "": - sys.stderr.write('password not available, exiting...') - sys.exit(1) - elif passwd == passwd_scr: - pass - elif passwd and passwd_scr: - # execute self, with password_scr as passwd, - # if that fails, continue with "passwd" argument as password - if len(sys.argv) > 1: - comm = sys.argv[0] - skip_next = False - for w in sys.argv[1:]: - if skip_next: - skip_next = False - elif w in ['-p', '-S']: - skip_next = True - else: - comm += ' ' + w - comm += ' -p ' + passwd_scr - ret = os.system(comm) - if ret != -1 and os.WIFEXITED(ret) and os.WEXITSTATUS(ret) == 0: - # success - sys.exit(0) - else: - sys.stderr.write('Use of password from "passwd_script" failed, trying "passwd" argument\n') - else: # use stdin - p = os.popen(sys.argv[0], 'w', 1024) - for par in params: - if par not in ['passwd', 'passwd_script']: - p.write(par + '=' + params[par] + '\n') - p.write('passwd=' + passwd_scr + '\n') - p.flush() - if p.close() == None: - # success - sys.exit(0) - else: - sys.stderr.write('Use of password from "passwd_script" failed, trying "passwd" argument\n') - elif passwd_scr: - passwd = passwd_scr - # passwd all set - - - - ### Order of events - # 0) If verbose, prepare log file handle - # 1) Open socket - # 2) Log in - # 3) Evaluate task. Task will be one of: - # 3a - Check status and print to stdout (or log file if verbose) - # 3b - Turn a port off, then confirm - # 3c - Turn a port on, then confirm - # 3d - Reboot by turning a port off, then on, and confirming each step. - - if verbose: - setup_logging() - - sock = setup_socket() - - # Ok, now lets log in... - do_login(sock) - - # Now we should be at the outside Control screen - - if action == POWER_STATUS: - # We should be at the Control screen, so we need to write a '1' - # to kick things off - sock.write("1\r") - statusval = do_status_check(sock) - backout(sock) - sock.write("4\r") # Logs out - - elif action == POWER_OFF: - sock.write("1\r") - do_power_off(sock) - backout(sock) # Return to control screen - statusval = do_status_check(sock) - if statusval == OFF: - if verbose: - logit("Power Off successful\n") - print "Power Off successful" - backout(sock) - sock.write("4\r") # Logs out - sock.close() - sys.exit(0) - else: - if verbose: - logit("Power Off unsuccessful\n") - logit("Undetermined error\n") - sys.stderr.write("Power Off unsuccessful") - backout(sock) - sock.write("4\r") # Logs out - sock.close() - sys.exit(1) - - elif action == POWER_ON: - sock.write("1\r") - do_power_on(sock) - backout(sock) # Return to control screen - statusval = do_status_check(sock) - if statusval == ON: - if verbose: - logit("Power On successful\n") - print "Power On successful" - backout(sock) - sock.write("4\r") # logs out - sock.close() - sys.exit(0) - else: - if verbose: - logit("Power On unsuccessful\n") - logit("Undetermined error\n") - sys.stderr.write("Power On unsuccessful") - backout(sock) - sock.write("4\r") # Logs out - sock.close() - sys.exit(1) - - elif action == POWER_REBOOT: - sock.write("1\r") - do_power_off(sock) - backout(sock) # Return to control screen - statusval = do_status_check(sock) - if statusval == OFF: - if verbose: - logit("Power Off successful\n") - print "Power Off successful" - backout(sock) - else: - if verbose: - logit("Power Off unsuccessful\n") - logit("Undetermined error\n") - sys.stderr.write("Power Off unsuccessful") - backout(sock) - sock.write("4\r") # Logs out - sock.close() - sys.exit(1) - do_power_on(sock) - backout(sock) # Return to control screen - statusval = do_status_check(sock) - if statusval == ON: - if verbose: - logit("Power Reboot successful\n") - print "Power Reboot successful" - backout(sock) - sock.write("4\r") # Logs out - sock.close() - sys.exit(0) - else: - if verbose: - logit("Power Reboot unsuccessful\n") - logit("Undetermined error\n") - sys.stderr.write("Power Reboot unsuccessful") - backout(sock) - sock.write("4\r") # Logs out - sock.close() - sys.exit(1) - - sock.close() - -def backout(sock): - sock.write(chr(27)) - - while (1): - i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT) - - if regex_list[i] == SCREEN_END: - break - elif regex_list[i] == SCREEN_END_2: - sock.write(chr(27)) - -def setup_socket(): - ## Time to open telnet session and log in. - try: - sock = Telnet(address.strip()) - except socket.error, (errno, msg): - my_msg = "FENCE: A problem was encountered opening a telnet session with " + address - if verbose: - logit(my_msg) - logit("FENCE: Error number: %d -- Message: %s\n" % (errno, msg)) - logit("Firewall issue? Correct address?\n") - - sys.stderr.write(my_msg) - sys.stderr.write(("FENCE: Error number: %d -- Message: %s\n" % (errno, msg))) - sys.stderr.write("Firewall issue? Correct address?\n") - sys.exit(1) - - if verbose: - logit("\nsocket open to %s\n" % address) - - return sock - -def setup_logging( log_location="/tmp/apclog"): - global logfile - try: - logfile = open(log_location, 'a') - logfile.write("###############################################\n") - logfile.write("Telnetting to apc switch %s\n" % address) - now = time.localtime(time.time()) - logfile.write(time.asctime(now)) - except IOError, e: - sys.stderr.write("Failed to open log file %s" % log_location) - logfile = None - -def logit(instr): - if logfile != None: - logfile.write(instr) - -def do_login(sock): - result_code = 1 - - ## This loop tries to assemble complete telnet screens and passes - ## them to helper methods to handle responses accordingly. - while result_code: - try: - i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT) - except socket.error, (errno, msg): - my_msg = "FENCE: A problem was encountered opening a telnet session with " + address + "\n" - if verbose: - logit(my_msg) - logit("FENCE: Error number: %d -- Message: %s\n" % (errno, msg)) - - sys.stderr.write(my_msg) - sys.stderr.write(("FENCE: Error number: %d -- Message: %s\n" % (errno, msg))) - sys.exit(1) - - if i == CONTINUE_INDEX: # Capture the rest of the screen... - sock.write("\r") - ii,moo,txtt = sock.expect(regex_list, TELNET_TIMEOUT) - txt = txt + txtt - - ndbuf = sock.read_eager() # Scoop up remainder - if verbose: - logit(txt + ndbuf) - result_code,response = log_in(txt + ndbuf) - if result_code: - try: - sock.write(response) - except socket.error, (errno, msg): - if verbose: - logit("Error #%s" % errno) - logit(msg) - sys.stderr.write("Error #%s: %s" % (errno,msg)) - sys.exit(1) - -def log_in(buffer): - global FIRMWARE_REV - lines = buffer.splitlines() - - for i in lines: - if i.find(USERNAME) != (-1): - if verbose: - logit("Sending login: %s\n" % login) - return (NOT_COMPLETE, login + "\r") - elif i.find(PASSWORD) != (-1): - if verbose: - logit("Sending password: %s\n" % passwd) - return (NOT_COMPLETE, passwd + "\r") - elif i.find(CONTROL_CONSOLE) != (-1): - #while we are here, grab the firmware revision - rev_search_lines = buffer.splitlines() - for rev_search_line in rev_search_lines: #search screen again - rev_dex = rev_search_line.find(FIRMWARE_STR) - if rev_dex != (-1): #found revision line - scratch_rev = rev_search_line[rev_dex:] - v_dex = scratch_rev.find("v") - if v_dex != (-1): - if scratch_rev[v_dex + 1] == "3": #format is v3.3.4 - FIRMWARE_REV = 3 - break - return (COMPLETE, "1\r") - -def do_status_check(sock): - result_code = 1 - while result_code: - i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT) - if i == CONTINUE_INDEX: # Capture the rest of the screen... - sock.write("\r") - ii,moo,txtt = sock.expect(regex_list, TELNET_TIMEOUT) - txt = txt + txtt - - ndbuf = sock.read_eager() # Scoop up remainder - if verbose: - logit(txt + ndbuf) - (result_code,response,statusval) = return_status(txt + ndbuf) - if result_code: - try: - sock.write(response) - except socket.error, (errno, msg): - if verbose: - logit("Status check failed.") - logit("Error #%s" % errno) - logit(msg) - sys.stderr.write("Status check failed.") - sys.stderr.write("Error #%s: %s" % (errno,msg)) - sys.exit(1) - # Back from status check - value should be in status var - if response == SUCCESS: - if switchnum == "": - if verbose: - logit("Status check successful. Port %s is %s" % (port,statusval)) - print "Status check successful. Port %s is %s" % (port,statusval) - else: - if verbose: - logit("Status check successful. Port %s:%s is %s" % (switchnum, port, statusval)) - print "Status check successful. Port %s:%s is %s" % (switchnum, port, statusval) - - return statusval - else: - if verbose: - logit("Status check failed, unknown reason.") - sys.stderr.write("Status check failed, unknown reason.\n") - sock.close() - sys.exit(1) - -def return_status(buffer): - global switchnum, port - - lines = buffer.splitlines() - - for i in lines: - if i.find(CONTROL_CONSOLE) != (-1): - return (NOT_COMPLETE, "1\r", "Status Unknown") - elif i.find(DEVICE_MANAGER) != (-1): - if switchnum != "": - res = switchnum + "\r" - else: - if FIRMWARE_REV == 2: - res = "3\r" - elif FIRMWARE_REV == 3: - res = "2\r1\r" - else: #placeholder for future revisions - res = "3\r" - return (NOT_COMPLETE, res, "Status Unknown") - elif i.find(OUTLET_CONTROL) != (-1): - ls = buffer.splitlines() - portval = port.strip() - portval = " " + portval + " " - portval2 = " " + port.strip() + "- " - found_portval = False - for l in ls: - if l.find(portval) != (-1) or l.find(portval2) != (-1): - found_portval = True - linesplit = l.split() - linelen = len(linesplit) - return (COMPLETE,SUCCESS,linesplit[linelen - 1]) - elif i.find(MASTER) != (-1): - try: - e = int(port.strip()) - portval = port.strip() - switchval = switchnum.strip() - portval = switchval + ":" + portval - except ValueError, e: - portval = port.strip() - ls = buffer.splitlines() - found_portval = False - for l in ls: - words = l.split() - if len(words) > 3: - if words[2] == portval or words[3] == portval: - found_portval = True - linesplit = l.split() - linelen = len(linesplit) - return (COMPLETE, SUCCESS, linesplit[linelen - 3]) - return (COMPLETE, FAIL, "Incorrect port number") - return (NOT_COMPLETE, chr(27), "Status Unknown") - -def do_power_switch(sock, status): - result_code = 1 - - while result_code: - i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT) - if i == CONTINUE_INDEX: # Capture the rest of the screen... - sock.write("\r") - ii,moo,txtt = sock.expect(regex_list, TELNET_TIMEOUT) - txt = txt + txtt - - ndbuf = sock.read_eager() # Scoop up remainder - if verbose: - logit(txt + ndbuf) - - if status == "off": - result_code, response = power_off(txt + ndbuf) - elif status == "on": - result_code, response = power_on(txt + ndbuf) - else: - if verbose: - logit("Invalid status in do_power_switch() function") - sys.stderr.write("Invalid status in do_power_switch() function") - sys.exit(1) - - if result_code: - try: - sock.write(response) - except socket.error, (errno, msg): - if verbose: - logit("Error #%s" % errno) - logit(msg) - sys.stderr.write("Error #%s: %s" % (errno,msg)) - sys.exit(1) - # FIXME: always returns COMPLETE (0) - else: - try: - sock.write(response) - except socket.error, (errno, msg): - if verbose: - logit("Error #%s" % errno) - logit(msg) - sys.stderr.write("Error #%s: %s" % (errno,msg)) - sys.exit(1) - return COMPLETE - - -def power_switch(buffer, escape, control_outlet, control_outlet2): - # If port is not aliased, then outlet control screen will have the word - # 'Outlet' in the header. If the name is aliased, it will only have the - # alias in the header. - - outlet_search_str1 = "Outlet " + port.strip() + " ------------" - outlet_search_str2 = port.strip() + " ------------" - outlet_search_str3 = "Outlet " + switchnum.strip() + ":" + port.strip() + " ------" - outlet_search_str4 = " Outlet : " + port.strip() - outlet_search_str5 = " Outlet Name : " + port.strip() - master_search_str1 = "-------- Master" - lines = buffer.splitlines() - - for i in lines: - if i.find(CONTROL_CONSOLE) != (-1): - return (NOT_COMPLETE,"1\r") - - elif i.find(DEVICE_MANAGER) != (-1): - if switchnum != "": - res = switchnum + "\r" - else: - if FIRMWARE_REV == 2: - res = "3\r" - elif FIRMWARE_REV == 3: - #Changed for bz299191 - #res = "2\r1\r" - res = "2\r" - else: #placeholder for future revisions - sheesh - res = "3\r" - return (NOT_COMPLETE, res) - - elif (i.find(master_search_str1) != (-1)): - return (NOT_COMPLETE, port.strip() + "\r") - - elif i.find(outlet_search_str1) != (-1) and (switchnum == ""): - return (NOT_COMPLETE,"1\r") - - elif i.find(outlet_search_str2) != (-1) and (switchnum == ""): - return (NOT_COMPLETE,"1\r") - - elif i.find(outlet_search_str3) != (-1): - return (NOT_COMPLETE, "1\r") - - elif i == outlet_search_str4: - return (NOT_COMPLETE, "1\r") - - elif i == outlet_search_str5: - return (NOT_COMPLETE, "1\r") - - elif i.find(OUTLET_MANAGE) != (-1): - #Changed for bz299191 - #return (NOT_COMPLETE, "\r") - return (NOT_COMPLETE, "1\r") - - #elif i.find(OUTLET_CONTROL) != (-1) or i.find(OUTLET_MANAGE) != (-1): - elif i.find(OUTLET_CONTROL) != (-1): - ls = buffer.splitlines() - portval = port.strip() - portval = " " + portval + " " - found_portval = False - i = 0 - # look for aliased name - for l in ls: - i = i + 1 - if l.find(portval) != (-1): - found_portval = True - linesplit = l.split() - outlet_str = linesplit[0] - dex = outlet_str.find("-") - if dex <= (0): - if verbose: - logit("Problem identifying outlet\n") - logit("Looking for %s in string %s\n" % (portval,outlet_str)) - sys.stderr.write("Problem identifying outlet\n") - sys.stderr.write("Looking for %s in string %s\n" % (portval,outlet_str)) - sys.exit(1) - normalized_outlet_str = outlet_str[:dex] - return (NOT_COMPLETE, normalized_outlet_str + "\r") - # look for portnum - portval = " " + port.strip() + "-" - i = 0 - for l in ls: - i = i + 1 - if l.find(portval) != (-1): - found_portval = True - linesplit = l.split() - outlet_str = linesplit[0] - dex = outlet_str.find("-") - if dex <= (0): - if verbose: - logit("Problem identifying outlet\n") - logit("Looking for %s in string %s\n" % (portval,outlet_str)) - sys.stderr.write("Problem identifying outlet\n") - sys.stderr.write("Looking for %s in string %s\n" % (portval,outlet_str)) - sys.exit(1) - normalized_outlet_str = outlet_str[:dex] - return (NOT_COMPLETE, normalized_outlet_str + "\r") - if found_portval == False: - if verbose: - logit("Problem identifying outlet\n") - logit("Looking for '%s' in string '%s'\n" % (portval, ls)) - sys.stderr.write("Problem identifying outlet\n") - sys.stderr.write("Looking for '%s' in string '%s'\n" % (portval, ls)) - sys.exit(1) - - elif i.find(MASTER) != (-1): - ls = buffer.splitlines() - found_portval = False - # look for aliased name - portval = port.strip() - for l in ls: - words = l.strip().split() - if len(words) > 3: - if '----' not in words[0] and words[3].strip() == portval: - outlet_str = words[0] - dex = outlet_str.find("-") - if dex <= (0): - if verbose: - logit("Problem identifying outlet\n") - logit("Looking for %s in string %s\n" % (portval, outlet_str)) - sys.stderr.write("Problem identifying outlet\n") - sys.stderr.write("Looking for %s in string %s\n" % (portval, outlet_str)) - sys.exit(1) - normalized_outlet_str = outlet_str[:dex] - return (NOT_COMPLETE, (normalized_outlet_str + "\r")) - # look for portnum - portval = port.strip() - portval = switchnum.strip() + ":" + portval + " " - i = 0 - for l in ls: - i = i + 1 - if l.find(portval) != (-1): - found_portval = True - linesplit = l.split() - outlet_str = linesplit[0] - dex = outlet_str.find("-") - if dex <= (0): - if verbose: - logit("Problem identifying outlet\n") - logit("Looking for %s in string %s\n" % (portval,outlet_str)) - sys.stderr.write("Problem identifying outlet\n") - sys.stderr.write("Looking for %s in string %s\n" % (portval,outlet_str)) - sys.exit(1) - normalized_outlet_str = outlet_str[:dex] - return (NOT_COMPLETE, (normalized_outlet_str + "\r")) - if found_portval == False: - if verbose: - logit("Problem identifying outlet\n") - logit("Looking for '%s' in string '%s'\n" % (portval, ls)) - sys.stderr.write("Problem identifying outlet\n") - sys.stderr.write("Looking for '%s' in string '%s'\n" % (portval, ls)) - sys.exit(1) - - elif i.find(CONFIRM) != (-1): - return (NOT_COMPLETE,"YES\r") - - elif i.find(COMMAND_SUCCESS) != (-1): - return (COMPLETE,"\r") - - elif i.find(COMMAND_SUCCESS_2) != (-1): - return (COMPLETE,"\r") - - elif i.find(CONTROL_OUTLET) != (-1): - return (NOT_COMPLETE, control_outlet + "\r") - - elif i.find(CONTROL_OUTLET_2) != (-1): - return (NOT_COMPLETE, control_outlet2 + "\r") - - if (escape == True): - return (NOT_COMPLETE, chr(27)) - else: - raise "unknown screen encountered in \n" + str(lines) + "\n" - -def do_power_off(sock): - x = do_power_switch(sock, "off") - return x - -def power_off(buffer): - x = power_switch(buffer, False, "2", "3"); - return x - -def do_power_on(sock): - x = do_power_switch(sock, "on") - return x - -def power_on(buffer): - x = power_switch(buffer, True, "1", "1"); - return x + device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", + "action", "ipaddr", "login", "passwd", "passwd_script", + "secure", "port", "switch", "test" ] + + options = check_input(device_opt, process_input(device_opt)) + + ## + ## Fence agent specific defaults + ##### + options["ssh_options"] = "-1 -c blowfish" + + if 0 == options.has_key("-c"): + options["-c"] = "\n>" + + ## Support for -n [switch]:[plug] notation that was used before + if (-1 != options["-n"].find(":")): + (switch, plug) = options["-n"].split(":", 1) + options["-s"] = switch; + options["-n"] = plug; + + ## + ## Operate the fencing device + #### + conn = fence_login(options) + fence_action(conn, options, set_power_status, get_power_status) + + ## + ## Logout from system + ###### + conn.sendline("4") + conn.close() if __name__ == "__main__": - main() + main() diff --git a/fence/agents/bladecenter/Makefile b/fence/agents/bladecenter/Makefile index 6bd15a8..5a617df 100644 --- a/fence/agents/bladecenter/Makefile +++ b/fence/agents/bladecenter/Makefile @@ -11,7 +11,7 @@ ############################################################################### ############################################################################### -SOURCE= fence_bladecenter.pl +SOURCE= fence_bladecenter.py TARGET= fence_bladecenter top_srcdir=../.. @@ -19,12 +19,12 @@ include ${top_srcdir}/make/defines.mk all: $(TARGET) -fence_bladecenter: fence_bladecenter.pl +fence_bladecenter: fence_bladecenter.py : > $(TARGET) awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "\$$FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "\$$BUILD_DATE=\"(built `date`)\";" >> $(TARGET) + echo "FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET) + ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) + echo "BUILD_DATE=\"(built `date`)\";" >> $(TARGET) awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) chmod +x $(TARGET) diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py new file mode 100755 index 0000000..ff7ad67 --- /dev/null +++ b/fence/agents/bladecenter/fence_bladecenter.py @@ -0,0 +1,90 @@ +#!/usr/bin/python + +## +## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. +## +## The Following Agent Has Been Tested On: +## +## Model Firmware +## +--------------------+---------------------------+ +## (1) Main application BRET85K, rev 16 +## Boot ROM BRBR67D, rev 16 +## Remote Control BRRG67D, rev 16 +## +##### + +import sys, re, pexpect +sys.path.append("/usr/lib/fence") +from fencing import * + +#BEGIN_VERSION_GENERATION +FENCE_RELEASE_NAME="" +REDHAT_COPYRIGHT="" +BUILD_DATE="" +#END_VERSION_GENERATION + +def get_power_status(conn, options): + try: + node_cmd = "system:blade\[" + options["-n"] + "\]>" + + conn.send("env -T system:blade[" + options["-n"] + "]\r\n") + conn.log_expect(options, node_cmd, SHELL_TIMEOUT) + conn.send("power -state\r\n") + conn.log_expect(options, node_cmd, SHELL_TIMEOUT) + status = conn.before.splitlines()[-1] + conn.send("env -T system\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + except pexpect.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + fail(EC_TIMED_OUT) + + return status.lower().strip() + +def set_power_status(conn, options): + action = { + 'on' : "powerup", + 'off': "powerdown" + }[options["-o"]] + + try: + node_cmd = "system:blade\[" + options["-n"] + "\]>" + + conn.send("env -T system:blade[" + options["-n"] + "]\r\n") + conn.log_expect(options, node_cmd, SHELL_TIMEOUT) + conn.send("power -"+options["-o"]+"\r\n") + conn.log_expect(options, node_cmd, SHELL_TIMEOUT) + conn.send("env -T system\r\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + except pexpect.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + fail(EC_TIMED_OUT) + +def main(): + device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", + "action", "ipaddr", "login", "passwd", "passwd_script", + "cmd_prompt", "secure", "port", "identity_file" ] + + options = check_input(device_opt, process_input(device_opt)) + + ## + ## Fence agent specific defaults + ##### + if 0 == options.has_key("-c"): + options["-c"] = "system>" + + ## + ## Operate the fencing device + ###### + conn = fence_login(options) + fence_action(conn, options, set_power_status, get_power_status) + + ## + ## Logout from system + ###### + conn.send("exit\r\n") + conn.close() + +if __name__ == "__main__": + main() diff --git a/fence/agents/drac/Makefile b/fence/agents/drac/Makefile index 258f5ff..914d2c9 100644 --- a/fence/agents/drac/Makefile +++ b/fence/agents/drac/Makefile @@ -11,25 +11,38 @@ ############################################################################### ############################################################################### -SOURCE= fence_drac.pl -TARGET= fence_drac +SOURCE1= fence_drac.pl +TARGET1= fence_drac + +SOURCE2= fence_drac5.py +TARGET2= fence_drac5 top_srcdir=../.. include ${top_srcdir}/make/defines.mk -all: $(TARGET) +all: $(TARGET1) $(TARGET2) fence_drac: fence_drac.pl - : > $(TARGET) - awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "\$$FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "\$$BUILD_DATE=\"(built `date`)\";" >> $(TARGET) - awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) + : > $(TARGET1) + awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE1) >> $(TARGET1) + echo "\$$FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET1) + ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET1) + echo "\$$BUILD_DATE=\"(built `date`)\";" >> $(TARGET1) + awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE1) >> $(TARGET1) + chmod +x $(TARGET1) + +fence_drac5: fence_drac5.py + : > $(TARGET2) + awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE2) >> $(TARGET2) + echo "FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET2) + ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET2) + echo "BUILD_DATE=\"(built `date`)\";" >> $(TARGET2) + awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE2) >> $(TARGET2) + chmod +x $(TARGET2) -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} +copytobin: ${TARGET1} ${TARGET2} + cp ${TARGET1} ${top_srcdir}/bin/${TARGET1} + cp ${TARGET2} ${top_srcdir}/bin/${TARGET2} clean: - rm -f $(TARGET) + rm -f $(TARGET1) $(TARGET2) diff --git a/fence/agents/drac/fence_drac5.py b/fence/agents/drac/fence_drac5.py new file mode 100755 index 0000000..12cd5f7 --- /dev/null +++ b/fence/agents/drac/fence_drac5.py @@ -0,0 +1,79 @@ +#!/usr/bin/python + +## +## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. +## +## 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, modulename were removed +##### + +import sys, re, pexpect +sys.path.append("/usr/lib/fence") +from fencing import * + +#BEGIN_VERSION_GENERATION +FENCE_RELEASE_NAME="" +REDHAT_COPYRIGHT="" +BUILD_DATE="" +#END_VERSION_GENERATION + +def get_power_status(conn, options): + try: + conn.sendline("racadm serveraction powerstatus") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + except pexpect.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + fail(EC_TIMED_OUT) + + status = re.compile("Server power status: (.*)", re.IGNORECASE).search(conn.before).group(1) + return status.lower().strip() + +def set_power_status(conn, options): + action = { + 'on' : "powerup", + 'off': "powerdown" + }[options["-o"]] + + try: + conn.sendline("racadm serveraction " + action) + conn.log_expect(options, options["-c"], POWER_TIMEOUT) + except pexpect.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + fail(EC_TIMED_OUT) + +def main(): + device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", + "action", "ipaddr", "login", "passwd", "passwd_script", + "cmd_prompt", "secure", + "drac_version", "module_name" ] + + options = check_input(device_opt, process_input(device_opt)) + + ## + ## Fence agent specific defaults + ##### + if 0 == options.has_key("-c"): + options["-c"] = "\$" + + ## + ## Operate the fencing device + ###### + conn = fence_login(options) + fence_action(conn, options, set_power_status, get_power_status) + + ## + ## Logout from system + ###### + conn.sendline("exit") + conn.close() + +if __name__ == "__main__": + main() diff --git a/fence/agents/ilo/Makefile b/fence/agents/ilo/Makefile index 4ea4299..794eb13 100644 --- a/fence/agents/ilo/Makefile +++ b/fence/agents/ilo/Makefile @@ -11,7 +11,7 @@ ############################################################################### ############################################################################### -SOURCE= fence_ilo.pl +SOURCE= fence_ilo.py TARGET= fence_ilo top_srcdir=../.. @@ -22,9 +22,9 @@ all: $(TARGET) fence_ilo: $(SOURCE) : > $(TARGET) awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "\$$FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "\$$BUILD_DATE=\"(built `date`)\";" >> $(TARGET) + echo "FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET) + ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) + echo "BUILD_DATE=\"(built `date`)\";" >> $(TARGET) awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) chmod +x $(TARGET) diff --git a/fence/agents/ilo/fence_ilo.py b/fence/agents/ilo/fence_ilo.py new file mode 100755 index 0000000..3cada5e --- /dev/null +++ b/fence/agents/ilo/fence_ilo.py @@ -0,0 +1,102 @@ +#!/usr/bin/python + +## +## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. +## +## The Following Agent Has Been Tested On: +## +## iLO Version +## +---------------------------------------------+ +## iLO / firmware 1.91 / RIBCL 2.22 +## iLO2 / firmware 1.22 / RIBCL 2.22 +## iLO2 / firmware 1.50 / RIBCL 2.22 +##### + +import sys, re, pexpect, socket +sys.path.append("/usr/lib/fence") +from fencing import * +from OpenSSL import SSL + +#BEGIN_VERSION_GENERATION +FENCE_RELEASE_NAME="" +REDHAT_COPYRIGHT="" +BUILD_DATE="" +#END_VERSION_GENERATION + +def get_power_status(conn, options): + conn.send("\r\n") + conn.send("\r\n") + conn.send("\r\n") + conn.log_expect(options, "HOST_POWER=\"(.*?)\"", POWER_TIMEOUT) + + status = conn.match.group(1) + return status.lower().strip() + +def set_power_status(conn, options): + conn.send("\r\n") + conn.send("") + + if options.has_key("fw_processor") and options["fw_processor"] == "iLO2": + if options["fw_version"] > 1.29: + conn.send("\r\n") + else: + conn.send("\r\n") + elif options["-r"] < 2.21: + conn.send("\r\n") + else: + if options["-o"] == "off": + conn.send("\r\n") + else: + conn.send("\r\n") + conn.send("\r\n") + + return + +def main(): + device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", + "action", "ipaddr", "login", "passwd", "passwd_script", + "ssl", "ribcl" ] + + options = check_input(device_opt, process_input(device_opt)) + + options["-z"] = 1 + LOGIN_TIMEOUT = 10 + + ## + ## Login and get version number + #### + conn = fence_login(options) + try: + conn.send("\r\n") + conn.log_expect(options, [ "", "" ], LOGIN_TIMEOUT) + version = re.compile("= 2: + conn.send("\r\n") + else: + conn.send("\r\n") + + conn.send("\r\n") + if options["-r"] >= 2: + conn.send("\r\n") + conn.send("\r\n") + conn.log_expect(options, "", SHELL_TIMEOUT) + options["fw_version"] = float(re.compile("FIRMWARE_VERSION\s*=\s*\"(.*?)\"", re.IGNORECASE).search(conn.before).group(1)) + options["fw_processor"] = re.compile("MANAGEMENT_PROCESSOR\s*=\s*\"(.*?)\"", re.IGNORECASE).search(conn.before).group(1) + conn.send("\r\n") + except pexpect.TIMEOUT: + fail(EC_LOGIN_DENIED) + + ## + ## Fence operations + #### + fence_action(conn, options, set_power_status, get_power_status) + +if __name__ == "__main__": + main() diff --git a/fence/agents/lib/Makefile b/fence/agents/lib/Makefile new file mode 100644 index 0000000..3a0e48d --- /dev/null +++ b/fence/agents/lib/Makefile @@ -0,0 +1,48 @@ +############################################################################### +############################################################################### +## +## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. +## Copyright (C) 2004 Red Hat, Inc. All rights reserved. +## +## This copyrighted material is made available to anyone wishing to use, +## modify, copy, or redistribute it subject to the terms and conditions +## of the GNU General Public License v.2. +## +############################################################################### +############################################################################### + +SOURCE1= fencing.py.py +TARGET1= fencing.py + +SOURCE2= telnet_ssl.py +TARGET2= telnet_ssl + +top_srcdir=../.. +include ${top_srcdir}/make/defines.mk + +all: $(TARGET1) + +$(TARGET1): $(SOURCE1) + : > $(TARGET1) + awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE1) >> $(TARGET1) + echo "FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET1) + ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET1) + echo "BUILD_DATE=\"(built `date`)\";" >> $(TARGET1) + awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE1) >> $(TARGET1) + chmod +x $(TARGET1) + +$(TARGET2): $(SOURCE2) + : > $(TARGET2) + awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE2) >> $(TARGET2) + echo "FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET2) + ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET2) + echo "BUILD_DATE=\"(built `date`)\";" >> $(TARGET2) + awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE2) >> $(TARGET2) + chmod +x $(TARGET2) + +copytobin: ${TARGET1} ${TARGET2} + cp ${TARGET1} ${top_srcdir}/bin/${TARGET1} + cp ${TARGET2} ${top_srcdir}/bin/${TARGET2} + +clean: + rm -f $(TARGET1) $(TARGET2) diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py new file mode 100644 index 0000000..90457a2 --- /dev/null +++ b/fence/agents/lib/fencing.py.py @@ -0,0 +1,399 @@ +#!/usr/bin/python + +## +## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. +## +##### +import sys, getopt, time, os +import pexpect, re +import telnetlib + +## do not add code here. +#BEGIN_VERSION_GENERATION +FENCE_RELEASE_NAME="" +REDHAT_COPYRIGHT="" +BUILD_DATE="" +#END_VERSION_GENERATION + +POWER_TIMEOUT = 20 +SHELL_TIMEOUT = 3 +LOGIN_TIMEOUT = 5 + +LOG_MODE_VERBOSE = 100 +LOG_MODE_QUIET = 0 + +EC_BAD_ARGS = 2 +EC_LOGIN_DENIED = 3 +EC_CONNECTION_LOST = 4 +EC_TIMED_OUT = 5 +EC_WAITING_ON = 6 +EC_WAITING_OFF = 7 + +TELNET_PATH = "/usr/bin/telnet" +SSH_PATH = "/usr/bin/ssh" +SSL_PATH = "/usr/lib/fence/telnet_ssl" + +all_opt = { + "help" : { + "getopt" : "h", + "help" : "-h Display this help and exit", + "order" : 54 }, + "version" : { + "getopt" : "V", + "help" : "-V Output version information and exit", + "order" : 53 }, + "quiet" : { + "getopt" : "q", + "help" : "-q Quiet mode", + "order" : 50 }, + "verbose" : { + "getopt" : "v", + "help" : "-v Verbose mode", + "order" : 51 }, + "debug" : { + "getopt" : "D:", + "help" : "-D Debugging to output file", + "order" : 52 }, + "agent" : { + "getopt" : "", + "help" : "", + "order" : 1 }, + "action" : { + "getopt" : "o:", + "help" : "-o Action: status, reboot (default), off or on", + "order" : 1 }, + "ipaddr" : { + "getopt" : "a:", + "help" : "-a IP address or hostname of fencing device", + "order" : 1 }, + "login" : { + "getopt" : "l:", + "help" : "-l Login name", + "order" : 1 }, + "no_login" : { + "getopt" : "", + "help" : "", + "order" : 1 }, + "passwd" : { + "getopt" : "p:", + "help" : "-p Login password or passphrase", + "order" : 1 }, + "passwd_script" : { + "getopt" : "S:", + "help" : "-S