From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14862 invoked by alias); 16 Jul 2008 07:25:30 -0000 Received: (qmail 14683 invoked by uid 9702); 16 Jul 2008 07:25:28 -0000 Date: Wed, 16 Jul 2008 07:25:00 -0000 Message-ID: <20080716072526.14620.qmail@sourceware.org> From: fabbione@sourceware.org To: cluster-cvs@sources.redhat.com, cluster-devel@redhat.com Subject: Cluster Project branch, RHEL5, updated. cmirror_1_1_15-148-gedeac8b X-Git-Refname: refs/heads/RHEL5 X-Git-Reftype: branch X-Git-Oldrev: 6c8d7408095782bb00b5361a7df5973f3dcda183 X-Git-Newrev: edeac8b3f8ef1b4514d9275fe58353897fe64180 Mailing-List: contact cluster-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: cluster-cvs-owner@sourceware.org X-SW-Source: 2008-q3/txt/msg00072.txt.bz2 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=edeac8b3f8ef1b4514d9275fe58353897fe64180 The branch, RHEL5 has been updated via edeac8b3f8ef1b4514d9275fe58353897fe64180 (commit) via 841ca577604c1cab58a2321adb0f48015e09fbf4 (commit) via e98318fd87fff36f33a553d49ec034b2f013962d (commit) via 94da6e5daa9464eb8add92799a0a3b8dbb51e556 (commit) via 410322a9262782032419a95df24b914d746ab78e (commit) via 227fd2259db164351f4a87df11f0aaca7e8e8431 (commit) via 8c6f5b0f8c8f3f516cfa9c45788eaffae1b14716 (commit) via 1370e1d95e5d47cb769c6f5688bcc95a6323024c (commit) via f392c771b5685ee7976ddedb9dc91a72b6aa9131 (commit) via bb049ca7538ba651a11a11760ee4938ca11309ab (commit) via 7372abbeeedc2929c87e4e2dfdad5afefdb9eaa9 (commit) via afcd1c258fe77e99e903b3af0d2bbe4511ab30c9 (commit) via e8fd85b5708af3c90f2bc22a5dfba8ee4d650500 (commit) via 46ed9ea48925308cc6ba6a53dc003af47e439f11 (commit) via 7f0ff0d36300663872e33ea0f59d2f12c57ec71b (commit) via 04047258adecce9e67f41878cdb04704ce21d7d7 (commit) via f8f38be59e31ddb153c97ce911833987f4cd8aa9 (commit) via bcbc00f95c033fe4c6a1036c4866bc2ca983aae2 (commit) via 13e245d07bd086ef6cc13361ba0d36b34d6e874f (commit) via 7a3e7b32f17570de9f3f86ecbcda1af6971f232d (commit) via 3e174a998a07530f1cbfa05c0954f9c1d2fc85cd (commit) from 6c8d7408095782bb00b5361a7df5973f3dcda183 (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 edeac8b3f8ef1b4514d9275fe58353897fe64180 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 841ca577604c1cab58a2321adb0f48015e09fbf4 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 e98318fd87fff36f33a553d49ec034b2f013962d 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 94da6e5daa9464eb8add92799a0a3b8dbb51e556 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 410322a9262782032419a95df24b914d746ab78e 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 227fd2259db164351f4a87df11f0aaca7e8e8431 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 8c6f5b0f8c8f3f516cfa9c45788eaffae1b14716 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 1370e1d95e5d47cb769c6f5688bcc95a6323024c Author: Marek 'marx' Grac Date: Fri May 23 19:01:06 2008 +0200 [FENCE]: Fix #448133: New fence agent for HMC/LPAR commit f392c771b5685ee7976ddedb9dc91a72b6aa9131 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 bb049ca7538ba651a11a11760ee4938ca11309ab 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 7372abbeeedc2929c87e4e2dfdad5afefdb9eaa9 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 afcd1c258fe77e99e903b3af0d2bbe4511ab30c9 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 e8fd85b5708af3c90f2bc22a5dfba8ee4d650500 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 46ed9ea48925308cc6ba6a53dc003af47e439f11 Author: Fabio M. Di Nitto Date: Fri May 16 07:10:40 2008 +0200 [BUILD] Port fence/agents/lib/Makefile to RHEL5 Signed-off-by: Fabio M. Di Nitto commit 7f0ff0d36300663872e33ea0f59d2f12c57ec71b 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 04047258adecce9e67f41878cdb04704ce21d7d7 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 f8f38be59e31ddb153c97ce911833987f4cd8aa9 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 bcbc00f95c033fe4c6a1036c4866bc2ca983aae2 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 13e245d07bd086ef6cc13361ba0d36b34d6e874f 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 7a3e7b32f17570de9f3f86ecbcda1af6971f232d 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 3e174a998a07530f1cbfa05c0954f9c1d2fc85cd 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 | 999 +++++-------------------- fence/agents/bladecenter/Makefile | 10 +- fence/agents/bladecenter/fence_bladecenter.py | 90 +++ fence/agents/drac/Makefile | 36 +- fence/agents/drac/fence_drac5.py | 79 ++ fence/agents/ilo/Makefile | 8 +- fence/agents/ilo/fence_ilo.py | 102 +++ fence/agents/lib/Makefile | 50 ++ fence/agents/lib/fencing.py.py | 399 ++++++++++ fence/agents/lib/telnet_ssl.py | 72 ++ fence/agents/lpar/Makefile | 38 + fence/agents/lpar/fence_lpar.py | 97 +++ fence/agents/wti/Makefile | 8 +- fence/agents/wti/fence_wti.py | 109 +++ 15 files changed, 1264 insertions(+), 839 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 c41aedd..0aabcc3 100644 --- a/fence/agents/Makefile +++ b/fence/agents/Makefile @@ -15,6 +15,7 @@ include ${top_srcdir}/make/defines.mk all: + ${MAKE} -C lib all ${MAKE} -C apc all ${MAKE} -C apc_snmp all ${MAKE} -C bladecenter all @@ -26,6 +27,7 @@ all: # ${MAKE} -C ibmblade all ${MAKE} -C ilo all ${MAKE} -C ipmilan all + ${MAKE} -C lpar all ${MAKE} -C manual all ${MAKE} -C mcdata all # ${MAKE} -C rackswitch all @@ -41,6 +43,7 @@ all: # ${MAKE} -C zvm all install: all + ${MAKE} -C lib install ${MAKE} -C apc install ${MAKE} -C apc_snmp install ${MAKE} -C bladecenter install @@ -52,6 +55,7 @@ install: all # ${MAKE} -C ibmblade install ${MAKE} -C ilo install ${MAKE} -C ipmilan install + ${MAKE} -C lpar install ${MAKE} -C manual install ${MAKE} -C mcdata install # ${MAKE} -C rackswitch install @@ -67,6 +71,7 @@ install: all # ${MAKE} -C zvm install clean: + ${MAKE} -C lib clean ${MAKE} -C apc clean ${MAKE} -C apc_snmp clean ${MAKE} -C bladecenter clean @@ -78,6 +83,7 @@ clean: # ${MAKE} -C ibmblade clean ${MAKE} -C ilo clean ${MAKE} -C ipmilan clean + ${MAKE} -C lpar clean ${MAKE} -C manual clean ${MAKE} -C mcdata clean # ${MAKE} -C rackswitch clean diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py old mode 100644 new mode 100755 index 29c830f..4ac8be9 --- a/fence/agents/apc/fence_apc.py +++ b/fence/agents/apc/fence_apc.py @@ -1,829 +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: - res = "2\r1\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): - #return (NOT_COMPLETE, "1\r") - return (NOT_COMPLETE, "\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 944acdd..34dd24d 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 9ea0a7f..ce84f20 100644 --- a/fence/agents/drac/Makefile +++ b/fence/agents/drac/Makefile @@ -11,28 +11,40 @@ ############################################################################### ############################################################################### -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) install: all if [ ! -d ${sbindir} ]; then \ install -d ${sbindir}; \ fi - install -m755 ${TARGET} ${sbindir} + install -m755 ${TARGET1} ${TARGET2} ${sbindir} 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 4942d3b..089266e 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..0f6063d --- /dev/null +++ b/fence/agents/lib/Makefile @@ -0,0 +1,50 @@ +############################################################################### +############################################################################### +## +## 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) $(TARGET2) + +$(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) + +install: all + if [ ! -d ${DESTDIR}/usr/lib/fence ]; then \ + install -d ${DESTDIR}/usr/lib/fence; \ + fi + install -m755 ${TARGET1} ${TARGET2} ${DESTDIR}/usr/lib/fence + +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