This module contains extensions to 'atest' that proved to be useful
when doing virtualization testing of multiple KVM versions, on multiple
operating system versions (Fedora, RHEL5, RHEL6).

This attempts to kick off the sharing of site_*.py files that
might be useful to others.

Changes from v1 (based on feedback from [email protected]):
 * Configure logging so that messages are output in the same format
   as other autotest messages
 * Renamed private methods from using double underscores to a single
   underscore

Signed-off-by: Cleber Rosa <[email protected]>
---
 contrib/virt/site_job.py |  197 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 197 insertions(+), 0 deletions(-)
 create mode 100644 contrib/virt/site_job.py

diff --git a/contrib/virt/site_job.py b/contrib/virt/site_job.py
new file mode 100644
index 0000000..e75b438
--- /dev/null
+++ b/contrib/virt/site_job.py
@@ -0,0 +1,197 @@
+import os, re, sys, pwd, time, socket, getpass
+import inspect, new, logging, string, tempfile
+
+from autotest_lib.cli import topic_common, action_common
+from autotest_lib.cli import job
+from autotest_lib.client.common_lib import logging_config
+from autotest_lib.client.virt import virt_utils
+
+logging_config.LoggingConfig().configure_logging(verbose=True)
+
+
+class site_job(job.job):
+    pass
+
+
+class site_job_create(job.job_create):
+    """
+    Adds job manipulation including installing packages from brew
+    """
+
+    op_action = 'create'
+
+    def __init__(self):
+        super(site_job_create, self).__init__()
+        self.parser.add_option('-T', '--template', action='store_true',
+                               help='Control file is actually a template')
+        self.parser.add_option('--extra-cartesian-config',
+                               help='Add extra configuration to the cartesian '
+                               'config file')
+        self.parser.add_option('--timestamp', action='store_true',
+                               help='Add a timestamp to the name of the job')
+        self.parser.add_option('--koji-arch', default='x86_64',
+                               help='Default architecture for packages '
+                               'that will be fetched from koji build. '
+                               'This will be combined with "noarch".'
+                               'This option is used to help to validate '
+                               'packages from the job submitting machine.')
+        self.parser.add_option('--koji-tag', help='Sets a default koji tag '
+                               'for koji packages specified with --koji-pkg')
+        self.parser.add_option('--koji-pkg', action='append',
+                               help='Packages to add to host installation '
+                               'based on koji build. This options may be '
+                               'specified multiple times.')
+        self.koji_client = None
+
+
+    def parse(self):
+        '''
+        Parse options.
+
+        If any brew options is specified, instantiate KojiDownloader
+        '''
+        (self.command_line_options,
+         self.command_line_leftover) = super(site_job_create, self).parse()
+
+        #
+        # creating the new control file
+        #
+        if (self.command_line_options.template and
+            self.command_line_options.control_file):
+            generated_control_file = self._generate_control_file()
+            self.data['control_file'] = open(generated_control_file).read()
+
+        if self.command_line_options.koji_pkg:
+            if self.koji_client is None:
+                self.koji_client = virt_utils.KojiClient()
+
+        return (self.command_line_options, self.command_line_leftover)
+
+
+    def _process_options(self):
+        '''
+        Process all options given on command line
+        '''
+        all_options_valid = True
+
+        self._set_koji_tag()
+        if not self._check_koji_packages():
+            all_options_valid = False
+
+        return all_options_valid
+
+
+    def _set_koji_tag(self):
+        '''
+        Sets the default koji tag.
+
+        Configuration item on file is: koji_tag
+        '''
+        if self.command_line_options.koji_tag is not None:
+            virt_utils.set_default_koji_tag(self.command_line_options.koji_tag)
+
+
+    def _check_koji_packages(self):
+        '''
+        Check if packages specification are valid and exist on koji/brew
+
+        Configuration item on file is: koji_pkgs
+        '''
+        all_packages_found = True
+        if self.command_line_options.koji_pkg is not None:
+            logging.debug('Checking koji packages specification')
+            for pkg_spec_text in self.command_line_options.koji_pkg:
+                pkg_spec = virt_utils.KojiPkgSpec(pkg_spec_text)
+
+                if not (pkg_spec.is_valid() and
+                        self.koji_client.is_pkg_valid(pkg_spec)):
+                    logging.error('Koji package spec is not valid, skipping: '
+                                  '%s' % pkg_spec)
+                    all_packages_found = False
+                else:
+                    rpms = self.koji_client.get_pkg_rpm_info(
+                        pkg_spec,
+                        self.command_line_options.koji_arch)
+                    for subpackage in pkg_spec.subpackages:
+                        if subpackage not in [rpm['name'] for rpm in rpms]:
+                            logging.error('Package specified but not found in '
+                                          'koji: %s' % subpackage)
+                            all_packages_found = False
+
+                    rpms = ", ".join(rpm['nvr'] for rpm in rpms)
+                    logging.debug('Koji package spec is valid')
+                    logging.debug('Koji packages to be fetched and installed: '
+                                  '%s' % rpms)
+
+        return all_packages_found
+
+    def _generate_job_config(self):
+        '''
+        Converts all options given on the command line to config file syntax
+        '''
+        extra = []
+        if self.command_line_options.extra_cartesian_config:
+            extra.append(self.command_line_options.extra_cartesian_config)
+
+        if self.command_line_options.koji_tag:
+            extra.append("koji_tag = %s" % self.command_line_options.koji_tag)
+
+        if self.command_line_options.koji_pkg:
+            koji_pkgs = []
+            for koji_pkg in self.command_line_options.koji_pkg:
+                koji_pkgs.append('"%s"' % koji_pkg)
+            extra.append("koji_pkgs = [%s]" % ', '.join(koji_pkgs))
+
+        # add quotes...
+        extra = ["'%s'" % e for e in extra]
+        # ... and return as string that will be eval'd as a Python list
+        return "[%s]" % ', '.join(extra)
+
+
+    def _generate_control_file(self):
+        '''
+        Generates a controle file from a template
+        '''
+        custom_job_cfg = self._generate_job_config()
+        input_file = self.command_line_options.control_file
+        logging.debug('Generating control file from template: %s' % input_file)
+        template = string.Template(open(input_file).read())
+        output_fd, path = tempfile.mkstemp(prefix='atest_control_', dir='/tmp')
+        logging.debug('Generated control file to be saved at: %s' % path)
+        parameters_dict = {"custom_job_cfg": custom_job_cfg}
+        control_file_text = template.substitute(parameters_dict)
+        os.write(output_fd, control_file_text)
+        os.close(output_fd)
+        return path
+
+
+    def execute(self):
+        if not self._process_options():
+            self.generic_error('Some command line options validation failed. '
+                               'Aborting job creation.')
+            return
+
+        #
+        # add timestamp to the jobname
+        #
+        if self.command_line_options.timestamp:
+            logging.debug("Adding timestamp to jobname")
+            timestamp = time.strftime(" %m-%d-%Y %H:%M:%S", time.localtime())
+            self.jobname += timestamp
+            self.data['name'] = self.jobname
+
+        execute_results = super(site_job_create, self).execute()
+        self.output(execute_results)
+
+
+for cls in [getattr(job, n) for n in dir(job) if not n.startswith("_")]:
+    if not inspect.isclass(cls):
+        continue
+    cls_name = cls.__name__
+    site_cls_name = 'site_' + cls_name
+    if hasattr(sys.modules[__name__], site_cls_name):
+        continue
+    bases = (site_job, cls)
+    members = {'__doc__': cls.__doc__}
+    site_cls = new.classobj(site_cls_name, bases, members)
+    setattr(sys.modules[__name__], site_cls_name, site_cls)
-- 
1.7.4.4

_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to