fix merge conflicts
This commit is contained in:
commit
dbacf4c8e8
4 changed files with 170 additions and 66 deletions
|
|
@ -986,6 +986,12 @@ class TaskManager(object):
|
|||
for task in tasks:
|
||||
# note: tasks are in priority order
|
||||
self.logger.debug("task: %r" % task)
|
||||
if self.tasks.has_key(task['id']):
|
||||
# we were running this task, but it apparently has been
|
||||
# freed or reassigned. We can't do anything with it until
|
||||
# updateTasks notices this and cleans up.
|
||||
self.logger.debug("Task %(id)s freed or reassigned", task)
|
||||
continue
|
||||
if task['state'] == koji.TASK_STATES['ASSIGNED']:
|
||||
self.logger.debug("task is assigned")
|
||||
if self.host_id == task['host_id']:
|
||||
|
|
|
|||
141
cli/koji
141
cli/koji
|
|
@ -2050,6 +2050,8 @@ def anon_handle_list_tagged(options, session, args):
|
|||
parser.add_option("--paths", action="store_true", help=_("Show the file paths"))
|
||||
parser.add_option("--sigs", action="store_true", help=_("Show signatures"))
|
||||
parser.add_option("--maven", action="store_true", help=_("Show Maven builds only"))
|
||||
parser.add_option("--event", type='int', metavar="EVENT#", help=_("query at event"))
|
||||
parser.add_option("--repo", type='int', metavar="REPO#", help=_("query at event for a repo"))
|
||||
(options, args) = parser.parse_args(args)
|
||||
if len(args) == 0:
|
||||
parser.error(_("A tag name must be specified"))
|
||||
|
|
@ -2076,6 +2078,16 @@ def anon_handle_list_tagged(options, session, args):
|
|||
options.rpms = True
|
||||
if options.maven and not options.rpms:
|
||||
opts['maven_only'] = True
|
||||
if options.event is not None:
|
||||
opts['event'] = options.event
|
||||
if options.repo is not None:
|
||||
repo = session.repoInfo(options.repo)
|
||||
if not repo:
|
||||
print "No such repo: %s" % options.repo
|
||||
return
|
||||
repo['timestr'] = time.asctime(time.localtime(repo['create_ts']))
|
||||
print "Querying at event %(create_event)i (%(tag_name)s/%(timestr)s)" % repo
|
||||
opts['event'] = repo['create_event']
|
||||
|
||||
if options.rpms:
|
||||
rpms, builds = session.listTaggedRPMS(tag, **opts)
|
||||
|
|
@ -2491,6 +2503,14 @@ def anon_handle_rpminfo(options, session, args):
|
|||
print "Payload: %(payloadhash)s" %info
|
||||
print "Size: %(size)s" %info
|
||||
print "Build ID: %(build_id)s" %info
|
||||
if info['buildroot_id'] is None:
|
||||
print "No buildroot data available"
|
||||
else:
|
||||
br_info = session.getBuildroot(info['buildroot_id'])
|
||||
print "Buildroot: %(id)i (tag %(tag_name)s, arch %(arch)s, repo %(repo_id)i)" % br_info
|
||||
print "Build Host: %(host_name)s" % br_info
|
||||
print "Build Task: %(task_id)i" % br_info
|
||||
|
||||
|
||||
def anon_handle_buildinfo(options, session, args):
|
||||
"Print basic information about a build"
|
||||
|
|
@ -3882,35 +3902,57 @@ def handle_set_pkg_owner_global(options, session, args):
|
|||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("--verbose", action='store_true', help=_("List changes"))
|
||||
parser.add_option("--test", action='store_true', help=_("Test mode"))
|
||||
parser.add_option("--old-user", "--from", action="store", help=_("Only change ownership for packages belonging to this user"))
|
||||
(options, args) = parser.parse_args(args)
|
||||
if len(args) < 2:
|
||||
if options.old_user:
|
||||
if len(args) < 1:
|
||||
parser.error(_("Please specify an owner"))
|
||||
assert False
|
||||
elif len(args) < 2:
|
||||
parser.error(_("Please specify an owner and at least one package"))
|
||||
assert False
|
||||
activate_session(session)
|
||||
owner = args[0]
|
||||
packages = args[1:]
|
||||
user = session.getUser(owner)
|
||||
if not user:
|
||||
print "No such user: %s" % owner
|
||||
sys.exit(1)
|
||||
for package in args[1:]:
|
||||
entries = session.listPackages(pkgID=package, with_dups=True)
|
||||
opts = {'with_dups' : True}
|
||||
old_user = None
|
||||
if options.old_user:
|
||||
old_user = session.getUser(options.old_user)
|
||||
if not old_user:
|
||||
print _("No such user: %s") % options.old_user
|
||||
sys.exit(1)
|
||||
opts['userID'] = old_user['id']
|
||||
to_change = []
|
||||
for package in packages:
|
||||
entries = session.listPackages(pkgID=package, **opts)
|
||||
if not entries:
|
||||
print "No data for package %s" % package
|
||||
continue
|
||||
for entry in entries:
|
||||
if user['id'] == entry['owner_id']:
|
||||
if options.verbose:
|
||||
print "Preserving owner=%s for package %s in tag %s" \
|
||||
% (user['name'], package, entry['tag_name'] )
|
||||
else:
|
||||
if options.test:
|
||||
print "Would have changed owner for %s in tag %s: %s -> %s" \
|
||||
% (package, entry['tag_name'], entry['owner_name'], user['name'])
|
||||
continue
|
||||
if options.verbose:
|
||||
print "Changing owner for %s in tag %s: %s -> %s" \
|
||||
% (package, entry['tag_name'], entry['owner_name'], user['name'])
|
||||
session.packageListSetOwner(entry['tag_id'], package, user['id'])
|
||||
to_change.extend(entries)
|
||||
if not packages and options.old_user:
|
||||
entries = session.listPackages(**opts)
|
||||
if not entries:
|
||||
print "No data for user %s" % old_user['name']
|
||||
sys.exit(1)
|
||||
to_change.extend(entries)
|
||||
for entry in to_change:
|
||||
if user['id'] == entry['owner_id']:
|
||||
if options.verbose:
|
||||
print "Preserving owner=%s for package %s in tag %s" \
|
||||
% (user['name'], package, entry['tag_name'] )
|
||||
else:
|
||||
if options.test:
|
||||
print "Would have changed owner for %s in tag %s: %s -> %s" \
|
||||
% (entry['package_name'], entry['tag_name'], entry['owner_name'], user['name'])
|
||||
continue
|
||||
if options.verbose:
|
||||
print "Changing owner for %s in tag %s: %s -> %s" \
|
||||
% (entry['package_name'], entry['tag_name'], entry['owner_name'], user['name'])
|
||||
session.packageListSetOwner(entry['tag_id'], entry['package_name'], user['id'])
|
||||
|
||||
def anon_handle_watch_task(options, session, args):
|
||||
"Track progress of particular tasks"
|
||||
|
|
@ -4042,7 +4084,7 @@ def handle_move_pkg(options, session, args):
|
|||
if _running_in_bg() or options.nowait:
|
||||
return
|
||||
else:
|
||||
watch_tasks(session,tasks)
|
||||
return watch_tasks(session, tasks)
|
||||
|
||||
def handle_untag_pkg(options, session, args):
|
||||
"Remove a tag from one or more packages"
|
||||
|
|
@ -4050,22 +4092,69 @@ def handle_untag_pkg(options, session, args):
|
|||
usage += _("\n(Specify the --help global option for a list of other help options)")
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("--all", action="store_true", help=_("untag all versions of the package in this tag"))
|
||||
parser.add_option("--non-latest", action="store_true", help=_("untag all versions of the package in this tag except the latest"))
|
||||
parser.add_option("-n", "--test", action="store_true", help=_("test mode"))
|
||||
parser.add_option("-v", "--verbose", action="store_true", help=_("print details"))
|
||||
parser.add_option("--force", action="store_true", help=_("force operation"))
|
||||
(options, args) = parser.parse_args(args)
|
||||
if len(args) < 2:
|
||||
if options.non_latest and options.force:
|
||||
if len(args) < 1:
|
||||
parser.error(_("Please specify a tag"))
|
||||
assert False
|
||||
elif len(args) < 2:
|
||||
parser.error(_("This command takes at least two arguments: a tag name/ID and one or more package n-v-r's"))
|
||||
assert False
|
||||
activate_session(session)
|
||||
tag = session.getTag(args[0])
|
||||
if not tag:
|
||||
parser.error(_("Invalid tag: %s" % args[0]))
|
||||
if options.all:
|
||||
pkgs = []
|
||||
builds = []
|
||||
for pkg in args[1:]:
|
||||
pkgs.extend([x['nvr'] for x in session.listTagged(args[0], package=pkg)])
|
||||
builds.extend(session.listTagged(args[0], package=pkg))
|
||||
elif options.non_latest:
|
||||
if options.force and len(args) == 1:
|
||||
tagged = session.listTagged(args[0])
|
||||
else:
|
||||
tagged = []
|
||||
for pkg in args[1:]:
|
||||
tagged.extend(session.listTagged(args[0], package=pkg))
|
||||
# listTagged orders entries latest first
|
||||
seen_pkg = {}
|
||||
builds = []
|
||||
for binfo in tagged:
|
||||
if not seen_pkg.has_key(binfo['name']):
|
||||
#latest for this package
|
||||
if options.verbose:
|
||||
print _("Leaving latest build for package %(name)s: %(nvr)s") % binfo
|
||||
else:
|
||||
builds.append(binfo)
|
||||
seen_pkg[binfo['name']] = 1
|
||||
else:
|
||||
pkgs = args[1:]
|
||||
for pkg in pkgs:
|
||||
print pkg
|
||||
#XXX trap errors
|
||||
session.untagBuild(args[0], pkg, force=options.force)
|
||||
tagged = session.listTagged(args[0])
|
||||
idx = dict([(b['nvr'], b) for b in tagged])
|
||||
builds = []
|
||||
for nvr in args[1:]:
|
||||
binfo = idx.get(nvr)
|
||||
if binfo:
|
||||
builds.append(binfo)
|
||||
else:
|
||||
# not in tag, see if it even exists
|
||||
binfo = session.getBuild(nvr)
|
||||
if not binfo:
|
||||
print _("No such build: %s") % nvr
|
||||
else:
|
||||
print _("Build %s not in tag %s") % (nvr, tag['name'])
|
||||
if not options.force:
|
||||
sys.exit(1)
|
||||
builds.reverse()
|
||||
for binfo in builds:
|
||||
if options.test:
|
||||
print _("would have untagged %(nvr)s") % binfo
|
||||
else:
|
||||
if options.verbose:
|
||||
print _("untagging %(nvr)s") % binfo
|
||||
session.untagBuild(tag['name'], binfo['nvr'], force=options.force)
|
||||
|
||||
def handle_unblock_pkg(options, session, args):
|
||||
"[admin] Unblock a package in the listing for tag"
|
||||
|
|
|
|||
|
|
@ -480,18 +480,6 @@ def eventCondition(event, table=None):
|
|||
else:
|
||||
raise koji.GenericError, "Invalid event: %r" % event
|
||||
|
||||
def get_last_event():
|
||||
"""
|
||||
Get the id and timestamp of the last event that modified the
|
||||
system. Returns a map containing the following fields:
|
||||
- id
|
||||
- ts
|
||||
"""
|
||||
fields = ('id', 'ts')
|
||||
q = """SELECT id, EXTRACT(EPOCH FROM time) FROM events
|
||||
ORDER BY id DESC LIMIT 1"""
|
||||
return _singleRow(q, {}, fields, strict=True)
|
||||
|
||||
def readGlobalInheritance(event=None):
|
||||
c=context.cnx.cursor()
|
||||
fields = ('tag_id','parent_id','name','priority','maxdepth','intransitive',
|
||||
|
|
@ -1061,13 +1049,10 @@ def readTaggedRPMS(tag, package=None, arch=None, event=None,inherit=False,latest
|
|||
if isinstance(arch, basestring):
|
||||
q += """AND rpminfo.arch = %(arch)s
|
||||
"""
|
||||
elif isinstance(arch, (list, tuple)):
|
||||
q += """AND rpminfo.arch IN %(arch)s\n"""
|
||||
else:
|
||||
try:
|
||||
it = iter(arch)
|
||||
except TypeError:
|
||||
raise koji.GenericError, 'invalid arch option: %s' % arch
|
||||
q += """AND rpminfo.arch in (%s)
|
||||
""" % ','.join(["'%s'" % a for a in it])
|
||||
raise koji.GenericError, 'invalid arch option: %s' % arch
|
||||
|
||||
# unique constraints ensure that each of these queries will not report
|
||||
# duplicate rpminfo entries, BUT since we make the query multiple times,
|
||||
|
|
@ -2601,8 +2586,10 @@ def get_build(buildInfo, strict=False):
|
|||
owner_id: ID of the user who kicked off the build
|
||||
owner_name: name of the user who kicked off the build
|
||||
creation_event_id: id of the create_event
|
||||
creation_time: time the build was created
|
||||
creation_time: time the build was created (text)
|
||||
creation_ts: time the build was created (epoch)
|
||||
completion_time: time the build was completed (may be null)
|
||||
completion_ts: time the build was completed (epoch, may be null)
|
||||
|
||||
If there is no build matching the buildInfo given, and strict is specified,
|
||||
raise an error. Otherwise return None.
|
||||
|
|
@ -2619,6 +2606,8 @@ def get_build(buildInfo, strict=False):
|
|||
('build.task_id', 'task_id'), ('events.id', 'creation_event_id'), ('events.time', 'creation_time'),
|
||||
('package.id', 'package_id'), ('package.name', 'package_name'), ('package.name', 'name'),
|
||||
("package.name || '-' || build.version || '-' || build.release", 'nvr'),
|
||||
('EXTRACT(EPOCH FROM events.time)','creation_ts'),
|
||||
('EXTRACT(EPOCH FROM build.completion_time)','completion_ts'),
|
||||
('users.id', 'owner_id'), ('users.name', 'owner_name'))
|
||||
query = """SELECT %s
|
||||
FROM build
|
||||
|
|
@ -5197,7 +5186,28 @@ class RootExports(object):
|
|||
context.session.assertPerm('admin')
|
||||
return "%r" % context.opts
|
||||
|
||||
getLastEvent = staticmethod(get_last_event)
|
||||
def getLastEvent(self, before=None):
|
||||
"""
|
||||
Get the id and timestamp of the last event recorded in the system.
|
||||
Events are usually created as the result of a configuration change
|
||||
in the database.
|
||||
|
||||
If "before" (int or float) is specified, return the last event
|
||||
that occurred before that time (in seconds since the epoch).
|
||||
If there is no event before the given time, an error will be raised.
|
||||
"""
|
||||
fields = ('id', 'ts')
|
||||
values = {}
|
||||
q = """SELECT id, EXTRACT(EPOCH FROM time) FROM events"""
|
||||
if before is not None:
|
||||
if not isinstance(before, (int, long, float)):
|
||||
raise koji.GenericError, 'invalid type for before: %s' % type(before)
|
||||
# use the repr() conversion because it retains more precision than the
|
||||
# string conversion
|
||||
q += """ WHERE EXTRACT(EPOCH FROM time) < %(before)r"""
|
||||
values['before'] = before
|
||||
q += """ ORDER BY id DESC LIMIT 1"""
|
||||
return _singleRow(q, values, fields, strict=True)
|
||||
|
||||
def makeTask(self,*args,**opts):
|
||||
#this is mainly for debugging
|
||||
|
|
@ -6093,7 +6103,10 @@ class RootExports(object):
|
|||
"""Grant a permission to a user"""
|
||||
context.session.assertPerm('admin')
|
||||
user_id = get_user(userinfo,strict=True)['id']
|
||||
perm_id = get_perm_id(permission,strict=True)
|
||||
perm = lookup_perm(permission, strict=True)
|
||||
perm_id = perm['id']
|
||||
if perm['name'] in koji.auth.get_user_perms(user_id):
|
||||
raise koji.GenericError, 'user %s already has permission: %s' % (userinfo, perm['name'])
|
||||
insert = """INSERT INTO user_perms (user_id, perm_id)
|
||||
VALUES (%(user_id)i, %(perm_id)i)"""
|
||||
_dml(insert, locals())
|
||||
|
|
|
|||
34
util/kojira
34
util/kojira
|
|
@ -119,8 +119,21 @@ class ManagedRepo(object):
|
|||
|
||||
def tryDelete(self):
|
||||
"""Remove the repo from disk, if possible"""
|
||||
#we check just the event age first since it is faster
|
||||
age = time.time() - self.event_ts
|
||||
tag_info = session.getTag(self.tag_id)
|
||||
if not tag_info:
|
||||
self.logger.warn('Could not get info for tag %i, skipping delete of repo %i' %
|
||||
(self.tag_id, self.repo_id))
|
||||
return False
|
||||
tag_name = tag_info['name']
|
||||
path = pathinfo.repo(self.repo_id, tag_name)
|
||||
try:
|
||||
#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.
|
||||
mtime = os.stat(path).st_mtime
|
||||
except OSError:
|
||||
self.logger.error("Can't stat repo directory: %s" % path)
|
||||
return True
|
||||
age = time.time() - max(self.event_ts, mtime)
|
||||
if age < options.deleted_repo_lifetime:
|
||||
#XXX should really be called expired_repo_lifetime
|
||||
return False
|
||||
|
|
@ -133,23 +146,6 @@ class ManagedRepo(object):
|
|||
return False
|
||||
self.logger.info("Deleted repo %s" % self.repo_id)
|
||||
self.state = koji.REPO_DELETED
|
||||
tag_info = session.getTag(self.tag_id)
|
||||
if not tag_info:
|
||||
self.logger.warn('Could not get info for tag %i, skipping delete of repo %i' %
|
||||
(self.tag_id, self.repo_id))
|
||||
return False
|
||||
tag_name = tag_info['name']
|
||||
path = pathinfo.repo(self.repo_id, tag_name)
|
||||
#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.
|
||||
try:
|
||||
age = time.time() - os.stat(path).st_mtime
|
||||
except OSError:
|
||||
self.logger.error("Can't stat repo directory: %s" % path)
|
||||
return True
|
||||
if age < options.deleted_repo_lifetime:
|
||||
#XXX should really be called expired_repo_lifetime
|
||||
return False
|
||||
safe_rmtree(path, strict=False)
|
||||
return True
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue