changes for 3.0
[monitor.git] / reboot.py
index 98f74af..ba641c4 100755 (executable)
--- a/reboot.py
+++ b/reboot.py
@@ -8,17 +8,16 @@ import os, sys
 import xml, xmlrpclib
 import errno, time, traceback
 import urllib2
 import xml, xmlrpclib
 import errno, time, traceback
 import urllib2
+import urllib
 import threading, popen2
 import array, struct
 import threading, popen2
 import array, struct
-#from socket import *
-import socket
 import plc
 import base64
 from subprocess import PIPE, Popen
 import ssh.pxssh as pxssh
 import ssh.pexpect as pexpect
 import plc
 import base64
 from subprocess import PIPE, Popen
 import ssh.pxssh as pxssh
 import ssh.pexpect as pexpect
-
-plc_lock = threading.Lock()
+import socket
+import moncommands 
 
 # Use our versions of telnetlib and pyssh
 sys.path.insert(0, os.path.dirname(sys.argv[0]))
 
 # Use our versions of telnetlib and pyssh
 sys.path.insert(0, os.path.dirname(sys.argv[0]))
@@ -116,6 +115,7 @@ class Transport:
        TELNET = 1
        SSH    = 2
        HTTP   = 3
        TELNET = 1
        SSH    = 2
        HTTP   = 3
+       IPAL   = 4
 
        TELNET_TIMEOUT = 60
 
 
        TELNET_TIMEOUT = 60
 
@@ -124,10 +124,6 @@ class Transport:
                self.verbose = verbose
                self.transport = None
 
                self.verbose = verbose
                self.transport = None
 
-#      def __del__(self):
-#              if self.transport:
-#                      self.close()
-
        def open(self, host, username=None, password=None, prompt="User Name"):
                transport = None
 
        def open(self, host, username=None, password=None, prompt="User Name"):
                transport = None
 
@@ -236,11 +232,16 @@ class PCUControl(Transport,PCUModel,PCURecord):
                        elif '443' in supported_ports and self.portstatus['443'] == "open":
                                type = Transport.HTTP
                        elif '5869' in supported_ports and self.portstatus['5869'] == "open":
                        elif '443' in supported_ports and self.portstatus['443'] == "open":
                                type = Transport.HTTP
                        elif '5869' in supported_ports and self.portstatus['5869'] == "open":
-                               # For DRAC cards.  not sure how much it's used in the
-                               # protocol.. but racadm opens this port.
+                               # For DRAC cards. Racadm opens this port.
+                               type = Transport.HTTP
+                       elif '9100' in supported_ports and self.portstatus['9100'] == "open":
+                               type = Transport.IPAL
+                       elif '16992' in supported_ports and self.portstatus['16992'] == "open":
                                type = Transport.HTTP
                        else:
                                raise ExceptionPort("Unsupported Port: No transport from open ports")
                                type = Transport.HTTP
                        else:
                                raise ExceptionPort("Unsupported Port: No transport from open ports")
+               else:
+                       raise Exception("No Portstatus: No transport because no open ports")
                Transport.__init__(self, type, verbose)
 
        def run(self, node_port, dryrun):
                Transport.__init__(self, type, verbose)
 
        def run(self, node_port, dryrun):
@@ -274,108 +275,143 @@ class PCUControl(Transport,PCUModel,PCURecord):
                        import traceback
                        traceback.print_exc()
                        return "EOF connection reset" + str(err)
                        import traceback
                        traceback.print_exc()
                        return "EOF connection reset" + str(err)
-               #except Exception, err:
-               #       if self.verbose:
-               #               logger.debug("reboot: Exception")
-               #               logger.debug(err)
-               #       if self.transport:
-               #               self.transport.close()
-               #       import traceback
-               #       traceback.print_exc()
-               #       return  "generic exception; unknown problem."
-
+               except:
+                       from nodecommon import email_exception
+                       email_exception()
+                       raise Exception('unknown')
                
 class IPAL(PCUControl):
                
 class IPAL(PCUControl):
