add "koji wrapper-rpm --create-build" which creates a new build to contain the wrapper rpms

This commit is contained in:
Mike Bonnet 2011-11-08 13:53:14 -05:00 committed by Mike McLean
parent 3d28cc0ac3
commit b2edd9011c
8 changed files with 111 additions and 41 deletions

View file

@ -1140,7 +1140,7 @@ class MavenTask(MultiPlatformTask):
rpm_results = None
spec_url = self.opts.get('specfile')
if spec_url:
rpm_results = self.buildWrapperRPM(spec_url, self.build_task_id, build_tag, build_info, repo_id)
rpm_results = self.buildWrapperRPM(spec_url, self.build_task_id, target_info, build_info, repo_id)
if self.opts.get('scratch'):
self.session.host.moveMavenBuildToScratch(self.id, maven_results, rpm_results)
@ -1352,11 +1352,10 @@ class BuildMavenTask(BaseBuildTask):
'files': output_files}
class WrapperRPMTask(BaseBuildTask):
"""Build a wrapper rpm around jars output from a Maven build.
Can either be called as a subtask of a maven task or as a separate
top-level task. In the latter case it will permanently delete any
existing rpms associated with the build and replace them with the
newly-built rpms."""
"""Build a wrapper rpm around archives output from a Maven or Windows build.
May either be called as a subtask or as a separate
top-level task. In the latter case it can either associate the new rpms
with the existing build or create a new build."""
Methods = ['wrapperRPM']
@ -1376,10 +1375,10 @@ class WrapperRPMTask(BaseBuildTask):
raise koji.BuildError, "%s is not allowed to be defined in spec file" % tag
def checkHost(self, hostdata):
tag = self.params[1]
return self.checkHostArch(tag, hostdata)
target = self.params[1]
return self.checkHostArch(target['build_tag'], hostdata)
def handler(self, spec_url, build_tag, build, task, opts=None):
def handler(self, spec_url, build_target, build, task, opts=None):
if not opts:
opts = {}
@ -1499,6 +1498,7 @@ class WrapperRPMTask(BaseBuildTask):
repo_info = self.session.repoInfo(repo_id, strict=True)
event_id = repo_info['create_event']
build_tag = self.session.getTag(build_target['build_tag'], strict=True)
br_arch = self.find_arch('noarch', self.session.host.getHost(), self.session.getBuildConfig(build_tag['id'], event=event_id))
buildroot = BuildRoot(self.session, self.options, build_tag['id'], br_arch, self.id, install_group='wrapper-rpm-build', repo_id=repo_id)
@ -1529,12 +1529,12 @@ class WrapperRPMTask(BaseBuildTask):
localpath = self.localPath(relpath)
# RPM requires all SOURCE files in the srpm to be in the same directory, so
# we flatten any directory structure of the output files here.
# If multiple files in the build have the same basename, the last one
# listed will be the one that ends up in the srpm, which is rarely the right
# thing to do. In this case the build should be putting the output into a
# zipfile or tarball so that rpmbuild can then expand it in %setup, which
# will preserve the directory structure.
shutil.copy(localpath, specdir)
# If multiple files in the build have the same basename, duplicate files will
# have their relative path prepended to their name, with / replaced with -.
destpath = os.path.join(specdir, os.path.basename(relpath))
if os.path.exists(destpath):
destpath = os.path.join(specdir, relpath.replace('/', '-'))
shutil.copy(localpath, destpath)
# change directory to the specdir to the template can reference files there
os.chdir(specdir)
@ -1570,7 +1570,31 @@ class WrapperRPMTask(BaseBuildTask):
shutil.move(srpm, self.workdir)
srpm = os.path.join(self.workdir, os.path.basename(srpm))
buildroot.build(srpm)
self.new_build_id = None
if opts.get('create_build') and not opts.get('scratch'):
h = koji.get_rpm_header(srpm)
data = koji.get_header_fields(h, ['name', 'version', 'release', 'epoch'])
data['task_id'] = self.id
self.logger.info("Reading package config for %(name)s" % data)
pkg_cfg = self.session.getPackageConfig(build_target['dest_tag'], data['name'])
if not opts.get('skip_tag'):
# Make sure package is on the list for this tag
if pkg_cfg is None:
raise koji.BuildError, "package %s not in list for tag %s" \
% (data['name'], build_target['dest_tag_name'])
elif pkg_cfg['blocked']:
raise koji.BuildError, "package %s is blocked for tag %s" \
% (data['name'], build_target['dest_tag_name'])
self.new_build_id = self.session.host.initBuild(data)
try:
buildroot.build(srpm)
except (SystemExit, ServerExit, KeyboardInterrupt):
raise
except:
if self.new_build_id:
self.session.host.failBuild(self.id, self.new_build_id)
raise
resultdir = buildroot.resultdir()
srpm = None
@ -1582,6 +1606,8 @@ class WrapperRPMTask(BaseBuildTask):
if not srpm:
srpm = filename
else:
if self.new_build_id:
self.session.host.failBuild(self.id, self.new_build_id)
raise koji.BuildError, 'multiple srpms found in %s: %s, %s' % \
(resultdir, srpm, filename)
elif filename.endswith('.rpm'):
@ -1589,27 +1615,64 @@ class WrapperRPMTask(BaseBuildTask):
elif filename.endswith('.log'):
logs.append(filename)
else:
if self.new_build_id:
self.session.host.failBuild(self.id, self.new_build_id)
raise koji.BuildError, 'unexpected file found in %s: %s' % \
(resultdir, filename)
if not srpm:
if self.new_build_id:
self.session.host.failBuild(self.id, self.new_build_id)
raise koji.BuildError, 'no srpm found'
if not rpms:
if self.new_build_id:
self.session.host.failBuild(self.id, self.new_build_id)
raise koji.BuildError, 'no rpms found'
for rpm in [srpm] + rpms:
self.uploadFile(os.path.join(resultdir, rpm))
try:
for rpm in [srpm] + rpms:
self.uploadFile(os.path.join(resultdir, rpm))
except (SystemExit, ServerExit, KeyboardInterrupt):
raise
except:
if self.new_build_id:
self.session.host.failBuild(self.id, self.new_build_id)
raise
results = {'buildroot_id': buildroot.id,
'srpm': srpm,
'rpms': rpms,
'logs': logs}
if not task and not opts.get('scratch'):
# Called as a standalone top-level task, so import the rpms now.
if not task:
# Called as a standalone top-level task, so handle the rpms now.
# Otherwise we let the parent task handle it.
self.session.host.importWrapperRPMs(self.id, build['id'], results)
uploaddir = self.getUploadDir()
relsrpm = uploaddir + '/' + srpm
relrpms = [uploaddir + '/' + r for r in rpms]
rellogs = [uploaddir + '/' + l for l in logs]
if opts.get('scratch'):
self.session.host.moveBuildToScratch(self.id, relsrpm, relrpms, {'noarch': rellogs})
else:
if opts.get('create_build'):
brmap = dict.fromkeys([relsrpm] + relrpms, buildroot.id)
try:
self.session.host.completeBuild(self.id, self.new_build_id,
relsrpm, relrpms, brmap, {'noarch': rellogs})
except (SystemExit, ServerExit, KeyboardInterrupt):
raise
except:
self.session.host.failBuild(self.id, self.new_build_id)
raise
if not opts.get('skip_tag'):
tag_task_id = self.session.host.subtask(method='tagBuild',
arglist=[build_target['dest_tag'],
self.new_build_id, False, None, True],
label='tag', parent=self.id, arch='noarch')
self.wait(tag_task_id)
else:
self.session.host.importWrapperRPMs(self.id, build['id'], results)
# no need to upload logs, they've already been streamed to the hub
# during the build process

