Because beaker uses the 'push' method for running tests, there has always
been a catch-22 on how to start autotest after provisioning the box.

Currently, beaker uses a daemon called 'beah' to do all the initial
bootstrapping.  In order to move away from beah we needed another
alternate approach.

Bill P. suggested to use an env variable.  So that is what I did.
When autotest runs from the /etc/init.d on bootup it will look for
'AUTOTEST_HARNESS'.  If that is set, call 'autotest bootstrap'.  The
env will tell autotest to use the harness beaker, download an initial
control and pass that to the 'run' command.  autotest will proceed as normal.

This is kind of an ugly hack but I could not think of another solution to deal
with bootstrapping after provisioning.

Signed-off-by: Don Zickus <[email protected]>
---
 client/autotest_local.py |    2 +-
 client/cmdparser.py      |   78 ++++++++++++++++++++++++++++++++++++++++------
 client/shared/error.py   |    4 ++
 3 files changed, 73 insertions(+), 11 deletions(-)

diff --git a/client/autotest_local.py b/client/autotest_local.py
index ab5dbd6..0ebe42c 100644
--- a/client/autotest_local.py
+++ b/client/autotest_local.py
@@ -44,7 +44,7 @@ class AutotestLocalApp:
 
     def parse_cmdline(self):
         self.options, args = self.opt_parser.parse_args()
-        self.args = self.cmd_parser.parse_args(args)
+        self.args = self.cmd_parser.parse_args(args, self.options)
 
         # Check for a control file if not in prebuild mode.
         if len(args) != 1 and self.options.client_test_setup is None:
diff --git a/client/cmdparser.py b/client/cmdparser.py
index 5683835..90e3703 100644
--- a/client/cmdparser.py
+++ b/client/cmdparser.py
@@ -8,7 +8,8 @@ import os, re, sys, logging
 from autotest.client import os_dep, utils
 from autotest.client.shared import logging_config, logging_manager
 from autotest.client.shared.settings import settings
-from autotest.client.shared import packages
+from autotest.client.shared import packages, error
+from autotest.client import harness
 
 LOCALDIRTEST = "tests"
 GLOBALDIRTEST = settings.get_value('COMMON', 'test_dir', default="")
@@ -26,7 +27,7 @@ FETCHDIRTEST = os.path.join(output_dir, 'site_tests')
 if not os.path.isdir(FETCHDIRTEST):
     os.makedirs(FETCHDIRTEST)
 
-DEBUG = False
+DEBUG = True
 
 class CmdParserLoggingConfig(logging_config.LoggingConfig):
     """
@@ -35,16 +36,17 @@ class CmdParserLoggingConfig(logging_config.LoggingConfig):
     """
     def configure_logging(self, results_dir=None, verbose=False):
         super(CmdParserLoggingConfig, self).configure_logging(use_console=True,
-                                                              verbose=False)
-
-logging_manager.configure_logging(CmdParserLoggingConfig())
+                                                              verbose=verbose)
 
 class CommandParser(object):
     """
     A client-side command wrapper for the autotest client.
     """
 
-    COMMAND_LIST = ['help', 'list', 'run', 'fetch']
+    COMMAND_LIST = ['help', 'list', 'run', 'fetch', 'bootstrap']
+
+    def __init__(self):
+        self.internal_fetch = False
 
     @classmethod
     def _print_control_list(cls, pipe, path):
@@ -87,7 +89,7 @@ class CommandParser(object):
                     pipe.write(' %-50s %s\n' % (text, desc))
 
 
-    def fetch(self, args):
+    def fetch(self, args, options):
         """
         fetch a remote control file or packages
 
@@ -114,6 +116,9 @@ class CommandParser(object):
         pkgmgr.install_pkg(name, 'test', pkg_dir, install_dir,
             repo_url=url)
 
+        if self.internal_fetch:
+            return test_name
+
         raise SystemExit(0)
 
 
@@ -125,6 +130,8 @@ class CommandParser(object):
         @param args is not used here.
         """
         logging.info("Commands:")
+        logging.info("bootstrap [-H <harness>] Use harness to fetch control 
file")
+        logging.info("\tcan also export AUTOTEST_HARNESS=<harness> to avoid -H 
option")
         logging.info("fetch <url> [<file>]\tFetch a remote file/package and 
install it")
         logging.info("\tgit://...:[<branch>] [<file/directory>]")
         logging.info("\thttp://... [<file>]")
@@ -182,12 +189,14 @@ class CommandParser(object):
         raise SystemExit(0)
 
 
-    def parse_args(self, args):
+    def parse_args(self, args, options):
         """
         Process a client side command.
 
         @param args: Command line args.
         """
+        logging_manager.configure_logging(CmdParserLoggingConfig(), 
verbose=options.verbose)
+
         if len(args) and args[0] in self.COMMAND_LIST:
             cmd = args.pop(0)
         else:
@@ -199,7 +208,7 @@ class CommandParser(object):
             cmd = 'list_tests'
         try:
             try:
-                args = getattr(self, cmd)(args)
+                args = getattr(self, cmd)(args, options)
             except TypeError:
                 args = getattr(self, cmd)()
         except SystemExit, return_code:
@@ -215,7 +224,7 @@ class CommandParser(object):
         return args
 
 
-    def run(self, args):
+    def run(self, args, options):
         """
         Wrap args with a path and send it back to autotest.
         """
@@ -241,3 +250,52 @@ class CommandParser(object):
 
         logging.error("Can not find test %s", test)
         raise SystemExit(1)
+
+    def bootstrap(self, args, options):
+        """
+        Bootstrap autotest by fetching the control file first and pass it back
+
+        Currently this relies on a harness to retrieve the file
+        """
+        def harness_env():
+            if 'AUTOTEST_HARNESS' in os.environ:
+                return os.environ['AUTOTEST_HARNESS']
+            return None
+
+        class stub_job(object):
+            def config_set(self, name, value):
+                return
+
+        if not options.harness and not harness_env():
+            self.help()
+
+        if options.harness:
+            harness_name = options.harness
+        elif harness_env():
+            harness_name = harness_env()
+            options.harness = harness_name
+
+        if options.harness_args:
+            harness_args = options.harness_args
+        else:
+            harness_args = None
+
+        myjob=stub_job()
+
+        # let harness initialize itself
+        try:
+            myharness = harness.select(harness_name, myjob, harness_args)
+            if not getattr(myharness, 'bootstrap'):
+                raise error.HarnessError("Does not support bootstrapping\n")
+        except Exception, error_detail:
+            if DEBUG:
+                raise
+            sys.stderr.write("Harness %s failed to initialize -> %s\n" % 
(harness_name, error_detail))
+            self.help()
+            sys.exit(1)
+
+        # get remote control file and stick it in FETCHDIRTEST
+        control = myharness.bootstrap(FETCHDIRTEST)
+        args.append(control)
+
+        return args
diff --git a/client/shared/error.py b/client/shared/error.py
index cf7793a..a0b1667 100644
--- a/client/shared/error.py
+++ b/client/shared/error.py
@@ -307,6 +307,10 @@ class DataSyncError(NetCommunicationError):
     pass
 
 
+class HarnessError(JobError):
+    """Indicates problem with the harness."""
+    pass
+
 class InstallError(JobError):
     """Indicates an installation error which Terminates and fails the job."""
     pass
-- 
1.7.1

_______________________________________________
Autotest-kernel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/autotest-kernel

Reply via email to