-       def run(self, node_port, dryrun):
-               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
-                       self.ifThenSend("Enter >", 
-                                                       "P%d" % node_port, 
-                                                       ExceptionNotFound)
-               # Get the next prompt
-               self.ifElse("Enter >", ExceptionTimeout)
-
-               self.close()
-               return 0
-
-def ipal_reboot(ip, password, port, dryrun):
-       global verbose
-       global plc_lock
-       telnet = None
-
-       try:
-               #plc_lock.acquire()
-               #print "lock acquired"
-
-               #try:
-                       #telnet = telnetlib.Telnet(ip) # , timeout=TELNET_TIMEOUT)
-               telnet = telnetlib.Telnet(ip, timeout=TELNET_TIMEOUT)
-               #except:
-               #       import traceback
-               #       traceback.print_exc()
+       """ 
+               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!
+       """
 
 
+       def format_msg(self, data, cmd):
+               esc = chr(int('1b',16))
+               return "%c%s%c%s%c" % (esc, self.password, esc, data, cmd) # esc, 'q', chr(4))
+       
+       def recv_noblock(self, s, count):
+               import errno
 
 
-               telnet.set_debuglevel(verbose)
+               try:
+                       # TODO: make sleep backoff, before stopping.
+                       time.sleep(8)
+                       ret = s.recv(count, socket.MSG_DONTWAIT)
+               except socket.error, e:
+                       if e[0] == errno.EAGAIN:
+                               #raise Exception(e[1])
+                               raise ExceptionNotFound(e[1])
+                       else:
+                               # TODO: not other exceptions.
+                               raise Exception(e)
+               return ret
 
 
-               # XXX Some iPals require you to hit Enter a few times first
-               telnet_answer(telnet, "Password >", "\r\n\r\n")
+       def run(self, node_port, dryrun):
+               import errno
 
 
-               # Login
-               telnet_answer(telnet, "Password >", password)
+               power_on = False
 
 
-               # XXX Some iPals require you to hit Enter a few times first
-               telnet.write("\r\n\r\n")
+               print "open socket"
+               s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+               try:
+                       print "connect"
+                       s.connect((self.host, 9100))
+               except socket.error, e:
+                       s.close()
+                       if e[0] == errno.ECONNREFUSED:
+                               # cannot connect to remote host
+                               raise Exception(e[1])
+                       elif e[0] == errno.ETIMEDOUT:
+                               raise ExceptionTimeout(e[1])
+                       else:
+                               # TODO: what other conditions are there?
+                               raise Exception(e)
+                               
+               # get current status
+               print "Checking status"
+               s.send(self.format_msg("", 'O'))
+               ret = self.recv_noblock(s, 8)
+               print "Current status is '%s'" % ret
+
+               if ret == '':
+                       raise Exception("Status returned 'another session already open' on %s %s : %s" % (self.host, node_port, ret))
+                       
+                               
+               if node_port < len(ret):
+                       status = ret[node_port]
+                       if status == '1':
+                               # up
+                               power_on = True
+                       elif status == '0':
+                               # down
+                               power_on = False
+                       elif status == '6':
+                               raise ExceptionPort("IPAL reported 'Cable Error' on %s socket %s : %s" % (self.host, node_port, ret))
+                       else:
+                               raise Exception("Unknown status for PCU %s socket %s : %s" % (self.host, node_port, ret))
+               else:
+                       raise Exception("Mismatch between configured port and PCU %s status: %s %s" % (self.host, node_port, ret))
+                       
 
 
-               # P# - Pulse relay
                if not dryrun:
                if not dryrun:
-                       telnet_answer(telnet, "Enter >", "P%d" % port)
-
-               telnet.read_until("Enter >", TELNET_TIMEOUT)
+                       if power_on:
+                               print "Pulsing %s" % node_port
+                               s.send(self.format_msg("%s" % node_port, 'P'))
+                       else:
+                               # NOTE: turn power on ; do not pulse the port.
+                               print "Power was off, so turning on ..."
+                               s.send(self.format_msg("%s" % node_port, 'E'))
+                               #s.send(self.format_msg("%s" % node_port, 'P'))
+
+                       print "Receiving response."
+                       ret = self.recv_noblock(s, 8)
+                       print "Current status is '%s'" % ret
+
+                       if node_port < len(ret):
+                               status = ret[node_port]
+                               if status == '1':
+                                       # up
+                                       power_on = True
+                               elif status == '0':
+                                       # down
+                                       power_on = False
+                               elif status == '6':
+                                       raise ExceptionPort("IPAL reported 'Cable Error' on %s socket %s : %s" % (self.host, node_port, ret))
+                               else:
+                                       raise Exception("Unknown status for PCU %s socket %s : %s" % (self.host, node_port, ret))
+                       else:
+                               raise Exception("Mismatch between configured port and PCU %s status: %s %s" % (self.host, node_port, ret))
 
 
-               # Close
-               telnet.close()
+                       if power_on:
+                               return 0
+                       else:
+                               return "Failed Power On"
 
 
-               #print "lock released"
-               #plc_lock.release()
+               s.close()
                return 0
 
                return 0
 
-       except EOFError, err:
-               if verbose:
-                       logger.debug("ipal_reboot: EOF")
-                       logger.debug(err)
-               telnet.close()
-               import traceback
-               traceback.print_exc()
-               #print "lock released"
-               #plc_lock.release()
-               return errno.ECONNRESET
-       except socket.error, err:
-               logger.debug("ipal_reboot: Socket Error")
-               logger.debug(err)
-               import traceback
-               traceback.print_exc()
-
-               return errno.ETIMEDOUT
-               
-       except Exception, err:
-               if verbose:
-                       logger.debug("ipal_reboot: Exception")
-                       logger.debug(err)
-               if telnet:
-                       telnet.close()
-               import traceback
-               traceback.print_exc()
-               #print "lock released"
-               #plc_lock.release()
-               return  "ipal error"
+# 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):
 
 class APCEurope(PCUControl):
        def run(self, node_port, dryrun):
