As an attempt to fix problems found on our distro packages
for Fedora and RHEL, define that when autotest is running
using distro packages, it won't rsync any of the client code
to the client machines, instead, it will rely on the distro
packages themselves.

This of course reduces the usefulness of the autotest server,
since it can't test any client distro that does not have the
autotest client packaged, but this is an acceptable compromise
given the situation (frequently people using the distro
packages will be testing clients using that very same distro).

Simplify the code by ruling out rsyncs, and install/remove
autotest fom the clients using the distro supplied tools
(for now it works only for Fedora and RHEL).

Also add some more logging to the job log collector, so
we know which directories are being synced back to the
autotest server.

Signed-off-by: Lucas Meneghel Rodrigues <[email protected]>
---
 server/autotest_remote.py | 229 +++++++++++++++++++++++++++++-----------------
 1 file changed, 144 insertions(+), 85 deletions(-)

diff --git a/server/autotest_remote.py b/server/autotest_remote.py
index 8f7d9e3..d8b2341 100644
--- a/server/autotest_remote.py
+++ b/server/autotest_remote.py
@@ -3,10 +3,10 @@
 import re, os, sys, traceback, time, glob, tempfile, logging
 from autotest.server import installable_object, prebuild, utils
 from autotest.client import os_dep
+from autotest.client import utils as client_utils
 from autotest.client.shared import base_job, log, error, autotemp
 from autotest.client.shared import packages
 from autotest.client.shared.settings import settings, SettingsError
