Skip to content

Commit

Permalink
Enable kernel installs from koji
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
andrewschoen committed Jan 26, 2015
1 parent d7faab7 commit ec81c6b
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 9 deletions.
7 changes: 7 additions & 0 deletions teuthology/exceptions.py
Expand Up @@ -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):

"""
Expand Down
102 changes: 93 additions & 9 deletions teuthology/task/kernel.py
Expand Up @@ -9,11 +9,12 @@
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__)

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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))
Expand All @@ -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(
Expand All @@ -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',
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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]
Expand Down

0 comments on commit ec81c6b

Please sign in to comment.