@@ -474,6 +510,7 @@ class APCFolsom(PCUControl):
 
 class APCMaster(PCUControl):
        def run(self, node_port, dryrun):
 
 class APCMaster(PCUControl):
        def run(self, node_port, dryrun):
+               print "Rebooting %s" % self.host
                self.open(self.host, self.username)
                self.sendPassword(self.password)
 
                self.open(self.host, self.username)
                self.sendPassword(self.password)
 
@@ -530,6 +567,23 @@ class APC(PCUControl):
                else:
                        return ret
 
                else:
                        return ret
 
+class IntelAMT(PCUControl):
+       def run(self, node_port, dryrun):
+
+               cmd = moncommands.CMD()
+               #[cmd_str = "IntelAMTSDK/Samples/RemoteControl/remoteControl"
+               cmd_str = "cmdamt/remoteControl"
+
+               if dryrun:
+                       # NOTE: -p checks the power state of the host.
+                       # TODO: parse the output to find out if it's ok or not.
+                       cmd_str += " -p http://%s:16992/RemoteControlService  -user admin -pass '%s' " % (self.host, self.password )
+               else:
+                       cmd_str += " -A http://%s:16992/RemoteControlService -user admin -pass '%s' " % (self.host, self.password )
+                       
+               print cmd_str
+               return cmd.system(cmd_str, self.TELNET_TIMEOUT)
+
 class DRACRacAdm(PCUControl):
        def run(self, node_port, dryrun):
 
 class DRACRacAdm(PCUControl):
        def run(self, node_port, dryrun):
 
@@ -581,39 +635,55 @@ class HPiLO(PCUControl):
 class HPiLOHttps(PCUControl):
        def run(self, node_port, dryrun):
 
 class HPiLOHttps(PCUControl):
        def run(self, node_port, dryrun):
 
-               cmd = "cmdhttps/locfg.pl -s %s -f %s -u %s -p %s" % (
+               locfg = moncommands.CMD()
+               cmd = "cmdhttps/locfg.pl -s %s -f %s -u %s -p '%s' | grep 'MESSAGE' | grep -v 'No error'" % (
                                        self.host, "iloxml/Get_Network.xml", 
                                        self.username, self.password)
                                        self.host, "iloxml/Get_Network.xml", 
                                        self.username, self.password)
-               p_ilo  = Popen(cmd, stdout=PIPE, shell=True)
-               cmd2 = "grep 'MESSAGE' | grep -v 'No error'"
-               p_grep = Popen(cmd2, stdin=p_ilo.stdout, stdout=PIPE, stderr=PIPE, shell=True)
-               sout, serr = p_grep.communicate()
+               sout, serr = locfg.run_noexcept(cmd)
 
 
-               p_ilo.wait()
-               p_grep.wait()
                if sout.strip() != "":
                        print "sout: %s" % sout.strip()
                        return sout.strip()
 
                if not dryrun:
                if sout.strip() != "":
                        print "sout: %s" % sout.strip()
                        return sout.strip()
 
                if not dryrun:
-                       cmd = "cmdhttps/locfg.pl -s %s -f %s -u %s -p %s" % (
-                                       self.host, "iloxml/Reset_Server.xml", 
-                                       self.username, self.password)
-                       p_ilo = Popen(cmd, stdin=PIPE, stdout=PIPE, shell=True)
-                       cmd2 = "grep 'MESSAGE' | grep -v 'No error'"
-                       p_grep = Popen(cmd2, stdin=p_ilo.stdout, stdout=PIPE, stderr=PIPE)
-                       sout, serr = p_grep.communicate()
-                       p_ilo.wait()
-                       p_grep.wait()
+                       locfg = moncommands.CMD()
+                       cmd = "cmdhttps/locfg.pl -s %s -f %s -u %s -p '%s' | grep 'MESSAGE' | grep -v 'No error'" % (
+                                               self.host, "iloxml/Reset_Server.xml", 
+                                               self.username, self.password)
+                       sout, serr = locfg.run_noexcept(cmd)
 
                        if sout.strip() != "":
                                print "sout: %s" % sout.strip()
 
                        if sout.strip() != "":
                                print "sout: %s" % sout.strip()
-                               return sout.strip()
+                               #return sout.strip()
+               return 0
+
+class BayTechAU(PCUControl):
+       def run(self, node_port, dryrun):
+               self.open(self.host, self.username, None, "Enter user name:")
+               self.sendPassword(self.password, "Enter Password:")
+
+               #self.ifThenSend("RPC-16>", "Status")
+               self.ifThenSend("RPC3-NC>", "Reboot %d" % node_port)
+
+               # Reboot Outlet  N        (Y/N)?
+               if dryrun:
+                       self.ifThenSend("(Y/N)?", "N")
+               else:
+                       self.ifThenSend("(Y/N)?", "Y")
+               self.ifThenSend("RPC3-NC>", "")
 
 
+               self.close()
                return 0
 
 class BayTechGeorgeTown(PCUControl):
        def run(self, node_port, dryrun):
                return 0
 
 class BayTechGeorgeTown(PCUControl):
        def run(self, node_port, dryrun):
