improve error handling and reporting for hpilos.
Stephen Soltesz [Fri, 25 Jun 2010 20:22:05 +0000 (20:22 +0000)]
    the string returned is more suitable for return by the API.
    also, there is no false-positive return value of '0' for a pcu with an error

pcucontrol/models/HPiLO.py
pcucontrol/reboot.py
pcucontrol/util/command.py

index 78ceb0a..0f00f55 100644 (file)
@@ -1,60 +1,63 @@
 from pcucontrol.reboot import *
 from distutils.sysconfig import get_python_lib; 
+import subprocess
 
 class HPiLO(PCUControl):
-       supported_ports = [22,443]
-       def run(self, node_port, dryrun):
-               if self.type == Transport.SSH:
-                       return self.run_ssh(node_port, dryrun)
-               elif self.type == Transport.HTTP or self.type == Transport.HTTPS:
-                       return self.run_https(node_port, dryrun)
-               else:
-                       raise ExceptionNoTransport("Unimplemented Transport for HPiLO %s" % self.type)
-
-       def run_ssh(self, node_port, dryrun):
-
-               self.transport.open(self.host, self.username)
-               self.transport.sendPassword(self.password)
-
-               # </>hpiLO-> 
-               self.transport.ifThenSend("</>hpiLO->", "cd system1")
-
-               # Reboot Outlet  N        (Y/N)?
-               if dryrun:
-                       self.transport.ifThenSend("</system1>hpiLO->", "POWER")
-               else:
-                       # Reset this machine
-                       self.transport.ifThenSend("</system1>hpiLO->", "reset")
-
-               self.transport.ifThenSend("</system1>hpiLO->", "exit")
-
-               self.transport.close()
-               return 0
-               
-       def run_https(self, node_port, dryrun):
-
-               locfg = command.CMD()
-
-               cmd_str = get_python_lib(1) + "/pcucontrol/models/hpilo/"
-               
-               cmd = cmd_str + "locfg.pl -s %s -f %s -u %s -p '%s' | grep 'MESSAGE' | grep -v 'No error'" % (
-                                       self.host, cmd_str+"iloxml/Get_Network.xml", 
-                                       self.username, self.password)
-               sout, serr = locfg.run_noexcept(cmd)
-
-               if sout.strip() != "" or serr.strip() != "":
-                       print "sout: %s" % sout.strip()
-                       return sout.strip() + serr.strip()
-
-               if not dryrun:
-                       locfg = command.CMD()
-                       cmd = cmd_str + "locfg.pl -s %s -f %s -u %s -p '%s' | grep 'MESSAGE' | grep -v 'No error'" % (
-                                               self.host, cmd_str+"iloxml/Reset_Server.xml", 
-                                               self.username, self.password)
-                       sout, serr = locfg.run_noexcept(cmd)
-
-                       if sout.strip() != "":
-                               print "sout: %s" % sout.strip()
-                               #return sout.strip()
-
-               return 0
+    supported_ports = [22,443]
+    def run(self, node_port, dryrun):
+        if self.type == Transport.SSH:
+            return self.run_ssh(node_port, dryrun)
+        elif self.type == Transport.HTTP or self.type == Transport.HTTPS:
+            return self.run_https(node_port, dryrun)
+        else:
+            raise ExceptionNoTransport("Unimplemented Transport for HPiLO %s" % self.type)
+
+    def run_ssh(self, node_port, dryrun):
+
+        self.transport.open(self.host, self.username)
+        self.transport.sendPassword(self.password)
+
+        # </>hpiLO-> 
+        self.transport.ifThenSend("</>hpiLO->", "cd system1")
+
+        # Reboot Outlet  N      (Y/N)?
+        if dryrun:
+            self.transport.ifThenSend("</system1>hpiLO->", "POWER")
+        else:
+            # Reset this machine
+            self.transport.ifThenSend("</system1>hpiLO->", "reset")
+
+        self.transport.ifThenSend("</system1>hpiLO->", "exit")
+
+        self.transport.close()
+
+        # NOTE: if an error occurs earlier, an exception should be thrown
+        return 0
+        
+    def run_https(self, node_port, dryrun):
+
+        locfg = command.CMD()
+
+        cmd_str = get_python_lib(1) + "/pcucontrol/models/hpilo/"
+        
+        cmd = cmd_str + "locfg.pl -s %s -f %s -u %s -p '%s' "  % (
+                    self.host, cmd_str+"iloxml/Get_Network.xml", 
+                    self.username, self.password)
+        cmd_out, cmd_err = locfg.run_noexcept(cmd)
+
+        if locfg.s.returncode != 0:
+            return cmd_out.strip() + cmd_err.strip()
+
+        cmd = "grep 'MESSAGE' | grep -v 'No error'"
+        p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, 
+                            stderr=subprocess.STDOUT, close_fds=True)
+        (grep_in, grep_out ) = (p.stdin, p.stdout)
+        grep_in.write(cmd_out)
+        grep_in.close()         # close so read does not block
+        output = grep_out.read()
+        if output.strip() != "":
+            print "grep_out: %s" % output.strip()
+            return output.strip()
+
+        # NOTE: if an error occurs earlier, an exception should be thrown
+        return 0
index 0ec2abd..f7c2810 100755 (executable)
@@ -12,6 +12,7 @@ import urllib
 import array, struct
 import base64
 from subprocess import PIPE, Popen
+import subprocess
 import pcucontrol.transports.ssh.pxssh as pxssh
 import pcucontrol.transports.ssh.pexpect as pexpect
 import socket
index 6f112fb..42e00a9 100644 (file)
@@ -126,6 +126,7 @@ class CMD:
                f_out.close()
                f_in.close()
                f_err.close()
+               s.poll()
                s.kill(signal.SIGKILL)
 
                return (o_value, e_value)