View file

@ -1058,10 +1058,12 @@ def handle_maven_build(options, session, args):
return watch_tasks(session,[task_id],quiet=options.quiet)
def handle_wrapper_rpm(options, session, args):
"""[admin] Build wrapper rpms for any jars associated with the build. Any existing rpms will be deleted from the database and the filesystem."""
"""Build wrapper rpms for any archives associated with a build."""
usage = _("usage: %prog wrapper-rpm [options] target build-id|n-v-r URL")
usage += _("\n(Specify the --help global option for a list of other help options)")
parser = OptionParser(usage=usage)
parser.add_option("--create-build", action="store_true", help=_("Create a new build to contain wrapper rpms"))
parser.add_option("--skip-tag", action="store_true", help=_("If creating a new build, don't tag it"))
parser.add_option("--scratch", action="store_true", help=_("Perform a scratch build"))
parser.add_option("--nowait", action="store_true", help=_("Don't wait on build"))
parser.add_option("--background", action="store_true", help=_("Run the build at a lower priority"))
@ -1071,9 +1073,6 @@ def handle_wrapper_rpm(options, session, args):
parser.error(_("You must provide a build target, a build ID or NVR, and a SCM URL to a specfile fragment"))
assert False
activate_session(session)
if not session.hasPerm('admin'):
print "This action requires admin privileges"
return 1
target = args[0]
build_id = args[1]
@ -1084,6 +1083,10 @@ def handle_wrapper_rpm(options, session, args):
if build_opts.background:
priority = 5
opts = {}
if build_opts.create_build:
opts['create_build'] = True
if build_opts.skip_tag:
opts['skip_tag'] = True
if build_opts.scratch:
opts['scratch'] = True
task_id = session.wrapperRPM(build_id, url, target, priority, opts=opts)

View file

@ -6663,8 +6663,8 @@ class RootExports(object):
def wrapperRPM(self, build, url, target, priority=None, channel='maven', opts=None):
"""Create a top-level wrapperRPM task
build: The build to generate wrapper rpms for. Must be in the COMPLETE state, and have
associated Maven jars.
build: The build to generate wrapper rpms for. Must be in the COMPLETE state and have no
rpms already associated with it.
url: SCM URL to a specfile fragment
target: The build target to use when building the wrapper rpm. The build_tag of the target will
be used to populate the buildroot in which the rpms are built.
@ -6675,7 +6675,6 @@ class RootExports(object):
returns the task ID
"""
context.session.assertPerm('admin')
if not context.opts.get('EnableMaven'):
raise koji.GenericError, "Maven support not enabled"
@ -6683,7 +6682,7 @@ class RootExports(object):
opts = {}
build = self.getBuild(build, strict=True)
if list_rpms(build['id']) and not opts.get('scratch'):
if list_rpms(build['id']) and not (opts.get('scratch') or opts.get('create_build')):
raise koji.PreBuildError, 'wrapper rpms for %s have already been built' % koji.buildLabel(build)
build_target = self.getBuildTarget(target)
if not build_target:
@ -6699,7 +6698,7 @@ class RootExports(object):
taskOpts['priority'] = koji.PRIO_DEFAULT + priority
taskOpts['channel'] = channel
return make_task('wrapperRPM', [url, build_tag, build, None, opts], **taskOpts)
return make_task('wrapperRPM', [url, build_target, build, None, opts], **taskOpts)
def winBuild(self, vm, url, target, opts=None, priority=None, channel='vm'):
"""
@ -9595,8 +9594,8 @@ class HostExports(object):
import_archive(filepath, buildinfo, type, typeInfo)
def importWrapperRPMs(self, task_id, build_id, rpm_results):
"""Import the wrapper rpms and associate them with the given build. Any existing
rpms are deleted before import."""
"""Import the wrapper rpms and associate them with the given build. The build
must not have any existing rpms associated with it."""
if not context.opts.get('EnableMaven'):
raise koji.GenericError, "Maven support not enabled"
host = Host()

View file

@ -2036,12 +2036,12 @@ def taskLabel(taskInfo):
extra = build_tag['name']
elif method == 'wrapperRPM':
if taskInfo.has_key('request'):
build_tag = taskInfo['request'][1]
build_target = taskInfo['request'][1]
build = taskInfo['request'][2]
if build:
extra = '%s, %s' % (build_tag['name'], buildLabel(build))
extra = '%s, %s' % (build_target['name'], buildLabel(build))
else:
extra = build_tag['name']
extra = build_target['name']
elif method == 'winbuild':
if taskInfo.has_key('request'):
vm = taskInfo['request'][0]

View file

@ -519,9 +519,9 @@ class DependantTask(BaseTaskHandler):
self.wait(subtasks, all=True)
class MultiPlatformTask(BaseTaskHandler):
def buildWrapperRPM(self, spec_url, build_task_id, build_tag, build, repo_id, **opts):
def buildWrapperRPM(self, spec_url, build_task_id, build_target, build, repo_id, **opts):
task = self.session.getTaskInfo(build_task_id)
arglist = [spec_url, build_tag, build, task, {'repo_id': repo_id}]
arglist = [spec_url, build_target, build, task, {'repo_id': repo_id}]
rpm_task_id = self.session.host.subtask(method='wrapperRPM',
arglist=arglist,

View file

@ -363,7 +363,7 @@ class WinBuildTask(MultiPlatformTask):
rpm_results = None
spec_url = opts.get('specfile')
if spec_url:
rpm_results = self.buildWrapperRPM(spec_url, task_id, build_tag, build_info, repo_id,
rpm_results = self.buildWrapperRPM(spec_url, task_id, target_info, build_info, repo_id,
channel='default')
if opts.get('scratch'):

View file

@ -375,7 +375,7 @@ _TASKS = ['build',
# Tasks that can exist without a parent
_TOPLEVEL_TASKS = ['build', 'buildNotification', 'chainbuild', 'maven', 'wrapperRPM', 'winbuild', 'newRepo', 'tagBuild', 'tagNotification', 'waitrepo', 'createLiveCD', 'createAppliance']
# Tasks that can have children
_PARENT_TASKS = ['build', 'chainbuild', 'maven', 'winbuild', 'newRepo']
_PARENT_TASKS = ['build', 'chainbuild', 'maven', 'winbuild', 'newRepo', 'wrapperRPM']
def tasks(req, owner=None, state='active', view='tree', method='all', hostID=None, channelID=None, start=None, order='-id'):
values = _initValues(req, 'Tasks', 'tasks')
@ -574,8 +574,8 @@ def taskinfo(req, taskID):
deps = [server.getTaskInfo(depID, request=True) for depID in params[0]]
values['deps'] = deps
elif task['method'] == 'wrapperRPM':
buildTag = params[1]
values['buildTag'] = buildTag
buildTarget = params[1]
values['buildTarget'] = buildTarget
if params[3]:
wrapTask = server.getTaskInfo(params[3]['id'], request=True)
values['wrapTask'] = wrapTask

View file

@ -132,7 +132,12 @@ $value
#end if
#elif $task.method == 'wrapperRPM'
<strong>Spec File URL:</strong> $params[0]<br/>
#if 'locked' in $buildTarget
#set $buildTag = $buildTarget
<strong>Build Tag:</strong> <a href="taginfo?tagID=$buildTag.id">$buildTag.name</a><br/>
#else
<strong>Build Target:</strong> <a href="buildtargetinfo?targetID=$buildTarget.id">$buildTarget.name</a><br/>
#end if
#if $params[2]
<strong>Build:</strong> <a href="buildinfo?buildID=$params[2].id">$koji.buildLabel($params[2])</a><br/>
#end if