|
|
6e61fb |
# -*- coding: utf-8 -*-
|
|
|
6e61fb |
import os
|
|
|
6e61fb |
try:
|
|
|
6e61fb |
import koji
|
|
|
6e61fb |
from koji_cli.lib import activate_session
|
|
|
6e61fb |
HAS_KOJI = True
|
|
|
6e61fb |
except ImportError:
|
|
|
6e61fb |
HAS_KOJI = False
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def get_profile_name(profile):
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
Return a koji profile name.
|
|
|
6e61fb |
|
|
|
6e61fb |
:param str profile: profile name, like "koji" or "cbs", or None. If None,
|
|
|
6e61fb |
we will use return the "KOJI_PROFILE" environment
|
|
|
6e61fb |
variable. If we could find no profile name, raise
|
|
|
6e61fb |
ValueError.
|
|
|
6e61fb |
:returns: str, the profile name
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
if profile:
|
|
|
6e61fb |
return profile
|
|
|
6e61fb |
profile = os.getenv('KOJI_PROFILE')
|
|
|
6e61fb |
if profile:
|
|
|
6e61fb |
return profile
|
|
|
6e61fb |
raise ValueError('set a profile "koji" argument for this task, or set '
|
|
|
6e61fb |
'the KOJI_PROFILE environment variable')
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def get_session(profile):
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
Return an anonymous koji session for this profile name.
|
|
|
6e61fb |
|
|
|
6e61fb |
:param str profile: profile name, like "koji" or "cbs". If None, we will
|
|
|
6e61fb |
use a profile name from the "KOJI_PROFILE" environment
|
|
|
6e61fb |
variable.
|
|
|
6e61fb |
:returns: anonymous koji.ClientSession
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
profile = get_profile_name(profile)
|
|
|
6e61fb |
# Note, get_profile_module() raises koji.ConfigurationError if we
|
|
|
6e61fb |
# could not find this profile's name in /etc/koji.conf.d/*.conf and
|
|
|
6e61fb |
# ~/.koji/config.d/*.conf.
|
|
|
6e61fb |
mykoji = koji.get_profile_module(profile)
|
|
|
6e61fb |
# Workaround https://pagure.io/koji/issue/1022 . Koji 1.17 will not need
|
|
|
6e61fb |
# this.
|
|
|
6e61fb |
if '~' in str(mykoji.config.cert):
|
|
|
6e61fb |
mykoji.config.cert = os.path.expanduser(mykoji.config.cert)
|
|
|
6e61fb |
if '~' in str(mykoji.config.ca):
|
|
|
6e61fb |
mykoji.config.ca = os.path.expanduser(mykoji.config.ca)
|
|
|
6e61fb |
# Note, Koji has a grab_session_options() method that can also create a
|
|
|
6e61fb |
# stripped-down dict of our module's (OptParse) configuration, like:
|
|
|
6e61fb |
# opts = mykoji.grab_session_options(mykoji.config)
|
|
|
6e61fb |
# The idea is that callers then pass that opts dict into ClientSession's
|
|
|
6e61fb |
# constructor.
|
|
|
6e61fb |
# There are two reasons we don't use that here:
|
|
|
6e61fb |
# 1. The dict is only suitable for the ClientSession(..., opts), not for
|
|
|
6e61fb |
# activate_session(..., opts). activate_session() really wants the full
|
|
|
6e61fb |
# set of key/values in mykoji.config.
|
|
|
6e61fb |
# 2. We may call activate_session() later outside of this method, so we
|
|
|
6e61fb |
# need to preserve all the configuration data from mykoji.config inside
|
|
|
6e61fb |
# the ClientSession object. We might as well just store it in the
|
|
|
6e61fb |
# ClientSession's .opts and then pass that into activate_session().
|
|
|
6e61fb |
opts = vars(mykoji.config)
|
|
|
6e61fb |
# Force an anonymous session (noauth):
|
|
|
6e61fb |
opts['noauth'] = True
|
|
|
6e61fb |
session = mykoji.ClientSession(mykoji.config.server, opts)
|
|
|
6e61fb |
# activate_session with noauth will simply ensure that we can connect with
|
|
|
6e61fb |
# a getAPIVersion RPC. Let's avoid it here because it just slows us down.
|
|
|
6e61fb |
# activate_session(session, opts)
|
|
|
6e61fb |
return session
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def ensure_logged_in(session):
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
Authenticate this Koji session (if necessary).
|
|
|
6e61fb |
|
|
|
6e61fb |
:param session: a koji.ClientSession
|
|
|
6e61fb |
:returns: None
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
if not session.logged_in:
|
|
|
6e61fb |
session.opts['noauth'] = False
|
|
|
6e61fb |
# Log in ("activate") this session:
|
|
|
6e61fb |
# Note: this can raise SystemExit if there is a problem, eg with
|
|
|
6e61fb |
# Kerberos:
|
|
|
6e61fb |
activate_session(session, session.opts)
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
# inheritance display utils
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def describe_inheritance_rule(rule):
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
Given a dictionary representing a koji inheritance rule (i.e., one of the
|
|
|
6e61fb |
elements of getInheritanceData()'s result), return a tuple of strings to be
|
|
|
6e61fb |
appended to a module's stdout_lines array conforming to the output of
|
|
|
6e61fb |
koji's taginfo CLI command, e.g.:
|
|
|
6e61fb |
0 .... a-parent-tag
|
|
|
6e61fb |
10 M... another-parent-tag
|
|
|
6e61fb |
maxdepth: 1
|
|
|
6e61fb |
100 .F.. yet-another-parent-tag
|
|
|
6e61fb |
package filter: ^prefix-
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
# koji_cli/commands.py near the end of anon_handle_taginfo()
|
|
|
6e61fb |
flags = '%s%s%s%s' % (
|
|
|
6e61fb |
'M' if rule['maxdepth'] not in ('', None) else '.',
|
|
|
6e61fb |
'F' if rule['pkg_filter'] not in ('', None) else '.',
|
|
|
6e61fb |
'I' if rule['intransitive'] else '.',
|
|
|
6e61fb |
'N' if rule['noconfig'] else '.',
|
|
|
6e61fb |
)
|
|
|
6e61fb |
|
|
|
6e61fb |
result = ["%4d %s %s" % (rule['priority'], flags, rule['name'])]
|
|
|
6e61fb |
|
|
|
6e61fb |
if rule['maxdepth'] not in ('', None):
|
|
|
6e61fb |
result.append(" maxdepth: %d" % rule['maxdepth'])
|
|
|
6e61fb |
if rule['pkg_filter'] not in ('', None):
|
|
|
6e61fb |
result.append(" package filter: %s" % rule['pkg_filter'])
|
|
|
6e61fb |
|
|
|
6e61fb |
return tuple(result)
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def describe_inheritance(rules):
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
Given a sequence of dictionaries representing koji inheritance rules (i.e.,
|
|
|
6e61fb |
getInheritanceData()'s result), return a tuple of strings to be appended to
|
|
|
6e61fb |
a module's stdout_lines array conforming to the output of koji's taginfo
|
|
|
6e61fb |
CLI command. See describe_inheritance_rule for sample output.
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
|
|
|
6e61fb |
# each invocation of describe_inheritance_rule yields a tuple of strings
|
|
|
6e61fb |
# to be appended to a module's stdout_lines result, so concatenate them:
|
|
|
6e61fb |
# sum(…, tuple()) will flatten tuples of tuples into just the child tuples
|
|
|
6e61fb |
# > sum( ((1, 2), (3, 4)), tuple() ) ⇒ (1, 2) + (3, 4) + (,) ⇒ (1, 2, 3, 4)
|
|
|
6e61fb |
return sum(tuple(map(describe_inheritance_rule, rules)), tuple())
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
# permission utils
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
perm_cache = {}
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def get_perms(session):
|
|
|
6e61fb |
global perm_cache
|
|
|
6e61fb |
if not perm_cache:
|
|
|
6e61fb |
perm_cache = dict([
|
|
|
6e61fb |
(perm['name'], perm['id']) for perm in session.getAllPerms()
|
|
|
6e61fb |
])
|
|
|
6e61fb |
return perm_cache
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def get_perm_id(session, name):
|
|
|
6e61fb |
perms = get_perms(session)
|
|
|
6e61fb |
return perms[name]
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def get_perm_name(session, id_):
|
|
|
6e61fb |
perms = get_perms(session)
|
|
|
6e61fb |
for perm_name, perm_id in perms.items():
|
|
|
6e61fb |
if perm_id == id_:
|
|
|
6e61fb |
return perm_name
|