#!/usr/bin/python # rpmci_binrpm_builder_main.py: # Implementation of rpm-binrpm-builder # # Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php) # Copyright (C) 2010 Red Hat, Inc. # Written by Colin Walters import os import sys import time import shutil import optparse from ConfigParser import SafeConfigParser import logging import tempfile import subprocess import urllib import glib import gobject import gio from . import msgqueue from . import subtask from . import rpmutils from . import versioned_repos from . import artifact class BinRPMBuilder(object): def __init__(self, options, config): self.config = config self._options = options srpm_msgqueue_dir = config.get('SRPM', 'msgqueue') self._srpm_msgqueue = msgqueue.MessageQueue(srpm_msgqueue_dir) build_msgqueue_dir = config.get('build', 'msgqueue') self._build_msgqueue = msgqueue.MessageQueue(build_msgqueue_dir) self._artifactset = artifact.ArtifactSet.from_config(config) self._artifact_to_repo = {} artifact_basedir = config.get('build', 'artifactdir') for artifact_iter in self._artifactset.artifacts: artifact_repopath = os.path.join(artifact_basedir, artifact_iter.name) artifact_repo = versioned_repos.BaseRepo(artifact_repopath, 'repo-' + artifact_iter.name) self._artifact_to_repo[artifact] = artifact_repo self._srcrepo = versioned_repos.VersionedRepo(config.get('SRPM', 'srpm_dir')) def start(self): latest = self._srcrepo.get_latest_version() logging.info("Doing an initial build now") if latest is not None: self._rebuild_to_repoversion(latest.version) self._srpm_msgqueue.connect(self._on_srpm_message) self._build_msgqueue.connect(self._on_build_message) def _target_for_srpm(self, srpm_name): (name, ver, rest) = srpm_name.rsplit('-', 2) for target in self._artifactset.get_build_targets(): if target.name == name: return target return None def _srpm_for_target(self, target): latest = self._srcrepo.get_latest_version() for rpm in latest.iter_rpms(): basename = os.path.basename(rpm) srpm_name = rpmutils.get_rpm_name(basename) if srpm_name == target.module: return rpm return None def _mock_root_from_os_arch(self, target_os, architecture): fedora_os_master = self.config.get('fedora', 'master') if target_os == fedora_os_master: mock_os = 'fedora-devel' else: mock_os = buildtarget.os if architecture == 'i686': arch = 'i386' else: arch = architecture return '%s-%s' % (mock_os, arch) def _on_build_message(self, q, messages): rebuild_all = False for msg in messages: if 'rebuild' in msg.payload: logging.info("Processing rebuild all message") rebuild_all = True q.consume(msg) if rebuild_all: latest_repo = self._srcrepo.get_latest_version() self._rebuild_to_repoversion(latest_repo.version) def _on_srpm_message(self, q, messages): msg_list = list(messages) num_msgs = len(msg_list) logging.debug("Starting processing of %d messages" % (num_msgs, )) latest_repoversion = -1 for msg in msg_list: repoversion = msg.payload['version'] if repoversion > latest_repoversion: latest_repoversion = repoversion logging.debug("Processing update to repository version %r" % (repoversion, )) q.consume(msg) self._rebuild_to_repoversion(repoversion) logging.debug("Processed %d messages successfully" % (num_msgs, )) def _rebuild_to_repoversion(self, repoversion): exec_basedir = os.path.dirname(sys.argv[0]) for artifact in self._artifactset.artifacts: logging.info("Preparing rebuild of artifact %r" % (artifact.name, )) artifact_srpms = set() failed = False for target in artifact.targets: srpm = self._srpm_for_target(target) if srpm is None: logger.warn("Couldn't find srpm for target %r of artifact %r" % (target.module, artifact.name)) failed = True break artifact_srpms.add(srpm) if failed: continue taskid = 'mock-many-srpms-%s' % (artifact.name, ) arch_roots = [] for arch in artifact.architectures: arch_roots.append(self._mock_root_from_os_arch(artifact.os, arch)) base_artifactdir = self.config.get('build', 'artifactdir') artifactdir = os.path.join(base_artifactdir, artifact.name) base_logdir = self.config.get('build', 'logdir') logdir = os.path.join(base_logdir, artifact.name) args = [os.path.join(exec_basedir, 'mock-many-srpms'), '--skip-have-build', '--resultdir=' + artifactdir, '--logdir=' + logdir] for root in arch_roots: args.append('--root=' + root) args.extend(artifact_srpms) subtask.spawn_sync(taskid, args) def main(): if hasattr('glib', 'threads_init'): glib.threads_init() opts = optparse.OptionParser("usage: %prog [options]") opts.add_option('-c', '--config', dest='config', help="Path to configuration file") opts.add_option('', '--debug', action='store_true', help="Print verbose debugging") (options, args) = opts.parse_args() if options.config is None: print "Must specify --config" sys.exit(1) config = SafeConfigParser({'home': os.environ['HOME']}) config.read(options.config) level = logging.DEBUG if options.debug else logging.INFO logging.basicConfig(stream=sys.stderr, level=level) subtask.global_configure(config) builder = BinRPMBuilder(options, config) builder.start() logging.info("Awaiting events") loop = glib.MainLoop() loop.run()