+               # this initial open/close is to prevent things from raising an
+               # exception.  the pcu always is weird during the first connection, and
+               # even if it's not, what does it matter to open a second connection
+               # right away?
+               self.open(self.host, self.username, None, "Enter user name:")
+               self.close()
+               time.sleep(1)
                self.open(self.host, self.username, None, "Enter user name:")
                self.sendPassword(self.password, "Enter Password:")
 
                self.open(self.host, self.username, None, "Enter user name:")
                self.sendPassword(self.password, "Enter Password:")
 
@@ -652,6 +722,7 @@ class BayTechCtrlCUnibe(PCUControl):
 
                # Control Outlets  (5 ,1).........5
                try:
 
                # Control Outlets  (5 ,1).........5
                try:
+                       #index = s.expect("Enter Request")
                        index = s.expect(["Enter Request :"])
 
                        if index == 0:
                        index = s.expect(["Enter Request :"])
 
                        if index == 0:
@@ -666,7 +737,8 @@ class BayTechCtrlCUnibe(PCUControl):
                                        print "Reboot %d" % node_port
                                        s.send("Reboot %d\r\n" % node_port)
 
                                        print "Reboot %d" % node_port
                                        s.send("Reboot %d\r\n" % node_port)
 
-                                       index = s.expect(["(Y/N)?"])
+                                       time.sleep(5)
+                                       index = s.expect(["\(Y/N\)\?", "Port in use", "DS-RPC>"])
                                        if index == 0:
                                                if dryrun:
                                                        print "sending N"
                                        if index == 0:
                                                if dryrun:
                                                        print "sending N"
@@ -674,16 +746,21 @@ class BayTechCtrlCUnibe(PCUControl):
                                                else:
                                                        print "sending Y"
                                                        s.send("Y\r\n")
                                                else:
                                                        print "sending Y"
                                                        s.send("Y\r\n")
+                                       elif index == 1:
+                                               raise ExceptionPrompt("PCU Reported 'Port in use.'")
+                                       elif index == 2:
+                                               raise ExceptionSequence("Issued command 'Reboot' failed.")
 
 
-                               #index = s.expect(["DS-RPC>"])
+                               time.sleep(5)
+                               index = s.expect(["DS-RPC>"])
                                #print "got prompt back"
 
                        s.close()
 
                except pexpect.EOF:
                                #print "got prompt back"
 
                        s.close()
 
                except pexpect.EOF:
-                       raise ExceptionPrompt("EOF before 'Enter Request' Prompt")
+                       raise ExceptionPrompt("EOF before expected Prompt")
                except pexpect.TIMEOUT:
                except pexpect.TIMEOUT:
-                       raise ExceptionPrompt("Timeout before 'Enter Request' Prompt")
+                       raise ExceptionPrompt("Timeout before expected Prompt")
 
                return 0
 
 
                return 0
 
@@ -703,44 +780,61 @@ class BayTechCtrlC(PCUControl):
                # Otherwise, the login succeeded.
 
                # Send a ctrl-c to the remote process.
                # Otherwise, the login succeeded.
 
                # Send a ctrl-c to the remote process.
-               print "sending ctrl-c"
+               print "SENDING ctrl-c"
                s.send(chr(3))
 
                # Control Outlets  (5 ,1).........5
                try:
                s.send(chr(3))
 
                # Control Outlets  (5 ,1).........5
                try:
+                       print "EXPECTING: ", "Enter Request :"
                        index = s.expect(["Enter Request :"])
 
                        if index == 0:
                        index = s.expect(["Enter Request :"])
 
                        if index == 0:
-                               print "5"
+                               print "SENDING: 5"
                                s.send("5\r\n")
                                s.send("5\r\n")
-                               index = s.expect(["DS-RPC>", "Enter user name:"])
+                               print "EXPECTING: ", "DS-RPC>"
+                               index = s.expect(["DS-RPC>", "Enter user name:", "Port in use."])
                                if index == 1:
                                        print "sending username"
                                        s.send(self.username + "\r\n")
                                        index = s.expect(["DS-RPC>"])
                                if index == 1:
                                        print "sending username"
                                        s.send(self.username + "\r\n")
                                        index = s.expect(["DS-RPC>"])
+                               elif index == 2:
+                                       raise ExceptionPrompt("PCU Reported 'Port in use.'")
 
                                if index == 0:
 
                                if index == 0:
-                                       print "Reboot %d" % node_port
+                                       print "SENDING: Reboot %d" % node_port
                                        s.send("Reboot %d\r\n" % node_port)
 
                                        s.send("Reboot %d\r\n" % node_port)
 
-                                       index = s.expect(["(Y/N)?"])
+                                       print "SLEEPING: 5"
+                                       time.sleep(5)
+                                       print "EXPECTING: ", "Y/N?"
+                                       index = s.expect(["\(Y/N\)\?", "Port in use", "DS-RPC>"])
                                        if index == 0:
                                                if dryrun:
                                                        print "sending N"
                                                        s.send("N\r\n")
                                                else:
                                        if index == 0:
                                                if dryrun:
                                                        print "sending N"
                                                        s.send("N\r\n")
                                                else:
-                                                       print "sending Y"
+                                                       print "SENDING: Y"
                                                        s.send("Y\r\n")
                                                        s.send("Y\r\n")
-
-                               #index = s.expect(["DS-RPC>"])
-                               #print "got prompt back"
+                                       elif index == 1:
+                                               raise ExceptionPrompt("PCU Reported 'Port in use.'")
+                                       elif index == 2:
+                                               raise ExceptionSequence("Issued command 'Reboot' failed.")
+
+                               # NOTE: for some reason, the script times out with the
+                               # following line.  In manual tests, it works correctly, but
+                               # with automated tests, evidently it fails.
+                               print "SLEEPING: 5"
+                               time.sleep(5)
+                               #print "TOTAL--", s.allstr, "--EOT"
+                               index = s.expect(["DS-RPC>"])
+                               print "got prompt back"
 
                        s.close()
 
                except pexpect.EOF:
                        raise ExceptionPrompt("EOF before 'Enter Request' Prompt")
                except pexpect.TIMEOUT:
 
                        s.close()
 
                except pexpect.EOF:
                        raise ExceptionPrompt("EOF before 'Enter Request' Prompt")
                except pexpect.TIMEOUT:
-                       raise ExceptionPrompt("Timeout before 'Enter Request' Prompt")
+                       raise ExceptionPrompt("Timeout before Prompt")
 
                return 0
 
 
                return 0
 
@@ -760,6 +854,7 @@ class BayTech(PCUControl):
                        # even after login...
                        print "msg: %s" % msg
                        self.transport.write(self.username + "\r\n")
                        # even after login...
                        print "msg: %s" % msg
                        self.transport.write(self.username + "\r\n")
+                       time.sleep(5)
                        self.ifThenSend("DS-RPC>", "Reboot %d" % node_port)
 
                # Reboot Outlet  N        (Y/N)?
                        self.ifThenSend("DS-RPC>", "Reboot %d" % node_port)
 
                # Reboot Outlet  N        (Y/N)?
@@ -767,6 +862,7 @@ class BayTech(PCUControl):
                        self.ifThenSend("(Y/N)?", "N")
                else:
                        self.ifThenSend("(Y/N)?", "Y")
                        self.ifThenSend("(Y/N)?", "N")
                else:
                        self.ifThenSend("(Y/N)?", "Y")
+               time.sleep(5)
                self.ifThenSend("DS-RPC>", "")
 
                self.close()
                self.ifThenSend("DS-RPC>", "")
 
                self.close()
@@ -829,19 +925,43 @@ class ePowerSwitchGood(PCUControl):
                        # failing here means the User/passwd is wrong (hopefully)
                        raise ExceptionPassword("Incorrect username/password")
 
                        # failing here means the User/passwd is wrong (hopefully)
                        raise ExceptionPassword("Incorrect username/password")
 
-               # TODO: after verifying that the user/password is correct, we should
-               # actually reboot the given node.
-
+               # NOTE: after verifying that the user/password is correct, 
+               #               actually reboot the given node.
                if not dryrun:
                if not dryrun:
-                       # add data to handler,
-                       # fetch url one more time on cmd.html, econtrol.html or whatever.
-                       pass
+                       try:
+                               data = urllib.urlencode({'P%d' % node_port : "r"})
+                               req = urllib2.Request(self.url + "cmd.html")
+                               req.add_header("Authorization", authheader)
+                               # add data to handler,
+                               f = urllib2.urlopen(req, data)
+                               if self.verbose: print f.read()
+                       except:
+                               import traceback; traceback.print_exc()
+                               from nodecommon import email_exception
+                               email_exception()
 
 
-               if self.verbose: print f.read()
+                               # fetch url one more time on cmd.html, econtrol.html or whatever.
+                               # pass
+               else:
+                       if self.verbose: print f.read()
 
                self.close()
                return 0
 
 
                self.close()
                return 0
 
+class CustomPCU(PCUControl):
+       def run(self, node_port, dryrun):
+               url = "https://www-itec.uni-klu.ac.at/plab-pcu/index.php" 
+
+               if not dryrun:
+                       # Turn host off, then on
+                       formstr = "plab%s=off" % node_port
+                       os.system("curl --user %s:%s --form '%s' --insecure %s" % (self.username, self.password, formstr, url))
+                       time.sleep(5)
+                       formstr = "plab%s=on" % node_port
+                       os.system("curl --user %s:%s --form '%s' --insecure %s" % (self.username, self.password, formstr, url))
+               else:
+                       os.system("curl --user %s:%s --insecure %s" % (self.username, self.password, url))
+
 
 class ePowerSwitchOld(PCUControl):
        def run(self, node_port, dryrun):
 
 class ePowerSwitchOld(PCUControl):
        def run(self, node_port, dryrun):
@@ -1053,9 +1173,10 @@ def runcmd(command, args, username, password, timeout = None):
                                out += "; output follows:\n" + data
                        raise Exception, out
 
                                out += "; output follows:\n" + data
                        raise Exception, out
 
-def racadm_reboot(ip, username, password, port, dryrun):
+def racadm_reboot(host, username, password, port, dryrun):
        global verbose
 
        global verbose
 
+       ip = socket.gethostbyname(host)
        try:
                cmd = "/usr/sbin/racadm"
                os.stat(cmd)
        try:
                cmd = "/usr/sbin/racadm"
                os.stat(cmd)
@@ -1085,11 +1206,16 @@ def pcu_name(pcu):
        else:
                return None
 
        else:
                return None
 
-def get_pcu_values(pcu_id):
-       # TODO: obviously, this shouldn't be loaded each time...
-       import soltesz
-       fb =soltesz.dbLoad("findbadpcus")
+#import database
+from monitor import database
+fb = None
 
 
+def get_pcu_values(pcu_id):
+       global fb
+       if fb == None:
+               # this shouldn't be loaded each time...
+               fb = database.dbLoad("findbadpcus")
+               
        try:
                values = fb['nodes']["id_%s" % pcu_id]['values']
        except:
        try:
                values = fb['nodes']["id_%s" % pcu_id]['values']
        except:
@@ -1097,27 +1223,22 @@ def get_pcu_values(pcu_id):
 
        return values
 
 
        return values
 
-def check_open_port(values, port_list):
-       ret = False
-
-       if 'portstatus' in values:
-               for port in port_list:
-                       if      port in values['portstatus'] and \
-                               values['portstatus'][port] == "open":
-
-                               ret = True
-       
-       return ret
+def reboot(nodename):
+       return reboot_policy(nodename, True, False)
        
 def reboot_policy(nodename, continue_probe, dryrun):
        global verbose
 
        pcu = plc.getpcu(nodename)
        if not pcu:
        
 def reboot_policy(nodename, continue_probe, dryrun):
        global verbose
 
        pcu = plc.getpcu(nodename)
        if not pcu:
+               logger.debug("no pcu for %s" % nodename)
+               print "no pcu for %s" % nodename
                return False # "%s has no pcu" % nodename
 
        values = get_pcu_values(pcu['pcu_id'])
        if values == None:
                return False # "%s has no pcu" % nodename
 
        values = get_pcu_values(pcu['pcu_id'])
        if values == None:
+               logger.debug("No values for pcu probe %s" % nodename)
+               print "No values for pcu probe %s" % nodename
                return False #"no info for pcu_id %s" % pcu['pcu_id']
        
        # Try the PCU first
                return False #"no info for pcu_id %s" % pcu['pcu_id']
        
        # Try the PCU first
@@ -1126,8 +1247,10 @@ def reboot_policy(nodename, continue_probe, dryrun):
        ret = reboot_test(nodename, values, continue_probe, verbose, dryrun)
 
        if ret != 0:
        ret = reboot_test(nodename, values, continue_probe, verbose, dryrun)
 
        if ret != 0:
+               print ret
                return False
        else:
                return False
        else:
+               print "return true"
                return True
 
 def reboot_test(nodename, values, continue_probe, verbose, dryrun):
                return True
 
 def reboot_test(nodename, values, continue_probe, verbose, dryrun):
@@ -1135,15 +1258,17 @@ def reboot_test(nodename, values, continue_probe, verbose, dryrun):
 
        try:
                # DataProbe iPal (many sites)
 
        try:
                # DataProbe iPal (many sites)
-               if  continue_probe and values['model'].find("Dataprobe IP-41x/IP-81x") >= 0:
-                       ipal = IPAL(values, verbose, ['23'])
+               if  continue_probe and values['model'].find("IP-41x_IP-81x") >= 0:
+                       ipal = IPAL(values, verbose, ['23', '80', '9100'])
                        rb_ret = ipal.reboot(values[nodename], dryrun)
                                
                # APC Masterswitch (Berkeley)
                        rb_ret = ipal.reboot(values[nodename], dryrun)
                                
                # APC Masterswitch (Berkeley)
-               elif continue_probe and values['model'].find("APC AP79xx/Masterswitch") >= 0:
+               elif continue_probe and ( values['model'].find("AP79xx") >= 0 or \
+                                                                 values['model'].find("Masterswitch") >= 0 ):
+                       print values
 
                        # TODO: make a more robust version of APC
 
                        # TODO: make a more robust version of APC
-                       if values['pcu_id'] in [1163,1055,1111,1231,1113,1127,1128,1148]:
+                       if values['pcu_id'] in [1102,1163,1055,1111,1231,1113,1127,1128,1148]:
                                apc = APCEurope(values, verbose, ['22', '23'])
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
                                apc = APCEurope(values, verbose, ['22', '23'])
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
@@ -1151,11 +1276,11 @@ def reboot_test(nodename, values, continue_probe, verbose, dryrun):
                                apc = APCBrazil(values, verbose, ['22', '23'])
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
                                apc = APCBrazil(values, verbose, ['22', '23'])
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
-                       elif values['pcu_id'] in [1221]:
+                       elif values['pcu_id'] in [1221,1225,1220]:
                                apc = APCBerlin(values, verbose, ['22', '23'])
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
                                apc = APCBerlin(values, verbose, ['22', '23'])
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
-                       elif values['pcu_id'] in [1173,1221,1220,1225]:
+                       elif values['pcu_id'] in [1173,1240,47]:
                                apc = APCFolsom(values, verbose, ['22', '23'])
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
                                apc = APCFolsom(values, verbose, ['22', '23'])
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
@@ -1164,12 +1289,16 @@ def reboot_test(nodename, values, continue_probe, verbose, dryrun):
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
                # BayTech DS4-RPC
                                rb_ret = apc.reboot(values[nodename], dryrun)
 
                # BayTech DS4-RPC
-               elif continue_probe and values['model'].find("Baytech DS4-RPC") >= 0:
-                       if values['pcu_id'] in [1052,1209,1002,1008,1041,1013,1022]:
+               elif continue_probe and values['model'].find("DS4-RPC") >= 0:
+                       if values['pcu_id'] in [1056,1237,1052,1209,1002,1008,1041,1013,1022]:
                                # These  require a 'ctrl-c' to be sent... 
                                baytech = BayTechCtrlC(values, verbose, ['22', '23'])
                                rb_ret = baytech.reboot(values[nodename], dryrun)
 
                                # These  require a 'ctrl-c' to be sent... 
                                baytech = BayTechCtrlC(values, verbose, ['22', '23'])
                                rb_ret = baytech.reboot(values[nodename], dryrun)
 
+                       elif values['pcu_id'] in [93]:
+                               baytech = BayTechAU(values, verbose, ['22', '23'])
+                               rb_ret = baytech.reboot(values[nodename], dryrun)
+
                        elif values['pcu_id'] in [1057]:
                                # These  require a 'ctrl-c' to be sent... 
                                baytech = BayTechCtrlCUnibe(values, verbose, ['22', '23'])
                        elif values['pcu_id'] in [1057]:
                                # These  require a 'ctrl-c' to be sent... 
                                baytech = BayTechCtrlCUnibe(values, verbose, ['22', '23'])
@@ -1189,7 +1318,7 @@ def reboot_test(nodename, values, continue_probe, verbose, dryrun):
                                rb_ret = baytech.reboot(values[nodename], dryrun)
 
                # iLO
                                rb_ret = baytech.reboot(values[nodename], dryrun)
 
                # iLO
-               elif continue_probe and values['model'].find("HP iLO") >= 0:
+               elif continue_probe and values['model'].find("ilo") >= 0:
                        try:
                                hpilo = HPiLO(values, verbose, ['22'])
                                rb_ret = hpilo.reboot(0, dryrun)
                        try:
                                hpilo = HPiLO(values, verbose, ['22'])
                                rb_ret = hpilo.reboot(0, dryrun)
@@ -1201,12 +1330,16 @@ def reboot_test(nodename, values, continue_probe, verbose, dryrun):
                                rb_ret = hpilo.reboot(0, dryrun)
 
                # DRAC ssh
                                rb_ret = hpilo.reboot(0, dryrun)
 
                # DRAC ssh
-               elif continue_probe and values['model'].find("Dell RAC") >= 0:
+               elif continue_probe and values['model'].find("DRAC") >= 0:
                        # TODO: I don't think DRACRacAdm will throw an exception for the
                        # default method to catch...
                        try:
                        # TODO: I don't think DRACRacAdm will throw an exception for the
                        # default method to catch...
                        try:
-                               drac = DRACRacAdm(values, verbose, ['443', '5869'])
-                               rb_ret = drac.reboot(0, dryrun)
+                               if values['pcu_id'] in [1402]:
+                                       drac = DRAC(values, verbose, ['22'])
+                                       rb_ret = drac.reboot(0, dryrun)
+                               else:
+                                       drac = DRACRacAdm(values, verbose, ['443', '5869'])
+                                       rb_ret = drac.reboot(0, dryrun)
                        except:
                                drac = DRAC(values, verbose, ['22'])
                                rb_ret = drac.reboot(0, dryrun)
                        except:
                                drac = DRAC(values, verbose, ['22'])
                                rb_ret = drac.reboot(0, dryrun)
@@ -1215,20 +1348,26 @@ def reboot_test(nodename, values, continue_probe, verbose, dryrun):
                                wti = WTIIPS4(values, verbose, ['23'])
                                rb_ret = wti.reboot(values[nodename], dryrun)
 
                                wti = WTIIPS4(values, verbose, ['23'])
                                rb_ret = wti.reboot(values[nodename], dryrun)
 
