tumbi-assembler/pungi/phases/osbs.py
Qixiang Wan 80fa723b1d Include phase name in log for some phases
Phases createiso, liveimages, image_build, ostree_installer and osbs are
done in parallel, logs from these phases are mixed and and it's not
obvious which log message belongs to which phase. This change adds phase
name in log message for these phases.

The new mixin 'PhaseLoggerMixin' is added to extend a Pungi phase with a
logging logger which copy handlers from compose's logger but with
formatter changed.

Fixes: #58
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-11-23 16:47:22 +08:00

126 lines
4.8 KiB
Python

# -*- coding: utf-8 -*-
import json
import os
from kobo.threads import ThreadPool, WorkerThread
from .base import ConfigGuardedPhase, PhaseLoggerMixin
from .. import util
from ..wrappers import kojiwrapper
from ..paths import translate_path
class OSBSPhase(PhaseLoggerMixin, ConfigGuardedPhase):
name = 'osbs'
def __init__(self, compose):
super(OSBSPhase, self).__init__(compose)
self.pool = ThreadPool(logger=self.logger)
self.pool.metadata = {}
def run(self):
for variant in self.compose.get_variants():
for conf in util.get_variant_data(self.compose.conf, self.name, variant):
self.pool.add(OSBSThread(self.pool))
self.pool.queue_put((self.compose, variant, conf))
self.pool.start()
def dump_metadata(self):
"""Create a file with image metadata if the phase actually ran."""
if self._skipped:
return
with open(self.compose.paths.compose.metadata('osbs.json'), 'w') as f:
json.dump(self.pool.metadata, f, indent=4, sort_keys=True,
separators=(',', ': '))
class OSBSThread(WorkerThread):
def process(self, item, num):
compose, variant, config = item
self.num = num
with util.failable(compose, bool(config.pop('failable', None)), variant, '*', 'osbs',
logger=self.pool._logger):
self.worker(compose, variant, config)
def worker(self, compose, variant, config):
msg = 'OSBS phase for variant %s' % variant.uid
self.pool.log_info('[BEGIN] %s' % msg)
koji = kojiwrapper.KojiWrapper(compose.conf['koji_profile'])
koji.login()
# Start task
try:
source = util.resolve_git_url(config.pop('url'))
target = config.pop('target')
except KeyError as exc:
raise RuntimeError('OSBS: missing config key %s for %s'
% (exc, variant.uid))
priority = config.pop('priority', None)
config['yum_repourls'] = [self._get_repo(compose, variant)]
task_id = koji.koji_proxy.buildContainer(source, target, config,
priority=priority)
# Wait for it to finish and capture the output into log file (even
# though there is not much there).
log_dir = os.path.join(compose.paths.log.topdir(), 'osbs')
util.makedirs(log_dir)
log_file = os.path.join(log_dir, '%s-%s-watch-task.log'
% (variant.uid, self.num))
if koji.watch_task(task_id, log_file) != 0:
raise RuntimeError('OSBS: task %s failed: see %s for details'
% (task_id, log_file))
# Only real builds get the metadata.
if not config.get('scratch', False):
self._add_metadata(koji.koji_proxy, variant, task_id)
self.pool.log_info('[DONE ] %s' % msg)
def _add_metadata(self, koji_proxy, variant, task_id):
# Create metadata
result = koji_proxy.getTaskResult(task_id)
build_id = int(result['koji_builds'][0])
buildinfo = koji_proxy.getBuild(build_id)
archives = koji_proxy.listArchives(build_id)
metadata = {
'name': buildinfo['name'],
'version': buildinfo['version'],
'release': buildinfo['release'],
'creation_time': buildinfo['creation_time'],
}
for archive in archives:
data = {
'filename': archive['filename'],
'size': archive['size'],
'checksum': archive['checksum'],
}
data.update(archive['extra'])
data.update(metadata)
arch = archive['extra']['image']['arch']
self.pool.log_debug('Created Docker base image %s-%s-%s.%s' % (
metadata['name'], metadata['version'], metadata['release'], arch))
self.pool.metadata.setdefault(
variant.uid, {}).setdefault(arch, []).append(data)
def _get_repo(self, compose, variant):
"""
Write a .repo file pointing to current variant and return URL to the
file.
"""
os_tree = compose.paths.compose.os_tree('$basearch', variant,
create_dir=False)
repo_file = os.path.join(compose.paths.work.tmp_dir(None, variant),
'compose-rpms-%s.repo' % self.num)
with open(repo_file, 'w') as f:
f.write('[%s]\n' % compose.compose_id)
f.write('name=Compose %s (RPMs)\n' % compose.compose_id)
f.write('baseurl=%s\n' % translate_path(compose, os_tree))
f.write('enabled=1\n')
f.write('gpgcheck=0\n')
return translate_path(compose, repo_file)