flake8: follow E265 rule

This commit is contained in:
Yuming Zhu 2020-02-25 22:50:14 +08:00
parent 642508ccf6
commit 97cfaa4fcf
27 changed files with 794 additions and 793 deletions

View file

@ -131,7 +131,7 @@ def main(options, session):
tm.findHandlers(globals()) tm.findHandlers(globals())
tm.findHandlers(vars(koji.tasks)) tm.findHandlers(vars(koji.tasks))
if options.plugin: if options.plugin:
#load plugins # load plugins
pt = koji.plugin.PluginTracker(path=options.pluginpath.split(':')) pt = koji.plugin.PluginTracker(path=options.pluginpath.split(':'))
for name in options.plugin: for name in options.plugin:
logger.info('Loading plugin: %s' % name) logger.info('Loading plugin: %s' % name)
@ -192,9 +192,9 @@ class BuildRoot(object):
self._new(*args,**kwargs) self._new(*args,**kwargs)
def _load(self, data): def _load(self, data):
#manage an existing buildroot # manage an existing buildroot
if isinstance(data, dict): if isinstance(data, dict):
#assume data already pulled from db # assume data already pulled from db
self.id = data['id'] self.id = data['id']
else: else:
self.id = data self.id = data
@ -291,7 +291,7 @@ class BuildRoot(object):
opts['tag_macros'][macro] = self.config['extra'][key] opts['tag_macros'][macro] = self.config['extra'][key]
output = koji.genMockConfig(self.name, self.br_arch, managed=True, **opts) output = koji.genMockConfig(self.name, self.br_arch, managed=True, **opts)
#write config # write config
with open(configfile,'w') as fo: with open(configfile,'w') as fo:
fo.write(output) fo.write(output)
@ -398,7 +398,7 @@ class BuildRoot(object):
"""Run mock""" """Run mock"""
mockpath = getattr(self.options,"mockpath","/usr/bin/mock") mockpath = getattr(self.options,"mockpath","/usr/bin/mock")
cmd = [mockpath, "-r", self.mockcfg] cmd = [mockpath, "-r", self.mockcfg]
#if self.options.debug_mock: # if self.options.debug_mock:
# cmd.append('--debug') # cmd.append('--debug')
# TODO: should we pass something like --verbose --trace instead? # TODO: should we pass something like --verbose --trace instead?
if 'mock.new_chroot' in self.config['extra']: if 'mock.new_chroot' in self.config['extra']:
@ -495,7 +495,7 @@ class BuildRoot(object):
ts_offsets[fname] = position ts_offsets[fname] = position
incremental_upload(self.session, fname, fd, uploadpath, logger=self.logger) incremental_upload(self.session, fname, fd, uploadpath, logger=self.logger)
#clean up and return exit status of command # clean up and return exit status of command
for (fname, (fd, inode, size, fpath)) in logs.items(): for (fname, (fd, inode, size, fpath)) in logs.items():
if not fd: if not fd:
continue continue
@ -507,7 +507,7 @@ class BuildRoot(object):
return status[1] return status[1]
else: else:
#in no case should exceptions propagate past here # in no case should exceptions propagate past here
try: try:
self.session._forget() self.session._forget()
if workdir: if workdir:
@ -524,7 +524,7 @@ class BuildRoot(object):
os.setreuid(uid,uid) os.setreuid(uid,uid)
os.execvp(cmd[0],cmd) os.execvp(cmd[0],cmd)
except: except:
#diediedie # diediedie
print("Failed to exec mock") print("Failed to exec mock")
print(''.join(traceback.format_exception(*sys.exc_info()))) print(''.join(traceback.format_exception(*sys.exc_info())))
os._exit(1) os._exit(1)
@ -656,9 +656,9 @@ class BuildRoot(object):
ts = rpm.TransactionSet() ts = rpm.TransactionSet()
for h in ts.dbMatch(): for h in ts.dbMatch():
pkg = koji.get_header_fields(h, fields) pkg = koji.get_header_fields(h, fields)
#skip our fake packages # skip our fake packages
if pkg['name'] in ['buildsys-build', 'gpg-pubkey']: if pkg['name'] in ['buildsys-build', 'gpg-pubkey']:
#XXX config # XXX config
continue continue
pkg['payloadhash'] = koji.hex_string(pkg['sigmd5']) pkg['payloadhash'] = koji.hex_string(pkg['sigmd5'])
del pkg['sigmd5'] del pkg['sigmd5']
@ -744,9 +744,9 @@ class BuildRoot(object):
external_repos = self.session.getExternalRepoList(self.repo_info['tag_id'], external_repos = self.session.getExternalRepoList(self.repo_info['tag_id'],
event=self.repo_info['create_event']) event=self.repo_info['create_event'])
if not external_repos: if not external_repos:
#nothing to do # nothing to do
return return
#index external repos by expanded url # index external repos by expanded url
erepo_idx = {} erepo_idx = {}
for erepo in external_repos: for erepo in external_repos:
# substitute $arch in the url with the arch of the repo we're generating # substitute $arch in the url with the arch of the repo we're generating
@ -781,7 +781,7 @@ class BuildRoot(object):
pkgorigins = r.getinfo(librepo.LRR_YUM_REPOMD)['origin']['location_href'] pkgorigins = r.getinfo(librepo.LRR_YUM_REPOMD)['origin']['location_href']
koji.util.rmtree(tmpdir) koji.util.rmtree(tmpdir)
elif yum_available: elif yum_available:
#XXX - cheap hack to get relative paths # XXX - cheap hack to get relative paths
repomdpath = os.path.join(repodir, self.br_arch, 'repodata', 'repomd.xml') repomdpath = os.path.join(repodir, self.br_arch, 'repodata', 'repomd.xml')
with koji.openRemoteFile(repomdpath, **opts) as fo: with koji.openRemoteFile(repomdpath, **opts) as fo:
try: try:
@ -796,8 +796,8 @@ class BuildRoot(object):
relpath = os.path.join(repodir, self.br_arch, pkgorigins) relpath = os.path.join(repodir, self.br_arch, pkgorigins)
with koji.openRemoteFile(relpath, **opts) as fo: with koji.openRemoteFile(relpath, **opts) as fo:
#at this point we know there were external repos at the create event, # at this point we know there were external repos at the create event,
#so there should be an origins file. # so there should be an origins file.
origin_idx = {} origin_idx = {}
# don't use 'with GzipFile' as it is not supported on py2.6 # don't use 'with GzipFile' as it is not supported on py2.6
fo2 = GzipFile(fileobj=fo, mode='r') fo2 = GzipFile(fileobj=fo, mode='r')
@ -807,7 +807,7 @@ class BuildRoot(object):
parts=line.split(None, 2) parts=line.split(None, 2)
if len(parts) < 2: if len(parts) < 2:
continue continue
#first field is formated by yum as [e:]n-v-r.a # first field is formated by yum as [e:]n-v-r.a
nvra = "%(name)s-%(version)s-%(release)s.%(arch)s" % koji.parse_NVRA(parts[0]) nvra = "%(name)s-%(version)s-%(release)s.%(arch)s" % koji.parse_NVRA(parts[0])
origin_idx[nvra] = parts[1] origin_idx[nvra] = parts[1]
fo2.close() fo2.close()
@ -874,7 +874,7 @@ class BuildRoot(object):
class ChainBuildTask(BaseTaskHandler): class ChainBuildTask(BaseTaskHandler):
Methods = ['chainbuild'] Methods = ['chainbuild']
#mostly just waiting on other tasks # mostly just waiting on other tasks
_taskWeight = 0.1 _taskWeight = 0.1
def handler(self, srcs, target, opts=None): def handler(self, srcs, target, opts=None):
@ -896,7 +896,7 @@ class ChainBuildTask(BaseTaskHandler):
raise koji.GenericError('unknown build target: %s' % target) raise koji.GenericError('unknown build target: %s' % target)
nvrs = [] nvrs = []
for n_level, build_level in enumerate(srcs): for n_level, build_level in enumerate(srcs):
#if there are any nvrs to wait on, do so # if there are any nvrs to wait on, do so
if nvrs: if nvrs:
task_id = self.session.host.subtask(method='waitrepo', task_id = self.session.host.subtask(method='waitrepo',
arglist=[target_info['build_tag_name'], None, nvrs], arglist=[target_info['build_tag_name'], None, nvrs],
@ -904,7 +904,7 @@ class ChainBuildTask(BaseTaskHandler):
parent=self.id) parent=self.id)
self.wait(task_id, all=True, failany=True) self.wait(task_id, all=True, failany=True)
nvrs = [] nvrs = []
#kick off the builds for this level # kick off the builds for this level
build_tasks = [] build_tasks = []
for n_src, src in enumerate(build_level): for n_src, src in enumerate(build_level):
if SCM.is_scm_url(src): if SCM.is_scm_url(src):
@ -915,11 +915,11 @@ class ChainBuildTask(BaseTaskHandler):
build_tasks.append(task_id) build_tasks.append(task_id)
else: else:
nvrs.append(src) nvrs.append(src)
#next pass will wait for these # next pass will wait for these
if build_tasks: if build_tasks:
#the level could have been all nvrs # the level could have been all nvrs
self.wait(build_tasks, all=True, failany=True) self.wait(build_tasks, all=True, failany=True)
#see what builds we created in this batch so the next pass can wait for them also # see what builds we created in this batch so the next pass can wait for them also
for build_task in build_tasks: for build_task in build_tasks:
builds = self.session.listBuilds(taskID=build_task) builds = self.session.listBuilds(taskID=build_task)
if builds: if builds:
@ -929,7 +929,7 @@ class ChainBuildTask(BaseTaskHandler):
class BuildTask(BaseTaskHandler): class BuildTask(BaseTaskHandler):
Methods = ['build'] Methods = ['build']
#we mostly just wait on other tasks # we mostly just wait on other tasks
_taskWeight = 0.2 _taskWeight = 0.2
def handler(self, src, target, opts=None): def handler(self, src, target, opts=None):
@ -949,7 +949,7 @@ class BuildTask(BaseTaskHandler):
self.event_id = repo_info['create_event'] self.event_id = repo_info['create_event']
else: else:
repo_info = None repo_info = None
#we'll wait for a repo later (self.getRepo) # we'll wait for a repo later (self.getRepo)
self.event_id = None self.event_id = None
task_info = self.session.getTaskInfo(self.id) task_info = self.session.getTaskInfo(self.id)
target_info = None target_info = None
@ -959,7 +959,7 @@ class BuildTask(BaseTaskHandler):
dest_tag = target_info['dest_tag'] dest_tag = target_info['dest_tag']
build_tag = target_info['build_tag'] build_tag = target_info['build_tag']
if repo_info is not None: if repo_info is not None:
#make sure specified repo matches target # make sure specified repo matches target
if repo_info['tag_id'] != target_info['build_tag']: if repo_info['tag_id'] != target_info['build_tag']:
raise koji.BuildError('Repo/Target mismatch: %s/%s' \ raise koji.BuildError('Repo/Target mismatch: %s/%s' \
% (repo_info['tag_name'], target_info['build_tag_name'])) % (repo_info['tag_name'], target_info['build_tag_name']))
@ -970,7 +970,7 @@ class BuildTask(BaseTaskHandler):
raise koji.GenericError('unknown build target: %s' % target) raise koji.GenericError('unknown build target: %s' % target)
build_tag = repo_info['tag_id'] build_tag = repo_info['tag_id']
if target is None: if target is None:
#ok, call it skip-tag for the buildroot tag # ok, call it skip-tag for the buildroot tag
self.opts['skip_tag'] = True self.opts['skip_tag'] = True
dest_tag = build_tag dest_tag = build_tag
else: else:
@ -978,7 +978,7 @@ class BuildTask(BaseTaskHandler):
if not taginfo: if not taginfo:
raise koji.GenericError('neither tag nor target: %s' % target) raise koji.GenericError('neither tag nor target: %s' % target)
dest_tag = taginfo['id'] dest_tag = taginfo['id']
#policy checks... # policy checks...
policy_data = { policy_data = {
'user_id' : task_info['owner'], 'user_id' : task_info['owner'],
'source' : src, 'source' : src,
@ -991,7 +991,7 @@ class BuildTask(BaseTaskHandler):
if not self.opts.get('skip_tag'): if not self.opts.get('skip_tag'):
policy_data['tag'] = dest_tag #id policy_data['tag'] = dest_tag #id
if not SCM.is_scm_url(src) and not opts.get('scratch'): if not SCM.is_scm_url(src) and not opts.get('scratch'):
#let hub policy decide # let hub policy decide
self.session.host.assertPolicy('build_from_srpm', policy_data) self.session.host.assertPolicy('build_from_srpm', policy_data)
if opts.get('repo_id') is not None: if opts.get('repo_id') is not None:
# use of this option is governed by policy # use of this option is governed by policy
@ -1024,11 +1024,11 @@ class BuildTask(BaseTaskHandler):
% (data['name'], target_info['dest_tag_name'])) % (data['name'], target_info['dest_tag_name']))
# TODO - more pre tests # TODO - more pre tests
archlist = self.getArchList(build_tag, h, extra=extra_arches) archlist = self.getArchList(build_tag, h, extra=extra_arches)
#let the system know about the build we're attempting # let the system know about the build we're attempting
if not self.opts.get('scratch'): if not self.opts.get('scratch'):
#scratch builds do not get imported # scratch builds do not get imported
build_id = self.session.host.initBuild(data) build_id = self.session.host.initBuild(data)
#(initBuild raises an exception if there is a conflict) # (initBuild raises an exception if there is a conflict)
failany = (self.opts.get('fail_fast', False) failany = (self.opts.get('fail_fast', False)
or not getattr(self.options, 'build_arch_can_fail', False)) or not getattr(self.options, 'build_arch_can_fail', False))
try: try:
@ -1037,16 +1037,16 @@ class BuildTask(BaseTaskHandler):
repo_info['id'], failany=failany) repo_info['id'], failany=failany)
if opts.get('scratch'): if opts.get('scratch'):
#scratch builds do not get imported # scratch builds do not get imported
self.session.host.moveBuildToScratch(self.id,srpm,rpms,logs=logs) self.session.host.moveBuildToScratch(self.id,srpm,rpms,logs=logs)
else: else:
self.session.host.completeBuild(self.id,build_id,srpm,rpms,brmap,logs=logs) self.session.host.completeBuild(self.id,build_id,srpm,rpms,brmap,logs=logs)
except (SystemExit,ServerExit,KeyboardInterrupt): except (SystemExit,ServerExit,KeyboardInterrupt):
#we do not trap these # we do not trap these
raise raise
except: except:
if not self.opts.get('scratch'): if not self.opts.get('scratch'):
#scratch builds do not get imported # scratch builds do not get imported
self.session.host.failBuild(self.id, build_id) self.session.host.failBuild(self.id, build_id)
# reraise the exception # reraise the exception
raise raise
@ -1067,7 +1067,7 @@ class BuildTask(BaseTaskHandler):
return src return src
else: else:
raise koji.BuildError('Invalid source specification: %s' % src) raise koji.BuildError('Invalid source specification: %s' % src)
#XXX - other methods? # XXX - other methods?
def getSRPMFromSRPM(self, src, build_tag, repo_id): def getSRPMFromSRPM(self, src, build_tag, repo_id):
# rebuild srpm in mock, so it gets correct disttag, rpm version, etc. # rebuild srpm in mock, so it gets correct disttag, rpm version, etc.
@ -1085,7 +1085,7 @@ class BuildTask(BaseTaskHandler):
return srpm return srpm
def getSRPMFromSCM(self, url, build_tag, repo_id): def getSRPMFromSCM(self, url, build_tag, repo_id):
#TODO - allow different ways to get the srpm # TODO - allow different ways to get the srpm
task_id = self.session.host.subtask(method='buildSRPMFromSCM', task_id = self.session.host.subtask(method='buildSRPMFromSCM',
arglist=[url, build_tag, {'repo_id': repo_id, 'scratch': self.opts.get('scratch')}], arglist=[url, build_tag, {'repo_id': repo_id, 'scratch': self.opts.get('scratch')}],
label='srpm', label='srpm',
@ -1100,7 +1100,7 @@ class BuildTask(BaseTaskHandler):
return srpm return srpm
def readSRPMHeader(self, srpm): def readSRPMHeader(self, srpm):
#srpm arg should be a path relative to <BASEDIR>/work # srpm arg should be a path relative to <BASEDIR>/work
self.logger.debug("Reading SRPM") self.logger.debug("Reading SRPM")
relpath = "work/%s" % srpm relpath = "work/%s" % srpm
opts = dict([(k, getattr(self.options, k)) for k in ('topurl','topdir')]) opts = dict([(k, getattr(self.options, k)) for k in ('topurl','topdir')])
@ -1117,7 +1117,7 @@ class BuildTask(BaseTaskHandler):
buildconfig = self.session.getBuildConfig(build_tag, event=self.event_id) buildconfig = self.session.getBuildConfig(build_tag, event=self.event_id)
arches = buildconfig['arches'] arches = buildconfig['arches']
if not arches: if not arches:
#XXX - need to handle this better # XXX - need to handle this better
raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig) raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig)
tag_archlist = [koji.canonArch(a) for a in arches.split()] tag_archlist = [koji.canonArch(a) for a in arches.split()]
self.logger.debug('arches: %s' % arches) self.logger.debug('arches: %s' % arches)
@ -1139,13 +1139,13 @@ class BuildTask(BaseTaskHandler):
if excludearch: if excludearch:
archlist = [ a for a in archlist if a not in excludearch ] archlist = [ a for a in archlist if a not in excludearch ]
self.logger.debug('archlist after excludearch: %r' % archlist) self.logger.debug('archlist after excludearch: %r' % archlist)
#noarch is funny # noarch is funny
if 'noarch' not in excludearch and \ if 'noarch' not in excludearch and \
( 'noarch' in buildarchs or 'noarch' in exclusivearch ): ( 'noarch' in buildarchs or 'noarch' in exclusivearch ):
archlist.append('noarch') archlist.append('noarch')
override = self.opts.get('arch_override') override = self.opts.get('arch_override')
if self.opts.get('scratch') and override: if self.opts.get('scratch') and override:
#only honor override for scratch builds # only honor override for scratch builds
self.logger.debug('arch override: %s' % override) self.logger.debug('arch override: %s' % override)
archlist = override.split() archlist = override.split()
archdict = {} archdict = {}
@ -1248,9 +1248,9 @@ class BuildTask(BaseTaskHandler):
return srpm,rpms,brmap,logs return srpm,rpms,brmap,logs
def tagBuild(self,build_id,dest_tag): def tagBuild(self,build_id,dest_tag):
#XXX - need options to skip tagging and to force tagging # XXX - need options to skip tagging and to force tagging
#create the tagBuild subtask # create the tagBuild subtask
#this will handle the "post tests" # this will handle the "post tests"
task_id = self.session.host.subtask(method='tagBuild', task_id = self.session.host.subtask(method='tagBuild',
arglist=[dest_tag,build_id,False,None,True], arglist=[dest_tag,build_id,False,None,True],
label='tag', label='tag',
@ -1279,7 +1279,7 @@ class BaseBuildTask(BaseTaskHandler):
(self.id, self.method, (self.id, self.method,
', '.join(tag_arches), ', '.join(host_arches))) ', '.join(tag_arches), ', '.join(host_arches)))
return False return False
#otherwise... # otherwise...
# This is in principle an error condition, but this is not a good place # This is in principle an error condition, but this is not a good place
# to fail. Instead we proceed and let the task fail normally. # to fail. Instead we proceed and let the task fail normally.
return True return True
@ -1448,7 +1448,7 @@ class BuildArchTask(BaseBuildTask):
ret['brootid'] = broot.id ret['brootid'] = broot.id
broot.expire() broot.expire()
#Let TaskManager clean up # Let TaskManager clean up
return ret return ret
@ -1525,7 +1525,7 @@ class MavenTask(MultiPlatformTask):
raise raise
except: except:
if not self.opts.get('scratch'): if not self.opts.get('scratch'):
#scratch builds do not get imported # scratch builds do not get imported
self.session.host.failBuild(self.id, self.build_id) self.session.host.failBuild(self.id, self.build_id)
# reraise the exception # reraise the exception
raise raise
@ -1988,7 +1988,7 @@ class WrapperRPMTask(BaseBuildTask):
gid = grp.getgrnam('mock')[2] gid = grp.getgrnam('mock')[2]
self.chownTree(specdir, uid, gid) self.chownTree(specdir, uid, gid)
#build srpm # build srpm
self.logger.debug("Running srpm build") self.logger.debug("Running srpm build")
buildroot.build_srpm(specfile, specdir, None) buildroot.build_srpm(specfile, specdir, None)
@ -2327,7 +2327,7 @@ class ChainMavenTask(MultiPlatformTask):
class TagBuildTask(BaseTaskHandler): class TagBuildTask(BaseTaskHandler):
Methods = ['tagBuild'] Methods = ['tagBuild']
#XXX - set weight? # XXX - set weight?
def handler(self, tag_id, build_id, force=False, fromtag=None, ignore_success=False): def handler(self, tag_id, build_id, force=False, fromtag=None, ignore_success=False):
task = self.session.getTaskInfo(self.id) task = self.session.getTaskInfo(self.id)
@ -2336,11 +2336,11 @@ class TagBuildTask(BaseTaskHandler):
self.session.getBuild(build_id, strict=True) self.session.getBuild(build_id, strict=True)
self.session.getTag(tag_id, strict=True) self.session.getTag(tag_id, strict=True)
#several basic sanity checks have already been run (and will be run # several basic sanity checks have already been run (and will be run
#again when we make the final call). Our job is to perform the more # again when we make the final call). Our job is to perform the more
#computationally expensive 'post' tests. # computationally expensive 'post' tests.
#XXX - add more post tests # XXX - add more post tests
self.session.host.tagBuild(self.id,tag_id,build_id,force=force,fromtag=fromtag) self.session.host.tagBuild(self.id,tag_id,build_id,force=force,fromtag=fromtag)
self.session.host.tagNotification(True, tag_id, fromtag, build_id, user_id, ignore_success) self.session.host.tagNotification(True, tag_id, fromtag, build_id, user_id, ignore_success)
except Exception as e: except Exception as e:
@ -2376,7 +2376,7 @@ class BuildBaseImageTask(BuildImageTask):
target_info = self.session.getBuildTarget(target, strict=True) target_info = self.session.getBuildTarget(target, strict=True)
build_tag = target_info['build_tag'] build_tag = target_info['build_tag']
repo_info = self.getRepo(build_tag) repo_info = self.getRepo(build_tag)
#check requested arches against build tag # check requested arches against build tag
buildconfig = self.session.getBuildConfig(build_tag) buildconfig = self.session.getBuildConfig(build_tag)
if not buildconfig['arches']: if not buildconfig['arches']:
raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig) raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig)
@ -2475,11 +2475,11 @@ class BuildBaseImageTask(BuildImageTask):
results) results)
except (SystemExit,ServerExit,KeyboardInterrupt): except (SystemExit,ServerExit,KeyboardInterrupt):
#we do not trap these # we do not trap these
raise raise
except: except:
if not opts.get('scratch'): if not opts.get('scratch'):
#scratch builds do not get imported # scratch builds do not get imported
if bld_info: if bld_info:
self.session.host.failBuild(self.id, bld_info['id']) self.session.host.failBuild(self.id, bld_info['id'])
# reraise the exception # reraise the exception
@ -2512,7 +2512,7 @@ class BuildApplianceTask(BuildImageTask):
target_info = self.session.getBuildTarget(target, strict=True) target_info = self.session.getBuildTarget(target, strict=True)
build_tag = target_info['build_tag'] build_tag = target_info['build_tag']
repo_info = self.getRepo(build_tag) repo_info = self.getRepo(build_tag)
#check requested arch against build tag # check requested arch against build tag
buildconfig = self.session.getBuildConfig(build_tag) buildconfig = self.session.getBuildConfig(build_tag)
if not buildconfig['arches']: if not buildconfig['arches']:
raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig) raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig)
@ -2561,11 +2561,11 @@ class BuildApplianceTask(BuildImageTask):
self.session.host.moveImageBuildToScratch(self.id, results) self.session.host.moveImageBuildToScratch(self.id, results)
except (SystemExit,ServerExit,KeyboardInterrupt): except (SystemExit,ServerExit,KeyboardInterrupt):
#we do not trap these # we do not trap these
raise raise
except: except:
if not opts.get('scratch'): if not opts.get('scratch'):
#scratch builds do not get imported # scratch builds do not get imported
if bld_info: if bld_info:
self.session.host.failBuild(self.id, bld_info['id']) self.session.host.failBuild(self.id, bld_info['id'])
# reraise the exception # reraise the exception
@ -2597,7 +2597,7 @@ class BuildLiveCDTask(BuildImageTask):
target_info = self.session.getBuildTarget(target, strict=True) target_info = self.session.getBuildTarget(target, strict=True)
build_tag = target_info['build_tag'] build_tag = target_info['build_tag']
repo_info = self.getRepo(build_tag) repo_info = self.getRepo(build_tag)
#check requested arch against build tag # check requested arch against build tag
buildconfig = self.session.getBuildConfig(build_tag) buildconfig = self.session.getBuildConfig(build_tag)
if not buildconfig['arches']: if not buildconfig['arches']:
raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig) raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig)
@ -2645,11 +2645,11 @@ class BuildLiveCDTask(BuildImageTask):
self.session.host.moveImageBuildToScratch(self.id, results) self.session.host.moveImageBuildToScratch(self.id, results)
except (SystemExit,ServerExit,KeyboardInterrupt): except (SystemExit,ServerExit,KeyboardInterrupt):
#we do not trap these # we do not trap these
raise raise
except: except:
if not opts.get('scratch'): if not opts.get('scratch'):
#scratch builds do not get imported # scratch builds do not get imported
if bld_info: if bld_info:
self.session.host.failBuild(self.id, bld_info['id']) self.session.host.failBuild(self.id, bld_info['id'])
# reraise the exception # reraise the exception
@ -2683,7 +2683,7 @@ class BuildLiveMediaTask(BuildImageTask):
target_info = self.session.getBuildTarget(target, strict=True) target_info = self.session.getBuildTarget(target, strict=True)
build_tag = target_info['build_tag'] build_tag = target_info['build_tag']
repo_info = self.getRepo(build_tag) repo_info = self.getRepo(build_tag)
#check requested arch against build tag # check requested arch against build tag
buildconfig = self.session.getBuildConfig(build_tag) buildconfig = self.session.getBuildConfig(build_tag)
if not buildconfig['arches']: if not buildconfig['arches']:
raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig) raise koji.BuildError("No arches for tag %(name)s [%(id)s]" % buildconfig)
@ -2783,11 +2783,11 @@ class BuildLiveMediaTask(BuildImageTask):
self.session.host.moveImageBuildToScratch(self.id, results) self.session.host.moveImageBuildToScratch(self.id, results)
except (SystemExit, ServerExit, KeyboardInterrupt): except (SystemExit, ServerExit, KeyboardInterrupt):
#we do not trap these # we do not trap these
raise raise
except: except:
if not opts.get('scratch'): if not opts.get('scratch'):
#scratch builds do not get imported # scratch builds do not get imported
if bld_info: if bld_info:
self.session.host.failBuild(self.id, bld_info['id']) self.session.host.failBuild(self.id, bld_info['id'])
# reraise the exception # reraise the exception
@ -2953,7 +2953,7 @@ class ImageTask(BaseTaskHandler):
baseurl = '%s/%s' % (repopath, arch) baseurl = '%s/%s' % (repopath, arch)
self.logger.debug('BASEURL: %s' % baseurl) self.logger.debug('BASEURL: %s' % baseurl)
self.ks.handler.repo.repoList.append(repo_class(baseurl=baseurl, name='koji-%s-%i' % (target_info['build_tag_name'], repo_info['id']))) self.ks.handler.repo.repoList.append(repo_class(baseurl=baseurl, name='koji-%s-%i' % (target_info['build_tag_name'], repo_info['id'])))
#inject url if provided # inject url if provided
if opts.get('install_tree_url'): if opts.get('install_tree_url'):
self.ks.handler.url(url=opts['install_tree_url']) self.ks.handler.url(url=opts['install_tree_url'])
@ -3285,7 +3285,7 @@ class LiveCDTask(ImageTask):
## livemedia-creator # livemedia-creator
class LiveMediaTask(ImageTask): class LiveMediaTask(ImageTask):
Methods = ['createLiveMedia'] Methods = ['createLiveMedia']
@ -3410,7 +3410,7 @@ class LiveMediaTask(ImageTask):
'--no-virt', '--no-virt',
'--resultdir', resultdir, '--resultdir', resultdir,
'--project', name, '--project', name,
#'--tmp', '/tmp' # '--tmp', '/tmp'
] ]
@ -3508,10 +3508,10 @@ class LiveMediaTask(ImageTask):
if not opts.get('scratch'): if not opts.get('scratch'):
# TODO - generate list of rpms in image # TODO - generate list of rpms in image
# (getImagePackages doesn't work here) # (getImagePackages doesn't work here)
#hdrlist = self.getImagePackages(os.path.join(broot.rootdir(), # hdrlist = self.getImagePackages(os.path.join(broot.rootdir(),
# cachedir[1:])) # cachedir[1:]))
imgdata ['rpmlist'] = [] imgdata ['rpmlist'] = []
#broot.markExternalRPMs(hdrlist) # broot.markExternalRPMs(hdrlist)
broot.expire() broot.expire()
return imgdata return imgdata
@ -3666,10 +3666,10 @@ class OzImageTask(BaseTaskHandler):
the way we want the way we want
""" """
return { return {
#Oz specific # Oz specific
'oz_data_dir': os.path.join(self.workdir, 'oz_data'), 'oz_data_dir': os.path.join(self.workdir, 'oz_data'),
'oz_screenshot_dir': os.path.join(self.workdir, 'oz_screenshots'), 'oz_screenshot_dir': os.path.join(self.workdir, 'oz_screenshots'),
#IF specific # IF specific
'imgdir': os.path.join(self.workdir, 'scratch_images'), 'imgdir': os.path.join(self.workdir, 'scratch_images'),
'tmpdir': os.path.join(self.workdir, 'oz-tmp'), 'tmpdir': os.path.join(self.workdir, 'oz-tmp'),
'verbose': True, 'verbose': True,
@ -4251,7 +4251,7 @@ class BaseImageTask(OzImageTask):
} }
# record the RPMs that were installed # record the RPMs that were installed
if not opts.get('scratch'): if not opts.get('scratch'):
#fields = ('name', 'version', 'release', 'arch', 'epoch', 'size', # fields = ('name', 'version', 'release', 'arch', 'epoch', 'size',
# 'payloadhash', 'buildtime') # 'payloadhash', 'buildtime')
icicle = xml.dom.minidom.parseString(images['raw']['icicle']) icicle = xml.dom.minidom.parseString(images['raw']['icicle'])
self.logger.debug('ICICLE: %s' % images['raw']['icicle']) self.logger.debug('ICICLE: %s' % images['raw']['icicle'])
@ -4540,7 +4540,7 @@ class BuildIndirectionImageTask(OzImageTask):
bld_info, target_info, bd) bld_info, target_info, bd)
except: except:
if not opts.get('scratch'): if not opts.get('scratch'):
#scratch builds do not get imported # scratch builds do not get imported
if bld_info: if bld_info:
self.session.host.failBuild(self.id, bld_info['id']) self.session.host.failBuild(self.id, bld_info['id'])
# reraise the exception # reraise the exception
@ -4770,7 +4770,7 @@ class BuildSRPMFromSCMTask(BaseBuildTask):
'repo_id': repo_id} 'repo_id': repo_id}
if self.options.scm_credentials_dir is not None and os.path.isdir(self.options.scm_credentials_dir): if self.options.scm_credentials_dir is not None and os.path.isdir(self.options.scm_credentials_dir):
rootopts['bind_opts'] = {'dirs' : {self.options.scm_credentials_dir : '/credentials',}} rootopts['bind_opts'] = {'dirs' : {self.options.scm_credentials_dir : '/credentials',}}
## Force internal_dev_setup back to true because bind_opts is used to turn it off # Force internal_dev_setup back to true because bind_opts is used to turn it off
rootopts['internal_dev_setup'] = True rootopts['internal_dev_setup'] = True
br_arch = self.find_arch('noarch', self.session.host.getHost(), self.session.getBuildConfig(build_tag['id'], event=event_id)) br_arch = self.find_arch('noarch', self.session.host.getHost(), self.session.getBuildConfig(build_tag['id'], event=event_id))
broot = BuildRoot(self.session, self.options, build_tag['id'], br_arch, self.id, **rootopts) broot = BuildRoot(self.session, self.options, build_tag['id'], br_arch, self.id, **rootopts)
@ -4820,7 +4820,7 @@ class BuildSRPMFromSCMTask(BaseBuildTask):
# Run spec file sanity checks. Any failures will throw a BuildError # Run spec file sanity checks. Any failures will throw a BuildError
self.spec_sanity_checks(spec_file) self.spec_sanity_checks(spec_file)
#build srpm # build srpm
self.logger.debug("Running srpm build") self.logger.debug("Running srpm build")
broot.build_srpm(spec_file, sourcedir, scm.source_cmd) broot.build_srpm(spec_file, sourcedir, scm.source_cmd)
@ -4841,7 +4841,7 @@ class BuildSRPMFromSCMTask(BaseBuildTask):
if srpm_name != os.path.basename(srpm): if srpm_name != os.path.basename(srpm):
raise koji.BuildError('srpm name mismatch: %s != %s' % (srpm_name, os.path.basename(srpm))) raise koji.BuildError('srpm name mismatch: %s != %s' % (srpm_name, os.path.basename(srpm)))
#upload srpm and return # upload srpm and return
self.uploadFile(srpm) self.uploadFile(srpm)
brootid = broot.id brootid = broot.id
@ -4941,7 +4941,7 @@ Status: %(status)s\r
server = smtplib.SMTP(self.options.smtphost) server = smtplib.SMTP(self.options.smtphost)
if self.options.smtp_user is not None and self.options.smtp_pass is not None: if self.options.smtp_user is not None and self.options.smtp_pass is not None:
server.login(self.options.smtp_user, self.options.smtp_pass) server.login(self.options.smtp_user, self.options.smtp_pass)
#server.set_debuglevel(True) # server.set_debuglevel(True)
server.sendmail(from_addr, recipients, message) server.sendmail(from_addr, recipients, message)
server.quit() server.quit()
@ -5192,9 +5192,9 @@ class NewRepoTask(BaseTaskHandler):
for fn in os.listdir(path): for fn in os.listdir(path):
if fn != 'groups' and os.path.isfile("%s/%s/pkglist" % (path, fn)): if fn != 'groups' and os.path.isfile("%s/%s/pkglist" % (path, fn)):
arches.append(fn) arches.append(fn)
#see if we can find a previous repo to update from # see if we can find a previous repo to update from
#only shadowbuild tags should start with SHADOWBUILD, their repos are auto # only shadowbuild tags should start with SHADOWBUILD, their repos are auto
#expired. so lets get the most recent expired tag for newRepo shadowbuild tasks. # expired. so lets get the most recent expired tag for newRepo shadowbuild tasks.
if tinfo['name'].startswith('SHADOWBUILD'): if tinfo['name'].startswith('SHADOWBUILD'):
oldrepo_state = koji.REPO_EXPIRED oldrepo_state = koji.REPO_EXPIRED
else: else:
@ -5242,7 +5242,7 @@ class CreaterepoTask(BaseTaskHandler):
_taskWeight = 1.5 _taskWeight = 1.5
def handler(self, repo_id, arch, oldrepo): def handler(self, repo_id, arch, oldrepo):
#arch is the arch of the repo, not the task # arch is the arch of the repo, not the task
rinfo = self.session.repoInfo(repo_id, strict=True) rinfo = self.session.repoInfo(repo_id, strict=True)
if rinfo['state'] != koji.REPO_INIT: if rinfo['state'] != koji.REPO_INIT:
raise koji.GenericError("Repo %(id)s not in INIT state (got %(state)s)" % rinfo) raise koji.GenericError("Repo %(id)s not in INIT state (got %(state)s)" % rinfo)
@ -5253,7 +5253,7 @@ class CreaterepoTask(BaseTaskHandler):
if not os.path.isdir(self.repodir): if not os.path.isdir(self.repodir):
raise koji.GenericError("Repo directory missing: %s" % self.repodir) raise koji.GenericError("Repo directory missing: %s" % self.repodir)
groupdata = os.path.join(toprepodir, 'groups', 'comps.xml') groupdata = os.path.join(toprepodir, 'groups', 'comps.xml')
#set up our output dir # set up our output dir
self.outdir = '%s/repo' % self.workdir self.outdir = '%s/repo' % self.workdir
self.datadir = '%s/repodata' % self.outdir self.datadir = '%s/repodata' % self.outdir
pkglist = os.path.join(self.repodir, 'pkglist') pkglist = os.path.join(self.repodir, 'pkglist')
@ -5286,7 +5286,7 @@ class CreaterepoTask(BaseTaskHandler):
cmd.extend(['-i', pkglist]) cmd.extend(['-i', pkglist])
if os.path.isfile(groupdata): if os.path.isfile(groupdata):
cmd.extend(['-g', groupdata]) cmd.extend(['-g', groupdata])
#attempt to recycle repodata from last repo # attempt to recycle repodata from last repo
if pkglist and oldrepo and self.options.createrepo_update: if pkglist and oldrepo and self.options.createrepo_update:
# old repo could be from inherited tag, so path needs to be # old repo could be from inherited tag, so path needs to be
# composed from that tag, not rinfo['tag_name'] # composed from that tag, not rinfo['tag_name']
@ -5459,7 +5459,7 @@ class createDistRepoTask(BaseTaskHandler):
"sparc64", "s390x": "s390", "ppc64": "ppc"} "sparc64", "s390x": "s390", "ppc64": "ppc"}
def handler(self, tag, repo_id, arch, keys, opts): def handler(self, tag, repo_id, arch, keys, opts):
#arch is the arch of the repo, not the task # arch is the arch of the repo, not the task
self.rinfo = self.session.repoInfo(repo_id, strict=True) self.rinfo = self.session.repoInfo(repo_id, strict=True)
if self.rinfo['state'] != koji.REPO_INIT: if self.rinfo['state'] != koji.REPO_INIT:
raise koji.GenericError("Repo %(id)s not in INIT state (got %(state)s)" % self.rinfo) raise koji.GenericError("Repo %(id)s not in INIT state (got %(state)s)" % self.rinfo)
@ -6047,7 +6047,7 @@ enabled=1
class WaitrepoTask(BaseTaskHandler): class WaitrepoTask(BaseTaskHandler):
Methods = ['waitrepo'] Methods = ['waitrepo']
#mostly just waiting # mostly just waiting
_taskWeight = 0.2 _taskWeight = 0.2
PAUSE = 60 PAUSE = 60
@ -6101,7 +6101,7 @@ class WaitrepoTask(BaseTaskHandler):
(koji.util.duration(start), taginfo['name'])) (koji.util.duration(start), taginfo['name']))
return repo return repo
else: else:
#no check requested -- return first ready repo # no check requested -- return first ready repo
return repo return repo
if (time.time() - start) > (self.TIMEOUT * 60.0): if (time.time() - start) > (self.TIMEOUT * 60.0):
@ -6140,7 +6140,7 @@ def get_options():
parser.add_option("--debug-xmlrpc", action="store_true", default=False, parser.add_option("--debug-xmlrpc", action="store_true", default=False,
help="show xmlrpc debug output") help="show xmlrpc debug output")
parser.add_option("--debug-mock", action="store_true", default=False, parser.add_option("--debug-mock", action="store_true", default=False,
#obsolete option # obsolete option
help=SUPPRESS_HELP) help=SUPPRESS_HELP)
parser.add_option("--skip-main", action="store_true", default=False, parser.add_option("--skip-main", action="store_true", default=False,
help="don't actually run main") help="don't actually run main")
@ -6163,7 +6163,7 @@ def get_options():
if args: if args:
parser.error("incorrect number of arguments") parser.error("incorrect number of arguments")
#not reached # not reached
assert False # pragma: no cover assert False # pragma: no cover
# load local config # load local config
@ -6256,12 +6256,12 @@ def get_options():
if getattr(options, name, None) is None: if getattr(options, name, None) is None:
setattr(options, name, value) setattr(options, name, value)
#honor topdir # honor topdir
if options.topdir: if options.topdir:
koji.BASEDIR = options.topdir koji.BASEDIR = options.topdir
koji.pathinfo.topdir = options.topdir koji.pathinfo.topdir = options.topdir
#make sure workdir exists # make sure workdir exists
if not os.path.exists(options.workdir): if not os.path.exists(options.workdir):
koji.ensuredir(options.workdir) koji.ensuredir(options.workdir)
@ -6308,7 +6308,7 @@ def quit(msg=None, code=1):
if __name__ == "__main__": if __name__ == "__main__":
koji.add_file_logger("koji", "/var/log/kojid.log") koji.add_file_logger("koji", "/var/log/kojid.log")
#note we're setting logging params for all of koji* # note we're setting logging params for all of koji*
options = get_options() options = get_options()
if options.log_level: if options.log_level:
lvl = getattr(logging, options.log_level, None) lvl = getattr(logging, options.log_level, None)
@ -6326,7 +6326,7 @@ if __name__ == "__main__":
if options.admin_emails: if options.admin_emails:
koji.add_mail_logger("koji", options.admin_emails) koji.add_mail_logger("koji", options.admin_emails)
#start a session and login # start a session and login
session_opts = koji.grab_session_options(options) session_opts = koji.grab_session_options(options)
session = koji.ClientSession(options.server, session_opts) session = koji.ClientSession(options.server, session_opts)
if options.cert and os.path.isfile(options.cert): if options.cert and os.path.isfile(options.cert):
@ -6360,14 +6360,14 @@ if __name__ == "__main__":
quit("Could not connect to Kerberos authentication service: '%s'" % e.args[1]) quit("Could not connect to Kerberos authentication service: '%s'" % e.args[1])
else: else:
quit("No username/password supplied and Kerberos missing or not configured") quit("No username/password supplied and Kerberos missing or not configured")
#make session exclusive # make session exclusive
try: try:
session.exclusiveSession(force=options.force_lock) session.exclusiveSession(force=options.force_lock)
except koji.AuthLockError: except koji.AuthLockError:
quit("Error: Unable to get lock. Trying using --force-lock") quit("Error: Unable to get lock. Trying using --force-lock")
if not session.logged_in: if not session.logged_in:
quit("Error: Unknown login error") quit("Error: Unknown login error")
#make sure it works # make sure it works
try: try:
ret = session.echo("OK") ret = session.echo("OK")
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
@ -6377,7 +6377,7 @@ if __name__ == "__main__":
# run main # run main
if options.daemon: if options.daemon:
#detach # detach
koji.daemonize() koji.daemonize()
main(options, session) main(options, session)
# not reached # not reached

View file

@ -164,7 +164,7 @@ class RepoMerge(object):
n = self.yumbase.add_enable_repo(rid, baseurls=[r]) n = self.yumbase.add_enable_repo(rid, baseurls=[r])
n._merge_rank = count n._merge_rank = count
#setup our sacks # setup our sacks
self.yumbase._getSacks(archlist=self.archlist) self.yumbase._getSacks(archlist=self.archlist)
self.sort_and_filter() self.sort_and_filter()
@ -205,8 +205,8 @@ class RepoMerge(object):
if reponum == 0 and not pkg.basepath: if reponum == 0 and not pkg.basepath:
# this is the first repo (i.e. the koji repo) and appears # this is the first repo (i.e. the koji repo) and appears
# to be using relative urls # to be using relative urls
#XXX - kind of a hack, but yum leaves us little choice # XXX - kind of a hack, but yum leaves us little choice
#force the pkg object to report a relative location # force the pkg object to report a relative location
loc = """<location href="%s"/>\n""" % yum.misc.to_xml(pkg.remote_path, attrib=True) loc = """<location href="%s"/>\n""" % yum.misc.to_xml(pkg.remote_path, attrib=True)
pkg._return_remote_location = make_const_func(loc) pkg._return_remote_location = make_const_func(loc)
if pkg.sourcerpm in seen_srpms: if pkg.sourcerpm in seen_srpms:
@ -296,8 +296,8 @@ class RepoMerge(object):
if reponum == 0 and not pkg.basepath: if reponum == 0 and not pkg.basepath:
# this is the first repo (i.e. the koji repo) and appears # this is the first repo (i.e. the koji repo) and appears
# to be using relative urls # to be using relative urls
#XXX - kind of a hack, but yum leaves us little choice # XXX - kind of a hack, but yum leaves us little choice
#force the pkg object to report a relative location # force the pkg object to report a relative location
loc = """<location href="%s"/>\n""" % yum.misc.to_xml(pkg.remote_path, attrib=True) loc = """<location href="%s"/>\n""" % yum.misc.to_xml(pkg.remote_path, attrib=True)
pkg._return_remote_location = make_const_func(loc) pkg._return_remote_location = make_const_func(loc)

View file