-from autotest.client.shared import utils as client_utils
 
 
 autoserv_prebuild = settings.get_value('AUTOSERV', 'enable_server_prebuild',
@@ -17,6 +17,39 @@ class AutodirNotFoundError(Exception):
     """No Autotest installation could be found."""
 
 
+# Paths you'll find when autotest is installed via distro package
+SYSTEM_WIDE_PATHS = ['/usr/bin/autotest-local',
+                     '/usr/bin/autotest-local-streamhandler',
+                     '/usr/bin/autotest-daemon',
+                     '/usr/bin/autotest-daemon-monitor']
+
+
+def _server_system_wide_install():
+    for path in SYSTEM_WIDE_PATHS:
+        try:
+            os_dep.command(path)
+        except ValueError:
+            return False
+    return True
+
+
+def _client_system_wide_install(host):
+    for path in SYSTEM_WIDE_PATHS:
+        try:
+            host.run('test -x %s' % utils.sh_escape(path))
+        except:
+            return False
+    return True
+
+# For now, the only fully developed distro package is in Fedora/RHEL
+_yum_install_cmd = 'yum -y install autotest-framework'
+_yum_uninstall_cmd = 'yum -y remove autotest-framework'
+INSTALL_CLIENT_CMD_MAPPING = {'Fedora': _yum_install_cmd,
+                              'RHEL': _yum_install_cmd}
+UNINSTALL_CLIENT_CMD_MAPPING = {'Fedora': _yum_uninstall_cmd,
+                                'RHEL': _yum_uninstall_cmd}
+
+
 class BaseAutotest(installable_object.InstallableObject):
     """
     This class represents the Autotest program.
@@ -34,6 +67,8 @@ class BaseAutotest(installable_object.InstallableObject):
         self.got = False
         self.installed = False
         self.serverdir = utils.get_server_dir()
+        self.os_vendor = client_utils.get_os_vendor()
+        self.server_system_wide_install = _server_system_wide_install()
         super(BaseAutotest, self).__init__()
 
 
@@ -65,31 +100,24 @@ class BaseAutotest(installable_object.InstallableObject):
             logging.debug('Using existing host autodir: %s', autodir)
             return autodir
 
-
-        system_wide = True
-        autotest_system_wide = '/usr/bin/autotest-local'
-        try:
-            host.run('test -x %s' % utils.sh_escape(autotest_system_wide))
-            logging.info("System wide install detected")
-        except:
-            system_wide = False
-
-        for path in Autotest.get_client_autodir_paths(host):
-            try:
+        if not _server_system_wide_install():
+            for path in Autotest.get_client_autodir_paths(host):
                 try:
                     autotest_binary = os.path.join(path, 'autotest')
                     host.run('test -x %s' % utils.sh_escape(autotest_binary))
+                    host.run('test -w %s' % utils.sh_escape(path))
+                    logging.debug('Found existing autodir at %s', path)
+                    return path
                 except error.AutoservRunError:
-                    if system_wide:
-                        pass
-                    else:
-                        raise
+                    logging.debug('%s does not exist on %s', autotest_binary,
+                                  host.hostname)
+        else:
+            for path in Autotest.get_client_autodir_paths(host):
                 host.run('test -w %s' % utils.sh_escape(path))
                 logging.debug('Found existing autodir at %s', path)
+                host.autodir = path
                 return path
-            except error.AutoservRunError:
-                logging.debug('%s does not exist on %s', autotest_binary,
-                              host.hostname)
+
         raise AutodirNotFoundError
 
 
@@ -179,26 +207,11 @@ class BaseAutotest(installable_object.InstallableObject):
 
 
     def _install_using_send_file(self, host, autodir):
-        system_wide = True
-        try:
-            autotest_local = os_dep.command('autotest-local')
-            autotest_local_streamhandler = 
os_dep.command('autotest-local-streamhandler')
-            autotest_daemon = os_dep.command('autotest-daemon')
-            autotest_daemon_monitor = os_dep.command('autotest-daemon-monitor')
-        except:
-            system_wide = False
-
         dirs_to_exclude = set(["tests", "site_tests", "deps", "profilers"])
         light_files = [os.path.join(self.source_material, f)
                        for f in os.listdir(self.source_material)
                        if f not in dirs_to_exclude]
 
-        if system_wide:
-            light_files.append(autotest_local)
-            light_files.append(autotest_local_streamhandler)
-            light_files.append(autotest_daemon)
-            light_files.append(autotest_daemon_monitor)
-
         # there should be one and only one grubby tarball
         grubby_glob = os.path.join(self.source_material,
                                    "deps/grubby/grubby-*.tar.bz2")
@@ -249,6 +262,30 @@ class BaseAutotest(installable_object.InstallableObject):
         host.setup()
         logging.info("Installing autotest on %s", host.hostname)
 
+        if self.server_system_wide_install:
+            msg_install = ("Autotest seems to be installed in the "
+                           "client on a system wide location, proceeding...")
+
+            logging.info("Verifying client package install")
+            if _client_system_wide_install(host):
+                logging.info(msg_install)
+                self.installed = True
+                return
+
+            install_cmd = INSTALL_CLIENT_CMD_MAPPING.get(self.os_vendor, None)
+            if install_cmd is not None:
+                logging.info(msg_install)
+                host.run(install_cmd)
+                if _client_system_wide_install(host):
+                    logging.info("Autotest seems to be installed in the "
+                                 "client on a system wide location, 
proceeding...")
+                    self.installed = True
+                    return
+
+            raise error.AutoservError("The autotest client package "
+                                      "does not seem to be installed "
+                                      "on %s" % host.hostname)
+
         # set up the autotest directory on the remote machine
         if not autodir:
             autodir = self.get_install_dir(host)
@@ -302,6 +339,14 @@ class BaseAutotest(installable_object.InstallableObject):
         """
         if not self.installed:
             return
+        if self.server_system_wide_install:
+            uninstall_cmd = UNINSTALL_CLIENT_CMD_MAPPING.get(self.os_vendor,
+                                                             None)
+            if uninstall_cmd is not None:
+                logging.info("Trying to uninstall autotest using distro "
+                             "provided package manager")
+                host.run(uninstall_cmd)
+            return
         if not host:
             host = self.host
         autodir = host.get_autodir()
@@ -318,14 +363,15 @@ class BaseAutotest(installable_object.InstallableObject):
         if not location:
             location = os.path.join(self.serverdir, '../client')
             location = os.path.abspath(location)
-        # If there's stuff run on our client directory already, it
-        # can cause problems. Try giving it a quick clean first.
-        cwd = os.getcwd()
-        os.chdir(location)
-        try:
-            utils.system('tools/make_clean', ignore_status=True)
-        finally:
-            os.chdir(cwd)
+        if not self.server_system_wide_install:
+            # If there's stuff run on our client directory already, it
+            # can cause problems. Try giving it a quick clean first.
+            cwd = os.getcwd()
+            os.chdir(location)
+            try:
+                utils.system('tools/make_clean', ignore_status=True)
+            finally:
+                os.chdir(cwd)
         super(BaseAutotest, self).get(location)
         self.got = True
 
@@ -486,15 +532,22 @@ class _BaseRun(object):
         self.tag = tag
         self.parallel_flag = parallel_flag
         self.background = background
+        self.server_system_wide_install = _server_system_wide_install()
+
         self.autodir = Autotest.get_installed_autodir(self.host)
-        control = os.path.join(self.autodir, 'control')
-        if tag:
-            control += '.' + tag
 
         tmpdir = os.path.join(self.autodir, 'tmp')
         state_dir = settings.get_value('COMMON', 'test_output_dir',
                                        default=tmpdir)
 
+        if self.server_system_wide_install:
+            control = os.path.join(state_dir, 'control')
+        else:
+            control = os.path.join(self.autodir, 'control')
+
+        if tag:
+            control += '.' + tag
+
         self.manual_control_file = control
         self.manual_control_init_state = os.path.join(state_dir,
                           os.path.basename(control) + ".init.state")
@@ -506,26 +559,33 @@ class _BaseRun(object):
                           os.path.basename(control) + ".autoserv.init.state")
         self.remote_control_state = os.path.join(state_dir,
                           os.path.basename(control) + ".autoserv.state")
+        logging.debug("Remote control file: %s", self.remote_control_file)
+        logging.debug("Remote control init state: %s", 
self.remote_control_init_state)
+        logging.debug("Remote control state: %s", self.remote_control_state)
 
         self.config_file = os.path.join(self.autodir, 'global_config.ini')
 
 
-    def verify_machine(self):
-        system_wide = True
-        binary = os.path.join('/usr/bin/autotest-local')
+    def _verify_machine_system_wide(self):
+        if not _client_system_wide_install(self.host):
+            raise error.AutoservInstallError("Autotest does not appear "
+                                             "to be installed")
+
+
+    def _verify_machine_local(self):
+        binary = os.path.join(self.autodir, 'autotest')
         try:
             self.host.run('test -x %s' % binary)
         except:
-            system_wide = False
+            raise error.AutoservInstallError("Autotest does not appear "
+                                             "to be installed")
 
-        if not system_wide:
-            binary = os.path.join(self.autodir, 'autotest')
-            try:
-                self.host.run('test -x %s' % binary)
-            except:
-                raise error.AutoservInstallError(
-                    "Autotest does not appear to be installed")
 
+    def verify_machine(self):
+        if self.server_system_wide_install:
+            self._verify_machine_system_wide()
+        else:
+            self._verify_machine_local()
         if not self.parallel_flag:
             tmpdir = os.path.join(self.autodir, 'tmp')
             download = os.path.join(self.autodir, 'tests/download')
@@ -550,14 +610,8 @@ class _BaseRun(object):
 
 
     def get_background_cmd(self, section):
-        system_wide = True
         system_wide_client_path = '/usr/bin/autotest-local-streamhandler'
-        try:
-            self.host.run('test -x %s' % system_wide_client_path)
-        except:
-            system_wide = False
-
-        if system_wide:
+        if self.server_system_wide_install:
             cmd = ['nohup', system_wide_client_path]
         else:
             cmd = ['nohup', os.path.join(self.autodir, 'autotest_client')]
@@ -567,14 +621,8 @@ class _BaseRun(object):
 
 
     def get_daemon_cmd(self, section, monitor_dir):
-        system_wide = True
         system_wide_client_path = '/usr/bin/autotest-daemon'
-        try:
-            self.host.run('test -x %s' % system_wide_client_path)
-        except:
-            system_wide = False
-
-        if system_wide:
+        if self.server_system_wide_install:
             cmd = ['nohup', system_wide_client_path,
                    monitor_dir, '-H autoserv']
         else:
@@ -587,14 +635,8 @@ class _BaseRun(object):
 
 
     def get_monitor_cmd(self, monitor_dir, stdout_read, stderr_read):
-        system_wide = True
         system_wide_client_path = '/usr/bin/autotest-daemon-monitor'
-        try:
-            system_wide = self.host.run('test -x %s' % system_wide_client_path)
-        except:
-            system_wide = False
-
-        if system_wide:
+        if self.server_system_wide_install:
             cmd = [system_wide_client_path,
                    monitor_dir, str(stdout_read), str(stderr_read)]
         else:
@@ -625,9 +667,12 @@ class _BaseRun(object):
 
         @param client_log_prefix: Optional prefix to prepend to log files.
         """
-        client_config_file = self._create_client_config_file(client_log_prefix)
-        self.host.send_file(client_config_file, self.config_file)
-        os.remove(client_config_file)
+        if not self.server_system_wide_install:
+            client_config_file = 
self._create_client_config_file(client_log_prefix)
+            self.host.send_file(client_config_file, self.config_file)
+            os.remove(client_config_file)
+        else:
+            logging.info("System wide install, not overriding client config")
 
 
     def _create_client_config_file(self, client_log_prefix=None):
@@ -768,8 +813,13 @@ class _BaseRun(object):
 
     def execute_section(self, section, timeout, stderr_redirector,
                         client_disconnect_timeout):
-        logging.info("Executing %s/autotest %s/control phase %d",
-                     self.autodir, self.autodir, section)
+        if self.server_system_wide_install:
+            autotest_local_bin = "/usr/bin/autotest-local"
+        else:
+            autotest_local_bin = os.path.join(self.autodir, "autotest")
+
+        logging.info("Executing %s %s phase %d",
+                     autotest_local_bin, self.remote_control_file , section)
 
         if self.background:
             result = self._execute_in_background(section, timeout)
@@ -895,9 +945,18 @@ class log_collector(object):
         self.host = host
         if not client_tag:
             client_tag = "default"
-        self.client_results_dir = os.path.join(host.get_autodir(), "results",
-                                               client_tag)
+        if _server_system_wide_install():
+            output_dir = settings.get_value("CLIENT", "output_dir")
+        else:
+            output_dir = host.get_autodir()
+
+        self.client_results_dir = os.path.join(output_dir,
+                                               "results", client_tag)
+
         self.server_results_dir = results_dir
+        logging.debug("Log collector initialized")
+        logging.debug("Client results dir: %s", self.client_results_dir)
+        logging.debug("Server results dir: %s", self.server_results_dir)
 
 
     def collect_client_job_results(self):
@@ -916,7 +975,7 @@ class log_collector(object):
 
         # Copy all dirs in default to results_dir
         try:
-            self.host.get_file(self.client_results_dir + '/',
+            self.host.get_file(self.client_results_dir + "/",
                                self.server_results_dir, preserve_symlinks=True)
         except Exception:
             # well, don't stop running just because we couldn't get logs
-- 
1.8.1.4

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

Reply via email to