Attached is a very large patch that adds support for running a
distributed Autotest service.  Previously, the scheduler could only
execute autoservs locally and all results were written directly to the
local filesystem.  This placed a limit on the number of machines that
could be concurrently tested by a single Autotest service instance due
to the strain of running many autoserv processes on a single machine.

With this change, the scheduler can spread autoserv processes among a
number of machines and gather all results to a single results
repository machine.  This allows vastly improved scalability for a
single Autotest service instance.  See
http://autotest.kernel.org/wiki/DistributedServerSetup for more
details.

Note that the single-server setup is still supported and the global
configuration defaults to this setup, so existing service instances
should continue to run.

Steve

Signed-off-by: Steve Howard <showard@google.com>




git-svn-id: http://test.kernel.org/svn/autotest/trunk@2596 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/client/common_lib/utils.py b/client/common_lib/utils.py
index 77d7e81..cde942f 100644
--- a/client/common_lib/utils.py
+++ b/client/common_lib/utils.py
@@ -21,7 +21,8 @@
 
 
 class BgJob(object):
-    def __init__(self, command, stdout_tee=None, stderr_tee=None, verbose=True):
+    def __init__(self, command, stdout_tee=None, stderr_tee=None, verbose=True,
+                 stdin=None):
         self.command = command
         self.stdout_tee = stdout_tee
         self.stderr_tee = stderr_tee
@@ -32,7 +33,8 @@
         self.sp = subprocess.Popen(command, stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE,
                                    preexec_fn=self._reset_sigpipe, shell=True,
-                                   executable="/bin/bash")
+                                   executable="/bin/bash",
+                                   stdin=stdin)
 
 
     def output_prepare(self, stdout_file=None, stderr_file=None):
@@ -300,7 +302,7 @@
 
 
 def run(command, timeout=None, ignore_status=False,
-        stdout_tee=None, stderr_tee=None, verbose=True):
+        stdout_tee=None, stderr_tee=None, verbose=True, stdin=None):
     """
     Run a command on the host.
 
@@ -316,6 +318,7 @@
                         will be written as it is generated (data will still
                         be stored in result.stdout)
             stderr_tee: likewise for stderr
+            stdin: stdin to pass to the executed process
 
     Returns:
             a CmdResult object
@@ -324,8 +327,9 @@
             CmdError: the exit code of the command
                     execution was not 0
     """
-    bg_job = join_bg_jobs((BgJob(command, stdout_tee, stderr_tee, verbose),),
-                          timeout)[0]
+    bg_job = join_bg_jobs(
+        (BgJob(command, stdout_tee, stderr_tee, verbose, stdin=stdin),),
+        timeout)[0]
     if not ignore_status and bg_job.result.exit_status:
         raise error.CmdError(command, bg_job.result,
                              "Command returned non-zero exit status")