.
git-svn-id: http://test.kernel.org/svn/autotest/trunk@541 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/conmux/drivers/reboot-apc b/conmux/drivers/reboot-apc
index 6a5d36f..e66dc39 100755
--- a/conmux/drivers/reboot-apc
+++ b/conmux/drivers/reboot-apc
@@ -3,32 +3,89 @@
# Reboot a machine connected to an APC power strip
#
# Copyright 2007 Google Inc., Martin J. Bligh <mbligh@google.com>
+set P "reboot-apc"
-set ip_addr [lindex $argv 0]
-set port [lindex $argv 1]
+#
+# OPTIONS: options parser.
+#
+proc shift {_list} {
+ upvar $_list list
+ set res [lindex $list 0]
+ set list [lreplace $list 0 0]
+ return $res
+}
-spawn telnet $ip_addr
+proc arg {_list arg} {
+ upvar $_list list
+ if {[llength $list] < 1} {
+ puts stderr "$arg: required argument missing"
+ exit 1
+ }
+ return [shift list]
+}
set timeout 10
+set user {apc}
+set pass {apc}
+set host [lindex $argv 0]
+set outlet [lindex $argv 1]
+shift argv
+shift argv
+while {[llength $argv] > 0} {
+puts "length [llength $argv]"
+ switch -- [shift argv] {
+ -p { set pass [arg argv p]}
+ -u { set user [arg argv u]}
+ }
+}
+
+if {[llength $argv] > 0} {
+ puts stderr "Usage: $P <host> <outlet> [-u <user>] [-p <pass>]"
+ exit 1
+}
+
+if {[string compare $host ""] == 0 ||
+ [string compare $outlet ""] == 0} \
+ {
+ puts stderr "host and outlet required"
+ exit 1
+ }
+
+spawn telnet $host
expect "User Name :"
-send "apc\r"
+send $user
+send "\r"
expect "Password :"
-send "apc\r"
+send $pass
+send "\r"
expect "1- Device Manager"
expect "> "
send "1\r"
-expect "3- Outlet Control/Configuration"
-expect "> "
-send "3\r"
-expect "Press <ENTER> to continue..."
+# We get a different prompt if we're just an outlet controller
+# decide which response we need to enter
+set timeout 2
+expect {
+ "3- Outlet Control/Configuration" {
+ send "3\r"
+ exp_continue
+ }
+ "2- Outlet Control" {
+ send "2\r"
+ exp_continue
+ }
+}
send "\r"
expect "> "
-send $port
+send $outlet
send "\r"
-expect "1- Control Outlet"
-expect "> "
-send "1\r"
+# Here too, if we're just an outlet controller we don't get the option
+# to modify configuration
+expect {
+ "1- Control Outlet" {
+ send "1\r"
+ }
+}
expect "3- Immediate Reboot"
expect "> "
send "3\r"
diff --git a/server.old/monitor_queue b/server.old/monitor_queue
new file mode 100755
index 0000000..75428cc
--- /dev/null
+++ b/server.old/monitor_queue
@@ -0,0 +1,70 @@
+#!/usr/bin/python -u
+# monitor_queue <client> <spool_directory> <resultsdir> [<conmux_console>]
+import os, time, sys
+from subprocess import *
+
+if (len(sys.argv) < 4):
+ print "Usage: monitor_queue <client> <spool_directory> <resultsdir> [<conmux_console>]"
+ sys.exit(1)
+(client, spooldir, resultsdir) = sys.argv[1:4]
+if len(sys.argv) == 5:
+ console = sys.argv[4]
+else:
+ console = None
+if not os.path.exists(spooldir):
+ print "spooldir %s does not exist" % spooldir
+ sys.exit(1)
+if not os.path.exists(resultsdir):
+ print "resultsdir %s does not exist" % resultsdir
+ sys.exit(1)
+
+
+def pick_job(jobs):
+ # Pick the next job to run. Currently we just pick the oldest job
+ # However, this would be the place to put prioritizations.
+ if not jobs:
+ return None
+ return sorted(jobs, key=lambda x:os.stat(x).st_mtime, reverse=True)[0]
+
+
+def run_job(control):
+ print "Executing job: " + next_job
+
+ # First set up some paths.
+ results = os.path.join(resultsdir, next_job)
+ if os.path.exists(results):
+ print "Resultsdir %s already present, " % results,
+ results = "%s.%d" % (results, int(time.time()))
+ print "changing to %s" % results
+ os.mkdir(results)
+ debug = os.path.join(results, 'debug')
+ os.mkdir(debug)
+
+ # Now run the job
+ runjob_cmd = ' '.join([runjob, client, next_job, results])
+ if console:
+ runjob_cmd += ' ' + console
+ server_log = open(os.path.join(debug, 'server.log'), 'w');
+ p = Popen(runjob_cmd, shell=True, stdout=server_log, stderr=STDOUT)
+ (pid, ret) = os.waitpid(p.pid, 0)
+ file.close(server_log)
+ print "Completed job: %s (%d) " % (next_job, ret)
+ return ret
+
+
+dir = os.path.abspath(os.path.dirname(sys.argv[0]))
+runjob = os.path.join(dir, 'runjob')
+os.chdir(spooldir)
+print "monitoring spool directory: " + spooldir
+while True:
+ jobs = [j for j in os.listdir(spooldir) if not j.startswith('.')]
+ next_job = pick_job(jobs)
+ if not next_job:
+ time.sleep(10)
+ continue
+ ret = run_job(next_job)
+ if ret == 1: # Ooops. the machine is stuffed.
+ print "WARNING: client %s failed verify_machine" % client
+ sleep(600)
+ continue
+ os.remove(next_job)
diff --git a/server.old/runjob b/server.old/runjob
new file mode 100755
index 0000000..1a0c25f
--- /dev/null
+++ b/server.old/runjob
@@ -0,0 +1,156 @@
+#!/usr/bin/python
+import sys, os, re, commands, time, signal
+from subprocess import *
+
+# Execute a job on a remote client. We use ssh to connect.
+#
+# autotest-client is run on the other end. It will connect us with
+# stdout and stderr outputs:
+#
+# stdout: standard output of autotest binary (job spew)
+# stderr: Control stream (read from named pipe on client
+#
+# We want to just log stdout to a server-side file.
+# Stderr is what we're monitoring closely for status.
+# If the stderr stream gives us an EOF, the autotest-client exited
+
+# Return codes:
+# 0 - success
+# 1 - verify machine failed
+# 2 - execute job failed
+
+autodir = '/usr/local/autotest' # default. changed by retrieve_config
+
+def parse_arguments():
+ # First parse arguments, do setup, etc.
+ if len(sys.argv) < 4:
+ sys.stderr.write("Usage: runjob <client> <control_file> <results> [<conmux_console>]\n")
+ sys.exit(1)
+ (client, control, results) = sys.argv[1:4]
+ if len(sys.argv) == 5:
+ console = sys.argv[4]
+ else:
+ console = None
+ if not os.path.exists(control):
+ sys.stderr.write("Control file %s does not exist\n" % control)
+ sys.exit(1)
+ return (client, control, results, console)
+
+
+def retrieve_config(client):
+ # Grab the autotest.conf file from the client,
+ # so we can use config information
+ print "Retrieving autotest.conf from %s" % client
+ local_conf = "/tmp/autotest.conf.%d" % os.getpid()
+ if os.path.exists(local_conf):
+ os.remove(local_conf)
+ os.system("scp -q root@%s:/etc/autotest.conf %s" % (client, local_conf))
+
+ # Now to find out what $AUTODIR is on the client
+ # This is disgusting, but will have to do for now.
+ # We can't source it (security nightmare)
+ global autodir
+ if os.path.exists(local_conf):
+ for line in open(local_conf, 'r').readlines():
+ dir = re.search(r'autodir=(\S+)', line).group(1)
+ if dir:
+ autodir = re.sub('[\'\"]', '', dir)
+ print "autodir set to " + autodir
+
+
+def verify_machine(client):
+ autotest_bin = os.path.join(autodir, 'bin/autotest')
+ ret = os.system("ssh -q root@%s ls %s > /dev/null" % (client, autotest_bin))
+ if ret != 0:
+ return False
+ return True
+
+
+def clean_house(client):
+ path = os.path.join(autodir, 'control')
+ ret = os.system("ssh -q root@%s rm -f %s" % (client, path))
+ path = os.path.join(autodir, 'control.state')
+ ret = os.system("ssh -q root@%s rm -f %s" % (client, path))
+
+
+def push_control(remote_control):
+ # Push the control file we want to sue to the client
+ print "Pushing control file %s to %s" % (control, client)
+ ret = os.system("scp -q %s root@%s:%s" % \
+ (control, client, remote_control))
+ if ret != 0:
+ raise "pushing control file failed"
+
+
+def execute_section(client, autodir, remote_control, section):
+ print "Executing %s/bin/autotest %s/control phase %d" % \
+ (autodir, autodir, section)
+ client_log = open("%s/debug/client.log.%d" % (results, section), 'w')
+ if section > 0:
+ remote_control = '-c ' + remote_control
+ cmd = "ssh -q root@%s %s/bin/autotest_client %s" % \
+ (client, autodir, remote_control)
+ f = Popen(cmd, shell=True, stdout=client_log, stderr=PIPE).stderr
+ line = None
+ for line in iter(f.readline, ''):
+ print line,
+ sys.stdout.flush()
+ return line
+
+
+def execute_control(client, autodir, remote_control):
+ section = 0
+ while True:
+ last = execute_section(client, autodir, remote_control, section)
+ section += 1
+ if re.match('DONE', last):
+ print "Client complete"
+ return True
+ elif re.match('REBOOT', last):
+ print "Client is rebooting"
+ time.sleep(300)
+ else:
+ sys.stderr.write("Aborting - unknown return code: %s\n"\
+ % last)
+ return False
+
+
+def retrieve_results(client, autodir, results):
+ ret = os.system("scp -rq root@%s:%s/results/default/* %s" % \
+ (client,autodir,results))
+ if ret != 0:
+ raise "retrieve results failed"
+
+
+# MAIN PROGRAM
+
+ret = 0
+(client, control, results, console) = parse_arguments()
+debug = os.path.join(results, 'debug')
+if not os.path.exists(debug):
+ os.makedirs(debug)
+
+if console:
+ console_log = open(os.path.join(debug, "console.log"), 'w')
+ conmux_path = os.path.join(os.path.dirname(sys.argv[0]), \
+ '../conmux/console')
+ cmd = os.path.abspath(conmux_path) + ' ' + console
+ # For some incomprehensible reason, conmux won't redirect to a file.
+ con = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)
+ Popen(['cat'], stdin=con.stdout, stdout=console_log)
+ con_pid = con.pid
+else:
+ con_pid = None
+
+retrieve_config(client)
+if not verify_machine(client):
+ sys.exit(1)
+clean_house(client)
+remote_control = "%s/control" % autodir
+push_control(remote_control)
+if not execute_control(client, autodir, remote_control):
+ ret = 2
+retrieve_results(client, autodir, results)
+if con_pid:
+ os.kill(con_pid, signal.SIGTERM)
+sys.exit(ret)
diff --git a/server.old/start_all_queues b/server.old/start_all_queues
new file mode 100755
index 0000000..3978ce4
--- /dev/null
+++ b/server.old/start_all_queues
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+import os, os.path, sys
+
+dir = os.path.abspath(os.path.dirname(sys.argv[0]))
+monitor_queue = os.path.join(dir, 'monitor_queue')
+
+if len(sys.argv) < 2:
+ print "Usage: start_all_queues <top_level_dir>"
+ sys.exit(1)
+
+top_dir = os.path.abspath(sys.argv[1])
+queue_dir = os.path.join(top_dir, 'queue')
+results_dir = os.path.join(top_dir, 'results')
+
+for machine in os.listdir(queue_dir):
+ queue = os.path.join(queue_dir, machine)
+ results = os.path.join(results_dir, machine)
+
+ if not os.path.exists(results):
+ print "No results directory: %s" % results
+ sys.exit(1)
+
+ console_path = "/usr/local/conmux/etc/%s.cf" % machine
+ if os.path.exists(console_path):
+ console = machine
+ else:
+ console = ''
+
+ cmd = ' '.join([monitor_queue, machine, queue, results, console])
+ print cmd
+ os.system("nohup %s > %s/.log 2>&1 &" % (cmd,queue))
+
diff --git a/server.old/testkernel b/server.old/testkernel
new file mode 100755
index 0000000..c680403
--- /dev/null
+++ b/server.old/testkernel
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+# testkernel <client> <control> <kernel> <config> <patches ...>
+#
+# Create a config that builds the kernel+patches specified,
+# then runs the tests specified in the control file supplied.
+#
+# Run that control file on the comma-separated list of machines supplied
+# by dumping a control file in $AUTOTEST_DIR/queue/machine.
+import os, sys, time
+
+if len(sys.argv) < 5:
+ print "Usage: testkernel <client> <control> <kernel> <config> <patches ...>"
+ sys.exit(1)
+(client, control, kernel, config) = sys.argv[1:5]
+if len(sys.argv) > 5:
+ patches = sys.argv[5:]
+else:
+ patches = []
+
+
+# Need to be careful to create the control file atomically, so don't end up
+# executing half of it. Try to create it in the same filesystem, then move it.
+queuedir = os.path.join(os.environ['AUTOTEST_DIR'], 'queue')
+tmpfile = os.path.join(queuedir, 'tmp_control.%d' % os.getpid())
+c = open(tmpfile, 'w')
+print >> c, "def step_init():"
+print >> c, "\t" + "job.next_step([step_test])"
+print >> c, "\t" + "testkernel = job.kernel('%s')" % kernel
+if patches:
+ patch_list = ', '.join(["'%s'" % x for x in patches])
+ print >> c, "\t" + "testkernel.patch(%s)" % patch_list
+print >> c, "\t" + "testkernel.config('%s')" % config
+print >> c, "\t" + "testkernel.build()"
+print >> c, "\t" + "testkernel.boot()"
+print >> c, ""
+print >> c, "def step_test():"
+
+for line in open(control, 'r'):
+ print >> c, "\t" + line,
+c.close()
+# This is pretty revolting, but will do as a hack for testing
+jobname = os.path.basename(control) + '.' + os.path.basename(kernel)
+output = os.path.join(queuedir, client, jobname)
+if os.path.exists(output):
+ output += ".%d" % int(time.time())
+os.rename(tmpfile, output)