-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))
- 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.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
-
- 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
-
-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_telnet_or_ssh(self, node_port, dryrun):
- self.open(self.host, self.username)
- self.sendPassword(self.password)
-
- first = True
- for val in self.reboot_sequence:
- if first:
- self.ifThenSend("\r\n> ", val, ExceptionPassword)
- first = False
- else:
- self.ifThenSend("\r\n> ", val)
-
- if not dryrun:
- self.ifThenSend("Enter 'YES' to continue or <ENTER> to cancel",
- "YES\r\n",
- ExceptionSequence)
- else:
- self.ifThenSend("Enter 'YES' to continue or <ENTER> to cancel",
- "", ExceptionSequence)
- self.ifThenSend("Press <ENTER> to continue...", "", ExceptionSequence)
-
- self.close()
- return 0
-
- 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(self, node_port, dryrun):
- self.reboot_sequence = ["1", "2", str(node_port), "3"]
- return super(APCControl12p3, self).run(node_port, dryrun)
-
-class APCControl1p4(APCControl):
- def run(self, node_port, dryrun):
- self.reboot_sequence = ["1", str(node_port), "4"]
- return super(APCControl1p4, self).run(node_port, dryrun)
-
-class APCControl121p3(APCControl):
- def run(self, node_port, dryrun):
- self.reboot_sequence = ["1", "2", "1", str(node_port), "3"]
- return super(APCControl121p3, self).run(node_port, dryrun)
-
-class APCControl121p1(APCControl):
- def run(self, node_port, dryrun):
- self.reboot_sequence = ["1", "2", "1", str(node_port), "1", "3"]
- return super(APCControl121p1, self).run(node_port, dryrun)
-
-class APCControl13p13(APCControl):
- def run(self, node_port, dryrun):
- self.reboot_sequence = ["1", "3", str(node_port), "1", "3"]
- return super(APCControl13p13, self).run(node_port, dryrun)
-
-
-class IntelAMT(PCUControl):
- supported_ports = [16992]
-
- def run(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, self.TELNET_TIMEOUT)
-
-class DRAC(PCUControl):
- supported_ports = [22,443,5869]
- def run(self, node_port, dryrun):
- if self.type == Transport.DRAC:
- print "trying racadm_reboot..."
- return racadm_reboot(self.host, self.username, self.password, node_port, dryrun)
- elif self.type == Transport.SSH:
- return self.run_ssh(node_port, dryrun)
- else:
- raise ExceptionNoTransport("No implementation for open ports")
-
- 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=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(self, node_port, dryrun):
- self.open(self.host, self.username)
- self.sendPassword(self.password)
-
- print "logging in..."
- self.transport.write("\r\n")
- # Testing Reboot ?
- if dryrun:
- self.ifThenSend("[%s]#" % self.username, "getsysinfo")
- else:
- # Reset this machine
- self.ifThenSend("[%s]#" % self.username, "serveraction powercycle")
-
- self.ifThenSend("[%s]#" % self.username, "exit")
-
- self.close()
- return 0
-
-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.open(self.host, self.username)
- self.sendPassword(self.password)
-
- # </>hpiLO->
- self.ifThenSend("</>hpiLO->", "cd system1")
-
- # Reboot Outlet N (Y/N)?
- if dryrun:
- self.ifThenSend("</system1>hpiLO->", "POWER")
- else:
- # Reset this machine
- self.ifThenSend("</system1>hpiLO->", "reset")
-
- self.ifThenSend("</system1>hpiLO->", "exit")
-
- self.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
-
-class BayTechRPC3NC(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 BayTechRPC16(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("RPC-16>", "Reboot %d" % node_port)
-
- # Reboot Outlet N (Y/N)?
- if dryrun:
- self.ifThenSend("(Y/N)?", "N")
- else:
- self.ifThenSend("(Y/N)?", "Y")
- self.ifThenSend("RPC-16>", "")
-
- self.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(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(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(self, node_port, dryrun):
- self.open(self.host, self.username)
- self.sendPassword(self.password)
-
- # Control Outlets (5 ,1).........5
- self.ifThenSend("Enter Request :", "5")
-
- # Reboot N
- try:
- self.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.ifThenSend("DS-RPC>", "Reboot %d" % node_port)
-
- # Reboot Outlet N (Y/N)?
- if dryrun:
- self.ifThenSend("(Y/N)?", "N")
- else:
- self.ifThenSend("(Y/N)?", "Y")
- time.sleep(5)
- self.ifThenSend("DS-RPC>", "")
-
- self.close()
- return 0
-
-class WTIIPS4(PCUControl):
- supported_ports = [23]
- def run(self, node_port, dryrun):
- self.open(self.host)
- self.sendPassword(self.password, "Enter Password:")
-
- self.ifThenSend("IPS> ", "/Boot %s" % node_port)
- if not dryrun:
- self.ifThenSend("Sure? (Y/N): ", "N")
- else:
- self.ifThenSend("Sure? (Y/N): ", "Y")
-
- self.ifThenSend("IPS> ", "")
-
- self.close()
- return 0
-
-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(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()
-
- 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):
- 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.close()
- return 0
-
-class ePowerSwitchOld(PCUControl):
- supported_ports = [80]
- def run(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
-
-class ManualPCU(PCUControl):
- supported_ports = [22,23,80,443]
-
- 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.
- pass
- return 0
-
-class PM211MIP(ManualPCU):
- supported_ports = [80,443]
-
-### 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(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"
-
-### 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.
-
-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
-
-### 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