X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=pcucontrol%2Freboot.py;h=2e6d2d543ec85770c1f2ed6c277a31e7529aa98f;hb=8e65cdcaaf08982f5f744297c009359ec74d31b5;hp=f753471db5177267858a5fad90b1f8fa10b41d0b;hpb=ac1e9bb99f3acb754054737870093606d56030a1;p=monitor.git diff --git a/pcucontrol/reboot.py b/pcucontrol/reboot.py index f753471..2e6d2d5 100755 --- a/pcucontrol/reboot.py +++ b/pcucontrol/reboot.py @@ -117,7 +117,7 @@ class Transport: HTTP = 3 IPAL = 4 - TELNET_TIMEOUT = 60 + TELNET_TIMEOUT = 120 def __init__(self, type, verbose): self.type = type @@ -204,6 +204,7 @@ class Transport: if self.transport != None: output = self.transport.read_until(expected, self.TELNET_TIMEOUT) if output.find(expected) == -1: + print "OUTPUT: --%s--" % output raise ErrorClass, "'%s' not found" % expected else: self.transport.write(buffer + "\r\n") @@ -218,6 +219,9 @@ class Transport: class PCUControl(Transport,PCUModel,PCURecord): + + supported_ports = [] + def __init__(self, plc_pcu_record, verbose, supported_ports=[]): PCUModel.__init__(self, plc_pcu_record) PCURecord.__init__(self, plc_pcu_record) @@ -275,13 +279,37 @@ class PCUControl(Transport,PCUModel,PCURecord): import traceback traceback.print_exc() return "EOF connection reset" + str(err) - + +class IPMI(PCUControl): + + supported_ports = [80,443,623] + + # TODO: get exit codes to determine success or failure... + def run(self, node_port, dryrun): + + if not dryrun: + cmd = "ipmitool -I lanplus -H %s -U %s -P '%s' power cycle" + p = os.popen(cmd % ( self.host, self.username, self.password) ) + result = p.read() + print "RESULT: ", result + else: + cmd = "ipmitool -I lanplus -H %s -U %s -P '%s' user list" + p = os.popen(cmd % ( self.host, self.username, self.password) ) + result = p.read() + print "RESULT: ", result + + if "Error" in result: + return result + else: + return 0 + class IPAL(PCUControl): """ This now uses a proprietary format for communicating with the PCU. I prefer it to Telnet, and Web access, since it's much lighter weight and, more importantly, IT WORKS!! HHAHHHAHAHAHAHAHA! """ + supported_ports = [23,80,9100] def format_msg(self, data, cmd): esc = chr(int('1b',16)) @@ -303,6 +331,37 @@ class IPAL(PCUControl): return ret def run(self, node_port, dryrun): + if self.type == Transport.IPAL: + return self.run_ipal(node_port, dryrun) + elif self.type == Transport.TELNET: + return self.run_telnet(node_port, dryrun) + else: + raise Exception("Unimplemented Transport for IPAL") + + def run_telnet(self, node_port, dryrun): + # TELNET version of protocol... + self.open(self.host) + ## XXX Some iPals require you to hit Enter a few times first + self.ifThenSend("Password >", "\r\n\r\n", ExceptionNotFound) + # Login + self.ifThenSend("Password >", self.password, ExceptionPassword) + self.transport.write("\r\n\r\n") + if not dryrun: # P# - Pulse relay + print "node_port %s" % node_port + self.ifThenSend("Enter >", + "P7", # % node_port, + ExceptionNotFound) + print "send newlines" + self.transport.write("\r\n\r\n") + print "after new lines" + # Get the next prompt + print "wait for enter" + self.ifElse("Enter >", ExceptionTimeout) + print "closing " + self.close() + return 0 + + def run_ipal(self, node_port, dryrun): import errno power_on = False @@ -329,7 +388,6 @@ class IPAL(PCUControl): if ret == '': raise Exception("Status returned 'another session already open' %s : %s" % (node_port, ret)) - if node_port < len(ret): status = ret[node_port] @@ -380,27 +438,6 @@ class IPAL(PCUControl): s.close() return 0 -# TELNET version of protocol... -# #self.open(self.host) -# ## XXX Some iPals require you to hit Enter a few times first -# #self.ifThenSend("Password >", "\r\n\r\n", ExceptionNotFound) -# # Login -# self.ifThenSend("Password >", self.password, ExceptionPassword) -# self.transport.write("\r\n\r\n") -# if not dryrun: # P# - Pulse relay -# print "node_port %s" % node_port -# self.ifThenSend("Enter >", -# "P7", # % node_port, -# ExceptionNotFound) -# print "send newlines" -# self.transport.write("\r\n\r\n") -# print "after new lines" -# # Get the next prompt -# print "wait for enter" -# self.ifElse("Enter >", ExceptionTimeout) -# print "closing " -# self.close() -# return 0 class APCEurope(PCUControl): def run(self, node_port, dryrun): @@ -498,6 +535,7 @@ class APCFolsom(PCUControl): return 0 class APCMaster(PCUControl): + supported_ports = [22,23] def run(self, node_port, dryrun): print "Rebooting %s" % self.host self.open(self.host, self.username) @@ -557,11 +595,13 @@ class APC(PCUControl): return ret class IntelAMT(PCUControl): + supported_ports = [16992] + def run(self, node_port, dryrun): cmd = command.CMD() - #[cmd_str = "IntelAMTSDK/Samples/RemoteControl/remoteControl" - cmd_str = "cmdamt/remoteControl" + # TODO: need to make this path universal; not relative to pwd. + cmd_str = "pcucontrol/models/intelamt/remoteControl" if dryrun: # NOTE: -p checks the power state of the host. @@ -582,6 +622,7 @@ class DRACRacAdm(PCUControl): return 0 class DRAC(PCUControl): + supported_ports = [22,443,5869] def run(self, node_port, dryrun): self.open(self.host, self.username) self.sendPassword(self.password) @@ -601,6 +642,7 @@ class DRAC(PCUControl): return 0 class HPiLO(PCUControl): + supported_ports = [22,443] def run(self, node_port, dryrun): self.open(self.host, self.username) self.sendPassword(self.password) @@ -622,6 +664,7 @@ class HPiLO(PCUControl): class HPiLOHttps(PCUControl): + supported_ports = [22,443] def run(self, node_port, dryrun): locfg = command.CMD() @@ -821,6 +864,7 @@ class BayTechCtrlC(PCUControl): return 0 class BayTech(PCUControl): + supported_ports = [22,23] def run(self, node_port, dryrun): self.open(self.host, self.username) self.sendPassword(self.password) @@ -851,6 +895,7 @@ class BayTech(PCUControl): return 0 class WTIIPS4(PCUControl): + supported_ports = [23] def run(self, node_port, dryrun): self.open(self.host) self.sendPassword(self.password, "Enter Password:") @@ -967,6 +1012,7 @@ class ePowerSwitchOld(PCUControl): return 0 class ePowerSwitch(PCUControl): + supported_ports = [80] def run(self, node_port, dryrun): self.url = "http://%s:%d/" % (self.host,80) uri = "%s:%d" % (self.host,80) @@ -1000,6 +1046,15 @@ class ePowerSwitch(PCUControl): self.close() return 0 +class ManualPCU(PCUControl): + supported_ports = [22,23,80,443,9100,16992] + + def run(self, node_port, dryrun): + if not dryrun: + # TODO: send email message to monitor admin requesting manual + # intervention. This should always be an option for ridiculous, + # custom jobs. + return 0 ### rebooting european BlackBox PSE boxes # Thierry Parmentelat - May 11 2005 @@ -1010,6 +1065,29 @@ class ePowerSwitch(PCUControl): # curl --http1.0 --basic --user : --data P=r \ # http://:/cmd.html && echo OK +# log in: + +## BB PSMaverick +class BlackBoxPSMaverick(PCUControl): + supported_ports = [80] + + def run(self, node_port, dryrun): + if not dryrun: + # send reboot signal. + cmd = "curl -s --data 'P%s=r' --anyauth --user '%s:%s' http://%s/config/home_f.html" % ( node_port, self.username, self.password, self.host) + else: + # else, just try to log in + cmd = "curl -s --anyauth --user '%s:%s' http://%s/config/home_f.html" % ( self.username, self.password, self.host) + + p = os.popen(cmd) + result = p.read() + print "RESULT: ", result + + if len(result.split()) > 3: + return 0 + else: + return result + def bbpse_reboot (pcu_ip,username,password,port_in_pcu,http_port, dryrun): global verbose @@ -1233,6 +1311,33 @@ def reboot_policy(nodename, continue_probe, dryrun): print "return true" return True +class Unknown(PCUControl): + supported_ports = [22,23,80,443,5869,9100,16992] + +def model_to_object(modelname): + if "AMT" in modelname: + return IntelAMT + elif "DS4-RPC" in modelname: + return BayTech + elif "ilo2" in modelname: + return HPiLO + elif "IP-41x" in modelname: + return IPAL + elif "AP79xx" in modelname or "Masterswitch" in modelname: + return APCMaster + elif "DRAC" in modelname: + return DRAC + elif "WTI" in modelname: + return WTIIPS4 + elif "ePowerSwitch" in modelname: + return ePowerSwitch + elif "ipmi" in modelname: + return IPMI + elif "bbsemaverick" in modelname: + return BlackBoxPSMaverick + else: + return Unknown + def reboot_test(nodename, values, continue_probe, verbose, dryrun): rb_ret = "" if 'plc_pcu_stats' in values: @@ -1258,11 +1363,11 @@ def reboot_test(nodename, values, continue_probe, verbose, dryrun): apc = APCBrazil(values, verbose, ['22', '23']) rb_ret = apc.reboot(values[nodename], dryrun) - elif values['pcu_id'] in [1221,1225,1220]: + elif values['pcu_id'] in [1221,1225,1220,1192]: apc = APCBerlin(values, verbose, ['22', '23']) rb_ret = apc.reboot(values[nodename], dryrun) - elif values['pcu_id'] in [1173,1240,47]: + elif values['pcu_id'] in [1173,1240,47,1363,1405,1401,1372,1371]: apc = APCFolsom(values, verbose, ['22', '23']) rb_ret = apc.reboot(values[nodename], dryrun) @@ -1330,7 +1435,17 @@ def reboot_test(nodename, values, continue_probe, verbose, dryrun): amt = IntelAMT(values, verbose, ['16992']) rb_ret = amt.reboot(values[nodename], dryrun) - # BlackBox PSExxx-xx (e.g. PSE505-FR) + elif continue_probe and values['model'].find("bbsemaverick") >=0: + print "TRYING BlackBoxPSMaverick" + bbe = BlackBoxPSMaverick(values, verbose, ['80']) + rb_ret = bbe.reboot(values[nodename], dryrun) + + elif continue_probe and values['model'].find("ipmi") >=0: + + print "TRYING IPMI" + ipmi = IPMI(values, verbose, ['80', '443', '623']) + rb_ret = ipmi.reboot(values[nodename], dryrun) + elif continue_probe and values['model'].find("ePowerSwitch") >=0: # TODO: allow a different port than http 80. if values['pcu_id'] in [1089, 1071, 1046, 1035, 1118]: