Thanks Ramon and Mohd. Attached is our latest, heavily refactored
version of this agent. outlet naming and grouping should all work now -
on every 7900 series switch. Please try it. Just rename it fence_apc
when you drop it into /sbin and make certain the executable bits are set.
-J
Ramon van Alteren wrote:
Hi,
Mohd Irwan Jamaluddin wrote:
I'm running Red Hat Cluster Suite on RHEL 4 U3 with APC 7950
( http://www.apc.com/resource/include/techspec_index.cfm?base_sku=AP7950 )
as the fencing device. The version of my fence package is 1.32.18-0.
I try to execute some fence_apc commands but I've got errors. Below are the details:
[root@orarac01 ~]# fence_apc -a 10.0.6.150 -l apc -p apc -n 02 \
-o Reboot -T -v
failed: unrecognised Reboot response
Same error occured for On/Off option.
Also, I found a weird problem if I put "2" instead of "02" for the Outlet Number option (-n option).
Below are the error message:
[root@orarac01 ~]# fence_apc -a 10.0.6.150 -l apc -p apc -n 2 \
-o Reboot -T -v
failed: unrecognised menu response
H
Anyone have ever faced similar problem with me? Here I attached the apclog for reference.
we're running fencing through an apc 7920 which I assume is similar.
I've hacked up the fence_apc until it worked, it accepts outlet names
and numbers if I remember correctly.
I've attached ours to the mail, it's originally from cluster-1.02 but
works for me on cluster-1.03 as well.
No guarantees implied ;-) WFM, YMMV
Thanks in advanced for your response.
Hope it helps
Ramon
------------------------------------------------------------------------
#!/usr/bin/perl
###############################################################################
###############################################################################
##
## 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.
##
###############################################################################
###############################################################################
use Getopt::Std;
use Net::Telnet ();
# Get the program name from $0 and strip directory names
$_=$0;
s/.*\///;
my $pname = $_;
# Change these if the text returned by your equipment is different.
# Test by running script with options -t -v and checking /tmp/apclog
my $immediate = 'immediate'; # # Or 'delayed' - action string prefix on menu
my $masterswitch = 'masterswitch plus '; # 'Device Manager' option to choose
my $login_prompt = '/: /';
my $cmd_prompt = '/> /';
my $max_open_tries = 3; # How many telnet attempts to make. Because the
# APC can fail repeated login attempts, this number
# should be more than 1
my $open_wait = 5; # Seconds to wait between each telnet attempt
my $telnet_timeout = 2; # Seconds to wait for matching telent response
my $debuglog = '/tmp/apclog';# Location of debugging log when in verbose mode
$opt_o = 'reboot'; # Default fence action.
my $logged_in = 0;
my $t = new Net::Telnet;
# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and
# "#END_VERSION_GENERATION" It is generated by the Makefile
#BEGIN_VERSION_GENERATION
$FENCE_RELEASE_NAME="1.02.00";
$REDHAT_COPYRIGHT=("Copyright (C) Red Hat, Inc. 2004 All rights reserved.");
$BUILD_DATE="(built Wed Jun 28 13:17:53 CEST 2006)";
#END_VERSION_GENERATION
sub usage
{
print "Usage:\n";
print "\n";
print "$pname [options]\n";
print "\n";
print "Options:\n";
print " -a <ip> IP address or hostname of MasterSwitch\n";
print " -h usage\n";
print " -l <name> Login name\n";
print " -n <num> Outlet number to change: [<switch>:]<outlet> \n";
print " -o <string> Action: Reboot (default), Off or On\n";
print " -p <string> Login password\n";
print " -q quiet mode\n";
print " -T Test mode (cancels action)\n";
print " -V version\n";
print " -v Log to file /tmp/apclog\n";
exit 0;
}
sub fail
{
($msg)=@_;
print $msg."\n" unless defined $opt_q;
if (defined $t)
{
# make sure we don't get stuck in a loop due to errors
$t->errmode('return');
logout() if $logged_in;
$t->close
}
exit 1;
}
sub fail_usage
{
($msg)=@_;
print STDERR $msg."\n" if $msg;
print STDERR "Please use '-h' for usage.\n";
exit 1;
}
sub version
{
print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n";
print "$SISTINA_COPYRIGHT\n" if ( $SISTINA_COPYRIGHT );
exit 0;
}
sub login
{
for (my $i=0; $i<$max_open_tries; $i++)
{
$t->open($opt_a);
($_) = $t->waitfor($login_prompt);
# Expect 'User Name : '
if (! /name/i) {
$t->close;
sleep($open_wait);
next;
}
$t->print($opt_l);
($_) = $t->waitfor($login_prompt);
# Expect 'Password : '
if (! /password/i ) {
$t->close;
sleep($open_wait);
next;
}
# Send password
$t->print($opt_p);
(my $dummy, $_) = $t->waitfor('/(>|(?i:user name|password)\s*:) /');
if (/> /)
{
$logged_in = 1;
# send newline to flush prompt
$t->print("");
return;
}
else
{
fail "invalid username or password";
}
}
fail "failed: telnet failed: ". $t->errmsg."\n"
}
# print_escape_char() -- utility subroutine for sending the 'Esc' character
sub print_escape_char
{
# The APC menu uses "<esc>" to go 'up' menues. We must set
# the output_record_separator to "" so that "\n" is not printed
# after the "<esc>" character
$ors=$t->output_record_separator;
$t->output_record_separator("");
$t->print("\x1b"); # send escape
$t->output_record_separator("$ors");
}
# Determine if the switch is a working state. Also check to make sure that
# the switch has been specified in the case that there are slave switches
# present. This assumes that we are at the main menu.
sub identify_switch
{
($_) = $t->waitfor($cmd_prompt);
print_escape_char();
# determine what type of switch we are dealling with
($_) = $t->waitfor($cmd_prompt);
if ( /Switched Rack PDU: Communication Established/i)
{
# No further test needed
}
elsif ( /MS plus 1 : Serial Communication Established/i )
{
if ( defined $switchnum )
{
$masterswitch = $masterswitch . $switchnum;
}
elsif ( /MS plus [^1] : Serial Communication Established/i )
{
fail "multiple switches detected. 'switch' must be defined.";
}
else
{
$switchnum = 1;
}
}
else
{
fail "APC is in undetermined state"
}
# send a newline to cause APC to reprint the menu
$t->print("");
}
# Navigate through menus to the appropriate outlet control menu of the apc
# MasterSwitch and 79xx series switches. Uses multi-line (mostly)
# case-insensitive matches to recognise menus and works out what option number
# to select from each menu.
sub navigate
{
# Limit the ammount of menu depths to 20. We should never be this deep
for(my $i=20; $i ; $i--)
{
# Get the new text from the menu
($_) = $t->waitfor($cmd_prompt);
# Identify next option
if (
# "Control Console", "1- Device Manager"
/--\s*control console.*(\d+)\s*-\s*device manager/is ||
# "Device Manager", "2- Outlet Control"
/--\s*device manager.*(\d+)\s*-\s*outlet control/is ||
#
# APC MasterSwitch Menus
#
# "Device Manager", "1- MasterSwitch plus 1"
/--\s*device manager.*(\d+)\s*-\s*$masterswitch/is ||
# "Device Manager", "1- Cluster Node 0 ON"
/--\s*(?:device manager|$masterswitch).*(\d+)\s*-\s+Outlet\s+$switchnum:$opt_n\D[^\n]*\s(?-i:ON|OFF)\*?\s/ism ||
# "MasterSwitch plus 1", "1- Outlet 1:1 Outlet #1 ON"
/--\s*$masterswitch.*(\d+)\s*-\s*Outlet\s+$switchnum:$opt_n\s[^\n]*\s(?-i:ON|OFF)\*?\s/ism ||
# Administrator outlet control menu
/--\s*Outlet $switchnum:$opt_n\D.*(\d+)\s*-\s*outlet control\s*$switchnum:?$opt_n\D/ism ||
#
# APC 79XX Menus
#
# "3- Outlet Control/Configuration"
/--\s*device manager.*(\d+)\s*-\s*Outlet Control/is ||
# "Device Manager", "1- Cluster Node 0 ON"
/--\s*Outlet Control.*(\d+)\s*-\s+Outlet\s+$opt_n\D[^\n]*\s(?-i:ON|OFF)\*?\s/ism ||
# "Device Manager", "1- <name> ON"
/--\s*Outlet Control.*(\d+)\s*-\s+$opt_n\D[^\n]*\s(?-i:ON|OFF)\*?\s/ism ||
# Administrator Outlet Control menu
/--\s*Outlet $opt_n\D.*(\d+)\s*-\s*control\s*outlet\s+$opt_n\D/ism ||
/--\s*Outlet $opt_n\D.*(\d+)\s*-\s*control\s*outlet/ism
) {
$t->print($1);
next;
}
# "Outlet Control X:N", "4- Immediate Reboot"
if (
/(\d+)\s*-\s*immediate $opt_o/is ||
/--\s*$opt_n.*(\d+)\s*-\s*immediate\s*$opt_o/is ||
/--\s*Control Outlet\D.*(\d+)\s*-\s*Immediate\s*$opt_o/is
) {
$t->print($1);
last;
}
fail "failed: unrecognised menu response\n";
}
}
sub logout
{
# send a newline to make sure that we refresh the menus
# ($t->waitfor() can hang otherwise)
$t->print("");
# Limit the ammount of menu depths to 20. We should never be this deep
for(my $i=20; $i ; $i--)
{
# Get the new text from the menu
($_) = $t->waitfor($cmd_prompt);
if (
# "Control Console", "4- Logout"
/--\s*control console.*(\d+)\s*-\s*Logout/is
) {
$t->print($1);
last;
}
else
{
print_escape_char();
next;
}
}
}
sub action
{
# "Enter 'YES' to continue or <ENTER> to cancel : "
($_) = $t->waitfor('/: /');
if (! /.*immediate $opt_o.*YES.*to continue/si ) {
fail "failed: unrecognised $opt_o response\n";
}
# Test mode?
$t->print($opt_T?'NO':'YES');
# "Success", "Press <ENTER> to continue..."
($_) = $t->waitfor('/continue/');
$t->print('');
if (defined $opt_T) {
logout();
print "success: test outlet $opt_n $opt_o\n" unless defined $opt_q;
$t->close;
# Allow the APC some time to clean connection
# before next login.
sleep 1;
exit 0;
} elsif ( /Success/i ) {
logout();
print "success: outlet $opt_n $opt_o\n" unless defined $opt_q;
$t->close;
# Allow the APC some time to clean connection
# before next login.
sleep 1;
exit 0;
}
fail "failed: unrecognised action response\n";
}
sub get_options_stdin
{
my $opt;
my $line = 0;
while( defined($in = <>) )
{
$_ = $in;
chomp;
# strip leading and trailing whitespace
s/^\s*//;
s/\s*$//;
# skip comments
next if /^#/;
$line+=1;
$opt=$_;
next unless $opt;
($name,$val)=split /\s*=\s*/, $opt;
if ( $name eq "" )
{
print STDERR "parse error: illegal name in option $line\n";
exit 2;
}
# DO NOTHING -- this field is used by fenced
elsif ($name eq "agent" )
{
}
elsif ($name eq "ipaddr" )
{
$opt_a = $val;
}
elsif ($name eq "login" )
{
$opt_l = $val;
}
elsif ($name eq "option" )
{
$opt_o = $val;
}
elsif ($name eq "passwd" )
{
$opt_p = $val;
}
elsif ($name eq "port" )
{
$opt_n = $val;
}
elsif ($name eq "switch" )
{
$switchnum = $val;
}
elsif ($name eq "test" )
{
$opt_T = $val;
}
elsif ($name eq "verbose" )
{
$opt_v = $val;
}
# Excess name/vals will fail
else
{
fail "parse error: unknown option \"$opt\"";
}
}
}
sub telnet_error
{
fail "failed: telnet returned: ".$t->errmsg."\n";
}
### MAIN #######################################################
if (@ARGV > 0) {
getopts("a:hl:n:o:p:qTvV") || fail_usage ;
usage if defined $opt_h;
version if defined $opt_V;
fail_usage "Unkown parameter." if (@ARGV > 0);
fail_usage "No '-a' flag specified." unless defined $opt_a;
fail_usage "No '-n' flag specified." unless defined $opt_n;
fail_usage "No '-l' flag specified." unless defined $opt_l;
fail_usage "No '-p' flag specified." unless defined $opt_p;
fail_usage "Unrecognised action '$opt_o' for '-o' flag"
unless $opt_o =~ /^(Off|On|Reboot)$/i;
if ( $opt_n =~ /(\d+):(\d+)/ ) {
$switchnum=($1);
$opt_n = ($2);
}
} else {
get_options_stdin();
fail "failed: no IP address" unless defined $opt_a;
fail "failed: no plug number" unless defined $opt_n;
fail "failed: no login name" unless defined $opt_l;
fail "failed: no password" unless defined $opt_p;
fail "failed: unrecognised action: $opt_o"
unless $opt_o =~ /^(Off|On|Reboot)$/i;
}
$t->timeout($telnet_timeout);
$t->input_log($debuglog) if $opt_v;
$t->errmode('return');
&login;
&identify_switch;
# Abort on failure beyond here
$t->errmode(\&telnet_error);
&navigate;
&action;
exit 0;
------------------------------------------------------------------------
--
Linux-cluster mailing list
Linux-cluster@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/linux-cluster
#!/usr/bin/python
###############################################################################
###############################################################################
##
## Copyright (C) 2006 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.
##
###############################################################################
###############################################################################
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
# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and
# "#END_VERSION_GENERATION" It is generated by the Makefile
#BEGIN_VERSION_GENERATION
FENCE_RELEASE_NAME="New APC Agent - test release"
REDHAT_COPYRIGHT=""
BUILD_DATE="September 21, 2006"
#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 = ""
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 -----"
CONTROL_OUTLET = "- Control Outlet -----"
CONTROL_OUTLET_2 = "- Outlet Control "
COMMAND_SUCCESS = "Command successfully issued."
COMMAND_SUCCESS_2 = " Success"
CONFIRM = "Enter 'YES' to continue or <ENTER> to cancel :"
CONTINUE = "Press <ENTER> to continue..."
SCREEN_END = "<ESC>- Main Menu, <ENTER>- Refresh, <CTRL-L>- Event Log"
SCREEN_END_2 = "<ESC>- Back, <ENTER>- Refresh, <CTRL-L>- Event Log"
USERNAME = "User Name :"
PASSWORD = "Password :"
MASTER = "------- MasterSwitch"
CONTINUE_INDEX = 0
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 <ipaddress> 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 " -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 main():
global address, login, passwd, port, action, verbose, logfile, switchnum
if len(sys.argv) > 1:
try:
opts, args = getopt.getopt(sys.argv[1:], "a:hl:o:n:p: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 == "-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 == "" or port == "":
usage()
sys.exit()
else: #Take args from stdin...
params = {}
#place params in dict
for line in sys.stdin:
val = line.split("=")
params[val[0]] = val[1]
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:
passwd = params["passwd"]
except KeyError, e:
sys.stderr.write("FENCE: Missing passwd param 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
### 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):
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):
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:
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:
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_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 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
if __name__ == "__main__":
main()
--
Linux-cluster mailing list
Linux-cluster@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/linux-cluster