@ -50,7 +50,7 @@ def register_plugin(plugin):
""" """
for v in six.itervalues(vars(plugin)): for v in six.itervalues(vars(plugin)):
if isinstance(v, six.class_types): if isinstance(v, six.class_types):
#skip classes # skip classes
continue continue
if callable(v): if callable(v):
if getattr(v, 'exported_cli', False): if getattr(v, 'exported_cli', False):
@ -166,12 +166,12 @@ def get_options():
value = os.path.expanduser(getattr(options, name)) value = os.path.expanduser(getattr(options, name))
setattr(options, name, value) setattr(options, name, value)
#honor topdir # honor topdir
if options.topdir: if options.topdir:
koji.BASEDIR = options.topdir koji.BASEDIR = options.topdir
koji.pathinfo.topdir = options.topdir koji.pathinfo.topdir = options.topdir
#pkgurl is obsolete # pkgurl is obsolete
if options.pkgurl: if options.pkgurl:
if options.topurl: if options.topurl:
warn("Warning: the pkgurl option is obsolete") warn("Warning: the pkgurl option is obsolete")

View file

@ -484,11 +484,11 @@ def handle_build(options, session, args):
opts[key] = val opts[key] = val
priority = None priority = None
if build_opts.background: if build_opts.background:
#relative to koji.PRIO_DEFAULT # relative to koji.PRIO_DEFAULT
priority = 5 priority = 5
# try to check that source is an SRPM # try to check that source is an SRPM
if '://' not in source: if '://' not in source:
#treat source as an srpm and upload it # treat source as an srpm and upload it
if not build_opts.quiet: if not build_opts.quiet:
print("Uploading srpm: %s" % source) print("Uploading srpm: %s" % source)
serverdir = unique_path('cli-build') serverdir = unique_path('cli-build')
@ -546,7 +546,7 @@ def handle_chain_build(options, session, args):
src_list = [] src_list = []
build_level = [] build_level = []
#src_lists is a list of lists of sources to build. # src_lists is a list of lists of sources to build.
# each list is block of builds ("build level") which must all be completed # each list is block of builds ("build level") which must all be completed
# before the next block begins. Blocks are separated on the command line with ':' # before the next block begins. Blocks are separated on the command line with ':'
for src in sources: for src in sources:
@ -571,7 +571,7 @@ def handle_chain_build(options, session, args):
priority = None priority = None
if build_opts.background: if build_opts.background:
#relative to koji.PRIO_DEFAULT # relative to koji.PRIO_DEFAULT
priority = 5 priority = 5
task_id = session.chainBuild(src_list, target, priority=priority) task_id = session.chainBuild(src_list, target, priority=priority)
@ -671,7 +671,7 @@ def handle_maven_build(options, session, args):
opts['skip_tag'] = True opts['skip_tag'] = True
priority = None priority = None
if build_opts.background: if build_opts.background:
#relative to koji.PRIO_DEFAULT # relative to koji.PRIO_DEFAULT
priority = 5 priority = 5
task_id = session.mavenBuild(source, target, opts, priority=priority) task_id = session.mavenBuild(source, target, opts, priority=priority)
if not build_opts.quiet: if not build_opts.quiet:
@ -894,7 +894,7 @@ def anon_handle_mock_config(goptions, session, args):
(options, args) = parser.parse_args(args) (options, args) = parser.parse_args(args)
activate_session(session, goptions) activate_session(session, goptions)
if args: if args:
#for historical reasons, we also accept buildroot name as first arg # for historical reasons, we also accept buildroot name as first arg
if not options.name: if not options.name:
options.name = args[0] options.name = args[0]
else: else:
@ -1155,7 +1155,7 @@ def handle_import(goptions, session, args):
if data['sourcepackage']: if data['sourcepackage']:
break break
else: else:
#no srpm included, check for build # no srpm included, check for build
binfo = session.getBuild(nvr) binfo = session.getBuild(nvr)
if not binfo: if not binfo:
print(_("Missing build or srpm: %s") % nvr) print(_("Missing build or srpm: %s") % nvr)
@ -1164,7 +1164,7 @@ def handle_import(goptions, session, args):
print(_("Aborting import")) print(_("Aborting import"))
return return
#local function to help us out below # local function to help us out below
def do_import(path, data): def do_import(path, data):
rinfo = dict([(k,data[k]) for k in ('name','version','release','arch')]) rinfo = dict([(k,data[k]) for k in ('name','version','release','arch')])
prev = session.getRPM(rinfo) prev = session.getRPM(rinfo)
@ -1391,13 +1391,13 @@ def _import_comps_alt(session, filename, tag, options): # no cover 3.x
uservisible=bool(group.user_visible), uservisible=bool(group.user_visible),
description=group.description, description=group.description,
langonly=group.langonly) langonly=group.langonly)
#yum.comps does not support the biarchonly field # yum.comps does not support the biarchonly field
for ptype, pdata in [('mandatory', group.mandatory_packages), for ptype, pdata in [('mandatory', group.mandatory_packages),
('default', group.default_packages), ('default', group.default_packages),
('optional', group.optional_packages), ('optional', group.optional_packages),
('conditional', group.conditional_packages)]: ('conditional', group.conditional_packages)]:
for pkg in pdata: for pkg in pdata:
#yum.comps does not support basearchonly # yum.comps does not support basearchonly
pkgopts = {'type' : ptype} pkgopts = {'type' : ptype}
if ptype == 'conditional': if ptype == 'conditional':
pkgopts['requires'] = pdata[pkg] pkgopts['requires'] = pdata[pkg]
@ -1407,8 +1407,8 @@ def _import_comps_alt(session, filename, tag, options): # no cover 3.x
s_opts = ', '.join(["'%s': %r" % (k, pkgopts[k]) for k in sorted(pkgopts.keys())]) s_opts = ', '.join(["'%s': %r" % (k, pkgopts[k]) for k in sorted(pkgopts.keys())])
print(" Package: %s: {%s}" % (pkg, s_opts)) print(" Package: %s: {%s}" % (pkg, s_opts))
session.groupPackageListAdd(tag, group.groupid, pkg, force=force, **pkgopts) session.groupPackageListAdd(tag, group.groupid, pkg, force=force, **pkgopts)
#yum.comps does not support group dependencies # yum.comps does not support group dependencies
#yum.comps does not support metapkgs # yum.comps does not support metapkgs
def handle_import_sig(goptions, session, args): def handle_import_sig(goptions, session, args):
@ -1540,9 +1540,9 @@ def handle_prune_signed_copies(options, session, args):
# 4) for a specified tag, remove all signed copies (no inheritance) # 4) for a specified tag, remove all signed copies (no inheritance)
# (but skip builds that are multiply tagged) # (but skip builds that are multiply tagged)
#for now, we're just implementing mode #1 # for now, we're just implementing mode #1
#(with the modification that we check to see if the build was latest within # (with the modification that we check to see if the build was latest within
#the last N days) # the last N days)
if options.ignore_tag_file: if options.ignore_tag_file:
with open(options.ignore_tag_file) as fo: with open(options.ignore_tag_file) as fo:
options.ignore_tag.extend([line.strip() for line in fo.readlines()]) options.ignore_tag.extend([line.strip() for line in fo.readlines()])
@ -1579,7 +1579,7 @@ def handle_prune_signed_copies(options, session, args):
print("...got %i builds" % len(builds)) print("...got %i builds" % len(builds))
builds.sort() builds.sort()
else: else:
#single build # single build
binfo = session.getBuild(options.build) binfo = session.getBuild(options.build)
if not binfo: if not binfo:
parser.error('No such build: %s' % options.build) parser.error('No such build: %s' % options.build)
@ -1601,21 +1601,21 @@ def handle_prune_signed_copies(options, session, args):
time_str = time.asctime(time.localtime(ts)) time_str = time.asctime(time.localtime(ts))
return "%s: %s" % (time_str, fmt % x) return "%s: %s" % (time_str, fmt % x)
for nvr, binfo in builds: for nvr, binfo in builds:
#listBuilds returns slightly different data than normal # listBuilds returns slightly different data than normal
if 'id' not in binfo: if 'id' not in binfo:
binfo['id'] = binfo['build_id'] binfo['id'] = binfo['build_id']
if 'name' not in binfo: if 'name' not in binfo:
binfo['name'] = binfo['package_name'] binfo['name'] = binfo['package_name']
if options.debug: if options.debug:
print("DEBUG: %s" % nvr) print("DEBUG: %s" % nvr)
#see how recently this build was latest for a tag # see how recently this build was latest for a tag
is_latest = False is_latest = False
is_protected = False is_protected = False
last_latest = None last_latest = None
tags = {} tags = {}
for entry in session.queryHistory(build=binfo['id'])['tag_listing']: for entry in session.queryHistory(build=binfo['id'])['tag_listing']:
#we used queryHistory rather than listTags so we can consider tags # we used queryHistory rather than listTags so we can consider tags
#that the build was recently untagged from # that the build was recently untagged from
tags.setdefault(entry['tag.name'], 1) tags.setdefault(entry['tag.name'], 1)
if options.debug: if options.debug:
print("Tags: %s" % to_list(tags.keys())) print("Tags: %s" % to_list(tags.keys()))
@ -1633,43 +1633,43 @@ def handle_prune_signed_copies(options, session, args):
break break
if ignore_tag: if ignore_tag:
continue continue
#in order to determine how recently this build was latest, we have # in order to determine how recently this build was latest, we have
#to look at the tagging history. # to look at the tagging history.
hist = session.queryHistory(tag=tag_name, package=binfo['name'])['tag_listing'] hist = session.queryHistory(tag=tag_name, package=binfo['name'])['tag_listing']
if not hist: if not hist:
#really shouldn't happen # really shouldn't happen
raise koji.GenericError("No history found for %s in %s" % (nvr, tag_name)) raise koji.GenericError("No history found for %s in %s" % (nvr, tag_name))
timeline = [] timeline = []
for x in hist: for x in hist:
#note that for revoked entries, we're effectively splitting them into # note that for revoked entries, we're effectively splitting them into
#two parts: creation and revocation. # two parts: creation and revocation.
timeline.append((x['create_event'], 1, x)) timeline.append((x['create_event'], 1, x))
#at the same event, revokes happen first # at the same event, revokes happen first
if x['revoke_event'] is not None: if x['revoke_event'] is not None:
timeline.append((x['revoke_event'], 0, x)) timeline.append((x['revoke_event'], 0, x))
timeline.sort(key=lambda entry: entry[:2]) timeline.sort(key=lambda entry: entry[:2])
#find most recent creation entry for our build and crop there # find most recent creation entry for our build and crop there
latest_ts = None latest_ts = None
for i in range(len(timeline)-1, -1, -1): for i in range(len(timeline)-1, -1, -1):
#searching in reverse cronological order # searching in reverse cronological order
event_id, is_create, entry = timeline[i] event_id, is_create, entry = timeline[i]
if entry['build_id'] == binfo['id'] and is_create: if entry['build_id'] == binfo['id'] and is_create:
latest_ts = event_id latest_ts = event_id
break break
if not latest_ts: if not latest_ts:
#really shouldn't happen # really shouldn't happen
raise koji.GenericError("No creation event found for %s in %s" % (nvr, tag_name)) raise koji.GenericError("No creation event found for %s in %s" % (nvr, tag_name))
our_entry = entry our_entry = entry
if options.debug: if options.debug:
print(_histline(event_id, our_entry)) print(_histline(event_id, our_entry))
#now go through the events since most recent creation entry # now go through the events since most recent creation entry
timeline = timeline[i+1:] timeline = timeline[i+1:]
if not timeline: if not timeline:
is_latest = True is_latest = True
if options.debug: if options.debug:
print("%s is latest in tag %s" % (nvr, tag_name)) print("%s is latest in tag %s" % (nvr, tag_name))
break break
#before we go any further, is this a protected tag? # before we go any further, is this a protected tag?
protect_tag = False protect_tag = False
for pattern in options.protect_tag: for pattern in options.protect_tag:
if fnmatch.fnmatch(tag_name, pattern): if fnmatch.fnmatch(tag_name, pattern):
@ -1680,13 +1680,13 @@ def handle_prune_signed_copies(options, session, args):
# if this build was in this tag within that limit, then we will # if this build was in this tag within that limit, then we will
# not prune its signed copies # not prune its signed copies
if our_entry['revoke_event'] is None: if our_entry['revoke_event'] is None:
#we're still tagged with a protected tag # we're still tagged with a protected tag
if options.debug: if options.debug:
print("Build %s has protected tag %s" % (nvr, tag_name)) print("Build %s has protected tag %s" % (nvr, tag_name))
is_protected = True is_protected = True
break break
elif our_entry['revoke_ts'] > cutoff_ts: elif our_entry['revoke_ts'] > cutoff_ts:
#we were still tagged here sometime before the cutoff # we were still tagged here sometime before the cutoff
if options.debug: if options.debug:
print("Build %s had protected tag %s until %s" \ print("Build %s had protected tag %s until %s" \
% (nvr, tag_name, time.asctime(time.localtime(our_entry['revoke_ts'])))) % (nvr, tag_name, time.asctime(time.localtime(our_entry['revoke_ts']))))
@ -1696,40 +1696,40 @@ def handle_prune_signed_copies(options, session, args):
revoke_ts = None revoke_ts = None
others = {} others = {}
for event_id, is_create, entry in timeline: for event_id, is_create, entry in timeline:
#So two things can knock this build from the title of latest: # So two things can knock this build from the title of latest:
# - it could be untagged (entry revoked) # - it could be untagged (entry revoked)
# - another build could become latest (replaced) # - another build could become latest (replaced)
#Note however that if the superceding entry is itself revoked, then # Note however that if the superceding entry is itself revoked, then
#our build could become latest again # our build could become latest again
if options.debug: if options.debug:
print(_histline(event_id, entry)) print(_histline(event_id, entry))
if entry['build_id'] == binfo['id']: if entry['build_id'] == binfo['id']:
if is_create: if is_create:
#shouldn't happen # shouldn't happen
raise koji.GenericError("Duplicate creation event found for %s in %s" \ raise koji.GenericError("Duplicate creation event found for %s in %s" \
% (nvr, tag_name)) % (nvr, tag_name))
else: else:
#we've been revoked # we've been revoked
revoke_ts = entry['revoke_ts'] revoke_ts = entry['revoke_ts']
break break
else: else:
if is_create: if is_create:
#this build has become latest # this build has become latest
replaced_ts = entry['create_ts'] replaced_ts = entry['create_ts']
if entry['active']: if entry['active']:
#this entry not revoked yet, so we're done for this tag # this entry not revoked yet, so we're done for this tag
break break
#since this entry is revoked later, our build might eventually be # since this entry is revoked later, our build might eventually be
#uncovered, so we have to keep looking # uncovered, so we have to keep looking
others[entry['build_id']] = 1 others[entry['build_id']] = 1
else: else:
#other build revoked # other build revoked
#see if our build has resurfaced # see if our build has resurfaced
if entry['build_id'] in others: if entry['build_id'] in others:
del others[entry['build_id']] del others[entry['build_id']]
if replaced_ts is not None and not others: if replaced_ts is not None and not others:
#we've become latest again # we've become latest again
#(note: we're not revoked yet because that triggers a break above) # (note: we're not revoked yet because that triggers a break above)
replaced_ts = None replaced_ts = None
latest_ts = entry['revoke_ts'] latest_ts = entry['revoke_ts']
if last_latest is None: if last_latest is None:
@ -1738,25 +1738,25 @@ def handle_prune_signed_copies(options, session, args):
timestamps = [last_latest] timestamps = [last_latest]
if revoke_ts is None: if revoke_ts is None:
if replaced_ts is None: if replaced_ts is None:
#turns out we are still latest # turns out we are still latest
is_latest = True is_latest = True
if options.debug: if options.debug:
print("%s is latest (again) in tag %s" % (nvr, tag_name)) print("%s is latest (again) in tag %s" % (nvr, tag_name))
break break
else: else:
#replaced (but not revoked) # replaced (but not revoked)
timestamps.append(replaced_ts) timestamps.append(replaced_ts)
if options.debug: if options.debug:
print("tag %s: %s not latest (replaced %s)" \ print("tag %s: %s not latest (replaced %s)" \
% (tag_name, nvr, time.asctime(time.localtime(replaced_ts)))) % (tag_name, nvr, time.asctime(time.localtime(replaced_ts))))
elif replaced_ts is None: elif replaced_ts is None:
#revoked but not replaced # revoked but not replaced
timestamps.append(revoke_ts) timestamps.append(revoke_ts)
if options.debug: if options.debug:
print("tag %s: %s not latest (revoked %s)" \ print("tag %s: %s not latest (revoked %s)" \
% (tag_name, nvr, time.asctime(time.localtime(revoke_ts)))) % (tag_name, nvr, time.asctime(time.localtime(revoke_ts))))
else: else:
#revoked AND replaced # revoked AND replaced
timestamps.append(min(revoke_ts, replaced_ts)) timestamps.append(min(revoke_ts, replaced_ts))
if options.debug: if options.debug:
print("tag %s: %s not latest (revoked %s, replaced %s)" \ print("tag %s: %s not latest (revoked %s, replaced %s)" \
@ -1772,13 +1772,13 @@ def handle_prune_signed_copies(options, session, args):
continue continue
if is_protected: if is_protected:
continue continue
#not latest anywhere since cutoff, so we can remove all signed copies # not latest anywhere since cutoff, so we can remove all signed copies
rpms = session.listRPMs(buildID=binfo['id']) rpms = session.listRPMs(buildID=binfo['id'])
session.multicall = True session.multicall = True
for rpminfo in rpms: for rpminfo in rpms:
session.queryRPMSigs(rpm_id=rpminfo['id']) session.queryRPMSigs(rpm_id=rpminfo['id'])
by_sig = {} by_sig = {}
#index by sig # index by sig
for rpminfo, [sigs] in zip(rpms, session.multiCall()): for rpminfo, [sigs] in zip(rpms, session.multiCall()):
for sig in sigs: for sig in sigs:
sigkey = sig['sigkey'] sigkey = sig['sigkey']
@ -1799,7 +1799,7 @@ def handle_prune_signed_copies(options, session, args):
except OSError: except OSError:
continue continue
if not stat.S_ISREG(st.st_mode): if not stat.S_ISREG(st.st_mode):
#warn about this # warn about this
print("Skipping %s. Not a regular file" % signedpath) print("Skipping %s. Not a regular file" % signedpath)
continue continue
if st.st_mtime > cutoff_ts: if st.st_mtime > cutoff_ts:
@ -1819,7 +1819,7 @@ def handle_prune_signed_copies(options, session, args):
mycount +=1 mycount +=1
build_files += 1 build_files += 1
build_space += st.st_size build_space += st.st_size
#XXX - this makes some layout assumptions, but # XXX - this makes some layout assumptions, but
# pathinfo doesn't report what we need # pathinfo doesn't report what we need
mydir = os.path.dirname(signedpath) mydir = os.path.dirname(signedpath)
archdirs[mydir] = 1 archdirs[mydir] = 1
@ -2078,7 +2078,7 @@ def handle_list_signed(goptions, session, args):
for rinfo in rpms: for rinfo in rpms:
rpm_idx.setdefault(rinfo['id'], rinfo) rpm_idx.setdefault(rinfo['id'], rinfo)
tagged[rinfo['id']] = 1 tagged[rinfo['id']] = 1
#Now figure out which sig entries actually have live copies # Now figure out which sig entries actually have live copies
for sig in sigs: for sig in sigs:
rpm_id = sig['rpm_id'] rpm_id = sig['rpm_id']
sigkey = sig['sigkey'] sigkey = sig['sigkey']
@ -2862,7 +2862,7 @@ def anon_handle_list_pkgs(goptions, session, args):
# no limiting clauses were specified # no limiting clauses were specified
allpkgs = True allpkgs = True
opts['inherited'] = not options.noinherit opts['inherited'] = not options.noinherit
#hiding dups only makes sense if we're querying a tag # hiding dups only makes sense if we're querying a tag
if options.tag: if options.tag:
opts['with_dups'] = options.show_dups opts['with_dups'] = options.show_dups
else: else:
@ -3736,7 +3736,7 @@ def handle_add_target(goptions, session, args):
if len(args) > 2: if len(args) > 2:
dest_tag = args[2] dest_tag = args[2]
else: else:
#most targets have the same name as their destination # most targets have the same name as their destination
dest_tag = name dest_tag = name
activate_session(session, goptions) activate_session(session, goptions)
if not (session.hasPerm('admin') or session.hasPerm('target')): if not (session.hasPerm('admin') or session.hasPerm('target')):
@ -3866,7 +3866,7 @@ def anon_handle_list_targets(goptions, session, args):
targets = [x[1] for x in tmp_list] targets = [x[1] for x in tmp_list]
for target in targets: for target in targets:
print(fmt % target) print(fmt % target)
#pprint.pprint(session.getBuildTargets()) # pprint.pprint(session.getBuildTargets())
def _printInheritance(tags, sibdepths=None, reverse=False): def _printInheritance(tags, sibdepths=None, reverse=False):
@ -3992,7 +3992,7 @@ def anon_handle_list_tags(goptions, session, args):
tags = session.listTags(buildinfo.get('id',None), pkginfo.get('id',None)) tags = session.listTags(buildinfo.get('id',None), pkginfo.get('id',None))
tags.sort(key=lambda x: x['name']) tags.sort(key=lambda x: x['name'])
#if options.verbose: # if options.verbose:
# fmt = "%(name)s [%(id)i] %(perm)s %(locked)s %(arches)s" # fmt = "%(name)s [%(id)i] %(perm)s %(locked)s %(arches)s"
if options.show_id: if options.show_id:
fmt = "%(name)s [%(id)i]" fmt = "%(name)s [%(id)i]"
@ -4094,14 +4094,14 @@ def _print_histline(entry, **kwargs):
if len(edit) != 1: if len(edit) != 1:
bad_edit = "%i elements" % (len(edit)+1) bad_edit = "%i elements" % (len(edit)+1)
other = edit[0] other = edit[0]
#check edit for sanity # check edit for sanity
if create or not other[2]: if create or not other[2]:
bad_edit = "out of order" bad_edit = "out of order"
if event_id != other[0]: if event_id != other[0]:
bad_edit = "non-matching" bad_edit = "non-matching"
if bad_edit: if bad_edit:
print("Warning: unusual edit at event %i in table %s (%s)" % (event_id, table, bad_edit)) print("Warning: unusual edit at event %i in table %s (%s)" % (event_id, table, bad_edit))
#we'll simply treat them as separate events # we'll simply treat them as separate events
pprint.pprint(entry) pprint.pprint(entry)
pprint.pprint(edit) pprint.pprint(edit)
_print_histline(entry, **kwargs) _print_histline(entry, **kwargs)
@ -4415,11 +4415,11 @@ def anon_handle_list_history(goptions, session, args):
if x['revoke_event'] is not None: if x['revoke_event'] is not None:
if distinguish_match(x, 'revoked'): if distinguish_match(x, 'revoked'):
timeline.append((x['revoke_event'], table, 0, x.copy())) timeline.append((x['revoke_event'], table, 0, x.copy()))
#pprint.pprint(timeline[-1]) # pprint.pprint(timeline[-1])
if distinguish_match(x, 'created'): if distinguish_match(x, 'created'):
timeline.append((x['create_event'], table, 1, x)) timeline.append((x['create_event'], table, 1, x))
timeline.sort(key=lambda entry: entry[:3]) timeline.sort(key=lambda entry: entry[:3])
#group edits together # group edits together
new_timeline = [] new_timeline = []
last_event = None last_event = None
edit_index = {} edit_index = {}
@ -4892,7 +4892,7 @@ def handle_edit_tag(goptions, session, args):
opts['extra'] = extra opts['extra'] = extra
if options.remove_extra: if options.remove_extra:
opts['remove_extra'] = options.remove_extra opts['remove_extra'] = options.remove_extra
#XXX change callname # XXX change callname
session.editTag2(tag, **opts) session.editTag2(tag, **opts)
@ -4927,7 +4927,7 @@ def handle_lock_tag(goptions, session, args):
selected = [session.getTag(name, strict=True) for name in args] selected = [session.getTag(name, strict=True) for name in args]
for tag in selected: for tag in selected:
if options.master: if options.master:
#set the master lock # set the master lock
if tag['locked']: if tag['locked']:
print(_("Tag %s: master lock already set") % tag['name']) print(_("Tag %s: master lock already set") % tag['name'])
continue continue
@ -5293,12 +5293,12 @@ def anon_handle_list_external_repos(goptions, session, args):
def _pick_external_repo_priority(session, tag): def _pick_external_repo_priority(session, tag):
"""pick priority after current ones, leaving space for later insertions""" """pick priority after current ones, leaving space for later insertions"""
repolist = session.getTagExternalRepos(tag_info=tag) repolist = session.getTagExternalRepos(tag_info=tag)
#ordered by priority # ordered by priority
if not repolist: if not repolist:
priority = 5 priority = 5
else: else:
priority = (repolist[-1]['priority'] + 7) // 5 * 5 priority = (repolist[-1]['priority'] + 7) // 5 * 5
#at least 3 higher than current max and a multiple of 5 # at least 3 higher than current max and a multiple of 5
return priority return priority
@ -5404,7 +5404,7 @@ def handle_remove_external_repo(goptions, session, args):
return 0 return 0
tags = current_tags tags = current_tags
if delete: if delete:
#removing entirely # removing entirely
if current_tags and not options.force: if current_tags and not options.force:
print(_("Error: external repo %s used by tag(s): %s") % (repo, ', '.join(current_tags))) print(_("Error: external repo %s used by tag(s): %s") % (repo, ', '.join(current_tags)))
print(_("Use --force to remove anyway")) print(_("Use --force to remove anyway"))
@ -5708,10 +5708,10 @@ def _build_image_indirection(options, task_opts, session, args):
if not options.quiet: if not options.quiet:
print("Created task: %d" % task_id) print("Created task: %d" % task_id)
print("Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id)) print("Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id))
#if task_opts.wait or (task_opts.wait is None and not _running_in_bg()): # if task_opts.wait or (task_opts.wait is None and not _running_in_bg()):
# session.logout() # session.logout()
# return watch_tasks(session, [task_id], quiet=options.quiet) # return watch_tasks(session, [task_id], quiet=options.quiet)
#else: # else:
# return # return
@ -6045,7 +6045,7 @@ def handle_win_build(options, session, args):
opts[key] = val opts[key] = val
priority = None priority = None
if build_opts.background: if build_opts.background:
#relative to koji.PRIO_DEFAULT # relative to koji.PRIO_DEFAULT
priority = 5 priority = 5
task_id = session.winBuild(vm_name, scmurl, target, opts, priority=priority) task_id = session.winBuild(vm_name, scmurl, target, opts, priority=priority)
if not build_opts.quiet: if not build_opts.quiet:
@ -6376,7 +6376,7 @@ def handle_tag_build(opts, session, args):
tasks = [] tasks = []
for pkg in args[1:]: for pkg in args[1:]:
task_id = session.tagBuild(args[0], pkg, force=options.force) task_id = session.tagBuild(args[0], pkg, force=options.force)
#XXX - wait on task # XXX - wait on task
tasks.append(task_id) tasks.append(task_id)
print("Created task %d" % task_id) print("Created task %d" % task_id)
if _running_in_bg() or options.nowait: if _running_in_bg() or options.nowait:
@ -6468,7 +6468,7 @@ def handle_untag_build(goptions, session, args):
builds = [] builds = []
for binfo in tagged: for binfo in tagged:
if binfo['name'] not in seen_pkg: if binfo['name'] not in seen_pkg:
#latest for this package # latest for this package
if options.verbose: if options.verbose:
print(_("Leaving latest build for package %(name)s: %(nvr)s") % binfo) print(_("Leaving latest build for package %(name)s: %(nvr)s") % binfo)
else: else:

View file

@ -72,7 +72,7 @@ def arg_filter(arg):
pass pass
if arg in ARGMAP: if arg in ARGMAP:
return ARGMAP[arg] return ARGMAP[arg]
#handle lists/dicts? # handle lists/dicts?
return arg return arg
@ -148,7 +148,7 @@ class TaskWatcher(object):
self.level = level self.level = level
self.quiet = quiet self.quiet = quiet
#XXX - a bunch of this stuff needs to adapt to different tasks # XXX - a bunch of this stuff needs to adapt to different tasks
def str(self): def str(self):
if self.info: if self.info:
@ -189,7 +189,7 @@ class TaskWatcher(object):
sys.exit(1) sys.exit(1)
state = self.info['state'] state = self.info['state']
if last: if last:
#compare and note status changes # compare and note status changes
laststate = last['state'] laststate = last['state']
if laststate != state: if laststate != state:
if not self.quiet: if not self.quiet:
@ -555,7 +555,7 @@ def activate_session(session, options):
noauth = options.authtype == "noauth" or getattr(options, 'noauth', False) noauth = options.authtype == "noauth" or getattr(options, 'noauth', False)
runas = getattr(options, 'runas', None) runas = getattr(options, 'runas', None)
if noauth: if noauth:
#skip authentication # skip authentication
pass pass
elif options.authtype == "ssl" or os.path.isfile(options.cert) and options.authtype is None: elif options.authtype == "ssl" or os.path.isfile(options.cert) and options.authtype is None:
# authenticate using SSL client cert # authenticate using SSL client cert
@ -626,7 +626,7 @@ def _list_tasks(options, session):
tasklist = session.listTasks(callopts, qopts) tasklist = session.listTasks(callopts, qopts)
tasks = dict([(x['id'], x) for x in tasklist]) tasks = dict([(x['id'], x) for x in tasklist])
#thread the tasks # thread the tasks
for t in tasklist: for t in tasklist:
if t['parent'] is not None: if t['parent'] is not None:
parent = tasks.get(t['parent']) parent = tasks.get(t['parent'])

File diff suppressed because it is too large Load diff

View file

@ -64,7 +64,7 @@ class HandlerRegistry(object):
def __init__(self): def __init__(self):
self.funcs = {} self.funcs = {}
#introspection functions # introspection functions
self.register_function(self.list_api, name="_listapi") self.register_function(self.list_api, name="_listapi")
self.register_function(self.system_listMethods, name="system.listMethods") self.register_function(self.system_listMethods, name="system.listMethods")
self.register_function(self.system_methodSignature, name="system.methodSignature") self.register_function(self.system_methodSignature, name="system.methodSignature")
@ -106,7 +106,7 @@ class HandlerRegistry(object):
""" """
for v in six.itervalues(vars(plugin)): for v in six.itervalues(vars(plugin)):
if isinstance(v, type): if isinstance(v, type):
#skip classes # skip classes
continue continue
if callable(v): if callable(v):
if getattr(v, 'exported', False): if getattr(v, 'exported', False):
@ -138,8 +138,8 @@ class HandlerRegistry(object):
def list_api(self): def list_api(self):
funcs = [] funcs = []
for name, func in self.funcs.items(): for name, func in self.funcs.items():
#the keys in self.funcs determine the name of the method as seen over xmlrpc # the keys in self.funcs determine the name of the method as seen over xmlrpc
#func.__name__ might differ (e.g. for dotted method names) # func.__name__ might differ (e.g. for dotted method names)
args = self._getFuncArgs(func) args = self._getFuncArgs(func)
argspec = self.getargspec(func) argspec = self.getargspec(func)
funcs.append({'name': name, funcs.append({'name': name,
@ -164,7 +164,7 @@ class HandlerRegistry(object):
return koji.util.to_list(self.funcs.keys()) return koji.util.to_list(self.funcs.keys())
def system_methodSignature(self, method): def system_methodSignature(self, method):
#it is not possible to autogenerate this data # it is not possible to autogenerate this data
return 'signatures not supported' return 'signatures not supported'
def system_methodHelp(self, method): def system_methodHelp(self, method):
@ -268,7 +268,7 @@ class ModXMLRPCRequestHandler(object):
return response return response
def handle_upload(self, environ): def handle_upload(self, environ):
#uploads can't be in a multicall # uploads can't be in a multicall
context.method = None context.method = None
self.check_session() self.check_session()
self.enforce_lockout() self.enforce_lockout()
@ -280,13 +280,13 @@ class ModXMLRPCRequestHandler(object):
def check_session(self): def check_session(self):
if not hasattr(context, "session"): if not hasattr(context, "session"):
#we may be called again by one of our meta-calls (like multiCall) # we may be called again by one of our meta-calls (like multiCall)
#so we should only create a session if one does not already exist # so we should only create a session if one does not already exist
context.session = koji.auth.Session() context.session = koji.auth.Session()
try: try:
context.session.validate() context.session.validate()
except koji.AuthLockError: except koji.AuthLockError:
#might be ok, depending on method # might be ok, depending on method
if context.method not in ('exclusiveSession', 'login', 'krbLogin', 'logout'): if context.method not in ('exclusiveSession', 'login', 'krbLogin', 'logout'):
raise raise
@ -359,7 +359,7 @@ class ModXMLRPCRequestHandler(object):
"""Handle a single XML-RPC request""" """Handle a single XML-RPC request"""
pass pass
#XXX no longer used # XXX no longer used
def offline_reply(start_response, msg=None): def offline_reply(start_response, msg=None):
@ -395,13 +395,13 @@ def load_config(environ):
- all PythonOptions (except ConfigFile) are now deprecated and support for them - all PythonOptions (except ConfigFile) are now deprecated and support for them
will disappear in a future version of Koji will disappear in a future version of Koji
""" """
#get our config file(s) # get our config file(s)
cf = environ.get('koji.hub.ConfigFile', '/etc/koji-hub/hub.conf') cf = environ.get('koji.hub.ConfigFile', '/etc/koji-hub/hub.conf')
cfdir = environ.get('koji.hub.ConfigDir', '/etc/koji-hub/hub.conf.d') cfdir = environ.get('koji.hub.ConfigDir', '/etc/koji-hub/hub.conf.d')
config = koji.read_config_files([cfdir, (cf, True)], raw=True) config = koji.read_config_files([cfdir, (cf, True)], raw=True)
cfgmap = [ cfgmap = [
#option, type, default # option, type, default
['DBName', 'string', None], ['DBName', 'string', None],
['DBUser', 'string', None], ['DBUser', 'string', None],
['DBHost', 'string', None], ['DBHost', 'string', None],
@ -479,7 +479,7 @@ def load_config(environ):
# load policies # load policies
# (only from config file) # (only from config file)
if config and config.has_section('policy'): if config and config.has_section('policy'):
#for the moment, we simply transfer the policy conf to opts # for the moment, we simply transfer the policy conf to opts
opts['policy'] = dict(config.items('policy')) opts['policy'] = dict(config.items('policy'))
else: else:
opts['policy'] = {} opts['policy'] = {}
@ -504,7 +504,7 @@ def load_plugins(opts):
tracker.load(name) tracker.load(name)
except Exception: except Exception:
logger.error(''.join(traceback.format_exception(*sys.exc_info()))) logger.error(''.join(traceback.format_exception(*sys.exc_info())))
#make this non-fatal, but set ServerOffline # make this non-fatal, but set ServerOffline
opts['ServerOffline'] = True opts['ServerOffline'] = True
opts['OfflineMessage'] = 'configuration error' opts['OfflineMessage'] = 'configuration error'
return tracker return tracker
@ -542,7 +542,7 @@ _default_policies = {
def get_policy(opts, plugins): def get_policy(opts, plugins):
if not opts.get('policy'): if not opts.get('policy'):
return return
#first find available policy tests # first find available policy tests
alltests = [koji.policy.findSimpleTests([vars(kojihub), vars(koji.policy)])] alltests = [koji.policy.findSimpleTests([vars(kojihub), vars(koji.policy)])]
# we delay merging these to allow a test to be overridden for a specific policy # we delay merging these to allow a test to be overridden for a specific policy
for plugin_name in opts.get('Plugins', '').split(): for plugin_name in opts.get('Plugins', '').split():
@ -552,7 +552,7 @@ def get_policy(opts, plugins):
alltests.append(koji.policy.findSimpleTests(vars(plugin))) alltests.append(koji.policy.findSimpleTests(vars(plugin)))
policy = {} policy = {}
for pname, text in six.iteritems(opts['policy']): for pname, text in six.iteritems(opts['policy']):
#filter/merge tests # filter/merge tests
merged = {} merged = {}
for tests in alltests: for tests in alltests:
# tests can be limited to certain policies by setting a class variable # tests can be limited to certain policies by setting a class variable
@ -598,7 +598,7 @@ def setup_logging1():
global log_handler global log_handler
logger = logging.getLogger("koji") logger = logging.getLogger("koji")
logger.setLevel(logging.WARNING) logger.setLevel(logging.WARNING)
#stderr logging (stderr goes to httpd logs) # stderr logging (stderr goes to httpd logs)
log_handler = logging.StreamHandler() log_handler = logging.StreamHandler()
log_format = '%(asctime)s [%(levelname)s] SETUP p=%(process)s %(name)s: %(message)s' log_format = '%(asctime)s [%(levelname)s] SETUP p=%(process)s %(name)s: %(message)s'
log_handler.setFormatter(HubFormatter(log_format)) log_handler.setFormatter(HubFormatter(log_format))
@ -608,7 +608,7 @@ def setup_logging1():
def setup_logging2(opts): def setup_logging2(opts):
global log_handler global log_handler
"""Adjust logging based on configuration options""" """Adjust logging based on configuration options"""
#determine log level # determine log level
level = opts['LogLevel'] level = opts['LogLevel']
valid_levels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') valid_levels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
# the config value can be a single level name or a series of # the config value can be a single level name or a series of
@ -624,7 +624,7 @@ def setup_logging2(opts):
default = level default = level
if level not in valid_levels: if level not in valid_levels:
raise koji.GenericError("Invalid log level: %s" % level) raise koji.GenericError("Invalid log level: %s" % level)
#all our loggers start with koji # all our loggers start with koji
if name == '': if name == '':
name = 'koji' name = 'koji'
default = level default = level
@ -639,9 +639,9 @@ def setup_logging2(opts):
if opts.get('KojiDebug'): if opts.get('KojiDebug'):
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
elif default is None: elif default is None:
#LogLevel did not configure a default level # LogLevel did not configure a default level
logger.setLevel(logging.WARNING) logger.setLevel(logging.WARNING)
#log_handler defined in setup_logging1 # log_handler defined in setup_logging1
log_handler.setFormatter(HubFormatter(opts['LogFormat'])) log_handler.setFormatter(HubFormatter(opts['LogFormat']))
@ -746,7 +746,7 @@ def application(environ, start_response):
] ]
start_response('200 OK', headers) start_response('200 OK', headers)
if h.traceback: if h.traceback:
#rollback # rollback
context.cnx.rollback() context.cnx.rollback()
elif context.commit_pending: elif context.commit_pending:
# Currently there is not much data we can provide to the # Currently there is not much data we can provide to the
@ -764,7 +764,7 @@ def application(environ, start_response):
h.logger.debug("Returning %d bytes after %f seconds", len(response), h.logger.debug("Returning %d bytes after %f seconds", len(response),
time.time() - start) time.time() - start)
finally: finally:
#make sure context gets cleaned up # make sure context gets cleaned up
if hasattr(context, 'cnx'): if hasattr(context, 'cnx'):
try: try:
context.cnx.close() context.cnx.close()

View file

@ -128,7 +128,7 @@ for h in (
'RECOMMENDNAME', 'RECOMMENDVERSION', 'RECOMMENDFLAGS'): 'RECOMMENDNAME', 'RECOMMENDVERSION', 'RECOMMENDFLAGS'):
SUPPORTED_OPT_DEP_HDRS[h] = hasattr(rpm, 'RPMTAG_%s' % h) SUPPORTED_OPT_DEP_HDRS[h] = hasattr(rpm, 'RPMTAG_%s' % h)
## BEGIN kojikamid dup # BEGIN kojikamid dup #
class Enum(dict): class Enum(dict):
"""A simple class to track our enumerated constants """A simple class to track our enumerated constants
@ -167,7 +167,7 @@ class Enum(dict):
# deprecated # deprecated
getvalue = _notImplemented getvalue = _notImplemented
#read-only # read-only
__setitem__ = _notImplemented __setitem__ = _notImplemented
__delitem__ = _notImplemented __delitem__ = _notImplemented
clear = _notImplemented clear = _notImplemented
@ -176,7 +176,7 @@ class Enum(dict):
update = _notImplemented update = _notImplemented
setdefault = _notImplemented setdefault = _notImplemented
## END kojikamid dup # END kojikamid dup #
API_VERSION = 1 API_VERSION = 1
@ -215,7 +215,7 @@ AUTHTYPE_KERB = 1
AUTHTYPE_SSL = 2 AUTHTYPE_SSL = 2
AUTHTYPE_GSSAPI = 3 AUTHTYPE_GSSAPI = 3
#dependency types # dependency types
DEP_REQUIRE = 0 DEP_REQUIRE = 0
DEP_PROVIDE = 1 DEP_PROVIDE = 1
DEP_OBSOLETE = 2 DEP_OBSOLETE = 2
@ -225,7 +225,7 @@ DEP_ENHANCE = 5
DEP_SUPPLEMENT = 6 DEP_SUPPLEMENT = 6
DEP_RECOMMEND = 7 DEP_RECOMMEND = 7
#dependency flags # dependency flags
RPMSENSE_LESS = 2 RPMSENSE_LESS = 2
RPMSENSE_GREATER = 4 RPMSENSE_GREATER = 4
RPMSENSE_EQUAL = 8 RPMSENSE_EQUAL = 8
@ -266,7 +266,7 @@ TAG_UPDATE_TYPES = Enum((
'MANUAL', 'MANUAL',
)) ))
## BEGIN kojikamid dup # BEGIN kojikamid dup #
CHECKSUM_TYPES = Enum(( CHECKSUM_TYPES = Enum((
'md5', 'md5',
@ -274,9 +274,9 @@ CHECKSUM_TYPES = Enum((
'sha256', 'sha256',
)) ))
## END kojikamid dup # END kojikamid dup #
#PARAMETERS # PARAMETERS
BASEDIR = '/mnt/koji' BASEDIR = '/mnt/koji'
# default task priority # default task priority
PRIO_DEFAULT = 20 PRIO_DEFAULT = 20
@ -285,9 +285,9 @@ PRIO_DEFAULT = 20
DEFAULT_REQUEST_TIMEOUT = 60 * 60 * 12 DEFAULT_REQUEST_TIMEOUT = 60 * 60 * 12
DEFAULT_AUTH_TIMEOUT = 60 DEFAULT_AUTH_TIMEOUT = 60
## BEGIN kojikamid dup # BEGIN kojikamid dup #
#Exceptions # Exceptions
PythonImportError = ImportError # will be masked by koji's one PythonImportError = ImportError # will be masked by koji's one
class GenericError(Exception): class GenericError(Exception):
@ -302,7 +302,7 @@ class GenericError(Exception):
return str(self.args[0]) return str(self.args[0])
except: except:
return str(self.__dict__) return str(self.__dict__)
## END kojikamid dup # END kojikamid dup #
class LockError(GenericError): class LockError(GenericError):
"""Raised when there is a lock conflict""" """Raised when there is a lock conflict"""
@ -320,12 +320,12 @@ class ActionNotAllowed(GenericError):
"""Raised when the session does not have permission to take some action""" """Raised when the session does not have permission to take some action"""
faultCode = 1004 faultCode = 1004
## BEGIN kojikamid dup # BEGIN kojikamid dup #
class BuildError(GenericError): class BuildError(GenericError):
"""Raised when a build fails""" """Raised when a build fails"""
faultCode = 1005 faultCode = 1005
## END kojikamid dup # END kojikamid dup #
class AuthLockError(AuthError): class AuthLockError(AuthError):
"""Raised when a lock prevents authentication""" """Raised when a lock prevents authentication"""
@ -403,7 +403,7 @@ class MultiCallInProgress(object):
pass pass
#A function to get create an exception from a fault # A function to get create an exception from a fault
def convertFault(fault): def convertFault(fault):
"""Convert a fault to the corresponding Exception type, if possible""" """Convert a fault to the corresponding Exception type, if possible"""
code = getattr(fault, 'faultCode', None) code = getattr(fault, 'faultCode', None)
@ -415,7 +415,7 @@ def convertFault(fault):
ret = v(fault.faultString) ret = v(fault.faultString)
ret.fromFault = True ret.fromFault = True
return ret return ret
#otherwise... # otherwise...
return fault return fault
def listFaults(): def listFaults():
@ -440,7 +440,7 @@ def listFaults():
ret.sort(key=lambda x: x['faultCode']) ret.sort(key=lambda x: x['faultCode'])
return ret return ret
#functions for encoding/decoding optional arguments # functions for encoding/decoding optional arguments
def encode_args(*args, **opts): def encode_args(*args, **opts):
"""The function encodes optional arguments as regular arguments. """The function encodes optional arguments as regular arguments.
@ -481,10 +481,10 @@ def decode_int(n):
"""If n is not an integer, attempt to convert it""" """If n is not an integer, attempt to convert it"""
if isinstance(n, six.integer_types): if isinstance(n, six.integer_types):
return n return n
#else # else
return int(n) return int(n)
#commonly used functions # commonly used functions
def safe_xmlrpc_loads(s): def safe_xmlrpc_loads(s):
"""Load xmlrpc data from a string, but catch faults""" """Load xmlrpc data from a string, but catch faults"""
@ -493,7 +493,7 @@ def safe_xmlrpc_loads(s):
except Fault as f: except Fault as f:
return f return f
## BEGIN kojikamid dup # BEGIN kojikamid dup #
def ensuredir(directory): def ensuredir(directory):
@ -528,7 +528,7 @@ def ensuredir(directory):
raise raise
return directory return directory
## END kojikamid dup # END kojikamid dup #
def daemonize(): def daemonize():
"""Detach and run in background""" """Detach and run in background"""
@ -537,12 +537,12 @@ def daemonize():
os._exit(0) os._exit(0)
os.setsid() os.setsid()
signal.signal(signal.SIGHUP, signal.SIG_IGN) signal.signal(signal.SIGHUP, signal.SIG_IGN)
#fork again # fork again
pid = os.fork() pid = os.fork()
if pid: if pid:
os._exit(0) os._exit(0)
os.chdir("/") os.chdir("/")
#redirect stdin/stdout/sterr # redirect stdin/stdout/sterr
fd0 = os.open('/dev/null', os.O_RDONLY) fd0 = os.open('/dev/null', os.O_RDONLY)
fd1 = os.open('/dev/null', os.O_RDWR) fd1 = os.open('/dev/null', os.O_RDWR)
fd2 = os.open('/dev/null', os.O_RDWR) fd2 = os.open('/dev/null', os.O_RDWR)
@ -597,7 +597,7 @@ def rpm_hdr_size(f, ofs=None):
il = multibyte(data[0:4]) il = multibyte(data[0:4])
dl = multibyte(data[4:8]) dl = multibyte(data[4:8])
#this is what the section data says the size should be # this is what the section data says the size should be
hdrsize = 8 + 16 * il + dl hdrsize = 8 + 16 * il + dl
# hdrsize rounded up to nearest 8 bytes # hdrsize rounded up to nearest 8 bytes
@ -624,7 +624,7 @@ class RawHeader(object):
self._index() self._index()
def version(self): def version(self):
#fourth byte is the version # fourth byte is the version
return _ord(self.header[3]) return _ord(self.header[3])
def _index(self): def _index(self):
@ -635,7 +635,7 @@ class RawHeader(object):
il = multibyte(data[:4]) il = multibyte(data[:4])
dl = multibyte(data[4:8]) dl = multibyte(data[4:8])
#read the index (starts at offset 16) # read the index (starts at offset 16)
index = {} index = {}
for i in range(il): for i in range(il):
entry = [] entry = []
@ -643,30 +643,31 @@ class RawHeader(object):
ofs = 16 + i*16 + j*4 ofs = 16 + i*16 + j*4
data = [_ord(x) for x in self.header[ofs:ofs+4]] data = [_ord(x) for x in self.header[ofs:ofs+4]]
entry.append(multibyte(data)) entry.append(multibyte(data))
#print("Tag: %d, Type: %d, Offset: %x, Count: %d" % tuple(entry))
# print("Tag: %d, Type: %d, Offset: %x, Count: %d" % tuple(entry))
index[entry[0]] = entry index[entry[0]] = entry
self.datalen = dl self.datalen = dl
self.index = index self.index = index
def dump(self): def dump(self):
print("HEADER DUMP:") print("HEADER DUMP:")
#calculate start of store # calculate start of store
il = len(self.index) il = len(self.index)
store = 16 + il * 16 store = 16 + il * 16
#print("start is: %d" % start) # print("start is: %d" % start)
#print("index length: %d" % il) # print("index length: %d" % il)
print("Store at offset %d (%0x)" % (store, store)) print("Store at offset %d (%0x)" % (store, store))
#sort entries by offset, dtype # sort entries by offset, dtype
#also rearrange: tag, dtype, offset, count -> offset, dtype, tag, count # also rearrange: tag, dtype, offset, count -> offset, dtype, tag, count
order = sorted([(x[2], x[1], x[0], x[3]) for x in six.itervalues(self.index)]) order = sorted([(x[2], x[1], x[0], x[3]) for x in six.itervalues(self.index)])
next = store next = store
#map some rpmtag codes # map some rpmtag codes
tags = {} tags = {}
for name, code in six.iteritems(rpm.__dict__): for name, code in six.iteritems(rpm.__dict__):
if name.startswith('RPMTAG_') and isinstance(code, int): if name.startswith('RPMTAG_') and isinstance(code, int):
tags[code] = name[7:].lower() tags[code] = name[7:].lower()
for entry in order: for entry in order:
#tag, dtype, offset, count = entry # tag, dtype, offset, count = entry
offset, dtype, tag, count = entry offset, dtype, tag, count = entry
pos = store + offset pos = store + offset
if next is not None: if next is not None:
@ -679,17 +680,17 @@ class RawHeader(object):
print("Tag: %d [%s], Type: %d, Offset: %x, Count: %d" \ print("Tag: %d [%s], Type: %d, Offset: %x, Count: %d" \
% (tag, tags.get(tag, '?'), dtype, offset, count)) % (tag, tags.get(tag, '?'), dtype, offset, count))
if dtype == 0: if dtype == 0:
#null # null
print("[NULL entry]") print("[NULL entry]")
next = pos next = pos
elif dtype == 1: elif dtype == 1:
#char # char
for i in range(count): for i in range(count):
print("Char: %r" % self.header[pos]) print("Char: %r" % self.header[pos])
pos += 1 pos += 1
next = pos next = pos
elif dtype >= 2 and dtype <= 5: elif dtype >= 2 and dtype <= 5:
#integer # integer
n = 1 << (dtype - 2) n = 1 << (dtype - 2)
for i in range(count): for i in range(count):
data = [_ord(x) for x in self.header[pos:pos+n]] data = [_ord(x) for x in self.header[pos:pos+n]]
@ -738,7 +739,7 @@ class RawHeader(object):
return self._getitem(dtype, offset, count) return self._getitem(dtype, offset, count)
def _getitem(self, dtype, offset, count): def _getitem(self, dtype, offset, count):
#calculate start of store # calculate start of store
il = len(self.index) il = len(self.index)
store = 16 + il * 16 store = 16 + il * 16
pos = store + offset pos = store + offset
@ -752,10 +753,10 @@ class RawHeader(object):
end = self.header.find('\0', pos) end = self.header.find('\0', pos)
return self.header[pos:end] return self.header[pos:end]
elif dtype == 7: elif dtype == 7:
#raw data # raw data
return self.header[pos:pos+count] return self.header[pos:pos+count]
else: else:
#XXX - not all valid data types are handled # XXX - not all valid data types are handled
raise GenericError("Unable to read header data type: %x" % dtype) raise GenericError("Unable to read header data type: %x" % dtype)
def get(self, key, default=None): def get(self, key, default=None):
@ -1108,7 +1109,7 @@ def is_debuginfo(name):
def canonArch(arch): def canonArch(arch):
"""Given an arch, return the "canonical" arch""" """Given an arch, return the "canonical" arch"""
#XXX - this could stand to be smarter, and we should probably # XXX - this could stand to be smarter, and we should probably
# have some other related arch-mangling functions. # have some other related arch-mangling functions.
if fnmatch(arch, 'i?86') or arch == 'athlon': if fnmatch(arch, 'i?86') or arch == 'athlon':
return 'i386' return 'i386'
@ -1295,12 +1296,12 @@ BuildArch: noarch
#package requirements #package requirements
"""] """]
#add a requires entry for all the packages in buildgroup, and in # add a requires entry for all the packages in buildgroup, and in
#groups required by buildgroup # groups required by buildgroup
need = [buildgroup] need = [buildgroup]
seen_grp = {} seen_grp = {}
seen_pkg = {} seen_pkg = {}
#index groups # index groups
groups = dict([(g['name'], g) for g in grplist]) groups = dict([(g['name'], g) for g in grplist])
for group_name in need: for group_name in need:
if group_name in seen_grp: if group_name in seen_grp:
@ -1375,7 +1376,7 @@ def generate_comps(groups, expand_groups=False):
""" <biarchonly>%s</biarchonly> """ <biarchonly>%s</biarchonly>
""" % boolean_text(True)) """ % boolean_text(True))
#print grouplist, if any # print grouplist, if any
if g['grouplist'] and not expand_groups: if g['grouplist'] and not expand_groups:
data.append( data.append(
""" <grouplist> """ <grouplist>
@ -1383,7 +1384,7 @@ def generate_comps(groups, expand_groups=False):
grouplist = list(g['grouplist']) grouplist = list(g['grouplist'])
grouplist.sort(key=lambda x: x['name']) grouplist.sort(key=lambda x: x['name'])
for x in grouplist: for x in grouplist:
#['req_id','type','is_metapkg','name'] # ['req_id','type','is_metapkg','name']
name = x['name'] name = x['name']
thetype = x['type'] thetype = x['type']
tag = "groupreq" tag = "groupreq"
@ -1401,9 +1402,9 @@ def generate_comps(groups, expand_groups=False):
""" </grouplist> """ </grouplist>
""") """)
#print packagelist, if any # print packagelist, if any
def package_entry(pkg): def package_entry(pkg):
#p['package_id','type','basearchonly','requires','name'] # p['package_id','type','basearchonly','requires','name']
name = pkg['package'] name = pkg['package']
opts = 'type="%s"' % pkg['type'] opts = 'type="%s"' % pkg['type']
if pkg['basearchonly']: if pkg['basearchonly']:
@ -1424,7 +1425,7 @@ def generate_comps(groups, expand_groups=False):
""" % package_entry(p)) """ % package_entry(p))
# also include expanded list, if needed # also include expanded list, if needed
if expand_groups and g['grouplist']: if expand_groups and g['grouplist']:
#add a requires entry for all packages in groups required by buildgroup # add a requires entry for all packages in groups required by buildgroup
need = [req['name'] for req in g['grouplist']] need = [req['name'] for req in g['grouplist']]
seen_grp = {g['name'] : 1} seen_grp = {g['name'] : 1}
seen_pkg = {} seen_pkg = {}
@ -1484,12 +1485,12 @@ def genMockConfig(name, arch, managed=False, repoid=None, tag_name=None, **opts)
raise GenericError("please provide a repo and tag") raise GenericError("please provide a repo and tag")
topurls = opts.get('topurls') topurls = opts.get('topurls')
if not topurls: if not topurls:
#cli command still passes plain topurl # cli command still passes plain topurl
topurl = opts.get('topurl') topurl = opts.get('topurl')
if topurl: if topurl:
topurls = [topurl] topurls = [topurl]
if topurls: if topurls:
#XXX - PathInfo isn't quite right for this, but it will do for now # XXX - PathInfo isn't quite right for this, but it will do for now
pathinfos = [PathInfo(topdir=_u) for _u in topurls] pathinfos = [PathInfo(topdir=_u) for _u in topurls]
urls = ["%s/%s" % (_p.repo(repoid, tag_name), arch) for _p in pathinfos] urls = ["%s/%s" % (_p.repo(repoid, tag_name), arch) for _p in pathinfos]
else: else:
@ -1539,7 +1540,7 @@ def genMockConfig(name, arch, managed=False, repoid=None, tag_name=None, **opts)
if mavenrc: if mavenrc:
files['etc/mavenrc'] = mavenrc files['etc/mavenrc'] = mavenrc
#generate yum.conf # generate yum.conf
yc_parts = ["[main]\n"] yc_parts = ["[main]\n"]
# HTTP proxy for yum # HTTP proxy for yum
if opts.get('yum_proxy'): if opts.get('yum_proxy'):
@ -1780,7 +1781,7 @@ def read_config(profile_name, user_config=None):
result = config_defaults.copy() result = config_defaults.copy()
#note: later config files override earlier ones # note: later config files override earlier ones
# /etc/koji.conf.d # /etc/koji.conf.d
configs = ['/etc/koji.conf.d'] configs = ['/etc/koji.conf.d']
@ -1807,9 +1808,9 @@ def read_config(profile_name, user_config=None):
got_conf = True got_conf = True
result['profile'] = profile_name result['profile'] = profile_name
for name, value in config.items(profile_name): for name, value in config.items(profile_name):
#note the config_defaults dictionary also serves to indicate which # note the config_defaults dictionary also serves to indicate which
#options *can* be set via the config file. Such options should # options *can* be set via the config file. Such options should
#not have a default value set in the option parser. # not have a default value set in the option parser.
if name in result: if name in result:
if name in ('anon_retry', 'offline_retry', if name in ('anon_retry', 'offline_retry',
'use_fast_upload', 'krb_rdns', 'debug', 'use_fast_upload', 'krb_rdns', 'debug',
@ -1984,7 +1985,7 @@ class PathInfo(object):
def volumedir(self, volume): def volumedir(self, volume):
if volume == 'DEFAULT' or volume is None: if volume == 'DEFAULT' or volume is None:
return self.topdir return self.topdir
#else # else
return self.topdir + ("/vol/%s" % volume) return self.topdir + ("/vol/%s" % volume)
def build(self, build): def build(self, build):
@ -2141,7 +2142,7 @@ def is_cert_error(e):
'certificate expired' in ssl_reason): 'certificate expired' in ssl_reason):
return True return True
#otherwise # otherwise
return False return False
@ -2553,7 +2554,7 @@ class ClientSession(object):
handler, headers, request = self._prepCall('logout', ()) handler, headers, request = self._prepCall('logout', ())
self._sendCall(handler, headers, request) self._sendCall(handler, headers, request)
except AuthExpired: except AuthExpired:
#this can happen when an exclusive session is forced # this can happen when an exclusive session is forced
pass pass
self.setSession(None) self.setSession(None)
@ -2578,10 +2579,10 @@ class ClientSession(object):
return return
self.setSession(None) self.setSession(None)
#we've had some trouble with this method causing strange problems # we've had some trouble with this method causing strange problems
#(like infinite recursion). Possibly triggered by initialization failure, # (like infinite recursion). Possibly triggered by initialization failure,
#and possibly due to some interaction with __getattr__. # and possibly due to some interaction with __getattr__.
#Re-enabling with a small improvement # Re-enabling with a small improvement
def __del__(self): def __del__(self):
if self.__dict__: if self.__dict__:
try: try:
@ -2594,7 +2595,7 @@ class ClientSession(object):
return self._callMethod(name, args, opts) return self._callMethod(name, args, opts)
def _prepCall(self, name, args, kwargs=None): def _prepCall(self, name, args, kwargs=None):
#pass named opts in a way the server can understand # pass named opts in a way the server can understand
if kwargs is None: if kwargs is None:
kwargs = {} kwargs = {}
if name == 'rawUpload': if name == 'rawUpload':
@ -2713,27 +2714,27 @@ class ClientSession(object):
self.retries += 1 self.retries += 1
try: try:
return self._sendCall(handler, headers, request) return self._sendCall(handler, headers, request)
#basically, we want to retry on most errors, with a few exceptions # basically, we want to retry on most errors, with a few exceptions
# - faults (this means the call completed and failed) # - faults (this means the call completed and failed)
# - SystemExit, KeyboardInterrupt # - SystemExit, KeyboardInterrupt
# note that, for logged-in sessions the server should tell us (via a RetryError fault) # note that, for logged-in sessions the server should tell us (via a RetryError fault)
# if the call cannot be retried. For non-logged-in sessions, all calls should be read-only # if the call cannot be retried. For non-logged-in sessions, all calls should be read-only
# and hence retryable. # and hence retryable.
except Fault as fault: except Fault as fault:
#try to convert the fault to a known exception # try to convert the fault to a known exception
err = convertFault(fault) err = convertFault(fault)
if isinstance(err, ServerOffline): if isinstance(err, ServerOffline):
if self.opts.get('offline_retry', False): if self.opts.get('offline_retry', False):
secs = self.opts.get('offline_retry_interval', interval) secs = self.opts.get('offline_retry_interval', interval)
self.logger.debug("Server offline. Retrying in %i seconds", secs) self.logger.debug("Server offline. Retrying in %i seconds", secs)
time.sleep(secs) time.sleep(secs)
#reset try count - this isn't a typical error, this is a running server # reset try count - this isn't a typical error, this is a running server
#correctly reporting an outage # correctly reporting an outage
tries = 0 tries = 0
continue continue
raise err raise err
except (SystemExit, KeyboardInterrupt): except (SystemExit, KeyboardInterrupt):
#(depending on the python version, these may or may not be subclasses of Exception) # (depending on the python version, these may or may not be subclasses of Exception)
raise raise
except Exception as e: except Exception as e:
tb_str = ''.join(traceback.format_exception(*sys.exc_info())) tb_str = ''.join(traceback.format_exception(*sys.exc_info()))
@ -2744,8 +2745,8 @@ class ClientSession(object):
raise raise
if not self.logged_in: if not self.logged_in:
#in the past, non-logged-in sessions did not retry. For compatibility purposes # in the past, non-logged-in sessions did not retry. For compatibility purposes
#this behavior is governed by the anon_retry opt. # this behavior is governed by the anon_retry opt.
if not self.opts.get('anon_retry', False): if not self.opts.get('anon_retry', False):
raise raise
@ -2754,14 +2755,14 @@ class ClientSession(object):
if tries > max_retries: if tries > max_retries:
raise raise
#otherwise keep retrying # otherwise keep retrying
if self.logger.isEnabledFor(logging.DEBUG): if self.logger.isEnabledFor(logging.DEBUG):
self.logger.debug(tb_str) self.logger.debug(tb_str)
self.logger.info("Try #%s for call %s (%s) failed: %s", tries, self.callnum, name, e) self.logger.info("Try #%s for call %s (%s) failed: %s", tries, self.callnum, name, e)
if tries > 1: if tries > 1:
# first retry is immediate, after that we honor retry_interval # first retry is immediate, after that we honor retry_interval
time.sleep(interval) time.sleep(interval)
#not reached # not reached
def multiCall(self, strict=False, batch=None): def multiCall(self, strict=False, batch=None):
"""Execute a prepared multicall """Execute a prepared multicall
@ -2816,7 +2817,7 @@ class ClientSession(object):
else: else:
ret = self._callMethod('multiCall', (calls,), {}) ret = self._callMethod('multiCall', (calls,), {})
if strict: if strict:
#check for faults and raise first one # check for faults and raise first one
for entry in ret: for entry in ret:
if isinstance(entry, dict): if isinstance(entry, dict):
fault = Fault(entry['faultCode'], entry['faultString']) fault = Fault(entry['faultCode'], entry['faultString'])
@ -2825,7 +2826,7 @@ class ClientSession(object):
return ret return ret
def __getattr__(self, name): def __getattr__(self, name):
#if name[:1] == '_': # if name[:1] == '_':
# raise AttributeError("no attribute %r" % name) # raise AttributeError("no attribute %r" % name)
if name == '_apidoc': if name == '_apidoc':
return self.__dict__['_apidoc'] return self.__dict__['_apidoc']
@ -2953,7 +2954,7 @@ class ClientSession(object):
start = time.time() start = time.time()
# XXX - stick in a config or something # XXX - stick in a config or something
retries = 3 retries = 3
fo = open(localfile, "rb") #specify bufsize? fo = open(localfile, "rb") # specify bufsize?
totalsize = os.path.getsize(localfile) totalsize = os.path.getsize(localfile)
ofs = 0 ofs = 0
md5sum = hashlib.md5() md5sum = hashlib.md5()
@ -3207,15 +3208,15 @@ class DBHandler(logging.Handler):
columns.append(key) columns.append(key)
values.append("%%(%s)s" % key) values.append("%%(%s)s" % key)
data[key] = value % record.__dict__ data[key] = value % record.__dict__
#values.append(_quote(value % record.__dict__)) # values.append(_quote(value % record.__dict__))
columns = ",".join(columns) columns = ",".join(columns)
values = ",".join(values) values = ",".join(values)
command = "INSERT INTO %s (%s) VALUES (%s)" % (self.table, columns, values) command = "INSERT INTO %s (%s) VALUES (%s)" % (self.table, columns, values)
#note we're letting cursor.execute do the escaping # note we're letting cursor.execute do the escaping
cursor.execute(command, data) cursor.execute(command, data)
cursor.close() cursor.close()
#self.cnx.commit() # self.cnx.commit()
#XXX - committing here is most likely wrong, but we need to set commit_pending or something # XXX - committing here is most likely wrong, but we need to set commit_pending or something
# ...and this is really the wrong place for that # ...and this is really the wrong place for that
except: except:
self.handleError(record) self.handleError(record)
@ -3328,7 +3329,7 @@ def _taskLabel(taskInfo):
extra = build_target['name'] extra = build_target['name']
elif method == 'winbuild': elif method == 'winbuild':
if 'request' in taskInfo: if 'request' in taskInfo:
#vm = taskInfo['request'][0] # vm = taskInfo['request'][0]
url = taskInfo['request'][1] url = taskInfo['request'][1]
target = taskInfo['request'][2] target = taskInfo['request'][2]
module_info = _module_info(url) module_info = _module_info(url)

View file

@ -33,7 +33,7 @@ arches = {
"amd64": "x86_64", "amd64": "x86_64",
"ia32e": "x86_64", "ia32e": "x86_64",
#ppc64le # ppc64le
"ppc64le": "noarch", "ppc64le": "noarch",
# ppc # ppc
@ -73,7 +73,7 @@ arches = {
"armv5tejl": "armv5tel", "armv5tejl": "armv5tel",
"armv5tel": "noarch", "armv5tel": "noarch",
#arm hardware floating point # arm hardware floating point
"armv7hnl": "armv7hl", "armv7hnl": "armv7hl",
"armv7hl": "armv6hl", "armv7hl": "armv6hl",
"armv6hl": "noarch", "armv6hl": "noarch",
@ -86,7 +86,7 @@ arches = {
"sh4": "noarch", "sh4": "noarch",
"sh3": "noarch", "sh3": "noarch",
#itanium # itanium
"ia64": "noarch", "ia64": "noarch",
} }

View file

@ -79,7 +79,7 @@ class Session(object):
self._perms = None self._perms = None
self._groups = None self._groups = None
self._host_id = '' self._host_id = ''
#get session data from request # get session data from request
if args is None: if args is None:
environ = getattr(context, 'environ', {}) environ = getattr(context, 'environ', {})
args = environ.get('QUERY_STRING', '') args = environ.get('QUERY_STRING', '')
@ -97,7 +97,7 @@ class Session(object):
callnum = args['callnum'][0] callnum = args['callnum'][0]
except: except:
callnum = None callnum = None
#lookup the session # lookup the session
c = context.cnx.cursor() c = context.cnx.cursor()
fields = { fields = {
'authtype': 'authtype', 'authtype': 'authtype',
@ -125,10 +125,10 @@ class Session(object):
if not row: if not row:
raise koji.AuthError('Invalid session or bad credentials') raise koji.AuthError('Invalid session or bad credentials')
session_data = dict(zip(aliases, row)) session_data = dict(zip(aliases, row))
#check for expiration # check for expiration
if session_data['expired']: if session_data['expired']:
raise koji.AuthExpired('session "%i" has expired' % id) raise koji.AuthExpired('session "%i" has expired' % id)
#check for callnum sanity # check for callnum sanity
if callnum is not None: if callnum is not None:
try: try:
callnum = int(callnum) callnum = int(callnum)
@ -140,14 +140,14 @@ class Session(object):
raise koji.SequenceError("%d > %d (session %d)" \ raise koji.SequenceError("%d > %d (session %d)" \
% (lastcall, callnum, id)) % (lastcall, callnum, id))
elif lastcall == callnum: elif lastcall == callnum:
#Some explanation: # Some explanation:
#This function is one of the few that performs its own commit. # This function is one of the few that performs its own commit.
#However, our storage of the current callnum is /after/ that # However, our storage of the current callnum is /after/ that
#commit. This means the the current callnum only gets committed if # commit. This means the the current callnum only gets committed if
#a commit happens afterward. # a commit happens afterward.
#We only schedule a commit for dml operations, so if we find the # We only schedule a commit for dml operations, so if we find the
#callnum in the db then a previous attempt succeeded but failed to # callnum in the db then a previous attempt succeeded but failed to
#return. Data was changed, so we cannot simply try the call again. # return. Data was changed, so we cannot simply try the call again.
method = getattr(context, 'method', 'UNKNOWN') method = getattr(context, 'method', 'UNKNOWN')
if method not in RetryWhitelist: if method not in RetryWhitelist:
raise koji.RetryError( raise koji.RetryError(
@ -155,7 +155,7 @@ class Session(object):
% (callnum, method, id)) % (callnum, method, id))
# read user data # read user data
#historical note: # historical note:
# we used to get a row lock here as an attempt to maintain sanity of exclusive # we used to get a row lock here as an attempt to maintain sanity of exclusive
# sessions, but it was an imperfect approach and the lock could cause some # sessions, but it was an imperfect approach and the lock could cause some
# performance issues. # performance issues.
@ -166,25 +166,25 @@ class Session(object):
if user_data['status'] != koji.USER_STATUS['NORMAL']: if user_data['status'] != koji.USER_STATUS['NORMAL']:
raise koji.AuthError('logins by %s are not allowed' % user_data['name']) raise koji.AuthError('logins by %s are not allowed' % user_data['name'])
#check for exclusive sessions # check for exclusive sessions
if session_data['exclusive']: if session_data['exclusive']:
#we are the exclusive session for this user # we are the exclusive session for this user
self.exclusive = True self.exclusive = True
else: else:
#see if an exclusive session exists # see if an exclusive session exists
q = """SELECT id FROM sessions WHERE user_id=%(user_id)s q = """SELECT id FROM sessions WHERE user_id=%(user_id)s
AND "exclusive" = TRUE AND expired = FALSE""" AND "exclusive" = TRUE AND expired = FALSE"""
#should not return multiple rows (unique constraint) # should not return multiple rows (unique constraint)
c.execute(q, session_data) c.execute(q, session_data)
row = c.fetchone() row = c.fetchone()
if row: if row:
(excl_id,) = row (excl_id,) = row
if excl_id == session_data['master']: if excl_id == session_data['master']:
#(note excl_id cannot be None) # (note excl_id cannot be None)
#our master session has the lock # our master session has the lock
self.exclusive = True self.exclusive = True
else: else:
#a session unrelated to us has the lock # a session unrelated to us has the lock
self.lockerror = "User locked by another session" self.lockerror = "User locked by another session"
# we don't enforce here, but rely on the dispatcher to enforce # we don't enforce here, but rely on the dispatcher to enforce
# if appropriate (otherwise it would be impossible to steal # if appropriate (otherwise it would be impossible to steal
@ -193,11 +193,11 @@ class Session(object):
# update timestamp # update timestamp
q = """UPDATE sessions SET update_time=NOW() WHERE id = %(id)i""" q = """UPDATE sessions SET update_time=NOW() WHERE id = %(id)i"""
c.execute(q, locals()) c.execute(q, locals())
#save update time # save update time
context.cnx.commit() context.cnx.commit()
#update callnum (this is deliberately after the commit) # update callnum (this is deliberately after the commit)
#see earlier note near RetryError # see earlier note near RetryError
if callnum is not None: if callnum is not None:
q = """UPDATE sessions SET callnum=%(callnum)i WHERE id = %(id)i""" q = """UPDATE sessions SET callnum=%(callnum)i WHERE id = %(id)i"""
c.execute(q, locals()) c.execute(q, locals())
@ -218,7 +218,7 @@ class Session(object):
# grab perm and groups data on the fly # grab perm and groups data on the fly
if name == 'perms': if name == 'perms':
if self._perms is None: if self._perms is None:
#in a dict for quicker lookup # in a dict for quicker lookup
self._perms = dict([[name, 1] for name in get_user_perms(self.user_id)]) self._perms = dict([[name, 1] for name in get_user_perms(self.user_id)])
return self._perms return self._perms
elif name == 'groups': elif name == 'groups':
@ -254,7 +254,7 @@ class Session(object):
return override return override
else: else:
hostip = context.environ['REMOTE_ADDR'] hostip = context.environ['REMOTE_ADDR']
#XXX - REMOTE_ADDR not promised by wsgi spec # XXX - REMOTE_ADDR not promised by wsgi spec
if hostip == '127.0.0.1': if hostip == '127.0.0.1':
hostip = socket.gethostbyname(socket.gethostname()) hostip = socket.gethostbyname(socket.gethostname())
return hostip return hostip
@ -294,7 +294,7 @@ class Session(object):
self.checkLoginAllowed(user_id) self.checkLoginAllowed(user_id)
#create session and return # create session and return
sinfo = self.createSession(user_id, hostip, koji.AUTHTYPE_NORMAL) sinfo = self.createSession(user_id, hostip, koji.AUTHTYPE_NORMAL)
session_id = sinfo['session-id'] session_id = sinfo['session-id']
context.cnx.commit() context.cnx.commit()
@ -386,7 +386,7 @@ class Session(object):
# so get the local ip via a different method # so get the local ip via a different method
local_ip = socket.gethostbyname(context.environ['SERVER_NAME']) local_ip = socket.gethostbyname(context.environ['SERVER_NAME'])
remote_ip = context.environ['REMOTE_ADDR'] remote_ip = context.environ['REMOTE_ADDR']
#XXX - REMOTE_ADDR not promised by wsgi spec # XXX - REMOTE_ADDR not promised by wsgi spec
# it appears that calling setports() with *any* value results in authentication # it appears that calling setports() with *any* value results in authentication
# failing with "Incorrect net address", so return 0 (which prevents # failing with "Incorrect net address", so return 0 (which prevents
@ -466,11 +466,11 @@ class Session(object):
if self.master is not None: if self.master is not None:
raise koji.GenericError("subsessions cannot become exclusive") raise koji.GenericError("subsessions cannot become exclusive")
if self.exclusive: if self.exclusive:
#shouldn't happen # shouldn't happen
raise koji.GenericError("session is already exclusive") raise koji.GenericError("session is already exclusive")
user_id = self.user_id user_id = self.user_id
session_id = self.id session_id = self.id
#acquire a row lock on the user entry # acquire a row lock on the user entry
q = """SELECT id FROM users WHERE id=%(user_id)s FOR UPDATE""" q = """SELECT id FROM users WHERE id=%(user_id)s FOR UPDATE"""
c.execute(q, locals()) c.execute(q, locals())
# check that no other sessions for this user are exclusive # check that no other sessions for this user are exclusive
@ -481,13 +481,13 @@ class Session(object):
row = c.fetchone() row = c.fetchone()
if row: if row:
if force: if force:
#expire the previous exclusive session and try again # expire the previous exclusive session and try again
(excl_id,) = row (excl_id,) = row
q = """UPDATE sessions SET expired=TRUE,"exclusive"=NULL WHERE id=%(excl_id)s""" q = """UPDATE sessions SET expired=TRUE,"exclusive"=NULL WHERE id=%(excl_id)s"""
c.execute(q, locals()) c.execute(q, locals())
else: else:
raise koji.AuthLockError("Cannot get exclusive session") raise koji.AuthLockError("Cannot get exclusive session")
#mark this session exclusive # mark this session exclusive
q = """UPDATE sessions SET "exclusive"=TRUE WHERE id=%(session_id)s""" q = """UPDATE sessions SET "exclusive"=TRUE WHERE id=%(session_id)s"""
c.execute(q, locals()) c.execute(q, locals())
context.cnx.commit() context.cnx.commit()
@ -503,12 +503,12 @@ class Session(object):
def logout(self): def logout(self):
"""expire a login session""" """expire a login session"""
if not self.logged_in: if not self.logged_in:
#XXX raise an error? # XXX raise an error?
raise koji.AuthError("Not logged in") raise koji.AuthError("Not logged in")
update = """UPDATE sessions update = """UPDATE sessions
SET expired=TRUE,exclusive=NULL SET expired=TRUE,exclusive=NULL
WHERE id = %(id)i OR master = %(id)i""" WHERE id = %(id)i OR master = %(id)i"""
#note we expire subsessions as well # note we expire subsessions as well
c = context.cnx.cursor() c = context.cnx.cursor()
c.execute(update, {'id': self.id}) c.execute(update, {'id': self.id})
context.cnx.commit() context.cnx.commit()
@ -517,7 +517,7 @@ class Session(object):
def logoutChild(self, session_id): def logoutChild(self, session_id):
"""expire a subsession""" """expire a subsession"""
if not self.logged_in: if not self.logged_in:
#XXX raise an error? # XXX raise an error?
raise koji.AuthError("Not logged in") raise koji.AuthError("Not logged in")
update = """UPDATE sessions update = """UPDATE sessions
SET expired=TRUE,exclusive=NULL SET expired=TRUE,exclusive=NULL
@ -547,7 +547,7 @@ class Session(object):
(session_id,) = c.fetchone() (session_id,) = c.fetchone()
#add session id to database # add session id to database
q = """ q = """
INSERT INTO sessions (id, user_id, key, hostip, authtype, master) INSERT INTO sessions (id, user_id, key, hostip, authtype, master)
VALUES (%(session_id)i, %(user_id)i, %(key)s, %(hostip)s, %(authtype)i, %(master)s) VALUES (%(session_id)i, %(user_id)i, %(key)s, %(hostip)s, %(authtype)i, %(master)s)
@ -555,7 +555,7 @@ class Session(object):
c.execute(q, locals()) c.execute(q, locals())
context.cnx.commit() context.cnx.commit()
#return session info # return session info
return {'session-id' : session_id, 'session-key' : key} return {'session-id' : session_id, 'session-key' : key}
def subsession(self): def subsession(self):
@ -589,7 +589,7 @@ class Session(object):
def hasGroup(self, group_id): def hasGroup(self, group_id):
if not self.logged_in: if not self.logged_in:
return False return False
#groups indexed by id # groups indexed by id
return group_id in self.groups return group_id in self.groups
def isUser(self, user_id): def isUser(self, user_id):
@ -616,7 +616,7 @@ class Session(object):
return None return None
def getHostId(self): def getHostId(self):
#for compatibility # for compatibility
return self.host_id return self.host_id
def getUserId(self, username): def getUserId(self, username):
@ -805,7 +805,7 @@ def get_user_perms(user_id):
FROM user_perms JOIN permissions ON perm_id = permissions.id FROM user_perms JOIN permissions ON perm_id = permissions.id
WHERE active = TRUE AND user_id=%(user_id)s""" WHERE active = TRUE AND user_id=%(user_id)s"""
c.execute(q, locals()) c.execute(q, locals())
#return a list of permissions by name # return a list of permissions by name
return [row[0] for row in c.fetchall()] return [row[0] for row in c.fetchall()]
def get_user_data(user_id): def get_user_data(user_id):

View file

@ -171,7 +171,7 @@ def log_output(session, path, args, outfile, uploadpath, cwd=None, logerror=0, a
return status[1] return status[1]
## BEGIN kojikamid dup # BEGIN kojikamid dup #
class SCM(object): class SCM(object):
"SCM abstraction class" "SCM abstraction class"
@ -397,7 +397,7 @@ class SCM(object):
env = None env = None
def _run(cmd, chdir=None, fatal=False, log=True, _count=[0]): def _run(cmd, chdir=None, fatal=False, log=True, _count=[0]):
if globals().get('KOJIKAMID'): if globals().get('KOJIKAMID'):
#we've been inserted into kojikamid, use its run() # we've been inserted into kojikamid, use its run()
return run(cmd, chdir=chdir, fatal=fatal, log=log) # noqa: F821 return run(cmd, chdir=chdir, fatal=fatal, log=log) # noqa: F821
else: else:
append = (_count[0] > 0) append = (_count[0] > 0)
@ -546,7 +546,7 @@ class SCM(object):
# just use the same url # just use the same url
r['source'] = self.url r['source'] = self.url
return r return r
## END kojikamid dup # END kojikamid dup #
class TaskManager(object): class TaskManager(object):
@ -613,7 +613,7 @@ class TaskManager(object):
If nolocal is True, do not try to scan local buildroots. If nolocal is True, do not try to scan local buildroots.
""" """
#query buildroots in db that are not expired # query buildroots in db that are not expired
states = [koji.BR_STATES[x] for x in ('INIT', 'WAITING', 'BUILDING')] states = [koji.BR_STATES[x] for x in ('INIT', 'WAITING', 'BUILDING')]
db_br = self.session.listBuildroots(hostID=self.host_id, state=tuple(states)) db_br = self.session.listBuildroots(hostID=self.host_id, state=tuple(states))
# index by id # index by id
@ -627,8 +627,8 @@ class TaskManager(object):
self.logger.warn("Expiring taskless buildroot: %(id)i/%(tag_name)s/%(arch)s" % br) self.logger.warn("Expiring taskless buildroot: %(id)i/%(tag_name)s/%(arch)s" % br)
self.session.host.setBuildRootState(id, st_expired) self.session.host.setBuildRootState(id, st_expired)
elif task_id not in self.tasks: elif task_id not in self.tasks:
#task not running - expire the buildroot # task not running - expire the buildroot
#TODO - consider recycling hooks here (with strong sanity checks) # TODO - consider recycling hooks here (with strong sanity checks)
self.logger.info("Expiring buildroot: %(id)i/%(tag_name)s/%(arch)s" % br) self.logger.info("Expiring buildroot: %(id)i/%(tag_name)s/%(arch)s" % br)
self.logger.debug("Buildroot task: %r, Current tasks: %r" % (task_id, to_list(self.tasks.keys()))) self.logger.debug("Buildroot task: %r, Current tasks: %r" % (task_id, to_list(self.tasks.keys())))
self.session.host.setBuildRootState(id, st_expired) self.session.host.setBuildRootState(id, st_expired)
@ -640,13 +640,13 @@ class TaskManager(object):
local_only = [id for id in local_br if id not in db_br] local_only = [id for id in local_br if id not in db_br]
if local_only: if local_only:
missed_br = self.session.listBuildroots(buildrootID=tuple(local_only)) missed_br = self.session.listBuildroots(buildrootID=tuple(local_only))
#get all the task info in one call # get all the task info in one call
tasks = [] tasks = []
for br in missed_br: for br in missed_br:
task_id = br['task_id'] task_id = br['task_id']
if task_id: if task_id:
tasks.append(task_id) tasks.append(task_id)
#index # index
missed_br = dict([(row['id'], row) for row in missed_br]) missed_br = dict([(row['id'], row) for row in missed_br])
tasks = dict([(row['id'], row) for row in self.session.getTaskInfo(tasks)]) tasks = dict([(row['id'], row) for row in self.session.getTaskInfo(tasks)])
for id in local_only: for id in local_only:
@ -671,7 +671,7 @@ class TaskManager(object):
self.logger.warn("%s: invalid task %s" % (desc, br['task_id'])) self.logger.warn("%s: invalid task %s" % (desc, br['task_id']))
continue continue
if (task['state'] == koji.TASK_STATES['FAILED'] and age < self.options.failed_buildroot_lifetime): if (task['state'] == koji.TASK_STATES['FAILED'] and age < self.options.failed_buildroot_lifetime):
#XXX - this could be smarter # XXX - this could be smarter
# keep buildroots for failed tasks around for a little while # keep buildroots for failed tasks around for a little while
self.logger.debug("Keeping failed buildroot: %s" % desc) self.logger.debug("Keeping failed buildroot: %s" % desc)
continue continue
@ -689,17 +689,17 @@ class TaskManager(object):
continue continue
else: else:
age = min(age, time.time() - st.st_mtime) age = min(age, time.time() - st.st_mtime)
#note: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=192153) # note: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=192153)
#If rpmlib is installing in this chroot, removing it entirely # If rpmlib is installing in this chroot, removing it entirely
#can lead to a world of hurt. # can lead to a world of hurt.
#We remove the rootdir contents but leave the rootdir unless it # We remove the rootdir contents but leave the rootdir unless it
#is really old # is really old
if age > 3600*24: if age > 3600*24:
#dir untouched for a day # dir untouched for a day
self.logger.info("Removing buildroot: %s" % desc) self.logger.info("Removing buildroot: %s" % desc)
if topdir and safe_rmtree(topdir, unmount=True, strict=False) != 0: if topdir and safe_rmtree(topdir, unmount=True, strict=False) != 0:
continue continue
#also remove the config # also remove the config
try: try:
os.unlink(data['cfg']) os.unlink(data['cfg'])
except OSError as e: except OSError as e:
@ -726,7 +726,7 @@ class TaskManager(object):
self.logger.debug("Expired/stray buildroots: %d" % len(local_only)) self.logger.debug("Expired/stray buildroots: %d" % len(local_only))
def _scanLocalBuildroots(self): def _scanLocalBuildroots(self):
#XXX # XXX
configdir = '/etc/mock/koji' configdir = '/etc/mock/koji'
buildroots = {} buildroots = {}
for f in os.listdir(configdir): for f in os.listdir(configdir):
@ -785,13 +785,13 @@ class TaskManager(object):
# by this host. # by this host.
id = task['id'] id = task['id']
if id not in self.pids: if id not in self.pids:
#We don't have a process for this # We don't have a process for this
#Expected to happen after a restart, otherwise this is an error # Expected to happen after a restart, otherwise this is an error
stale.append(id) stale.append(id)
continue continue
tasks[id] = task tasks[id] = task
if task.get('alert', False): if task.get('alert', False):
#wake up the process # wake up the process
self.logger.info("Waking up task: %r" % task) self.logger.info("Waking up task: %r" % task)
os.kill(self.pids[id], signal.SIGUSR2) os.kill(self.pids[id], signal.SIGUSR2)
if not task['waiting']: if not task['waiting']:
@ -801,8 +801,8 @@ class TaskManager(object):
self.tasks = tasks self.tasks = tasks
self.logger.debug("Current tasks: %r" % self.tasks) self.logger.debug("Current tasks: %r" % self.tasks)
if len(stale) > 0: if len(stale) > 0:
#A stale task is one which is opened to us, but we know nothing # A stale task is one which is opened to us, but we know nothing
#about). This will happen after a daemon restart, for example. # about). This will happen after a daemon restart, for example.
self.logger.info("freeing stale tasks: %r" % stale) self.logger.info("freeing stale tasks: %r" % stale)
self.session.host.freeTasks(stale) self.session.host.freeTasks(stale)
for id, pid in list(self.pids.items()): for id, pid in list(self.pids.items()):
@ -844,15 +844,15 @@ class TaskManager(object):
self.logger.debug("Load Data:") self.logger.debug("Load Data:")
self.logger.debug(" hosts: %r" % hosts) self.logger.debug(" hosts: %r" % hosts)
self.logger.debug(" tasks: %r" % tasks) self.logger.debug(" tasks: %r" % tasks)
#now we organize this data into channel-arch bins # now we organize this data into channel-arch bins
bin_hosts = {} #hosts indexed by bin bin_hosts = {} #hosts indexed by bin
bins = {} #bins for this host bins = {} #bins for this host
our_avail = None our_avail = None
for host in hosts: for host in hosts:
host['bins'] = [] host['bins'] = []
if host['id'] == self.host_id: if host['id'] == self.host_id:
#note: task_load reported by server might differ from what we # note: task_load reported by server might differ from what we
#sent due to precision variation # sent due to precision variation
our_avail = host['capacity'] - host['task_load'] our_avail = host['capacity'] - host['task_load']
for chan in host['channels']: for chan in host['channels']:
for arch in host['arches'].split() + ['noarch']: for arch in host['arches'].split() + ['noarch']:
@ -867,7 +867,7 @@ class TaskManager(object):
elif not bins: elif not bins:
self.logger.info("No bins for this host. Missing channel/arch config?") self.logger.info("No bins for this host. Missing channel/arch config?")
# Note: we may still take an assigned task below # Note: we may still take an assigned task below
#sort available capacities for each of our bins # sort available capacities for each of our bins
avail = {} avail = {}
for bin in bins: for bin in bins:
avail[bin] = [host['capacity'] - host['task_load'] for host in bin_hosts[bin]] avail[bin] = [host['capacity'] - host['task_load'] for host in bin_hosts[bin]]
@ -889,7 +889,7 @@ class TaskManager(object):
if task['state'] == koji.TASK_STATES['ASSIGNED']: if task['state'] == koji.TASK_STATES['ASSIGNED']:
self.logger.debug("task is assigned") self.logger.debug("task is assigned")
if self.host_id == task['host_id']: if self.host_id == task['host_id']:
#assigned to us, we can take it regardless # assigned to us, we can take it regardless
if self.takeTask(task): if self.takeTask(task):
return True return True
elif task['state'] == koji.TASK_STATES['FREE']: elif task['state'] == koji.TASK_STATES['FREE']:
@ -897,18 +897,18 @@ class TaskManager(object):
self.logger.debug("task is free, bin=%r" % bin) self.logger.debug("task is free, bin=%r" % bin)
if bin not in bins: if bin not in bins:
continue continue
#see where our available capacity is compared to other hosts for this bin # see where our available capacity is compared to other hosts for this bin
#(note: the hosts in this bin are exactly those that could # (note: the hosts in this bin are exactly those that could
#accept this task) # accept this task)
bin_avail = avail.get(bin, [0]) bin_avail = avail.get(bin, [0])
if self.checkAvailDelay(task, bin_avail, our_avail): if self.checkAvailDelay(task, bin_avail, our_avail):
# decline for now and give the upper half a chance # decline for now and give the upper half a chance
continue continue
#otherwise, we attempt to open the task # otherwise, we attempt to open the task
if self.takeTask(task): if self.takeTask(task):
return True return True
else: else:
#should not happen # should not happen
raise Exception("Invalid task state reported by server") raise Exception("Invalid task state reported by server")
return False return False
@ -968,11 +968,11 @@ class TaskManager(object):
try: try:
(childpid, status) = os.waitpid(pid, os.WNOHANG) (childpid, status) = os.waitpid(pid, os.WNOHANG)
except OSError as e: except OSError as e:
#check errno # check errno
if e.errno != errno.ECHILD: if e.errno != errno.ECHILD:
#should not happen # should not happen
raise raise
#otherwise assume the process is gone # otherwise assume the process is gone
self.logger.info("%s: %s" % (prefix, e)) self.logger.info("%s: %s" % (prefix, e))
return True return True
if childpid != 0: if childpid != 0:
@ -1118,7 +1118,7 @@ class TaskManager(object):
if children: if children:
self._killChildren(task_id, children, sig=signal.SIGKILL, timeout=3.0) self._killChildren(task_id, children, sig=signal.SIGKILL, timeout=3.0)
#expire the task's subsession # expire the task's subsession
session_id = self.subsessions.get(task_id) session_id = self.subsessions.get(task_id)
if session_id: if session_id:
self.logger.info("Expiring subsession %i (task %i)" % (session_id, task_id)) self.logger.info("Expiring subsession %i (task %i)" % (session_id, task_id))
@ -1126,7 +1126,7 @@ class TaskManager(object):
self.session.logoutChild(session_id) self.session.logoutChild(session_id)
del self.subsessions[task_id] del self.subsessions[task_id]
except: except:
#not much we can do about it # not much we can do about it
pass pass
if wait: if wait:
return self._waitTask(task_id, pid) return self._waitTask(task_id, pid)
@ -1200,7 +1200,7 @@ class TaskManager(object):
self.status = "Load average %.2f > %.2f" % (loadavgs[0], maxload) self.status = "Load average %.2f > %.2f" % (loadavgs[0], maxload)
self.logger.info(self.status) self.logger.info(self.status)
return False return False
#XXX - add more checks # XXX - add more checks
return True return True
def takeTask(self, task): def takeTask(self, task):
@ -1250,7 +1250,7 @@ class TaskManager(object):
if state != 'OPEN': if state != 'OPEN':
self.logger.warn("Task %i changed is %s", task_id, state) self.logger.warn("Task %i changed is %s", task_id, state)
return False return False
#otherwise... # otherwise...
raise raise
if handler.Foreground: if handler.Foreground:
self.logger.info("running task in foreground") self.logger.info("running task in foreground")
@ -1263,27 +1263,27 @@ class TaskManager(object):
return True return True
def forkTask(self, handler): def forkTask(self, handler):
#get the subsession before we fork # get the subsession before we fork
newhub = self.session.subsession() newhub = self.session.subsession()
session_id = newhub.sinfo['session-id'] session_id = newhub.sinfo['session-id']
pid = os.fork() pid = os.fork()
if pid: if pid:
newhub._forget() newhub._forget()
return pid, session_id return pid, session_id
#in no circumstance should we return after the fork # in no circumstance should we return after the fork
#nor should any exceptions propagate past here # nor should any exceptions propagate past here
try: try:
self.session._forget() self.session._forget()
#set process group # set process group
os.setpgrp() os.setpgrp()
#use the subsession # use the subsession
self.session = newhub self.session = newhub
handler.session = self.session handler.session = self.session
#set a do-nothing handler for sigusr2 # set a do-nothing handler for sigusr2
signal.signal(signal.SIGUSR2, lambda *args: None) signal.signal(signal.SIGUSR2, lambda *args: None)
self.runTask(handler) self.runTask(handler)
finally: finally:
#diediedie # diediedie
try: try:
self.session.logout() self.session.logout()
finally: finally:
@ -1302,10 +1302,10 @@ class TaskManager(object):
tb = ''.join(traceback.format_exception(*sys.exc_info())).replace(r"\n", "\n") tb = ''.join(traceback.format_exception(*sys.exc_info())).replace(r"\n", "\n")
self.logger.warn("FAULT:\n%s" % tb) self.logger.warn("FAULT:\n%s" % tb)
except (SystemExit, koji.tasks.ServerExit, KeyboardInterrupt): except (SystemExit, koji.tasks.ServerExit, KeyboardInterrupt):
#we do not trap these # we do not trap these
raise raise
except koji.tasks.ServerRestart: except koji.tasks.ServerRestart:
#freeing this task will allow the pending restart to take effect # freeing this task will allow the pending restart to take effect
self.session.host.freeTasks([handler.id]) self.session.host.freeTasks([handler.id])
return return
except: except:
@ -1315,7 +1315,7 @@ class TaskManager(object):
e_class, e = sys.exc_info()[:2] e_class, e = sys.exc_info()[:2]
faultCode = getattr(e_class, 'faultCode', 1) faultCode = getattr(e_class, 'faultCode', 1)
if issubclass(e_class, koji.GenericError): if issubclass(e_class, koji.GenericError):
#just pass it through # just pass it through
tb = str(e) tb = str(e)
response = koji.xmlrpcplus.dumps(koji.xmlrpcplus.Fault(faultCode, tb)) response = koji.xmlrpcplus.dumps(koji.xmlrpcplus.Fault(faultCode, tb))

View file

@ -75,8 +75,8 @@ class DBWrapper:
if not self.cnx: if not self.cnx:
raise Exception('connection is closed') raise Exception('connection is closed')
self.cnx.cursor().execute('ROLLBACK') self.cnx.cursor().execute('ROLLBACK')
#We do this rather than cnx.rollback to avoid opening a new transaction # We do this rather than cnx.rollback to avoid opening a new transaction
#If our connection gets recycled cnx.rollback will be called then. # If our connection gets recycled cnx.rollback will be called then.
self.cnx = None self.cnx = None
@ -177,7 +177,7 @@ def connect():
return DBWrapper(conn) return DBWrapper(conn)
except psycopg2.Error: except psycopg2.Error:
del _DBconn.conn del _DBconn.conn
#create a fresh connection # create a fresh connection
opts = _DBopts opts = _DBopts
if opts is None: if opts is None:
opts = {} opts = {}

View file

@ -62,7 +62,7 @@ class PluginTracker(object):
def __init__(self, path=None, prefix='_koji_plugin__'): def __init__(self, path=None, prefix='_koji_plugin__'):
self.searchpath = path self.searchpath = path
#prefix should not have a '.' in it, this can cause problems. # prefix should not have a '.' in it, this can cause problems.
self.prefix = prefix self.prefix = prefix
self.plugins = {} self.plugins = {}
@ -71,9 +71,9 @@ class PluginTracker(object):
return self.plugins[name] return self.plugins[name]
mod_name = name mod_name = name
if self.prefix: if self.prefix:
#mod_name determines how the module is named in sys.modules # mod_name determines how the module is named in sys.modules
#Using a prefix helps prevent overlap with other modules # Using a prefix helps prevent overlap with other modules
#(no '.' -- it causes problems) # (no '.' -- it causes problems)
mod_name = self.prefix + name mod_name = self.prefix + name
if mod_name in sys.modules and not reload: if mod_name in sys.modules and not reload:
raise koji.PluginError('module name conflict: %s' % mod_name) raise koji.PluginError('module name conflict: %s' % mod_name)

View file

@ -31,7 +31,7 @@ from koji.util import to_list
class BaseSimpleTest(object): class BaseSimpleTest(object):
"""Abstract base class for simple tests""" """Abstract base class for simple tests"""
#Provide the name of the test # Provide the name of the test
name = None name = None
def __init__(self, str): def __init__(self, str):
@ -62,12 +62,12 @@ class FalseTest(BaseSimpleTest):
class AllTest(TrueTest): class AllTest(TrueTest):
name = 'all' name = 'all'
#alias for true # alias for true
class NoneTest(FalseTest): class NoneTest(FalseTest):
name = 'none' name = 'none'
#alias for false # alias for false
class HasTest(BaseSimpleTest): class HasTest(BaseSimpleTest):
@ -233,11 +233,11 @@ class SimpleRuleSet(object):
for line in lines: for line in lines:
rule = self.parse_line(line) rule = self.parse_line(line)
if rule is None: if rule is None:
#blank/etc # blank/etc
continue continue
tests, negate, action = rule tests, negate, action = rule
if action == '{': if action == '{':
#nested rules # nested rules
child = [] child = []
cursor.append([tests, negate, child]) cursor.append([tests, negate, child])
stack.append(cursor) stack.append(cursor)
@ -275,11 +275,11 @@ class SimpleRuleSet(object):
""" """
line = line.split('#', 1)[0].strip() line = line.split('#', 1)[0].strip()
if not line: if not line:
#blank or all comment # blank or all comment
return None return None
if line == '}': if line == '}':
return None, False, '}' return None, False, '}'
#?? allow }} ?? # ?? allow }} ??
negate = False negate = False
pos = line.rfind('::') pos = line.rfind('::')
if pos == -1: if pos == -1:
@ -328,7 +328,7 @@ class SimpleRuleSet(object):
if not check: if not check:
break break
else: else:
#all tests in current rule passed # all tests in current rule passed
value = True value = True
if negate: if negate:
value = not value value = not value
@ -393,11 +393,11 @@ def findSimpleTests(namespace):
if isinstance(value, type(BaseSimpleTest)) and issubclass(value, BaseSimpleTest): if isinstance(value, type(BaseSimpleTest)) and issubclass(value, BaseSimpleTest):
name = getattr(value, 'name', None) name = getattr(value, 'name', None)
if not name: if not name:
#use the class name # use the class name
name = key name = key
#but trim 'Test' from the end # but trim 'Test' from the end
if name.endswith('Test') and len(name) > 4: if name.endswith('Test') and len(name) > 4:
name = name[:-4] name = name[:-4]
ret.setdefault(name, value) ret.setdefault(name, value)
#...so first test wins in case of name overlap # ...so first test wins in case of name overlap
return ret return ret

View file

@ -48,7 +48,7 @@ class Rpmdiff:
PRCO = ( 'REQUIRES', 'PROVIDES', 'CONFLICTS', 'OBSOLETES') PRCO = ( 'REQUIRES', 'PROVIDES', 'CONFLICTS', 'OBSOLETES')
#{fname : (size, mode, mtime, flags, dev, inode, # {fname : (size, mode, mtime, flags, dev, inode,
# nlink, state, vflags, user, group, digest)} # nlink, state, vflags, user, group, digest)}
__FILEIDX = [ ['S', 0], __FILEIDX = [ ['S', 0],
['M', 1], ['M', 1],
@ -71,7 +71,7 @@ class Rpmdiff:
try: try:
PREREQ_FLAG=rpm.RPMSENSE_PREREQ PREREQ_FLAG=rpm.RPMSENSE_PREREQ
except: except:
#(proyvind): This seems ugly, but then again so does # (proyvind): This seems ugly, but then again so does
# this whole check as well. # this whole check as well.
PREREQ_FLAG=False PREREQ_FLAG=False

View file

@ -51,7 +51,7 @@ def scan_mounts(topdir):
logger.warning('Found deleted mountpoint: %s' % path) logger.warning('Found deleted mountpoint: %s' % path)
mplist.append(path) mplist.append(path)
fo.close() fo.close()
#reverse sort so deeper dirs come first # reverse sort so deeper dirs come first
mplist.sort(reverse=True) mplist.sort(reverse=True)
return mplist return mplist
@ -64,7 +64,7 @@ def umount_all(topdir):
rv = os.spawnvp(os.P_WAIT, cmd[0], cmd) rv = os.spawnvp(os.P_WAIT, cmd[0], cmd)
if rv != 0: if rv != 0:
raise koji.GenericError('umount failed (exit code %r) for %s' % (rv, path)) raise koji.GenericError('umount failed (exit code %r) for %s' % (rv, path))
#check mounts again # check mounts again
remain = scan_mounts(topdir) remain = scan_mounts(topdir)
if remain: if remain:
raise koji.GenericError("Unmounting incomplete: %r" % remain) raise koji.GenericError("Unmounting incomplete: %r" % remain)
@ -340,7 +340,7 @@ class BaseTaskHandler(object):
if self.workdir is None: if self.workdir is None:
return return
safe_rmtree(self.workdir, unmount=False, strict=True) safe_rmtree(self.workdir, unmount=False, strict=True)
#os.spawnvp(os.P_WAIT, 'rm', ['rm', '-rf', self.workdir]) # os.spawnvp(os.P_WAIT, 'rm', ['rm', '-rf', self.workdir])
def wait(self, subtasks=None, all=False, failany=False, canfail=None, def wait(self, subtasks=None, all=False, failany=False, canfail=None,
timeout=None): timeout=None):
@ -385,7 +385,7 @@ class BaseTaskHandler(object):
while True: while True:
finished, unfinished = self.session.host.taskWait(self.id) finished, unfinished = self.session.host.taskWait(self.id)
if len(unfinished) == 0: if len(unfinished) == 0:
#all done # all done
break break
elif len(finished) > 0: elif len(finished) > 0:
if all: if all:
@ -561,7 +561,7 @@ class BaseTaskHandler(object):
repo_info = self.session.getRepo(tag) repo_info = self.session.getRepo(tag)
taginfo = self.session.getTag(tag, strict=True) taginfo = self.session.getTag(tag, strict=True)
if not repo_info: if not repo_info:
#make sure there is a target # make sure there is a target
targets = self.session.getBuildTargets(buildTagID=taginfo['id']) targets = self.session.getBuildTargets(buildTagID=taginfo['id'])
if not targets: if not targets:
raise koji.BuildError('no repo (and no target) for tag %s' % taginfo['name']) raise koji.BuildError('no repo (and no target) for tag %s' % taginfo['name'])
@ -666,7 +666,7 @@ class ShutdownTask(BaseTaskHandler):
_taskWeight = 0.0 _taskWeight = 0.0
Foreground = True Foreground = True
def handler(self): def handler(self):
#note: this is a foreground task # note: this is a foreground task
raise ServerExit raise ServerExit
@ -677,7 +677,7 @@ class RestartTask(BaseTaskHandler):
_taskWeight = 0.1 _taskWeight = 0.1
Foreground = True Foreground = True
def handler(self, host): def handler(self, host):
#note: this is a foreground task # note: this is a foreground task
if host['id'] != self.session.host.getID(): if host['id'] != self.session.host.getID():
raise koji.GenericError("Host mismatch") raise koji.GenericError("Host mismatch")
self.manager.restart_pending = True self.manager.restart_pending = True
@ -691,7 +691,7 @@ class RestartVerifyTask(BaseTaskHandler):
_taskWeight = 0.1 _taskWeight = 0.1
Foreground = True Foreground = True
def handler(self, task_id, host): def handler(self, task_id, host):
#note: this is a foreground task # note: this is a foreground task
tinfo = self.session.getTaskInfo(task_id) tinfo = self.session.getTaskInfo(task_id)
state = koji.TASK_STATES[tinfo['state']] state = koji.TASK_STATES[tinfo['state']]
if state != 'CLOSED': if state != 'CLOSED':
@ -754,7 +754,7 @@ class RestartHostsTask(BaseTaskHandler):
class DependantTask(BaseTaskHandler): class DependantTask(BaseTaskHandler):
Methods = ['dependantTask'] Methods = ['dependantTask']
#mostly just waiting on other tasks # mostly just waiting on other tasks
_taskWeight = 0.2 _taskWeight = 0.2
def handler(self, wait_list, task_list): def handler(self, wait_list, task_list):

View file

@ -189,7 +189,7 @@ def dslice(dict_, keys, strict=True):
ret = {} ret = {}
for key in keys: for key in keys:
if strict or key in dict_: if strict or key in dict_:
#for strict we skip the has_key check and let the dict generate the KeyError # for strict we skip the has_key check and let the dict generate the KeyError
ret[key] = dict_[key] ret[key] = dict_[key]
return ret return ret
@ -639,13 +639,13 @@ def setup_rlimits(opts, logger=None):
class adler32_constructor(object): class adler32_constructor(object):
#mimicing the hashlib constructors # mimicing the hashlib constructors
def __init__(self, arg=''): def __init__(self, arg=''):
if six.PY3 and isinstance(arg, str): if six.PY3 and isinstance(arg, str):
arg = bytes(arg, 'utf-8') arg = bytes(arg, 'utf-8')
self._value = adler32(arg) & 0xffffffff self._value = adler32(arg) & 0xffffffff
#the bitwise and works around a bug in some versions of python # the bitwise and works around a bug in some versions of python
#see: https://bugs.python.org/issue1202 # see: https://bugs.python.org/issue1202
def update(self, arg): def update(self, arg):
if six.PY3 and isinstance(arg, str): if six.PY3 and isinstance(arg, str):

View file

@ -118,9 +118,10 @@ class RunRootTask(koji.tasks.BaseTaskHandler):
if weight is not None: if weight is not None:
weight = max(weight, 0.5) weight = max(weight, 0.5)
self.session.host.setTaskWeight(self.id, weight) self.session.host.setTaskWeight(self.id, weight)
#noarch is funny
# noarch is funny
if arch == "noarch": if arch == "noarch":
#we need a buildroot arch. Pick one that: # we need a buildroot arch. Pick one that:
# a) this host can handle # a) this host can handle
# b) the build tag can support # b) the build tag can support
# c) is canonical # c) is canonical
@ -130,16 +131,16 @@ class RunRootTask(koji.tasks.BaseTaskHandler):
tag_arches = self.session.getBuildConfig(root)['arches'] tag_arches = self.session.getBuildConfig(root)['arches']
if not tag_arches: if not tag_arches:
raise koji.BuildError("No arch list for tag: %s" % root) raise koji.BuildError("No arch list for tag: %s" % root)
#index canonical host arches # index canonical host arches
host_arches = set([koji.canonArch(a) for a in host_arches.split()]) host_arches = set([koji.canonArch(a) for a in host_arches.split()])
#pick the first suitable match from tag's archlist # pick the first suitable match from tag's archlist
for br_arch in tag_arches.split(): for br_arch in tag_arches.split():
br_arch = koji.canonArch(br_arch) br_arch = koji.canonArch(br_arch)
if br_arch in host_arches: if br_arch in host_arches:
#we're done # we're done
break break
else: else:
#no overlap # no overlap
raise koji.BuildError("host does not match tag arches: %s (%s)" % (root, tag_arches)) raise koji.BuildError("host does not match tag arches: %s (%s)" % (root, tag_arches))
else: else:
br_arch = arch br_arch = arch
@ -152,7 +153,7 @@ class RunRootTask(koji.tasks.BaseTaskHandler):
else: else:
repo_info = self.session.getRepo(root) repo_info = self.session.getRepo(root)
if not repo_info: if not repo_info:
#wait for it # wait for it
task_id = self.session.host.subtask(method='waitrepo', task_id = self.session.host.subtask(method='waitrepo',
arglist=[root, None, None], arglist=[root, None, None],
parent=self.id) parent=self.id)
@ -163,13 +164,13 @@ class RunRootTask(koji.tasks.BaseTaskHandler):
broot.workdir = self.workdir broot.workdir = self.workdir
broot.init() broot.init()
rootdir = broot.rootdir() rootdir = broot.rootdir()
#workaround for rpm oddness # workaround for rpm oddness
os.system('rm -f "%s"/var/lib/rpm/__db.*' % rootdir) os.system('rm -f "%s"/var/lib/rpm/__db.*' % rootdir)
#update buildroot state (so that updateBuildRootList() will work) # update buildroot state (so that updateBuildRootList() will work)
self.session.host.setBuildRootState(broot.id, 'BUILDING') self.session.host.setBuildRootState(broot.id, 'BUILDING')
try: try:
if packages: if packages:
#pkglog = '%s/%s' % (broot.resultdir(), 'packages.log') # pkglog = '%s/%s' % (broot.resultdir(), 'packages.log')
pkgcmd = ['--install'] + packages pkgcmd = ['--install'] + packages
status = broot.mock(pkgcmd) status = broot.mock(pkgcmd)
self.session.host.updateBuildRootList(broot.id, broot.getPackageList()) self.session.host.updateBuildRootList(broot.id, broot.getPackageList())
@ -179,9 +180,9 @@ class RunRootTask(koji.tasks.BaseTaskHandler):
if isinstance(command, str): if isinstance(command, str):
cmdstr = command cmdstr = command
else: else:
#we were passed an arglist # we were passed an arglist
#we still have to run this through the shell (for redirection) # we still have to run this through the shell (for redirection)
#but we can preserve the list structure precisely with careful escaping # but we can preserve the list structure precisely with careful escaping
cmdstr = ' '.join(["'%s'" % arg.replace("'", r"'\''") for arg in command]) cmdstr = ' '.join(["'%s'" % arg.replace("'", r"'\''") for arg in command])
# A nasty hack to put command output into its own file until mock can be # A nasty hack to put command output into its own file until mock can be
# patched to do something more reasonable than stuff everything into build.log # patched to do something more reasonable than stuff everything into build.log
@ -198,7 +199,7 @@ class RunRootTask(koji.tasks.BaseTaskHandler):
elif new_chroot is False: # None -> no option added elif new_chroot is False: # None -> no option added
mock_cmd.append('--old-chroot') mock_cmd.append('--old-chroot')
if skip_setarch: if skip_setarch:
#we can't really skip it, but we can set it to the current one instead of of the chroot one # we can't really skip it, but we can set it to the current one instead of of the chroot one
myarch = platform.uname()[5] myarch = platform.uname()[5]
mock_cmd.extend(['--arch', myarch]) mock_cmd.extend(['--arch', myarch])
mock_cmd.append('--') mock_cmd.append('--')
@ -235,9 +236,9 @@ class RunRootTask(koji.tasks.BaseTaskHandler):
if mount.startswith(safe_root): if mount.startswith(safe_root):
break break
else: else:
#no match # no match
raise koji.GenericError("read-write mount point is not safe: %s" % mount) raise koji.GenericError("read-write mount point is not safe: %s" % mount)
#normpath should have removed any .. dirs, but just in case... # normpath should have removed any .. dirs, but just in case...
if mount.find('/../') != -1: if mount.find('/../') != -1:
raise koji.GenericError("read-write mount point is not safe: %s" % mount) raise koji.GenericError("read-write mount point is not safe: %s" % mount)
@ -266,7 +267,7 @@ class RunRootTask(koji.tasks.BaseTaskHandler):
else: else:
opts = opts.split(',') opts = opts.split(',')
if 'bind' in opts: if 'bind' in opts:
#make sure dir exists # make sure dir exists
if not os.path.isdir(dev): if not os.path.isdir(dev):
error = koji.GenericError("No such directory or mount: %s" % dev) error = koji.GenericError("No such directory or mount: %s" % dev)
break break
@ -297,7 +298,7 @@ class RunRootTask(koji.tasks.BaseTaskHandler):
with open(fn, 'r') as fslog: with open(fn, 'r') as fslog:
for line in fslog.readlines(): for line in fslog.readlines():
mounts.add(line.strip()) mounts.add(line.strip())
#also, check /proc/mounts just in case # also, check /proc/mounts just in case
mounts |= set(scan_mounts(rootdir)) mounts |= set(scan_mounts(rootdir))
mounts = sorted(mounts) mounts = sorted(mounts)
# deeper directories first # deeper directories first

View file

@ -1,4 +1,4 @@
#koji hub plugin # koji hub plugin
# There is a kojid plugin that goes with this hub plugin. The kojid builder # There is a kojid plugin that goes with this hub plugin. The kojid builder
# plugin has a config file. This hub plugin has no config file. # plugin has a config file. This hub plugin has no config file.
@ -15,7 +15,6 @@ import kojihub
from koji.context import context from koji.context import context
from koji.plugin import export from koji.plugin import export
__all__ = ('runroot',) __all__ = ('runroot',)
@ -41,11 +40,11 @@ def runroot(tagInfo, arch, command, channel=None, **opts):
tag = kojihub.get_tag(tagInfo, strict=True) tag = kojihub.get_tag(tagInfo, strict=True)
if arch == 'noarch': if arch == 'noarch':
#not all arches can generate a proper buildroot for all tags # not all arches can generate a proper buildroot for all tags
if not tag['arches']: if not tag['arches']:
raise koji.GenericError('no arches defined for tag %s' % tag['name']) raise koji.GenericError('no arches defined for tag %s' % tag['name'])
#get all known arches for the system # get all known arches for the system
fullarches = kojihub.get_all_arches() fullarches = kojihub.get_all_arches()
tagarches = tag['arches'].split() tagarches = tag['arches'].split()

View file

@ -16,9 +16,9 @@ def get_install_requires():
'requests', 'requests',
'requests-kerberos', 'requests-kerberos',
'six', 'six',
#'libcomps', # 'libcomps',
#'rpm-py-installer', # it is optional feature # 'rpm-py-installer', # it is optional feature
#'rpm', # 'rpm',
] ]
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
# optional auth library for older hubs # optional auth library for older hubs
@ -62,9 +62,9 @@ setup(
'koji_cli_plugins': 'plugins/cli', 'koji_cli_plugins': 'plugins/cli',
}, },
# doesn't make sense, as we have only example config # doesn't make sense, as we have only example config
#data_files=[ # data_files=[
# ('/etc', ['cli/koji.conf']), # ('/etc', ['cli/koji.conf']),
#], # ],
scripts=[ scripts=[
'cli/koji', 'cli/koji',
'util/koji-gc', 'util/koji-gc',

View file

@ -50,7 +50,7 @@ def getTag(session, tag, event=None):
if (tag, event) in cache: if (tag, event) in cache:
ts, info = cache[(tag,event)] ts, info = cache[(tag,event)]
if now - ts < 600: if now - ts < 600:
#use the cache # use the cache
return info return info
info = session.getTag(tag, event=event) info = session.getTag(tag, event=event)
if info: if info:
@ -83,7 +83,7 @@ class ManagedRepo(object):
self.first_seen = time.time() self.first_seen = time.time()
if self.current: if self.current:
order = self.session.getFullInheritance(self.tag_id, event=self.event_id) order = self.session.getFullInheritance(self.tag_id, event=self.event_id)
#order may contain same tag more than once # order may contain same tag more than once
tags = {self.tag_id : 1} tags = {self.tag_id : 1}
for x in order: for x in order:
tags[x['parent_id']] = 1 tags[x['parent_id']] = 1
@ -156,13 +156,13 @@ class ManagedRepo(object):
- timestamp really, really old - timestamp really, really old
""" """
timeout = 36000 timeout = 36000
#XXX - config # XXX - config
if self.state != koji.REPO_INIT: if self.state != koji.REPO_INIT:
return False return False
age = time.time() - max(self.event_ts, self.first_seen) age = time.time() - max(self.event_ts, self.first_seen)
#the first_seen timestamp is also factored in because a repo can be # the first_seen timestamp is also factored in because a repo can be
#created from an older event and should not be expired based solely on # created from an older event and should not be expired based solely on
#that event's timestamp. # that event's timestamp.
return age > timeout return age > timeout
def tryDelete(self): def tryDelete(self):
@ -177,8 +177,8 @@ class ManagedRepo(object):
lifetime = self.options.deleted_repo_lifetime lifetime = self.options.deleted_repo_lifetime
# (should really be called expired_repo_lifetime) # (should really be called expired_repo_lifetime)
try: try:
#also check dir age. We do this because a repo can be created from an older event # also check dir age. We do this because a repo can be created from an older event
#and should not be removed based solely on that event's timestamp. # and should not be removed based solely on that event's timestamp.
mtime = os.stat(path).st_mtime mtime = os.stat(path).st_mtime
except OSError as e: except OSError as e:
if e.errno == 2: if e.errno == 2:
@ -200,7 +200,7 @@ class ManagedRepo(object):
if self.state != koji.REPO_EXPIRED: if self.state != koji.REPO_EXPIRED:
raise koji.GenericError("Repo not expired") raise koji.GenericError("Repo not expired")
if self.session.repoDelete(self.repo_id) > 0: if self.session.repoDelete(self.repo_id) > 0:
#cannot delete, we are referenced by a buildroot # cannot delete, we are referenced by a buildroot
self.logger.debug("Cannot delete repo %s, still referenced" % self.repo_id) self.logger.debug("Cannot delete repo %s, still referenced" % self.repo_id)
return False return False
self.logger.info("Deleted repo %s" % self.repo_id) self.logger.info("Deleted repo %s" % self.repo_id)
@ -299,9 +299,9 @@ class RepoManager(object):
(childpid, status) = os.waitpid(pid, os.WNOHANG) (childpid, status) = os.waitpid(pid, os.WNOHANG)
except OSError as e: except OSError as e:
if e.errno != errno.ECHILD: if e.errno != errno.ECHILD:
#should not happen # should not happen
raise raise
#otherwise assume the process is gone # otherwise assume the process is gone
self.logger.info("%s: %s" % (prefix, e)) self.logger.info("%s: %s" % (prefix, e))
return True return True
if childpid != 0: if childpid != 0:
@ -345,7 +345,7 @@ class RepoManager(object):
repo_id = data['id'] repo_id = data['id']
repo = self.repos.get(repo_id) repo = self.repos.get(repo_id)
if repo: if repo:
#we're already tracking it # we're already tracking it
if repo.state != data['state']: if repo.state != data['state']:
self.logger.info('State changed for repo %s: %s -> %s' self.logger.info('State changed for repo %s: %s -> %s'
%(repo_id, koji.REPO_STATES[repo.state], koji.REPO_STATES[data['state']])) %(repo_id, koji.REPO_STATES[repo.state], koji.REPO_STATES[data['state']]))
@ -383,7 +383,7 @@ class RepoManager(object):
repo.current = False repo.current = False
if repo.expire_ts is None: if repo.expire_ts is None:
repo.expire_ts = time.time() repo.expire_ts = time.time()
#also no point in further checking # also no point in further checking
continue continue
to_check.append(repo) to_check.append(repo)
if self.logger.isEnabledFor(logging.DEBUG): if self.logger.isEnabledFor(logging.DEBUG):
@ -441,7 +441,7 @@ class RepoManager(object):
Also, warn about any oddities""" Also, warn about any oddities"""
if self.delete_pids: if self.delete_pids:
#skip # skip
return return
if not os.path.exists(topdir): if not os.path.exists(topdir):
self.logger.debug("%s doesn't exist, skipping", topdir) self.logger.debug("%s doesn't exist, skipping", topdir)
@ -466,14 +466,14 @@ class RepoManager(object):
self.logger.debug("%s/%s not an int, skipping", tagdir, repo_id) self.logger.debug("%s/%s not an int, skipping", tagdir, repo_id)
continue continue
if repo_id in self.repos: if repo_id in self.repos:
#we're already managing it, no need to deal with it here # we're already managing it, no need to deal with it here
continue continue
repodir = "%s/%s" % (tagdir, repo_id) repodir = "%s/%s" % (tagdir, repo_id)
try: try:
# lstat because it could be link to another volume # lstat because it could be link to another volume
dirstat = os.lstat(repodir) dirstat = os.lstat(repodir)
except OSError: except OSError:
#just in case something deletes the repo out from under us # just in case something deletes the repo out from under us
self.logger.debug("%s deleted already?!", repodir) self.logger.debug("%s deleted already?!", repodir)
continue continue
symlink = False symlink = False
@ -513,18 +513,18 @@ class RepoManager(object):
stats = self.tag_use_stats.get(tag_id) stats = self.tag_use_stats.get(tag_id)
now = time.time() now = time.time()
if stats and now - stats['ts'] < 3600: if stats and now - stats['ts'] < 3600:
#use the cache # use the cache
return stats return stats
data = self.session.listBuildroots(tagID=tag_id, data = self.session.listBuildroots(tagID=tag_id,
queryOpts={'order': '-create_event_id', 'limit' : 100}) queryOpts={'order': '-create_event_id', 'limit' : 100})
#XXX magic number (limit) # XXX magic number (limit)
if data: if data:
tag_name = data[0]['tag_name'] tag_name = data[0]['tag_name']
else: else:
tag_name = "#%i" % tag_id tag_name = "#%i" % tag_id
stats = {'data': data, 'ts': now, 'tag_name': tag_name} stats = {'data': data, 'ts': now, 'tag_name': tag_name}
recent = [x for x in data if now - x['create_ts'] < 3600 * 24] recent = [x for x in data if now - x['create_ts'] < 3600 * 24]
#XXX magic number # XXX magic number
stats ['n_recent'] = len(recent) stats ['n_recent'] = len(recent)
self.tag_use_stats[tag_id] = stats self.tag_use_stats[tag_id] = stats
self.logger.debug("tag %s recent use count: %i" % (tag_name, len(recent))) self.logger.debug("tag %s recent use count: %i" % (tag_name, len(recent)))
@ -593,7 +593,7 @@ class RepoManager(object):
if n_deletes >= self.options.delete_batch_size: if n_deletes >= self.options.delete_batch_size:
break break
if repo.expired(): if repo.expired():
#try to delete # try to delete
if repo.tryDelete(): if repo.tryDelete():
n_deletes += 1 n_deletes += 1
del self.repos[repo.repo_id] del self.repos[repo.repo_id]
@ -652,7 +652,7 @@ class RepoManager(object):
t['build_tag'] for t in self.session.getBuildTargets() t['build_tag'] for t in self.session.getBuildTargets()
if not koji.util.multi_fnmatch(t['build_tag_name'], ignore) if not koji.util.multi_fnmatch(t['build_tag_name'], ignore)
]) ])
#index repos by tag # index repos by tag
tag_repos = {} tag_repos = {}
for repo in to_list(self.repos.values()): for repo in to_list(self.repos.values()):
tag_repos.setdefault(repo.tag_id, []).append(repo) tag_repos.setdefault(repo.tag_id, []).append(repo)
@ -931,7 +931,7 @@ def get_options():
'repo_tasks_limit' : 10, 'repo_tasks_limit' : 10,
'delete_batch_size' : 3, 'delete_batch_size' : 3,
'deleted_repo_lifetime': 7*24*3600, 'deleted_repo_lifetime': 7*24*3600,
#XXX should really be called expired_repo_lifetime # XXX should really be called expired_repo_lifetime
'dist_repo_lifetime': 7*24*3600, 'dist_repo_lifetime': 7*24*3600,
'recent_tasks_lifetime': 600, 'recent_tasks_lifetime': 600,
'sleeptime' : 15, 'sleeptime' : 15,
@ -1003,7 +1003,7 @@ if __name__ == "__main__":
sys.stderr.write("Cannot write to logfile: %s\n" % options.logfile) sys.stderr.write("Cannot write to logfile: %s\n" % options.logfile)
sys.exit(1) sys.exit(1)
koji.add_file_logger("koji", options.logfile) koji.add_file_logger("koji", options.logfile)
#note we're setting logging for koji.* # note we're setting logging for koji.*
logger = logging.getLogger("koji") logger = logging.getLogger("koji")
if options.debug: if options.debug:
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
@ -1024,7 +1024,7 @@ if __name__ == "__main__":
session.login() session.login()
elif koji.krbV and options.principal and options.keytab: elif koji.krbV and options.principal and options.keytab:
session.krb_login(options.principal, options.keytab, options.ccache) session.krb_login(options.principal, options.keytab, options.ccache)
#get an exclusive session # get an exclusive session
try: try:
session.exclusiveSession(force=options.force_lock) session.exclusiveSession(force=options.force_lock)
except koji.AuthLockError: except koji.AuthLockError:

View file

@ -1,10 +1,10 @@
#!/bin/bash #!/bin/bash
awk '/^## INSERT kojikamid dup/ {exit} {print $0}' kojikamid.py awk '/^# INSERT kojikamid dup #/ {exit} {print $0}' kojikamid.py
for fn in ../koji/__init__.py ../koji/daemon.py for fn in ../koji/__init__.py ../koji/daemon.py
do do
awk '/^## END kojikamid dup/ {p=0} p {print $0} /^## BEGIN kojikamid dup/ {p=1}' $fn awk '/^# END kojikamid dup #/ {p=0} p {print $0} /^# BEGIN kojikamid dup #/ {p=1}' $fn
done done
awk 'p {print $0} /^## INSERT kojikamid dup/ {p=1}' kojikamid.py awk 'p {print $0} /^# INSERT kojikamid dup #/ {p=1}' kojikamid.py

View file

@ -54,12 +54,12 @@ MANAGER_PORT = 7000
KOJIKAMID = True KOJIKAMID = True
## INSERT kojikamid dup # INSERT kojikamid dup #
class fakemodule(object): class fakemodule(object):
pass pass
#make parts of the above insert accessible as koji.X # make parts of the above insert accessible as koji.X
koji = fakemodule() koji = fakemodule()
koji.GenericError = GenericError # noqa: F821 koji.GenericError = GenericError # noqa: F821
koji.BuildError = BuildError # noqa: F821 koji.BuildError = BuildError # noqa: F821
@ -68,7 +68,7 @@ def encode_int(n):
"""If n is too large for a 32bit signed, convert it to a string""" """If n is too large for a 32bit signed, convert it to a string"""
if n <= 2147483647: if n <= 2147483647:
return n return n
#else # else
return str(n) return str(n)
class WindowsBuild(object): class WindowsBuild(object):

View file

@ -101,7 +101,7 @@ def get_options():
if args: if args:
parser.error("incorrect number of arguments") parser.error("incorrect number of arguments")
#not reached # not reached
assert False # pragma: no cover assert False # pragma: no cover
# load local config # load local config
@ -176,7 +176,7 @@ def get_options():
if os.path.exists(fn): if os.path.exists(fn):
setattr(options, name, fn) setattr(options, name, fn)
#make sure workdir exists # make sure workdir exists
if not os.path.exists(options.workdir): if not os.path.exists(options.workdir):
koji.ensuredir(options.workdir) koji.ensuredir(options.workdir)
@ -198,7 +198,7 @@ def main(options, session):
tm = VMTaskManager(options, session) tm = VMTaskManager(options, session)
tm.findHandlers(globals()) tm.findHandlers(globals())
if options.plugin: if options.plugin:
#load plugins # load plugins
pt = koji.plugin.PluginTracker(path=options.pluginpath.split(':')) pt = koji.plugin.PluginTracker(path=options.pluginpath.split(':'))
for name in options.plugin: for name in options.plugin:
logger.info('Loading plugin: %s', name) logger.info('Loading plugin: %s', name)
@ -1084,7 +1084,7 @@ class VMTaskManager(TaskManager):
if __name__ == "__main__": if __name__ == "__main__":
koji.add_file_logger("koji", "/var/log/kojivmd.log") koji.add_file_logger("koji", "/var/log/kojivmd.log")
#note we're setting logging params for all of koji* # note we're setting logging params for all of koji*
options = get_options() options = get_options()
if options.debug: if options.debug:
logging.getLogger("koji").setLevel(logging.DEBUG) logging.getLogger("koji").setLevel(logging.DEBUG)
@ -1097,7 +1097,7 @@ if __name__ == "__main__":
if options.admin_emails: if options.admin_emails:
koji.add_mail_logger("koji", options.admin_emails) koji.add_mail_logger("koji", options.admin_emails)
#start a session and login # start a session and login
session_opts = koji.grab_session_options(options) session_opts = koji.grab_session_options(options)
session = koji.ClientSession(options.server, session_opts) session = koji.ClientSession(options.server, session_opts)
if options.cert and os.path.isfile(options.cert): if options.cert and os.path.isfile(options.cert):
@ -1131,14 +1131,14 @@ if __name__ == "__main__":
quit("Could not connect to Kerberos authentication service: '%s'" % e.args[1]) quit("Could not connect to Kerberos authentication service: '%s'" % e.args[1])
else: else:
quit("No username/password supplied and Kerberos missing or not configured") quit("No username/password supplied and Kerberos missing or not configured")
#make session exclusive # make session exclusive
try: try:
session.exclusiveSession(force=options.force_lock) session.exclusiveSession(force=options.force_lock)
except koji.AuthLockError: except koji.AuthLockError:
quit("Error: Unable to get lock. Trying using --force-lock") quit("Error: Unable to get lock. Trying using --force-lock")
if not session.logged_in: if not session.logged_in:
quit("Error: Unknown login error") quit("Error: Unknown login error")
#make sure it works # make sure it works
try: try:
ret = session.echo("OK") ret = session.echo("OK")
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
@ -1148,7 +1148,7 @@ if __name__ == "__main__":
# run main # run main
if options.daemon: if options.daemon:
#detach # detach
koji.daemonize() koji.daemonize()
main(options, session) main(options, session)
elif not options.skip_main: elif not options.skip_main:

View file

@ -45,7 +45,7 @@ from kojiweb.util import _genHTML, _getValidTokens, _initValues
# Convenience definition of a commonly-used sort function # Convenience definition of a commonly-used sort function
_sortbyname = lambda x: x['name'] _sortbyname = lambda x: x['name']
#loggers # loggers
authlogger = logging.getLogger('koji.auth') authlogger = logging.getLogger('koji.auth')
def _setUserCookie(environ, user): def _setUserCookie(environ, user):
@ -790,7 +790,7 @@ def getfile(environ, taskID, name, volume='DEFAULT', offset=None, size=None):
if size > (file_size - offset): if size > (file_size - offset):
size = file_size - offset size = file_size - offset
#environ['koji.headers'].append(['Content-Length', str(size)]) # environ['koji.headers'].append(['Content-Length', str(size)])
return _chunk_file(server, environ, taskID, name, offset, size, volume) return _chunk_file(server, environ, taskID, name, offset, size, volume)

View file

@ -44,7 +44,7 @@ class URLNotFound(ServerError):
class Dispatcher(object): class Dispatcher(object):
def __init__(self): def __init__(self):
#we can't do much setup until we get a request # we can't do much setup until we get a request
self.firstcall = True self.firstcall = True
self.options = {} self.options = {}
self.startup_error = None self.startup_error = None
@ -66,7 +66,7 @@ class Dispatcher(object):
self.logger = logging.getLogger("koji.web") self.logger = logging.getLogger("koji.web")
cfgmap = [ cfgmap = [
#option, type, default # option, type, default
['SiteName', 'string', None], ['SiteName', 'string', None],
['KojiHubURL', 'string', 'http://localhost/kojihub'], ['KojiHubURL', 'string', 'http://localhost/kojihub'],
['KojiFilesURL', 'string', 'http://localhost/kojifiles'], ['KojiFilesURL', 'string', 'http://localhost/kojifiles'],
@ -156,7 +156,7 @@ class Dispatcher(object):
def setup_logging2(self, environ): def setup_logging2(self, environ):
"""Adjust logging based on configuration options""" """Adjust logging based on configuration options"""
opts = self.options opts = self.options
#determine log level # determine log level
level = opts['LogLevel'] level = opts['LogLevel']
valid_levels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') valid_levels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
# the config value can be a single level name or a series of # the config value can be a single level name or a series of
@ -172,7 +172,7 @@ class Dispatcher(object):
default = level default = level
if level not in valid_levels: if level not in valid_levels:
raise koji.GenericError("Invalid log level: %s" % level) raise koji.GenericError("Invalid log level: %s" % level)
#all our loggers start with koji # all our loggers start with koji
if name == '': if name == '':
name = 'koji' name = 'koji'
default = level default = level
@ -187,7 +187,7 @@ class Dispatcher(object):
if opts.get('KojiDebug'): if opts.get('KojiDebug'):
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
elif default is None: elif default is None:
#LogLevel did not configure a default level # LogLevel did not configure a default level
logger.setLevel(logging.WARNING) logger.setLevel(logging.WARNING)
self.formatter = HubFormatter(opts['LogFormat']) self.formatter = HubFormatter(opts['LogFormat'])
self.formatter.environ = environ self.formatter.environ = environ
@ -213,7 +213,7 @@ class Dispatcher(object):
def prep_handler(self, environ): def prep_handler(self, environ):
path_info = environ['PATH_INFO'] path_info = environ['PATH_INFO']
if not path_info: if not path_info:
#empty path info (no trailing slash) breaks our relative urls # empty path info (no trailing slash) breaks our relative urls
environ['koji.redirect'] = environ['REQUEST_URI'] + '/' environ['koji.redirect'] = environ['REQUEST_URI'] + '/'
raise ServerRedirect raise ServerRedirect
elif path_info == '/': elif path_info == '/':
@ -225,7 +225,7 @@ class Dispatcher(object):
func = self.handler_index.get(method) func = self.handler_index.get(method)
if not func: if not func:
raise URLNotFound raise URLNotFound
#parse form args # parse form args
data = {} data = {}
fs = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ.copy(), keep_blank_values=True) fs = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ.copy(), keep_blank_values=True)
for field in fs.list: for field in fs.list:
@ -245,7 +245,7 @@ class Dispatcher(object):
if not varkw: if not varkw:
# remove any unexpected args # remove any unexpected args
data = dslice(data, args, strict=False) data = dslice(data, args, strict=False)
#TODO (warning in header or something?) # TODO (warning in header or something?)
return func, data return func, data
@ -318,7 +318,7 @@ class Dispatcher(object):
except (NameError, AttributeError): except (NameError, AttributeError):
tb_str = ''.join(traceback.format_exception(*sys.exc_info())) tb_str = ''.join(traceback.format_exception(*sys.exc_info()))
self.logger.error(tb_str) self.logger.error(tb_str)
#fallback to simple error page # fallback to simple error page
return self.simple_error_page(message, err=tb_short) return self.simple_error_page(message, err=tb_short)
values = _initValues(environ, *desc) values = _initValues(environ, *desc)
values['etype'] = etype values['etype'] = etype

View file

@ -26,7 +26,7 @@ import hashlib
import os import os
import ssl import ssl
import stat import stat
#a bunch of exception classes that explainError needs # a bunch of exception classes that explainError needs
from socket import error as socket_error from socket import error as socket_error
from xml.parsers.expat import ExpatError from xml.parsers.expat import ExpatError