--- /dev/null
+from pcucontrol.reboot import *
+
+class APCControl(PCUControl):
+ supported_ports = [22,23,80,443]
+ reboot_sequence = []
+
+ def run(self, node_port, dryrun):
+ print "RUNNING!!!!!!!!!!!!"
+ if self.type == Transport.HTTPS or self.type == Transport.HTTP:
+ print "APC via http...."
+ return self.run_http_or_https(node_port, dryrun)
+ else:
+ print "APC via telnet/ssh...."
+ return self.run_telnet_or_ssh(node_port, dryrun)
+
+ def run_ssh(self, node_port, dryrun):
+ return self.run_telnet_or_ssh(node_port, dryrun)
+ def run_telnet(self, node_port, dryrun):
+ return self.run_telnet_or_ssh(node_port, dryrun)
+
+ def run_telnet_or_ssh(self, node_port, dryrun):
+ self.transport.open(self.host, self.username)
+ self.transport.sendPassword(self.password)
+
+ first = True
+ for val in self.reboot_sequence:
+ if first:
+ self.transport.ifThenSend("\r\n> ", val, ExceptionPassword)
+ first = False
+ else:
+ self.transport.ifThenSend("\r\n> ", val)
+
+ if not dryrun:
+ self.transport.ifThenSend("Enter 'YES' to continue or <ENTER> to cancel",
+ "YES\r\n",
+ ExceptionSequence)
+ else:
+ self.transport.ifThenSend("Enter 'YES' to continue or <ENTER> to cancel",
+ "", ExceptionSequence)
+ self.transport.ifThenSend("Press <ENTER> to continue...", "", ExceptionSequence)
+
+ self.transport.close()
+ return 0
+
+ def run_http(self, node_port, dryrun):
+ return self.run_http_or_https(node_port, dryrun)
+ def run_https(self, node_port, dryrun):
+ return self.run_http_or_https(node_port, dryrun)
+
+ def run_http_or_https(self, node_port, dryrun):
+ if not dryrun:
+ # send reboot signal.
+ # TODO: send a ManualPCU() reboot request for this PCU.
+ # NOTE: this model defies automation because, the port numbering
+ # and the form numbers are not consistent across models. There is
+ # not direct mapping from port# to form#.
+ return "Manual Reboot Required"
+
+ else:
+ # TODO: also send message for https, since that doesn't work this way...
+ if self.type == Transport.HTTPS:
+ cmd = self.get_https_cmd()
+ elif self.type == Transport.HTTP:
+ cmd = self.get_http_cmd()
+ else:
+ raise ExceptionNoTransport("Unsupported transport for http command")
+
+ cmd = cmd % ( self.username, self.password, self.host)
+ print "CMD: %s" % cmd
+
+ p = os.popen(cmd)
+ result = p.read()
+ if len(result.split('\n')) > 2:
+ self.logout()
+ return 0
+ else:
+ # NOTE: an error has occurred, so no need to log out.
+ print "RESULT: ", result
+ return result
+
+ def get_https_cmd(self):
+ version = self.get_version()
+ print "VERSION: %s" % version
+ if "AP96" in version:
+ cmd = "curl -s --insecure --user '%s:%s' https://%s/outlets.htm " + \
+ " | grep -E '^[^<]+' " + \
+ " | grep -v 'Protected Object' "
+ else:
+ # NOTE: no other case known right now...
+ cmd = "curl -s --insecure --user '%s:%s' https://%s/outlets.htm " + \
+ " | grep -E '^[^<]+' " + \
+ " | grep -v 'Protected Object' "
+
+ return cmd
+
+ def get_http_cmd(self):
+ version = self.get_version()
+ print "VERSION: %s" % version
+ if "AP7900" in version:
+ cmd = "curl -s --anyauth --user '%s:%s' http://%s/rPDUout.htm | grep -E '^[^<]+'"
+ elif "AP7920" in version:
+ cmd = "curl -s --anyauth --user '%s:%s' http://%s/ms3out.htm | grep -E '^[^<]+' "
+ else:
+ # default case...
+ print "USING DEFAULT"
+ cmd = "curl -s --anyauth --user '%s:%s' http://%s/ms3out.htm | grep -E '^[^<]+' "
+
+ return cmd
+
+ def get_version(self):
+ # NOTE: this command returns and formats all data.
+ #cmd = """curl -s --anyauth --user '%s:%s' http://%s/about.htm """ +
+ # """ | sed -e "s/<[^>]*>//g" -e "s/ //g" -e "/^$/d" """ +
+ # """ | awk '{line=$0 ; if ( ! /:/ && length(pline) > 0 ) \
+ # { print pline, line } else { pline=line} }' """ +
+ # """ | grep Model """
+
+ # NOTE: we may need to return software version, no model version to
+ # know which file to request on the server.
+
+ if self.type == Transport.HTTP:
+ cmd = """curl -s --anyauth --user '%s:%s' http://%s/about.htm """ + \
+ """ | sed -e "s/<[^>]*>//g" -e "s/ //g" -e "/^$/d" """ + \
+ """ | grep -E "AP[[:digit:]]+" """
+ #""" | grep -E "v[[:digit:]].*" """
+ elif self.type == Transport.HTTPS:
+ cmd = """curl -s --insecure --user '%s:%s' https://%s/about.htm """ + \
+ """ | sed -e "s/<[^>]*>//g" -e "s/ //g" -e "/^$/d" """ + \
+ """ | grep -E "AP[[:digit:]]+" """
+ #""" | grep -E "v[[:digit:]].*" """
+ else:
+ raise ExceptionNoTransport("Unsupported transport to get version")
+
+ cmd = cmd % ( self.username, self.password, self.host)
+ p = os.popen(cmd)
+ result = p.read()
+ return result.strip()
+
+ def logout(self):
+ # NOTE: log out again, to allow other uses to access the machine.
+ if self.type == Transport.HTTP:
+ cmd = """curl -s --anyauth --user '%s:%s' http://%s/logout.htm """ + \
+ """ | grep -E '^[^<]+' """
+ elif self.type == Transport.HTTPS:
+ cmd = """curl -s --insecure --user '%s:%s' http://%s/logout.htm """ + \
+ """ | grep -E '^[^<]+' """
+ else:
+ raise ExceptionNoTransport("Unsupported transport to logout")
+
+ cmd = cmd % ( self.username, self.password, self.host)
+ p = os.popen(cmd)
+ print p.read()
+
+class APCControl12p3(APCControl):
+ def run_telnet_or_ssh(self, node_port, dryrun):
+ self.reboot_sequence = ["1", "2", str(node_port), "3"]
+ return super(APCControl12p3, self).run_telnet_or_ssh(node_port, dryrun)
+
+class APCControl1p4(APCControl):
+ def run_telnet_or_ssh(self, node_port, dryrun):
+ self.reboot_sequence = ["1", str(node_port), "4"]
+ return super(APCControl1p4, self).run_telnet_or_ssh(node_port, dryrun)
+
+class APCControl121p3(APCControl):
+ def run_telnet_or_ssh(self, node_port, dryrun):
+ self.reboot_sequence = ["1", "2", "1", str(node_port), "3"]
+ return super(APCControl121p3, self).run_telnet_or_ssh(node_port, dryrun)
+
+class APCControl121p1(APCControl):
+ def run_telnet_or_ssh(self, node_port, dryrun):
+ self.reboot_sequence = ["1", "2", "1", str(node_port), "1", "3"]
+ return super(APCControl121p1, self).run_telnet_or_ssh(node_port, dryrun)
+
+class APCControl13p13(APCControl):
+ def run_telnet_or_ssh(self, node_port, dryrun):
+ self.reboot_sequence = ["1", "3", str(node_port), "1", "3"]
+ return super(APCControl13p13, self).run_telnet_or_ssh(node_port, dryrun)
--- /dev/null
+from pcucontrol.reboot import *
+
+class BayTechRPC3NC(PCUControl):
+ def run_telnet(self, node_port, dryrun):
+ return self.run_ssh(node_port, dryrun)
+
+ def run_ssh(self, node_port, dryrun):
+ self.transport.open(self.host, self.username, None, "Enter user name:")
+ self.transport.sendPassword(self.password, "Enter Password:")
+
+ #self.transport.ifThenSend("RPC-16>", "Status")
+ self.transport.ifThenSend("RPC3-NC>", "Reboot %d" % node_port)
+
+ # Reboot Outlet N (Y/N)?
+ if dryrun:
+ self.transport.ifThenSend("(Y/N)?", "N")
+ else:
+ self.transport.ifThenSend("(Y/N)?", "Y")
+ self.transport.ifThenSend("RPC3-NC>", "")
+
+ self.transport.close()
+ return 0
+
+class BayTechRPC16(PCUControl):
+ def run_telnet(self, node_port, dryrun):
+ return self.run_ssh(node_port, dryrun)
+ def run_ssh(self, node_port, dryrun):
+ self.transport.open(self.host, self.username, None, "Enter user name:")
+ self.transport.sendPassword(self.password, "Enter Password:")
+
+ #self.transport.ifThenSend("RPC-16>", "Status")
+
+ self.transport.ifThenSend("RPC-16>", "Reboot %d" % node_port)
+
+ # Reboot Outlet N (Y/N)?
+ if dryrun:
+ self.transport.ifThenSend("(Y/N)?", "N")
+ else:
+ self.transport.ifThenSend("(Y/N)?", "Y")
+ self.transport.ifThenSend("RPC-16>", "")
+
+ self.transport.close()
+ return 0
+
+class BayTechCtrlCUnibe(PCUControl):
+ """
+ For some reason, these units let you log in fine, but they hang
+ indefinitely, unless you send a Ctrl-C after the password. No idea
+ why.
+ """
+ def run_ssh(self, node_port, dryrun):
+ print "BayTechCtrlC %s" % self.host
+
+ ssh_options="-o StrictHostKeyChecking=no -o PasswordAuthentication=yes -o PubkeyAuthentication=no"
+ s = pxssh.pxssh()
+ if not s.login(self.host, self.username, self.password, ssh_options):
+ raise ExceptionPassword("Invalid Password")
+ # Otherwise, the login succeeded.
+
+ # Send a ctrl-c to the remote process.
+ print "sending ctrl-c"
+ s.send(chr(3))
+
+ # Control Outlets (5 ,1).........5
+ try:
+ #index = s.expect("Enter Request")
+ index = s.expect(["Enter Request :"])
+
+ if index == 0:
+ print "3"
+ s.send("3\r\n")
+ index = s.expect(["DS-RPC>", "Enter user name:"])
+ if index == 1:
+ s.send(self.username + "\r\n")
+ index = s.expect(["DS-RPC>"])
+
+ if index == 0:
+ print "Reboot %d" % node_port
+ time.sleep(5)
+ s.send("Reboot %d\r\n" % node_port)
+
+ time.sleep(5)
+ index = s.expect(["\(Y/N\)\?", "Port in use", "DS-RPC>"])
+ if index == 0:
+ if dryrun:
+ print "sending N"
+ s.send("N\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.")
+
+ time.sleep(5)
+ index = s.expect(["DS-RPC>"])
+ #print "got prompt back"
+
+ s.close()
+
+ except pexpect.EOF:
+ raise ExceptionPrompt("EOF before expected Prompt")
+ except pexpect.TIMEOUT:
+ raise ExceptionPrompt("Timeout before expected Prompt")
+
+ return 0
+
+class BayTechCtrlC(PCUControl):
+ """
+ For some reason, these units let you log in fine, but they hang
+ indefinitely, unless you send a Ctrl-C after the password. No idea
+ why.
+ """
+ def run_ssh(self, node_port, dryrun):
+ print "BayTechCtrlC %s" % self.host
+
+ ssh_options="-o StrictHostKeyChecking=no -o PasswordAuthentication=yes -o PubkeyAuthentication=no"
+ s = pxssh.pxssh()
+ if not s.login(self.host, self.username, self.password, ssh_options):
+ raise ExceptionPassword("Invalid Password")
+ # Otherwise, the login succeeded.
+
+ # Send a ctrl-c to the remote process.
+ print "SENDING ctrl-c"
+ s.send(chr(3))
+
+ # Control Outlets (5 ,1).........5
+ try:
+ print "EXPECTING: ", "Enter Request :"
+ index = s.expect(["Enter Request :"])
+
+ if index == 0:
+ print "SENDING: 5"
+ s.send("5\r\n")
+ 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>"])
+ elif index == 2:
+ raise ExceptionPrompt("PCU Reported 'Port in use.'")
+
+ if index == 0:
+ print "SENDING: Reboot %d" % node_port
+ s.send("Reboot %d\r\n" % node_port)
+
+ 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:
+ 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.")
+
+ # 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:
+ raise ExceptionPrompt("Timeout before Prompt")
+
+ return 0
+
+class BayTech(PCUControl):
+ supported_ports = [22,23]
+
+ def run_telnet(self, node_port, dryrun):
+ return self.run_ssh(node_port, dryrun)
+
+ def run_ssh(self, node_port, dryrun):
+ self.transport.open(self.host, self.username)
+ self.transport.sendPassword(self.password)
+
+ # Control Outlets (5 ,1).........5
+ self.transport.ifThenSend("Enter Request :", "5")
+
+ # Reboot N
+ try:
+ self.transport.ifThenSend("DS-RPC>", "Reboot %d" % node_port, ExceptionNotFound)
+ except ExceptionNotFound, msg:
+ # one machine is configured to ask for a username,
+ # even after login...
+ print "msg: %s" % msg
+ self.transport.write(self.username + "\r\n")
+ time.sleep(5)
+ self.transport.ifThenSend("DS-RPC>", "Reboot %d" % node_port)
+
+ # Reboot Outlet N (Y/N)?
+ if dryrun:
+ self.transport.ifThenSend("(Y/N)?", "N")
+ else:
+ self.transport.ifThenSend("(Y/N)?", "Y")
+ time.sleep(5)
+ self.transport.ifThenSend("DS-RPC>", "")
+
+ self.transport.close()
+ return 0
--- /dev/null
+from pcucontrol.reboot import *
+
+### rebooting european BlackBox PSE boxes
+# Thierry Parmentelat - May 11 2005
+# tested on 4-ports models known as PSE505-FR
+# uses http to POST a data 'P<port>=r'
+# relies on basic authentication within http1.0
+# first curl-based script was
+# curl --http1.0 --basic --user <username>:<password> --data P<port>=r \
+# http://<hostname>:<http_port>/cmd.html && echo OK
+
+# log in:
+
+## BB PSMaverick
+class BlackBoxPSMaverick(PCUControl):
+ supported_ports = [80]
+
+ def run_http(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
+
+ url = "http://%s:%d/cmd.html" % (pcu_ip,http_port)
+ data= "P%d=r" % port_in_pcu
+ if verbose:
+ logger.debug("POSTing '%s' on %s" % (data,url))
+
+ authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm()
+ uri = "%s:%d" % (pcu_ip,http_port)
+ authinfo.add_password (None, uri, username, password)
+ authhandler = urllib2.HTTPBasicAuthHandler( authinfo )
+
+ opener = urllib2.build_opener(authhandler)
+ urllib2.install_opener(opener)
+
+ if (dryrun):
+ return 0
+
+ try:
+ f = urllib2.urlopen(url,data)
+
+ r= f.read()
+ if verbose:
+ logger.debug(r)
+ return 0
+
+ except urllib2.URLError,err:
+ logger.info('Could not open http connection', err)
+ return "bbpse error"
--- /dev/null
+# Each method follows the following format:
+# CustomPCU_loginbase()
+#
+# This provides a simple means of lookup given the custom type.
+# The only problem might come up if a single site has multiple custom PCUs.
+# That would be pretty wierd though...
+
+from pcucontrol.reboot import *
+
+class CustomPCU_uniklu(PCUControl):
+ def run_http(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))
+
+
+
+
--- /dev/null
+from pcucontrol.reboot import *
+
+class DRAC(PCUControl):
+ supported_ports = [22,443,5869]
+ def run_drac(self, node_port, dryrun):
+ print "trying racadm_reboot..."
+ return racadm_reboot(self.host, self.username, self.password, node_port, dryrun)
+
+ def run_ssh(self, node_port, dryrun):
+ ssh_options="-o StrictHostKeyChecking=no "+\
+ "-o PasswordAuthentication=yes "+\
+ "-o PubkeyAuthentication=no"
+ s = pxssh.pxssh()
+ if not s.login(self.host, self.username, self.password, ssh_options,
+ original_prompts="Dell", login_timeout=Transport.TELNET_TIMEOUT):
+ raise ExceptionPassword("Invalid Password")
+
+ print "logging in..."
+ s.send("\r\n\r\n")
+ try:
+ # Testing Reboot ?
+ #index = s.expect(["DRAC 5", "[%s]#" % self.username ])
+ # NOTE: be careful to escape any characters used by 're.compile'
+ index = s.expect(["\$", "\[%s\]#" % self.username ])
+ print "INDEX:", index
+ if dryrun:
+ if index == 0:
+ s.send("racadm getsysinfo")
+ elif index == 1:
+ s.send("getsysinfo")
+ else:
+ if index == 0:
+ s.send("racadm serveraction powercycle")
+ elif index == 1:
+ s.send("serveraction powercycle")
+
+ s.send("exit")
+
+ except pexpect.EOF:
+ raise ExceptionPrompt("EOF before expected Prompt")
+ except pexpect.TIMEOUT:
+ print s
+ raise ExceptionPrompt("Timeout before expected Prompt")
+
+ s.close()
+
+ return 0
+
+class DRACDefault(PCUControl):
+ supported_ports = [22,443,5869]
+ def run_ssh(self, node_port, dryrun):
+ self.transport.open(self.host, self.username)
+ self.transport.sendPassword(self.password)
+
+ print "logging in..."
+ self.transport.write("\r\n")
+ # Testing Reboot ?
+ if dryrun:
+ self.transport.ifThenSend("[%s]#" % self.username, "getsysinfo")
+ else:
+ # Reset this machine
+ self.transport.ifThenSend("[%s]#" % self.username, "serveraction powercycle")
+
+ self.transport.ifThenSend("[%s]#" % self.username, "exit")
+
+ self.transport.close()
+ return 0
+
+### rebooting Dell systems via RAC card
+# Marc E. Fiuczynski - June 01 2005
+# tested with David Lowenthal's itchy/scratchy nodes at UGA
+#
+def runcmd(command, args, username, password, timeout = None):
+
+ result = [None]
+ result_ready = threading.Condition()
+
+ def set_result(x):
+
+ result_ready.acquire()
+ try:
+ result[0] = x
+ finally:
+ result_ready.notify()
+ result_ready.release()
+
+ def do_command(command, username, password):
+
+ try:
+ # Popen4 is a popen-type class that combines stdout and stderr
+ p = popen2.Popen4(command)
+
+ # read all output data
+ p.tochild.write("%s\n" % username)
+ p.tochild.write("%s\n" % password)
+ p.tochild.close()
+ data = p.fromchild.read()
+
+ while True:
+ # might get interrupted by a signal in poll() or waitpid()
+ try:
+ retval = p.wait()
+ set_result((retval, data))
+ break
+ except OSError, ex:
+ if ex.errno == errno.EINTR:
+ continue
+ raise ex
+ except Exception, ex:
+ set_result(ex)
+
+ if args:
+ command = " ".join([command] + args)
+
+ worker = threading.Thread(target = do_command, args = (command, username, password, ))
+ worker.setDaemon(True)
+ result_ready.acquire()
+ worker.start()
+ result_ready.wait(timeout)
+ try:
+ if result == [None]:
+ raise Exception, "command timed-out: '%s'" % command
+ finally:
+ result_ready.release()
+ result = result[0]
+
+ if isinstance(result, Exception):
+ raise result
+ else:
+ (retval, data) = result
+ if os.WIFEXITED(retval) and os.WEXITSTATUS(retval) == 0:
+ return data
+ else:
+ out = "system command ('%s') " % command
+ if os.WIFEXITED(retval):
+ out += "failed, rc = %d" % os.WEXITSTATUS(retval)
+ else:
+ out += "killed by signal %d" % os.WTERMSIG(retval)
+ if data:
+ out += "; output follows:\n" + data
+ raise Exception, out
+
+def racadm_reboot(host, username, password, port, dryrun):
+ global verbose
+
+ ip = socket.gethostbyname(host)
+ try:
+ cmd = "/usr/sbin/racadm"
+ os.stat(cmd)
+ if not dryrun:
+ output = runcmd(cmd, ["-r %s -i serveraction powercycle" % ip],
+ username, password)
+ else:
+ output = runcmd(cmd, ["-r %s -i getsysinfo" % ip],
+ username, password)
+
+ print "RUNCMD: %s" % output
+ if verbose:
+ logger.debug(output)
+ return 0
+
+ except Exception, err:
+ logger.debug("runcmd raised exception %s" % err)
+ if verbose:
+ logger.debug(err)
+ return err
--- /dev/null
+from pcucontrol.reboot import *
+
+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 = config.MONITOR_SCRIPT_ROOT + "/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
--- /dev/null
+from pcucontrol.reboot import *
+
+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 = [9100,23,80]
+
+ 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
+
+ try:
+ # TODO: make sleep backoff, before stopping.
+ time.sleep(4)
+ ret = s.recv(count, socket.MSG_DONTWAIT)
+ except socket.error, e:
+ if e[0] == errno.EAGAIN:
+ raise Exception(e[1])
+ else:
+ # TODO: not other exceptions.
+ raise Exception(e)
+ return ret
+
+ #def run(self, node_port, dryrun):
+ # if self.type == Transport.IPAL:
+ # ret = self.run_ipal(node_port, dryrun)
+ # if ret != 0:
+ # ret2 = self.run_telnet(node_port, dryrun)
+ # if ret2 != 0:
+ # return ret
+ # return ret2
+ # return ret
+ # elif self.type == Transport.TELNET:
+ # return self.run_telnet(node_port, dryrun)
+ # else:
+ # raise ExceptionNoTransport("Unimplemented Transport for IPAL")
+
+ def run_telnet(self, node_port, dryrun):
+ # TELNET version of protocol...
+ self.transport.open(self.host)
+ ## XXX Some iPals require you to hit Enter a few times first
+ self.transport.ifThenSend("Password >", "\r\n\r\n", ExceptionNotFound)
+ # Login
+ self.transport.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.transport.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.transport.ifElse("Enter >", ExceptionTimeout)
+ print "closing "
+ self.transport.close()
+ return 0
+
+ def run_ipal(self, node_port, dryrun):
+ import errno
+
+ power_on = False
+
+ 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])
+ 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' %s : %s" % (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
+ else:
+ raise Exception("Unknown status for PCU socket %s : %s" % (node_port, ret))
+ else:
+ raise Exception("Mismatch between configured port and PCU status: %s %s" % (node_port, ret))
+
+
+ if not dryrun:
+ 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
+ else:
+ raise Exception("Unknown status for PCU socket %s : %s" % (node_port, ret))
+ else:
+ raise Exception("Mismatch between configured port and PCU status: %s %s" % (node_port, ret))
+
+ if power_on:
+ return 0
+ else:
+ return "Failed Power On"
+
+ s.close()
+ return 0
--- /dev/null
+from pcucontrol.reboot import *
+
+class IntelAMT(PCUControl):
+ supported_ports = [16992]
+
+ def run_amt(self, node_port, dryrun):
+
+ cmd = command.CMD()
+ # TODO: need to make this path universal; not relative to pwd.
+ cmd_str = config.MONITOR_SCRIPT_ROOT + "/pcucontrol/models/intelamt/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, Transport.TELNET_TIMEOUT)
--- /dev/null
+from pcucontrol.reboot import *
+
+class ManualPCU(PCUControl):
+ supported_ports = [22,23,80,443]
+
+ def run_http(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.
+ pass
+ return 0
+
--- /dev/null
+
+from pcucontrol.reboot import *
+
+class OpenIPMI(PCUControl):
+
+ supported_ports = [80,443,623]
+
+ # TODO: get exit codes to determine success or failure...
+ def run_https(self, node_port, dryrun):
+
+ if not dryrun:
+ cmd = "ipmitool -I lanplus -H %s -U %s -P '%s' power cycle "
+ (i,p) = os.popen4(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 "
+ (i,p) = os.popen4(cmd % ( self.host, self.username, self.password) )
+ result = p.read()
+ print "RESULT: ", result
+
+ if "Error" in result:
+ return result
+ else:
+ return 0
--- /dev/null
+from pcucontrol.reboot import *
+from ManualPCU import *
+
+class PM211MIP(ManualPCU):
+ supported_ports = [80,443]
--- /dev/null
+from pcucontrol.reboot import *
+
+class WTIIPS4(PCUControl):
+ supported_ports = [23]
+ def run_telnet(self, node_port, dryrun):
+ self.transport.open(self.host)
+ self.transport.sendPassword(self.password, "Enter Password:")
+
+ self.transport.ifThenSend("IPS> ", "/Boot %s" % node_port)
+ if not dryrun:
+ self.transport.ifThenSend("Sure? (Y/N): ", "N")
+ else:
+ self.transport.ifThenSend("Sure? (Y/N): ", "Y")
+
+ self.transport.ifThenSend("IPS> ", "")
+
+ self.transport.close()
+ return 0
--- /dev/null
+
+from pcucontrol.reboot import *
+### rebooting x10toggle based systems addressed by port
+# Marc E. Fiuczynski - May 31 2005
+# tested on 4-ports models known as PSE505-FR
+# uses ssh and password to login to an account
+# that will cause the system to be powercycled.
+
+TELNET_TIMEOUT = 120
+def telnet_answer(telnet, expected, buffer):
+ global verbose
+
+ output = telnet.read_until(expected, TELNET_TIMEOUT)
+ #if verbose:
+ # logger.debug(output)
+ if output.find(expected) == -1:
+ raise ExceptionNotFound, "'%s' not found" % expected
+ else:
+ telnet.write(buffer + "\r\n")
+
+def x10toggle_reboot(ip, username, password, port, dryrun):
+ global verbose
+
+ ssh = None
+ try:
+ ssh = pyssh.Ssh(username, ip)
+ ssh.open()
+
+ # Login
+ telnet_answer(ssh, "password:", password)
+
+ if not dryrun:
+ # Reboot
+ telnet_answer(ssh, "x10toggle>", "A%d" % port)
+
+ # Close
+ output = ssh.close()
+ if verbose:
+ logger.debug(output)
+ return 0
+
+ except Exception, err:
+ if verbose:
+ logger.debug(err)
+ if ssh:
+ output = ssh.close()
+ if verbose:
+ logger.debug(output)
+ return errno.ETIMEDOUT
--- /dev/null
+from OpenIPMI import *
+from IPAL import *
+from APCControl import *
+from IntelAMT import *
+from DRAC import *
+from HPiLO import *
+from BayTech import *
+from WTIIPS4 import *
+from ePowerSwitch import *
+from BlackBoxPSMaverick import *
+from CustomPCU import *
+from ManualPCU import *
+from PM211MIP import *
--- /dev/null
+from pcucontrol.reboot import *
+
+class ePowerSwitchNew(PCUControl):
+ # NOTE:
+ # The old code used Python's HTTPPasswordMgrWithDefaultRealm()
+ # For some reason this both doesn't work and in some cases, actually
+ # hangs the PCU. Definitely not what we want.
+ #
+ # The code below is much simpler. Just letting things fail first,
+ # and then, trying again with authentication string in the header.
+ #
+ def run_http(self, node_port, dryrun):
+ self.transport = None
+ self.url = "http://%s:%d/" % (self.host,80)
+ uri = "%s:%d" % (self.host,80)
+
+ req = urllib2.Request(self.url)
+ try:
+ handle = urllib2.urlopen(req)
+ except IOError, e:
+ # NOTE: this is expected to fail initially
+ pass
+ else:
+ print self.url
+ print "-----------"
+ print handle.read()
+ print "-----------"
+ return "ERROR: not protected by HTTP authentication"
+
+ if not hasattr(e, 'code') or e.code != 401:
+ return "ERROR: failed for: %s" % str(e)
+
+ base64data = base64.encodestring("%s:%s" % (self.username, self.password))[:-1]
+ # NOTE: assuming basic realm authentication.
+ authheader = "Basic %s" % base64data
+ req.add_header("Authorization", authheader)
+
+ try:
+ f = urllib2.urlopen(req)
+ except IOError, e:
+ # failing here means the User/passwd is wrong (hopefully)
+ raise ExceptionPassword("Incorrect username/password")
+
+ # NOTE: after verifying that the user/password is correct,
+ # actually reboot the given node.
+ if not dryrun:
+ 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()
+
+ # fetch url one more time on cmd.html, econtrol.html or whatever.
+ # pass
+ else:
+ if self.verbose: print f.read()
+
+ return 0
+
+class ePowerSwitchOld(PCUControl):
+ def run_http(self, node_port, dryrun):
+ self.url = "http://%s:%d/" % (self.host,80)
+ uri = "%s:%d" % (self.host,80)
+
+ # create authinfo
+ authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm()
+ authinfo.add_password (None, uri, self.username, self.password)
+ authhandler = urllib2.HTTPBasicAuthHandler( authinfo )
+
+ # NOTE: it doesn't seem to matter whether this authinfo is here or not.
+ transport = urllib2.build_opener(authinfo)
+ f = transport.open(self.url)
+ if self.verbose: print f.read()
+
+ if not dryrun:
+ transport = urllib2.build_opener(authhandler)
+ f = transport.open(self.url + "cmd.html", "P%d=r" % node_port)
+ if self.verbose: print f.read()
+
+ self.transport.close()
+ return 0
+
+class ePowerSwitchOld(PCUControl):
+ supported_ports = [80]
+ def run_http(self, node_port, dryrun):
+ self.url = "http://%s:%d/" % (self.host,80)
+ uri = "%s:%d" % (self.host,80)
+
+ # TODO: I'm still not sure what the deal is here.
+ # two independent calls appear to need to be made before the
+ # reboot will succeed. It doesn't seem to be possible to do
+ # this with a single call. I have no idea why.
+
+ # create authinfo
+ authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm()
+ authinfo.add_password (None, uri, self.username, self.password)
+ authhandler = urllib2.HTTPBasicAuthHandler( authinfo )
+
+ # NOTE: it doesn't seem to matter whether this authinfo is here or not.
+ transport = urllib2.build_opener()
+ f = transport.open(self.url + "elogin.html", "pwd=%s" % self.password)
+ if self.verbose: print f.read()
+
+ if not dryrun:
+ transport = urllib2.build_opener(authhandler)
+ f = transport.open(self.url + "econtrol.html", "P%d=r" % node_port)
+ if self.verbose: print f.read()
+
+ # data= "P%d=r" % node_port
+ #self.open(self.host, self.username, self.password)
+ #self.sendHTTP("elogin.html", "pwd=%s" % self.password)
+ #self.sendHTTP("econtrol.html", data)
+ #self.sendHTTP("cmd.html", data)
+
+ #self.close()
+ return 0