Thanks for providing this.  I have a few minor comments, would you mind
putting this patch in a code review tool (like
http://codereview.appspot.com/)?

Thanks

Jean-Marc


On Tue, Jun 7, 2011 at 6:55 AM, Cleber Rosa <[email protected]> wrote:

> 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.
>
> Signed-off-by: Cleber Rosa <[email protected]>
> ---
>  contrib/virt/site_job.py |  193
> ++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 193 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..a062809
> --- /dev/null
> +++ b/contrib/virt/site_job.py
> @@ -0,0 +1,193 @@
> +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
> +
> +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
>
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to