add support for wrapping win-build output in rpms
This commit is contained in:
parent
b9f6cc7024
commit
64df809ab6
8 changed files with 155 additions and 89 deletions
126
builder/kojid
126
builder/kojid
|
|
@ -31,7 +31,7 @@ import glob
|
||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
from koji.daemon import incremental_upload, log_output, TaskManager, SCM
|
from koji.daemon import incremental_upload, log_output, TaskManager, SCM
|
||||||
from koji.tasks import ServerExit, BaseTaskHandler
|
from koji.tasks import ServerExit, BaseTaskHandler, MultiPlatformTask
|
||||||
from koji.util import parseStatus, isSuccess
|
from koji.util import parseStatus, isSuccess
|
||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
|
|
@ -1014,7 +1014,7 @@ class BuildArchTask(BaseTaskHandler):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
class MavenTask(BaseTaskHandler):
|
class MavenTask(MultiPlatformTask):
|
||||||
|
|
||||||
Methods = ['maven']
|
Methods = ['maven']
|
||||||
|
|
||||||
|
|
@ -1072,13 +1072,14 @@ class MavenTask(BaseTaskHandler):
|
||||||
raise koji.BuildError, "package %s is blocked for tag %s" \
|
raise koji.BuildError, "package %s is blocked for tag %s" \
|
||||||
% (build_info['name'], dest_tag['name'])
|
% (build_info['name'], dest_tag['name'])
|
||||||
|
|
||||||
self.build_id, build_info = self.session.host.initMavenBuild(self.id, build_info, maven_info)
|
build_info = self.session.host.initMavenBuild(self.id, build_info, maven_info)
|
||||||
|
self.build_id = build_info['id']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rpm_results = None
|
rpm_results = None
|
||||||
spec_url = self.opts.get('specfile')
|
spec_url = self.opts.get('specfile')
|
||||||
if spec_url:
|
if spec_url:
|
||||||
rpm_results = self.buildWrapperRPM(spec_url, build_tag, build_info, repo_id)
|
rpm_results = self.buildWrapperRPM(spec_url, self.build_task_id, build_tag, build_info, repo_id)
|
||||||
|
|
||||||
if not self.opts.get('scratch'):
|
if not self.opts.get('scratch'):
|
||||||
self.session.host.completeMavenBuild(self.id, self.build_id, maven_results, rpm_results)
|
self.session.host.completeMavenBuild(self.id, self.build_id, maven_results, rpm_results)
|
||||||
|
|
@ -1100,20 +1101,6 @@ class MavenTask(BaseTaskHandler):
|
||||||
arch='noarch')
|
arch='noarch')
|
||||||
self.wait(tag_task_id)
|
self.wait(tag_task_id)
|
||||||
|
|
||||||
def buildWrapperRPM(self, spec_url, build_tag, build, repo_id):
|
|
||||||
task = self.session.getTaskInfo(self.build_task_id)
|
|
||||||
arglist = [spec_url, build_tag, build, task, {'repo_id': repo_id}]
|
|
||||||
|
|
||||||
rpm_task_id = self.session.host.subtask(method='wrapperRPM',
|
|
||||||
arglist=arglist,
|
|
||||||
label='rpm',
|
|
||||||
parent=self.id,
|
|
||||||
arch='noarch')
|
|
||||||
results = self.wait(rpm_task_id)[rpm_task_id]
|
|
||||||
results['task_id'] = rpm_task_id
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
class BuildMavenTask(BaseTaskHandler):
|
class BuildMavenTask(BaseTaskHandler):
|
||||||
|
|
||||||
Methods = ['buildMaven']
|
Methods = ['buildMaven']
|
||||||
|
|
@ -1318,22 +1305,32 @@ class WrapperRPMTask(BaseTaskHandler):
|
||||||
if not opts:
|
if not opts:
|
||||||
opts = {}
|
opts = {}
|
||||||
|
|
||||||
|
if not (build or task):
|
||||||
|
raise koji.BuildError, 'build and/or task must be specified'
|
||||||
|
|
||||||
values = {}
|
values = {}
|
||||||
|
|
||||||
maven_info = None
|
if build:
|
||||||
|
maven_info = self.session.getMavenBuild(build['id'], strict=False)
|
||||||
|
win_info = self.session.getWinBuild(build['id'], strict=False)
|
||||||
|
else:
|
||||||
|
maven_info = None
|
||||||
|
win_info = None
|
||||||
|
|
||||||
|
# list of artifact paths relative to kojiroot (not exposed to the specfile)
|
||||||
|
artifact_relpaths = []
|
||||||
# map of file extension to a list of files
|
# map of file extension to a list of files
|
||||||
artifacts = {}
|
artifacts = {}
|
||||||
# list of all files
|
# list of all files
|
||||||
all_artifacts = []
|
all_artifacts = []
|
||||||
# list of all files with their maven repo path
|
# list of all files with their repo path
|
||||||
all_artifacts_with_path = []
|
all_artifacts_with_path = []
|
||||||
|
|
||||||
# makes generating relative paths easier
|
# makes generating relative paths easier
|
||||||
self.pathinfo = koji.PathInfo(topdir='')
|
self.pathinfo = koji.PathInfo(topdir='')
|
||||||
|
|
||||||
if task:
|
if task:
|
||||||
# called as a subtask of a maven build
|
# called as a subtask of a build
|
||||||
artifact_paths = self.session.listTaskOutput(task['id'])
|
artifact_paths = self.session.listTaskOutput(task['id'])
|
||||||
|
|
||||||
for artifact_path in artifact_paths:
|
for artifact_path in artifact_paths:
|
||||||
|
|
@ -1343,7 +1340,8 @@ class WrapperRPMTask(BaseTaskHandler):
|
||||||
# Exclude log files for consistency with the output of listArchives() used below
|
# Exclude log files for consistency with the output of listArchives() used below
|
||||||
continue
|
continue
|
||||||
relpath = os.path.join(self.pathinfo.task(task['id']), artifact_path)[1:]
|
relpath = os.path.join(self.pathinfo.task(task['id']), artifact_path)[1:]
|
||||||
artifacts.setdefault(ext, []).append(relpath)
|
artifact_relpaths.append(relpath)
|
||||||
|
artifacts.setdefault(ext, []).append(artifact_name)
|
||||||
all_artifacts.append(artifact_name)
|
all_artifacts.append(artifact_name)
|
||||||
all_artifacts_with_path.append(artifact_path)
|
all_artifacts_with_path.append(artifact_path)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1352,61 +1350,67 @@ class WrapperRPMTask(BaseTaskHandler):
|
||||||
if not build['state'] == koji.BUILD_STATES['COMPLETE']:
|
if not build['state'] == koji.BUILD_STATES['COMPLETE']:
|
||||||
raise koji.BuildError, 'cannot call wrapperRPM on a build that did not complete successfully'
|
raise koji.BuildError, 'cannot call wrapperRPM on a build that did not complete successfully'
|
||||||
|
|
||||||
maven_info = self.session.getMavenBuild(build['id'], strict=True)
|
|
||||||
|
|
||||||
# get the list of files from the build instead of the task, because the task output directory may
|
# get the list of files from the build instead of the task, because the task output directory may
|
||||||
# have already been cleaned up
|
# have already been cleaned up
|
||||||
build_artifacts = self.session.listArchives(buildID=build['id'], type='maven')
|
if maven_info:
|
||||||
|
build_artifacts = self.session.listArchives(buildID=build['id'], type='maven')
|
||||||
|
elif win_info:
|
||||||
|
build_artifacts = self.session.listArchives(buildID=build['id'], type='win')
|
||||||
|
else:
|
||||||
|
raise koji.BuildError, 'unsupported build type'
|
||||||
|
|
||||||
for artifact in build_artifacts:
|
for artifact in build_artifacts:
|
||||||
artifact_name = artifact['filename']
|
artifact_name = artifact['filename']
|
||||||
base, ext = os.path.splitext(artifact_name)
|
base, ext = os.path.splitext(artifact_name)
|
||||||
|
artifacts.setdefault(ext, []).append(artifact_name)
|
||||||
|
all_artifacts.append(artifact_name)
|
||||||
if ext == '.log':
|
if ext == '.log':
|
||||||
# listArchives() should never return .log files, but we check for completeness
|
# listArchives() should never return .log files, but we check for completeness
|
||||||
continue
|
continue
|
||||||
relpath = os.path.join(self.pathinfo.mavenbuild(build, maven_info), artifact_name)[1:]
|
if maven_info:
|
||||||
artifacts.setdefault(ext, []).append(relpath)
|
relpath = os.path.join(self.pathinfo.mavenbuild(build, maven_info), artifact_name)[1:]
|
||||||
all_artifacts.append(artifact_name)
|
artifact_relpaths.append(relpath)
|
||||||
repopath = os.path.join(self.pathinfo.mavenrepo(maven_info, artifact), artifact_name)[len('/maven2/'):]
|
repopath = self.pathinfo.mavenfile(artifact)
|
||||||
all_artifacts_with_path.append(repopath)
|
all_artifacts_with_path.append(repopath)
|
||||||
|
elif win_info:
|
||||||
|
repopath = self.pathinfo.winfile(artifact)
|
||||||
|
relpath = os.path.join(self.pathinfo.winbuild(build), repopath)[1:]
|
||||||
|
artifact_relpaths.append(relpath)
|
||||||
|
all_artifacts_with_path.append(repopath)
|
||||||
|
else:
|
||||||
|
# can't happen
|
||||||
|
assert False
|
||||||
|
|
||||||
if not artifacts:
|
if not artifacts:
|
||||||
raise koji.BuildError, 'no output found for %s' % (task and koji.taskLabel(task) or koji.buildLabel(build))
|
raise koji.BuildError, 'no output found for %s' % (task and koji.taskLabel(task) or koji.buildLabel(build))
|
||||||
|
|
||||||
artifacts_base = {}
|
values['artifacts'] = artifacts
|
||||||
# construct a map of just basenames to pass to the template
|
|
||||||
for key, vals in artifacts.items():
|
|
||||||
# sort the lists while we're at it
|
|
||||||
vals.sort()
|
|
||||||
artifacts_base[key] = [os.path.basename(val) for val in vals]
|
|
||||||
|
|
||||||
values['artifacts'] = artifacts_base
|
|
||||||
values['all_artifacts'] = all_artifacts
|
values['all_artifacts'] = all_artifacts
|
||||||
values['all_artifacts_with_path'] = all_artifacts_with_path
|
values['all_artifacts_with_path'] = all_artifacts_with_path
|
||||||
|
|
||||||
if build:
|
if build:
|
||||||
self.copy_fields(build, values, 'epoch', 'name', 'version', 'release')
|
self.copy_fields(build, values, 'epoch', 'name', 'version', 'release')
|
||||||
if not maven_info:
|
if maven_info:
|
||||||
maven_info = self.session.getMavenBuild(build['id'], strict=True)
|
values['maven_info'] = maven_info
|
||||||
values['maven_info'] = maven_info
|
elif win_info:
|
||||||
|
values['win_info'] = win_info
|
||||||
|
else:
|
||||||
|
# can't happen
|
||||||
|
assert False
|
||||||
else:
|
else:
|
||||||
# Get the pom info from the first pom and convert it to build format
|
task_result = self.session.getTaskResult(task['id'])
|
||||||
# so we can use it as substitution variables in the template.
|
if task['method'] == 'buildMaven':
|
||||||
# If there are no poms, populate the values dict with empty placeholders. If the spec file
|
maven_info = task_result['maven_info']
|
||||||
# doesn't require these variables, it should work. If it does, then the rpmbuild will
|
|
||||||
# likely fail.
|
|
||||||
poms = artifacts.get('.pom', [])
|
|
||||||
if poms:
|
|
||||||
pom_path = self.localPath(poms[0])
|
|
||||||
pom_info = koji.parse_pom(pom_path)
|
|
||||||
maven_info = koji.pom_to_maven_info(pom_info)
|
|
||||||
maven_nvr = koji.maven_info_to_nvr(maven_info)
|
maven_nvr = koji.maven_info_to_nvr(maven_info)
|
||||||
maven_nvr['release'] = '0.scratch'
|
maven_nvr['release'] = '0.scratch'
|
||||||
self.copy_fields(maven_nvr, values, 'epoch', 'name', 'version', 'release')
|
self.copy_fields(maven_nvr, values, 'epoch', 'name', 'version', 'release')
|
||||||
values['maven_info'] = maven_info
|
values['maven_info'] = maven_info
|
||||||
|
elif task['method'] == 'vmExec':
|
||||||
|
self.copy_fields(task_result, values, 'epoch', 'name', 'version', 'release')
|
||||||
|
values['win_info'] = {'platform': task_result['platform']}
|
||||||
else:
|
else:
|
||||||
values.update({'epoch': None, 'name': '', 'version': '', 'release': ''})
|
# can't happen
|
||||||
values['maven_info'] = {'group_id': '', 'artifact_id': '', 'version': ''}
|
assert False
|
||||||
|
|
||||||
scm = SCM(spec_url)
|
scm = SCM(spec_url)
|
||||||
scm.assert_allowed(self.options.allowed_scms)
|
scm.assert_allowed(self.options.allowed_scms)
|
||||||
|
|
@ -1442,11 +1446,19 @@ class WrapperRPMTask(BaseTaskHandler):
|
||||||
# set to the rpm _sourcedir so other files in the SCM may be referenced in the
|
# set to the rpm _sourcedir so other files in the SCM may be referenced in the
|
||||||
# specfile as well.
|
# specfile as well.
|
||||||
specdir = os.path.dirname(spec_template)
|
specdir = os.path.dirname(spec_template)
|
||||||
for key, filepaths in artifacts.items():
|
for relpath in artifact_relpaths:
|
||||||
for filepath in filepaths:
|
localpath = self.localPath(relpath)
|
||||||
localpath = self.localPath(filepath)
|
# RPM requires all SOURCE files in the srpm to be in the same directory, so
|
||||||
shutil.copy(localpath, specdir)
|
# 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)
|
||||||
|
|
||||||
|
# change directory to the specdir to the template can reference files there
|
||||||
|
os.chdir(specdir)
|
||||||
contents = Cheetah.Template.Template(file=spec_template,
|
contents = Cheetah.Template.Template(file=spec_template,
|
||||||
searchList=[values]).respond()
|
searchList=[values]).respond()
|
||||||
|
|
||||||
|
|
|
||||||
4
cli/koji
4
cli/koji
|
|
@ -4347,6 +4347,8 @@ def handle_win_build(options, session, args):
|
||||||
parser.add_option("--mem", type="int",
|
parser.add_option("--mem", type="int",
|
||||||
help=_("Amount of memory (in megabytes) to allocate to the build VM " + \
|
help=_("Amount of memory (in megabytes) to allocate to the build VM " + \
|
||||||
"(requires admin access)"))
|
"(requires admin access)"))
|
||||||
|
parser.add_option("--specfile", metavar="URL",
|
||||||
|
help=_("SCM URL of a spec file fragment to use to generate wrapper RPMs"))
|
||||||
parser.add_option("--scratch", action="store_true",
|
parser.add_option("--scratch", action="store_true",
|
||||||
help=_("Perform a scratch build"))
|
help=_("Perform a scratch build"))
|
||||||
parser.add_option("--repo-id", type="int", help=_("Use a specific repo"))
|
parser.add_option("--repo-id", type="int", help=_("Use a specific repo"))
|
||||||
|
|
@ -4382,7 +4384,7 @@ def handle_win_build(options, session, args):
|
||||||
vm_name = args[2]
|
vm_name = args[2]
|
||||||
opts = {}
|
opts = {}
|
||||||
for key in ('winspec', 'patches', 'cpus', 'mem',
|
for key in ('winspec', 'patches', 'cpus', 'mem',
|
||||||
'scratch', 'repo_id', 'skip_tag'):
|
'specfile', 'scratch', 'repo_id', 'skip_tag'):
|
||||||
val = getattr(build_opts, key)
|
val = getattr(build_opts, key)
|
||||||
if val is not None:
|
if val is not None:
|
||||||
opts[key] = val
|
opts[key] = val
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ INSERT INTO permissions (name) VALUES ('win-admin');
|
||||||
|
|
||||||
INSERT INTO channels (name) VALUES ('vm');
|
INSERT INTO channels (name) VALUES ('vm');
|
||||||
|
|
||||||
|
insert into archivetypes (name, description, extensions) values ('spec', 'RPM spec file', 'spec');
|
||||||
insert into archivetypes (name, description, extensions) values ('exe', 'Windows executable', 'exe');
|
insert into archivetypes (name, description, extensions) values ('exe', 'Windows executable', 'exe');
|
||||||
insert into archivetypes (name, description, extensions) values ('dll', 'Windows dynamic link library', 'dll');
|
insert into archivetypes (name, description, extensions) values ('dll', 'Windows dynamic link library', 'dll');
|
||||||
insert into archivetypes (name, description, extensions) values ('lib', 'Windows import library', 'lib');
|
insert into archivetypes (name, description, extensions) values ('lib', 'Windows import library', 'lib');
|
||||||
|
|
|
||||||
|
|
@ -692,6 +692,7 @@ insert into archivetypes (name, description, extensions) values ('zip', 'Zip arc
|
||||||
insert into archivetypes (name, description, extensions) values ('pom', 'Maven Project Object Management file', 'pom');
|
insert into archivetypes (name, description, extensions) values ('pom', 'Maven Project Object Management file', 'pom');
|
||||||
insert into archivetypes (name, description, extensions) values ('tar', 'Tar file', 'tar tar.gz tar.bz2');
|
insert into archivetypes (name, description, extensions) values ('tar', 'Tar file', 'tar tar.gz tar.bz2');
|
||||||
insert into archivetypes (name, description, extensions) values ('xml', 'XML file', 'xml');
|
insert into archivetypes (name, description, extensions) values ('xml', 'XML file', 'xml');
|
||||||
|
insert into archivetypes (name, description, extensions) values ('spec', 'RPM spec file', 'spec');
|
||||||
insert into archivetypes (name, description, extensions) values ('exe', 'Windows executable', 'exe');
|
insert into archivetypes (name, description, extensions) values ('exe', 'Windows executable', 'exe');
|
||||||
insert into archivetypes (name, description, extensions) values ('dll', 'Windows dynamic link library', 'dll');
|
insert into archivetypes (name, description, extensions) values ('dll', 'Windows dynamic link library', 'dll');
|
||||||
insert into archivetypes (name, description, extensions) values ('lib', 'Windows import library', 'lib');
|
insert into archivetypes (name, description, extensions) values ('lib', 'Windows import library', 'lib');
|
||||||
|
|
|
||||||
|
|
@ -4351,11 +4351,12 @@ def new_maven_build(build, maven_info):
|
||||||
VALUES (%(build_id)i, %(group_id)s, %(artifact_id)s, %(version)s)"""
|
VALUES (%(build_id)i, %(group_id)s, %(artifact_id)s, %(version)s)"""
|
||||||
_dml(insert, maven_info)
|
_dml(insert, maven_info)
|
||||||
|
|
||||||
def new_win_build(build_id, win_info):
|
def new_win_build(build_info, win_info):
|
||||||
"""
|
"""
|
||||||
Add Windows metadata to an existing build.
|
Add Windows metadata to an existing build.
|
||||||
win_info must contain a 'platform' key.
|
win_info must contain a 'platform' key.
|
||||||
"""
|
"""
|
||||||
|
build_id = build_info['id']
|
||||||
current = get_win_build(build_id, strict=False)
|
current = get_win_build(build_id, strict=False)
|
||||||
if current:
|
if current:
|
||||||
if current['platform'] != win_info['platform']:
|
if current['platform'] != win_info['platform']:
|
||||||
|
|
@ -4981,6 +4982,7 @@ def reset_build(build):
|
||||||
#nothing to do
|
#nothing to do
|
||||||
return
|
return
|
||||||
minfo = get_maven_build(binfo)
|
minfo = get_maven_build(binfo)
|
||||||
|
winfo = get_win_build(binfo)
|
||||||
koji.plugin.run_callbacks('preBuildStateChange', attribute='state', old=binfo['state'], new=koji.BUILD_STATES['CANCELED'], info=binfo)
|
koji.plugin.run_callbacks('preBuildStateChange', attribute='state', old=binfo['state'], new=koji.BUILD_STATES['CANCELED'], info=binfo)
|
||||||
q = """SELECT id FROM rpminfo WHERE build_id=%(id)i"""
|
q = """SELECT id FROM rpminfo WHERE build_id=%(id)i"""
|
||||||
ids = _fetchMulti(q, binfo)
|
ids = _fetchMulti(q, binfo)
|
||||||
|
|
@ -4996,12 +4998,16 @@ def reset_build(build):
|
||||||
for (archive_id,) in ids:
|
for (archive_id,) in ids:
|
||||||
delete = """DELETE FROM maven_archives WHERE archive_id=%(archive_id)i"""
|
delete = """DELETE FROM maven_archives WHERE archive_id=%(archive_id)i"""
|
||||||
_dml(delete, locals())
|
_dml(delete, locals())
|
||||||
|
delete = """DELETE FROM win_archives WHERE archive_id=%(archive_id)i"""
|
||||||
|
_dml(delete, locals())
|
||||||
delete = """DELETE FROM buildroot_archives WHERE archive_id=%(archive_id)i"""
|
delete = """DELETE FROM buildroot_archives WHERE archive_id=%(archive_id)i"""
|
||||||
_dml(delete, locals())
|
_dml(delete, locals())
|
||||||
delete = """DELETE FROM archiveinfo WHERE build_id=%(id)i"""
|
delete = """DELETE FROM archiveinfo WHERE build_id=%(id)i"""
|
||||||
_dml(delete, binfo)
|
_dml(delete, binfo)
|
||||||
delete = """DELETE FROM maven_builds WHERE build_id = %(id)i"""
|
delete = """DELETE FROM maven_builds WHERE build_id = %(id)i"""
|
||||||
_dml(delete, binfo)
|
_dml(delete, binfo)
|
||||||
|
delete = """DELETE FROM win_builds WHERE build_id = %(id)i"""
|
||||||
|
_dml(delete, binfo)
|
||||||
binfo['state'] = koji.BUILD_STATES['CANCELED']
|
binfo['state'] = koji.BUILD_STATES['CANCELED']
|
||||||
update = """UPDATE build SET state=%(state)i, task_id=NULL WHERE id=%(id)i"""
|
update = """UPDATE build SET state=%(state)i, task_id=NULL WHERE id=%(id)i"""
|
||||||
_dml(update, binfo)
|
_dml(update, binfo)
|
||||||
|
|
@ -5010,6 +5016,7 @@ def reset_build(build):
|
||||||
builddir = koji.pathinfo.build(binfo)
|
builddir = koji.pathinfo.build(binfo)
|
||||||
if os.path.exists(builddir):
|
if os.path.exists(builddir):
|
||||||
dirs_to_clear.append(builddir)
|
dirs_to_clear.append(builddir)
|
||||||
|
# Windows files exist under the builddir, and will be removed with the rpms
|
||||||
if minfo:
|
if minfo:
|
||||||
mavendir = koji.pathinfo.mavenbuild(binfo, minfo)
|
mavendir = koji.pathinfo.mavenbuild(binfo, minfo)
|
||||||
if os.path.exists(mavendir):
|
if os.path.exists(mavendir):
|
||||||
|
|
@ -8827,7 +8834,7 @@ class HostExports(object):
|
||||||
os.rename(fn,dest)
|
os.rename(fn,dest)
|
||||||
os.symlink(dest,fn)
|
os.symlink(dest,fn)
|
||||||
|
|
||||||
def moveWinBuildToScratch(self, task_id, results):
|
def moveWinBuildToScratch(self, task_id, results, rpm_results):
|
||||||
"Move a completed scratch build into place (not imported)"
|
"Move a completed scratch build into place (not imported)"
|
||||||
if not context.opts.get('EnableWin'):
|
if not context.opts.get('EnableWin'):
|
||||||
raise koji.GenericError, 'Windows support not enabled'
|
raise koji.GenericError, 'Windows support not enabled'
|
||||||
|
|
@ -8837,13 +8844,22 @@ class HostExports(object):
|
||||||
task.assertHost(host.id)
|
task.assertHost(host.id)
|
||||||
scratchdir = koji.pathinfo.scratch()
|
scratchdir = koji.pathinfo.scratch()
|
||||||
username = get_user(task.getOwner())['name']
|
username = get_user(task.getOwner())['name']
|
||||||
destdir = "%s/%s/task_%s" % (scratchdir, username, task_id)
|
destdir = os.path.join(scratchdir, username, 'task_%s' % task_id)
|
||||||
for relpath in results['output'].keys() + results['logs']:
|
for relpath in results['output'].keys() + results['logs']:
|
||||||
filename = os.path.join(koji.pathinfo.task(results['task_id']), relpath)
|
filename = os.path.join(koji.pathinfo.task(results['task_id']), relpath)
|
||||||
dest = os.path.join(destdir, relpath)
|
dest = os.path.join(destdir, relpath)
|
||||||
koji.ensuredir(os.path.dirname(dest))
|
koji.ensuredir(os.path.dirname(dest))
|
||||||
os.rename(filename, dest)
|
os.rename(filename, dest)
|
||||||
os.symlink(dest, filename)
|
os.symlink(dest, filename)
|
||||||
|
if rpm_results:
|
||||||
|
for relpath in [rpm_results['srpm']] + rpm_results['rpms'] + \
|
||||||
|
rpm_results['logs']:
|
||||||
|
filename = os.path.join(koji.pathinfo.task(rpm_results['task_id']),
|
||||||
|
relpath)
|
||||||
|
dest = os.path.join(destdir, 'rpms', relpath)
|
||||||
|
koji.ensuredir(os.path.dirname(dest))
|
||||||
|
os.rename(filename, dest)
|
||||||
|
os.symlink(dest, filename)
|
||||||
|
|
||||||
def initBuild(self,data):
|
def initBuild(self,data):
|
||||||
"""Create a stub build entry.
|
"""Create a stub build entry.
|
||||||
|
|
@ -8913,10 +8929,10 @@ class HostExports(object):
|
||||||
data['state'] = koji.BUILD_STATES['BUILDING']
|
data['state'] = koji.BUILD_STATES['BUILDING']
|
||||||
data['completion_time'] = None
|
data['completion_time'] = None
|
||||||
build_id = new_build(data)
|
build_id = new_build(data)
|
||||||
build_info['id'] = build_id
|
data['id'] = build_id
|
||||||
new_maven_build(build_info, maven_info)
|
new_maven_build(data, maven_info)
|
||||||
|
|
||||||
return build_id, build_info
|
return data
|
||||||
|
|
||||||
def completeMavenBuild(self, task_id, build_id, maven_results, rpm_results):
|
def completeMavenBuild(self, task_id, build_id, maven_results, rpm_results):
|
||||||
"""Complete the Maven build."""
|
"""Complete the Maven build."""
|
||||||
|
|
@ -9014,10 +9030,11 @@ class HostExports(object):
|
||||||
data['state'] = koji.BUILD_STATES['BUILDING']
|
data['state'] = koji.BUILD_STATES['BUILDING']
|
||||||
data['completion_time'] = None
|
data['completion_time'] = None
|
||||||
build_id = new_build(data)
|
build_id = new_build(data)
|
||||||
new_win_build(build_id, win_info)
|
data['id'] = build_id
|
||||||
return build_id
|
new_win_build(data, win_info)
|
||||||
|
return data
|
||||||
|
|
||||||
def completeWinBuild(self, task_id, build_id, results):
|
def completeWinBuild(self, task_id, build_id, results, rpm_results):
|
||||||
"""Complete a Windows build"""
|
"""Complete a Windows build"""
|
||||||
if not context.opts.get('EnableWin'):
|
if not context.opts.get('EnableWin'):
|
||||||
raise koji.GenericError, 'Windows support not enabled'
|
raise koji.GenericError, 'Windows support not enabled'
|
||||||
|
|
@ -9049,6 +9066,9 @@ class HostExports(object):
|
||||||
import_build_log(os.path.join(task_dir, relpath),
|
import_build_log(os.path.join(task_dir, relpath),
|
||||||
build_info, subdir=subdir)
|
build_info, subdir=subdir)
|
||||||
|
|
||||||
|
if rpm_results:
|
||||||
|
_import_wrapper(rpm_results['task_id'], build_info, rpm_results)
|
||||||
|
|
||||||
# update build state
|
# update build state
|
||||||
st_complete = koji.BUILD_STATES['COMPLETE']
|
st_complete = koji.BUILD_STATES['COMPLETE']
|
||||||
update = UpdateProcessor('build', clauses=['id=%(build_id)i'],
|
update = UpdateProcessor('build', clauses=['id=%(build_id)i'],
|
||||||
|
|
|
||||||
|
|
@ -1403,7 +1403,8 @@ class PathInfo(object):
|
||||||
group_path = maveninfo['group_id'].replace('.', '/')
|
group_path = maveninfo['group_id'].replace('.', '/')
|
||||||
artifact_id = maveninfo['artifact_id']
|
artifact_id = maveninfo['artifact_id']
|
||||||
version = maveninfo['version']
|
version = maveninfo['version']
|
||||||
return "%(group_path)s/%(artifact_id)s/%(version)s" % locals()
|
filename = maveninfo['filename']
|
||||||
|
return "%(group_path)s/%(artifact_id)s/%(version)s/%(filename)s" % locals()
|
||||||
|
|
||||||
def mavenrepo(self, build, maveninfo):
|
def mavenrepo(self, build, maveninfo):
|
||||||
"""Return the directory where the Maven artifact exists in the per-tag Maven repo
|
"""Return the directory where the Maven artifact exists in the per-tag Maven repo
|
||||||
|
|
@ -1411,7 +1412,7 @@ class PathInfo(object):
|
||||||
group_path = maveninfo['group_id'].replace('.', '/')
|
group_path = maveninfo['group_id'].replace('.', '/')
|
||||||
artifact_id = maveninfo['artifact_id']
|
artifact_id = maveninfo['artifact_id']
|
||||||
version = maveninfo['version']
|
version = maveninfo['version']
|
||||||
return self.topdir + "/maven2/" + self.mavenfile(maveninfo)
|
return self.topdir + "/maven2/" + os.path.dirname(self.mavenfile(maveninfo))
|
||||||
|
|
||||||
def rpm(self,rpminfo):
|
def rpm(self,rpminfo):
|
||||||
"""Return the path (relative to build_dir) where an rpm belongs"""
|
"""Return the path (relative to build_dir) where an rpm belongs"""
|
||||||
|
|
|
||||||
|
|
@ -439,3 +439,19 @@ class DependantTask(BaseTaskHandler):
|
||||||
subtasks.append(task_id)
|
subtasks.append(task_id)
|
||||||
if subtasks:
|
if subtasks:
|
||||||
self.wait(subtasks, all=True)
|
self.wait(subtasks, all=True)
|
||||||
|
|
||||||
|
class MultiPlatformTask(BaseTaskHandler):
|
||||||
|
def buildWrapperRPM(self, spec_url, build_task_id, build_tag, build, repo_id, **opts):
|
||||||
|
task = self.session.getTaskInfo(build_task_id)
|
||||||
|
arglist = [spec_url, build_tag, build, task, {'repo_id': repo_id}]
|
||||||
|
|
||||||
|
rpm_task_id = self.session.host.subtask(method='wrapperRPM',
|
||||||
|
arglist=arglist,
|
||||||
|
label='rpm',
|
||||||
|
parent=self.id,
|
||||||
|
arch='noarch',
|
||||||
|
**opts)
|
||||||
|
results = self.wait(rpm_task_id)[rpm_task_id]
|
||||||
|
results['task_id'] = rpm_task_id
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
|
||||||
53
vm/kojivmd
53
vm/kojivmd
|
|
@ -23,7 +23,7 @@
|
||||||
import koji
|
import koji
|
||||||
import koji.util
|
import koji.util
|
||||||
from koji.daemon import SCM, TaskManager
|
from koji.daemon import SCM, TaskManager
|
||||||
from koji.tasks import ServerExit, BaseTaskHandler
|
from koji.tasks import ServerExit, BaseTaskHandler, MultiPlatformTask
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
@ -274,7 +274,7 @@ class DaemonXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
class WinBuildTask(BaseTaskHandler):
|
class WinBuildTask(MultiPlatformTask):
|
||||||
"""
|
"""
|
||||||
Spawns a vmExec task to run a build, and imports the output.
|
Spawns a vmExec task to run a build, and imports the output.
|
||||||
"""
|
"""
|
||||||
|
|
@ -331,10 +331,10 @@ class WinBuildTask(BaseTaskHandler):
|
||||||
results = self.wait(task_id)[task_id]
|
results = self.wait(task_id)[task_id]
|
||||||
results['task_id'] = task_id
|
results['task_id'] = task_id
|
||||||
|
|
||||||
if opts.get('scratch'):
|
build_info = None
|
||||||
self.session.host.moveWinBuildToScratch(self.id, results)
|
if not opts.get('scratch'):
|
||||||
else:
|
build_info = koji.util.dslice(results, ['name', 'version', 'release', 'epoch'])
|
||||||
build_info = koji.util.dslice(results, ['name', 'version', 'release'])
|
build_info['package_name'] = build_info['name']
|
||||||
pkg_cfg = self.session.getPackageConfig(dest_tag['id'], build_info['name'], event=event_id)
|
pkg_cfg = self.session.getPackageConfig(dest_tag['id'], build_info['name'], event=event_id)
|
||||||
if not opts.get('skip_tag'):
|
if not opts.get('skip_tag'):
|
||||||
# Make sure package is on the list for this tag
|
# Make sure package is on the list for this tag
|
||||||
|
|
@ -345,25 +345,38 @@ class WinBuildTask(BaseTaskHandler):
|
||||||
raise koji.BuildError, "package %s is blocked for tag %s" \
|
raise koji.BuildError, "package %s is blocked for tag %s" \
|
||||||
% (build_info['name'], dest_tag['name'])
|
% (build_info['name'], dest_tag['name'])
|
||||||
|
|
||||||
# epoch is rpm-specific, so doesn't have a lot of relevance here
|
build_info = self.session.host.initWinBuild(self.id, build_info,
|
||||||
# but a value is required by the data model
|
koji.util.dslice(results, ['platform']))
|
||||||
build_info['epoch'] = None
|
build_id = build_info['id']
|
||||||
build_id = self.session.host.initWinBuild(self.id, build_info,
|
|
||||||
koji.util.dslice(results, ['platform']))
|
try:
|
||||||
try:
|
rpm_results = None
|
||||||
self.session.host.completeWinBuild(self.id, build_id, results)
|
spec_url = opts.get('specfile')
|
||||||
except (SystemExit, ServerExit, KeyboardInterrupt):
|
if spec_url:
|
||||||
raise
|
rpm_results = self.buildWrapperRPM(spec_url, task_id, build_tag, build_info, repo_id,
|
||||||
except:
|
channel='default')
|
||||||
|
|
||||||
|
if opts.get('scratch'):
|
||||||
|
self.session.host.moveWinBuildToScratch(self.id, results, rpm_results)
|
||||||
|
else:
|
||||||
|
self.session.host.completeWinBuild(self.id, build_id, results, rpm_results)
|
||||||
|
except (SystemExit, ServerExit, KeyboardInterrupt):
|
||||||
|
# we do not trap these
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
if not opts.get('scratch'):
|
||||||
|
# scratch builds do not get imported
|
||||||
self.session.host.failBuild(self.id, build_id)
|
self.session.host.failBuild(self.id, build_id)
|
||||||
raise
|
# reraise the exception
|
||||||
if not opts.get('skip_tag') and not opts.get('scratch'):
|
raise
|
||||||
task_id = self.session.host.subtask(method='tagBuild',
|
|
||||||
|
if not opts.get('scratch') and not opts.get('skip_tag'):
|
||||||
|
tag_task_id = self.session.host.subtask(method='tagBuild',
|
||||||
arglist=[dest_tag['id'], build_id],
|
arglist=[dest_tag['id'], build_id],
|
||||||
label='tag',
|
label='tag',
|
||||||
channel='default',
|
channel='default',
|
||||||
parent=self.id)
|
parent=self.id)
|
||||||
self.wait(task_id)
|
self.wait(tag_task_id)
|
||||||
|
|
||||||
class VMExecTask(BaseTaskHandler):
|
class VMExecTask(BaseTaskHandler):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue