koji version 1.10.1
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWMlJ6AAoJEI4ybUZMjacl2EwQANP3tcwNcnXQwAYV3I/a0O2g 4kuwSNRNxD2jhToqIkNJp7LoEsiUFDMHPFl0yxoDmu750wGAnUjCW2P+GlG1fOr/ Eh65hA9xEn8g8iWPJJSFip2Xz1sLQxrm/zKzV7xaBqiLc6sjZ/dIPfa/LWZjY/e9 yBnb+I3Wm/RU5QnENMrs1BU0tlZ613Npz9YqalZ4oxPLS4/XzbAJpFkeVLpj9IgM EpSEnoNWCMsoIeTN2Uh8YIpU6BzO5fiqPqYq5NqgZMulMPUkzk9xyJFzw5+GtkfF DGt5tIy+7J6t86G6VPtKOW+NIfohyJKxyQlz8Mcg8wYrIFiXAM6f6hw0hILhJ8nB 62McpzlsjvxE2lOLAlW+G2xaEQ272ew01gkx/vNTp0xHAZuHMSveyzTozDIbzcdg 7ENa8qbY4HGS7qL/Q/J7kHwKPofhKEHXPh2fVRmj/ogzIBM6em87OH3wtHWsz883 ay6BA9ngBNmBsSU/OBhXDM62BEhjV6oQTxYM1i0ZR2XeUNdJNI7ezHkroMivIEsn LafAslR0IpAUtaM8nHVUVLkMBGvUUxm30OTpRiENnkGrV4PnijCty5NLrogIoAtA kAf1HH69ls3Xs8rjZS0XXPdim2Vf7EgXvELWwA4AskD8JnA+wmXBfZML6Zhu1k0h FQd47eo4SjVNHRpNSUBG =Kbwm -----END PGP SIGNATURE----- Merge tag 'koji-1.10.1' into cgen koji version 1.10.1 Conflicts: hub/kojihub.py
This commit is contained in:
commit
ea491f5f03
3 changed files with 197 additions and 21 deletions
153
docs/Writing_a_plugin.md
Normal file
153
docs/Writing_a_plugin.md
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
# Writing Koji plugins
|
||||
|
||||
Depending on what you are trying to do, there are different ways to write a
|
||||
Koji plugin.
|
||||
|
||||
Each is described in this file, by use case.
|
||||
|
||||
## Adding new task types
|
||||
|
||||
Koji can do several things, for example build RPMs, or live CDs. Those are
|
||||
types of tasks which Koji knows about.
|
||||
|
||||
If you need to do something which Koji does not know yet how to do, you could
|
||||
create a Koji Builder plugin.
|
||||
|
||||
Such a plugin would minimally look like this:
|
||||
|
||||
from koji.tasks import BaseTaskHandler
|
||||
|
||||
class MyTask(BaseTaskHandler):
|
||||
Methods = ['mytask']
|
||||
_taskWeight = 2.0
|
||||
|
||||
def handler(self, arg1, arg2, kwarg1=None):
|
||||
self.logger.debug("Running my task...")
|
||||
|
||||
# Here is where you actually do something
|
||||
|
||||
A few explanations on what goes on here:
|
||||
|
||||
* Your task needs to inherit from `koji.tasks.BaseTaskHandler`
|
||||
* Your task must have a `Methods` attribute, which is a list of the method
|
||||
names your task can handle.
|
||||
* You can specify the weight of your task with the `_taskWeight` attribute.
|
||||
The more intensive (CPU, IO, ...) your task is, the higher this number
|
||||
should be.
|
||||
* The task object has a `logger` attribute, which is a Python logger with the
|
||||
usual `debug`, `info`, `warning` and `error` methods. The messages you send
|
||||
with it will end up in the Koji Builder logs (`kojid.log`)
|
||||
* Your task must have a `handler()` method. That is the method Koji will call
|
||||
to run your task. It is the method that should actually do what you need. It
|
||||
can have as many positional and named arguments as you want.
|
||||
|
||||
Save your plugin as e.g `mytask.py`, then install it in the Koji Builder
|
||||
plugins folder: `/usr/lib/koji-builder-plugins/`
|
||||
|
||||
Finally, edit the Koji Builder config file, `/etc/kojid/kojid.conf`:
|
||||
|
||||
# A space-separated list of plugins to enable
|
||||
plugins = mytask
|
||||
|
||||
Restart the Koji Builder service, and your plugin will be enabled.
|
||||
|
||||
You can try running a task from your new task type with the command-line:
|
||||
|
||||
$ koji make-task mytask arg1 arg2 kwarg1
|
||||
|
||||
## Exporting new API methods over XMLRPC
|
||||
|
||||
Koji clients talk to the Koji Hub via an XMLRPC API.
|
||||
|
||||
It is sometimes desirable to add to that API, so that clients can request
|
||||
things Koji does not expose right now.
|
||||
|
||||
Such a plugin would minimally look like this:
|
||||
|
||||
def mymethod(arg1, arg2, kwarg1=None):
|
||||
# Here is where you actually do something
|
||||
|
||||
mymethod.exported = True
|
||||
|
||||
A few explanations on what goes on here:
|
||||
|
||||
* Your plugin is just a method, with whatever positional and/or named
|
||||
arguments you need.
|
||||
* You must export your method by setting its `exported` attribute to `True`
|
||||
* The `context.session.assertPerm()` is how you ensure that the
|
||||
|
||||
Save your plugin as e.g `mymethod.py`, then install it in the Koji Hub plugins
|
||||
folder: `/usr/lib/koji-hub-plugins/`
|
||||
|
||||
Finally, edit the Koji Hub config file, `/etc/koji-hub/hub.conf`:
|
||||
|
||||
# A space-separated list of plugins to enable
|
||||
Plugins = mymethod
|
||||
|
||||
Restart the Koji Hub service, and your plugin will be enabled.
|
||||
|
||||
You can try calling the new XMLRPC API with the Python client library:
|
||||
|
||||
>>> import koji
|
||||
>>> session = koji.ClientSession("http://koji/example.org/kojihub")
|
||||
>>> session.mymethod(arg1, arg2, kwarg1='some value')
|
||||
|
||||
### Ensuring the user has the required permissions
|
||||
|
||||
If you want your new XMLRPC API to require specific permissions from the user,
|
||||
all you need to do is add the following to your method:
|
||||
|
||||
from koji.context import context
|
||||
|
||||
def mymethod(arg1, arg2, kwarg1=None):
|
||||
context.session.assertPerm("admin")
|
||||
|
||||
# Here is where you actually do something
|
||||
|
||||
mymethod.exported = True
|
||||
|
||||
In the example above, Koji will ensure that the user is an administrator. You
|
||||
could of course create your own permission, and check for that.
|
||||
|
||||
## Running code automatically triggered on events
|
||||
|
||||
You might want to run something automatically when something else happens in
|
||||
Koji.
|
||||
|
||||
A typical example is to automatically sign a package right after a build
|
||||
finished. Another would be to send a notification to a message bus after any
|
||||
kind of event.
|
||||
|
||||
This can be achieved with a plugin, which would look minimally as follows:
|
||||
|
||||
from koji.plugin import callback
|
||||
|
||||
@callback('preTag', 'postTag')
|
||||
def mycallback(cbtype, tag, build, user, force=False):
|
||||
# Here is where you actually do something
|
||||
|
||||
A few explanations on what goes on here:
|
||||
|
||||
* The `@callback` decorator allows you to declare which events should trigger
|
||||
your function. You can pass as many as you want. For a list of supported
|
||||
events, see `koji/plugins.py`.
|
||||
* The arguments of the function depend on the event you subscribed to. As a
|
||||
result, you need to know how it will be called by Koji. You probably should
|
||||
use `*kwargs` to be safe. You can see how callbacks are called in the
|
||||
`hub/kojihub.py` file, search for calls of the `run_callbacks` function.
|
||||
|
||||
Save your plugin as e.g `mycallback.py`, then install it in the Koji Hub
|
||||
plugins folder: `/usr/lib/koji-hub-plugins`
|
||||
|
||||
Finally, edit the Koji Hub config file, `/etc/koji-hub/hub.conf`:
|
||||
|
||||
# A space-separated list of plugins to enable
|
||||
Plugins = mycallback
|
||||
|
||||
Restart the Koji Hub service, and your plugin will be enabled.
|
||||
|
||||
You can try triggering your callback plugin with the command-line. For
|
||||
example, if you registered a callback for the `postTag` event, try tagging a
|
||||
build:
|
||||
|
||||
$ koji tag-build mytag mypkg-1.0-1
|
||||
|
|
@ -10387,33 +10387,42 @@ class Host(object):
|
|||
raise koji.AuthError, "This method requires an exclusive session"
|
||||
return True
|
||||
|
||||
def taskUnwait(self,parent):
|
||||
def taskUnwait(self, parent):
|
||||
"""Clear wait data for task"""
|
||||
c = context.cnx.cursor()
|
||||
#unwait the task
|
||||
q = """UPDATE task SET waiting='false' WHERE id = %(parent)s"""
|
||||
context.commit_pending = True
|
||||
c.execute(q,locals())
|
||||
update = UpdateProcessor('task', clauses=['id=%(parent)s'], values=locals())
|
||||
update.set(waiting=False)
|
||||
update.execute()
|
||||
#...and un-await its subtasks
|
||||
q = """UPDATE task SET awaited='false' WHERE parent=%(parent)s"""
|
||||
c.execute(q,locals())
|
||||
update = UpdateProcessor('task', clauses=['parent=%(parent)s'], values=locals())
|
||||
update.set(awaited=False)
|
||||
update.execute()
|
||||
|
||||
def taskSetWait(self,parent,tasks):
|
||||
def taskSetWait(self, parent, tasks):
|
||||
"""Mark task waiting and subtasks awaited"""
|
||||
self.taskUnwait(parent)
|
||||
c = context.cnx.cursor()
|
||||
#mark tasks awaited
|
||||
q = """UPDATE task SET waiting='true' WHERE id=%(parent)s"""
|
||||
context.commit_pending = True
|
||||
c.execute(q,locals())
|
||||
|
||||
# mark parent as waiting
|
||||
update = UpdateProcessor('task', clauses=['id=%(parent)s'], values=locals())
|
||||
update.set(waiting=True)
|
||||
update.execute()
|
||||
|
||||
# mark children awaited
|
||||
if tasks is None:
|
||||
#wait on all subtasks
|
||||
q = """UPDATE task SET awaited='true' WHERE parent=%(parent)s"""
|
||||
c.execute(q,locals())
|
||||
# wait on all subtasks
|
||||
update = UpdateProcessor('task', clauses=['parent=%(parent)s'], values=locals())
|
||||
update.set(awaited=True)
|
||||
update.execute()
|
||||
else:
|
||||
for id in tasks:
|
||||
q = """UPDATE task SET awaited='true' WHERE id=%(id)s"""
|
||||
c.execute(q,locals())
|
||||
# wait on specified subtasks
|
||||
update = UpdateProcessor('task', clauses=['id IN %(tasks)s', 'parent=%(parent)s'], values=locals())
|
||||
update.set(awaited=True)
|
||||
update.execute()
|
||||
# clear awaited flag on any other child tasks
|
||||
update = UpdateProcessor('task', values=locals(),
|
||||
clauses=['id NOT IN %(tasks)s', 'parent=%(parent)s', 'awaited=true'])
|
||||
update.set(awaited=False)
|
||||
update.execute()
|
||||
|
||||
|
||||
def taskWaitCheck(self,parent):
|
||||
"""Return status of awaited subtask
|
||||
|
|
|
|||
16
koji.spec
16
koji.spec
|
|
@ -15,7 +15,7 @@
|
|||
%define release %{baserelease}
|
||||
%endif
|
||||
Name: koji
|
||||
Version: 1.10.0
|
||||
Version: 1.10.1
|
||||
Release: %{release}%{?dist}
|
||||
License: LGPLv2 and GPLv2+
|
||||
# koji.ssl libs (from plague) are GPLv2+
|
||||
|
|
@ -320,6 +320,20 @@ fi
|
|||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Oct 29 2015 Mike McLean <mikem at redhat.com> - 1.10.1-1
|
||||
- fixes for SSL errors
|
||||
- add support for Image Factory generation of VMWare Fusion Vagrant boxes
|
||||
- cli: add download-task command
|
||||
- docs: Document how to write a plugin
|
||||
- fix for a rare deadlock issue in taskSetWait
|
||||
- use encode_int on rpm sizes
|
||||
- check for tag existence in add-pkg
|
||||
- Remove koji._forceAscii (unused)
|
||||
- Resolve the canonical hostname when constructing the Kerberos server principal
|
||||
- don't omit debuginfos on buildinfo page
|
||||
- correct error message in fastUpload
|
||||
- Check task method before trying to determine "scratch" status.
|
||||
|
||||
* Tue Jul 14 2015 Mike McLean <mikem at redhat.com> - 1.10.0-1
|
||||
- 1.10.0 release
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue