]> git-server-git.apps.pok.os.sepia.ceph.com Git - teuthology.git/commitdiff
Enable kernel installs from koji
authorAndrew Schoen <aschoen@redhat.com>
Thu, 22 Jan 2015 16:46:08 +0000 (10:46 -0600)
committerAndrew Schoen <aschoen@redhat.com>
Mon, 26 Jan 2015 21:12:15 +0000 (15:12 -0600)
This enables a kernel to be installed from koji by putting the
following stanza under 'kernel' in your yaml config, 'koji: <build_id>'.

Signed-off-by: Andrew Schoen <aschoen@redhat.com>
teuthology/exceptions.py
teuthology/task/kernel.py

index df3ac4369f57f6b8122b77a4fdfcc16245ba5c4a..d2f257af39c61dc6125d57df92c352de84f73474 100644 (file)
@@ -21,6 +21,13 @@ class BootstrapError(RuntimeError):
     pass
 
 
+class ConfigError(RuntimeError):
+    """
+    Meant to be used when an invalid config entry is found.
+    """
+    pass
+
+
 class CommandFailedError(Exception):
 
     """
index 69477c141e10633b65abff76e6988bd0a0dc7726..69e2d616bb84b4774d78d05b3f89bfe8c504da7f 100644 (file)
@@ -9,11 +9,12 @@ import re
 import shlex
 import urllib2
 import urlparse
+import ast
 
 from teuthology import misc as teuthology
 from ..orchestra import run
 from ..config import config as teuth_config
-from ..exceptions import UnsupportedPackageTypeError
+from ..exceptions import UnsupportedPackageTypeError, ConfigError
 
 log = logging.getLogger(__name__)
 
@@ -58,7 +59,7 @@ def normalize_config(ctx, config):
     """
     if config is None or \
             len(filter(lambda x: x in ['tag', 'branch', 'sha1', 'kdb',
-                                       'deb', 'rpm'],
+                                       'deb', 'rpm', 'brew'],
                        config.keys())) == len(config.keys()):
         new_config = {}
         if config is None:
@@ -177,7 +178,7 @@ def install_firmware(ctx, config):
     fw_dir = '/lib/firmware/updates'
 
     for role in config.iterkeys():
-        if config[role].find('distro') >= 0:
+        if isinstance(config[role], str) and config[role].find('distro') >= 0:
             log.info('Skipping firmware on distro kernel');
             return
         (role_remote,) = ctx.cluster.only(role).remotes.keys()
@@ -252,13 +253,33 @@ def download_kernel(ctx, config):
     """
     procs = {}
     for role, src in config.iteritems():
+        needs_download = False
+
         if src == 'distro':
             # don't need to download distro kernels
             log.debug("src is distro, skipping download");
             continue
 
         (role_remote,) = ctx.cluster.only(role).remotes.keys()
-        if src.find('/') >= 0:
+        if isinstance(src, dict):
+            # we're downloading a kernel from brew, the src dict here
+            # is the build_info retrieved from brew using koji
+            build_id = src["id"]
+            log.info("Downloading kernel with build_id {build_id} on {role}...".format(
+                build_id=build_id,
+                role=role
+            ))
+            needs_download = True
+            baseurl = "{brewroot}/kernel/{ver}/{rel}/x86_64/".format(
+                brewroot="http://download.devel.redhat.com/brewroot/packages",
+                ver=src["version"],
+                rel=src["release"],
+            )
+            pkg_name = "kernel-{ver}-{rel}.x86_64.rpm".format(
+                ver=src["version"],
+                rel=src["release"],
+            )
+        elif src.find('/') >= 0:
             # local package - src is path
             log.info('Copying kernel package {path} to {role}...'.format(
                 path=src, role=role))
@@ -277,6 +298,7 @@ def download_kernel(ctx, config):
             # gitbuilder package - src is sha1
             log.info('Downloading kernel {sha1} on {role}...'.format(sha1=src,
                                                                      role=role))
+            needs_download = True
             package_type = role_remote.os.package_type
             if package_type == 'rpm':
                 system_type, system_ver = teuthology.get_system_type(
@@ -300,13 +322,17 @@ def download_kernel(ctx, config):
                 dist=ldist,
                 )
 
+            pkg_name = gitbuilder_pkg_name(role_remote)
+
             log.info("fetching, gitbuilder baseurl is %s", baseurl)
+
+        if needs_download:
             proc = role_remote.run(
                 args=[
                     'rm', '-f', remote_pkg_path(role_remote),
                     run.Raw('&&'),
                     'echo',
-                    gitbuilder_pkg_name(role_remote),
+                    pkg_name,
                     run.Raw('|'),
                     'wget',
                     '-nv',
@@ -359,7 +385,7 @@ def install_and_reboot(ctx, config):
     kernel_title = ''
     for role, src in config.iteritems():
         (role_remote,) = ctx.cluster.only(role).remotes.keys()
-        if src.find('distro') >= 0:
+        if isinstance(src, str) and src.find('distro') >= 0:
             log.info('Installing distro kernel on {role}...'.format(role=role))
             install_kernel(role_remote)
             continue
@@ -1004,6 +1030,9 @@ def task(ctx, config):
     need_version = {}  # utsrelease or sha1
     kdb = {}
     for role, role_config in config.iteritems():
+        # gather information about this remote
+        (role_remote,) = ctx.cluster.only(role).remotes.keys()
+        system_type, system_ver = role_remote.os.name, role_remote.os.version
         if role_config.get('rpm') or role_config.get('deb'):
             # We only care about path - deb: vs rpm: is meaningless,
             # rpm: just happens to be parsed first.  Nothing is stopping
@@ -1021,11 +1050,66 @@ def task(ctx, config):
             if need_to_install_distro(ctx, role):
                 need_install[role] = 'distro'
                 need_version[role] = 'distro'
+        elif role_config.get("koji", None):
+            # installing a kernel from koji
+            build_id = role_config.get("koji")
+            if role_remote.os.package_type != "rpm":
+                msg = (
+                    "Installing a kernel from koji is only supported "
+                    "on rpm based systems. System type is {system_type}."
+                )
+                msg = msg.format(system_type=system_type)
+                log.error(msg)
+                ctx.summary["failure_reason"] = msg
+                ctx.summary["status"] = "dead"
+                raise ConfigError(msg)
+
+            # FIXME: this install should probably happen somewhere else
+            # but I'm not sure where, so we'll leave it here for now.
+            log.info("Installing koji on {0}".format(role))
+            role_remote.run(
+                args=["sudo", "yum", "-y", "install", "koji"],
+            )
+
+            # put all this in it's own function
+            py_cmd = ('import koji; '
+                      'hub = koji.ClientSession("{brewhub_url}"); '
+                      'print hub.getBuild({build_id})')
+            py_cmd = py_cmd.format(
+                build_id=build_id,
+                brewhub_url="http://brewhub.devel.redhat.com/brewhub"
+            )
+            proc = role_remote.run(
+                args=[
+                    'python', '-c', py_cmd
+                ],
+                stdout=StringIO(), stderr=StringIO(), check_status=False
+            )
+            if proc.exitstatus == 0:
+                # returns the __repr__ of a python dict
+                stdout = proc.stdout.getvalue().strip()
+                # take the __repr__ and makes it a python dict again
+                build_info = ast.literal_eval(stdout)
+            else:
+                # this should explode
+                msg = "Failed to query koji for build {0}".format(build_id)
+                log.error(msg)
+                log.error("stdout: {0}".format(proc.stdout.getvalue().strip()))
+                log.error("stderr: {0}".format(proc.stderr.getvalue().strip()))
+                ctx.summary["failure_reason"] = msg
+                ctx.summary["status"] = "dead"
+                raise RuntimeError(msg)
+
+            # end, things in a new function
+
+            need_install[role] = build_info
+            need_version[role] = "{ver}-{rel}.x86_64".format(
+                ver=build_info["version"],
+                rel=build_info["release"]
+            )
         else:
-            (role_remote,) = ctx.cluster.only(role).remotes.keys()
-            larch = role_remote.arch
             package_type = role_remote.os.package_type
-            system_type, system_ver = role_remote.os.name, role_remote.os.version
+            larch = role_remote.arch
             if package_type == 'rpm':
                 if '.' in system_ver:
                     system_ver = system_ver.split('.')[0]