-               # BlackBox PSExxx-xx (e.g. PSE505-FR)
-               elif continue_probe and \
-                       (values['model'].find("BlackBox PS5xx") >= 0 or
-                        values['model'].find("ePowerSwitch 1/4/8x") >=0 ):
+               elif continue_probe and values['model'].find("AMT") >= 0:
+                               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("ePowerSwitch") >=0:
                        # TODO: allow a different port than http 80.
                        if values['pcu_id'] in [1089, 1071, 1046, 1035, 1118]:
                                eps = ePowerSwitchGood(values, verbose, ['80'])
                        elif values['pcu_id'] in [1003]:
                        # TODO: allow a different port than http 80.
                        if values['pcu_id'] in [1089, 1071, 1046, 1035, 1118]:
                                eps = ePowerSwitchGood(values, verbose, ['80'])
                        elif values['pcu_id'] in [1003]:
+                               # OLD EPOWER
+                               print "OLD EPOWER"
                                eps = ePowerSwitch(values, verbose, ['80'])
                        else:
                                eps = ePowerSwitchGood(values, verbose, ['80'])
 
                        rb_ret = eps.reboot(values[nodename], dryrun)
                                eps = ePowerSwitch(values, verbose, ['80'])
                        else:
                                eps = ePowerSwitchGood(values, verbose, ['80'])
 
                        rb_ret = eps.reboot(values[nodename], dryrun)
+               elif continue_probe and values['pcu_id'] in [1122]:
+                       custom = CustomPCU(values, verbose, ['80', '443'])
+                       custom.reboot(values[nodename], dryrun)
 
                elif continue_probe:
                        rb_ret = "Unsupported_PCU"
 
                elif continue_probe:
                        rb_ret = "Unsupported_PCU"
@@ -1254,48 +1393,6 @@ def reboot_test(nodename, values, continue_probe, verbose, dryrun):
        #                                                                 pcu[nodename],
        #                                                                 dryrun)
 
        #                                                                 pcu[nodename],
        #                                                                 dryrun)
 
-# Returns true if rebooted via PCU
-def reboot_old(nodename, dryrun):
-       pcu = plc.getpcu(nodename)
-       if not pcu:
-               plc.nodePOD(nodename)
-               return False
-       # Try the PCU first
-       logger.debug("Trying PCU %s %s" % (pcu['hostname'], pcu['model']))
-
-       # APC Masterswitch (Berkeley)
-       if pcu['model'] == "APC Masterswitch":
-               err = apc_reboot(pcu['ip'], pcu['username'],pcu['password'], 
-                               pcu[nodename], pcu['protocol'], dryrun)
-
-       # DataProbe iPal (many sites)
-       elif pcu['protocol'] == "telnet" and pcu['model'].find("IP-4") >= 0:
-               err = ipal_reboot(pcu['ip'],pcu['password'], pcu[nodename], dryrun)
-
-       # BayTech DS4-RPC
-       elif pcu['protocol'] == "ssh" and \
-       (pcu['model'].find("Baytech") >= 0 or pcu['model'].find("DS4") >= 0):
-               err = baytech_reboot(pcu['ip'], pcu['username'],pcu['password'], pcu[nodename], dryrun)
-
-       # BlackBox PSExxx-xx (e.g. PSE505-FR)
-       elif pcu['protocol'] == "http" and (pcu['model'] == "bbpse"):
-               err = bbpse_reboot(pcu['ip'], pcu['username'], pcu['password'], pcu[nodename],80, dryrun)
-
-       # x10toggle
-       elif pcu['protocol'] == "ssh" and (pcu['model'] == "x10toggle"):
-               err = x10toggle_reboot(pcu['ip'], pcu['username'],pcu['password'], pcu[nodename], dryrun)
-
-       # 
-       elif pcu['protocol'] == "racadm" and (pcu['model'] == "RAC"):
-               err = racadm_reboot(pcu['ip'], pcu['username'],pcu['password'], pcu_[nodename], dryrun)
-
-       # Unknown or unsupported
-       else:
-               err = errno.EPROTONOSUPPORT
-               return False
-       return True 
-
-
 def main():
        logger.setLevel(logging.DEBUG)
        ch = logging.StreamHandler()
 def main():
        logger.setLevel(logging.DEBUG)
        ch = logging.StreamHandler()
@@ -1305,9 +1402,23 @@ def main():
        logger.addHandler(ch)
 
        try:
        logger.addHandler(ch)
 
        try:
-               print "Rebooting %s" % sys.argv[1]
-               reboot_policy(sys.argv[1], True, False)
+               if "test" in sys.argv:
+                       dryrun = True
+               else:
+                       dryrun = False
+
+               for node in sys.argv[1:]:
+                       if node == "test": continue
+
+                       print "Rebooting %s" % node
+                       if reboot_policy(node, True, dryrun):
+                               print "success"
+                       else:
+                               print "failed"
        except Exception, err:
        except Exception, err:
+               import traceback; traceback.print_exc()
+               from nodecommon import email_exception
+               email_exception()
                print err
 
 if __name__ == '__main__':
                print err
 
 if __name__ == '__main__':