Added a convenience script for making a single command line call.
authorStephen Soltesz <soltesz@cs.princeton.edu>
Mon, 14 Apr 2008 17:58:36 +0000 (17:58 +0000)
committerStephen Soltesz <soltesz@cs.princeton.edu>
Mon, 14 Apr 2008 17:58:36 +0000 (17:58 +0000)
racadm.py [new file with mode: 0755]

diff --git a/racadm.py b/racadm.py
new file mode 100755 (executable)
index 0000000..e627f10
--- /dev/null
+++ b/racadm.py
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+
+import threading
+
+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, dryrun):
+
+       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
+               return 0
+
+       except Exception, err:
+               logger.debug("runcmd raised exception %s" % err)
+               return -1
+
+
+from optparse import OptionParser
+parser = OptionParser()
+parser.set_defaults(ip="", user="", password="")
+parser.add_option("-r", "", dest="ip", metavar="nodename.edu", 
+                                       help="A single node name to add to the nodegroup")
+parser.add_option("-u", "", dest="user", metavar="username",
+                                       help="")
+parser.add_option("-p", "", dest="password", metavar="password",
+                                       help="")
+(options, args) = parser.parse_args()
+
+if __name__ == '__main__':
+       print options
+       if      options.ip is not "" and \
+               options.user is not "" and \
+               options.password is not "":
+
+               racadm_reboot(options.ip, options.user, options.password, False)
+       else:
+               parser.print_help()