-
- Koji is a system for building and tracking RPMs. It was designed with the following
- features in mind:
-
-
- Security
-
-
New buildroot for each build
-
nfs is used (mostly) read-only
-
-
- Leverage other software
-
-
Uses Yum and Mock open-source components
-
XML-RPC APIs for easy integration with other tools
-
-
- Flexibility
-
-
rich data model
-
active code base
-
-
- Usability
-
-
Web interface with Kerberos authentication
-
Thin, portable client
-
Users can create local buildroots
-
-
- Reproducibility
-
-
Buildroot contents are tracked in the database
-
Versioned data
-
-
-
-
This HOWTO document covers the basic tasks that a developer needs to be
- able to accomplish with Koji.
-
-
-
Getting started
-
-
The web interface
-
The primary interface for viewing Koji data is a web application. Most of the interface
- is read-only, but if you are logged in (see below) and have sufficient privileges there
- are some actions that can be performed though the web. For example:
-
-
Cancel a build
-
Resubmit a failed task
-
- Those with admin privileges will find additional actions, such as:
-
-
Create/Edit/Delete a tag
-
Create/Edit/Delete a target
-
Enable/Disable a build host
-
-
-
The web site utilizes Kerberos authentication. In order to log in you will
- need a valid Kerberos ticket and your web browser will need to be configured to send the
- Kerberos information to the server.
-
-
In Firefox or Mozilla, you will need to use the about:config page to set a few parameters.
- Use the search term 'negotiate' to filter the list. Change
- network.negotiate-auth.trusted-uris to the domain you want to authenticate against,
- e.g .example.com. You can leave network.negotiate-auth.delegation-uris blank, as it
- enables Kerberos ticket passing, which is not required. If you do not see those two
- config options listed, your version of Firefox or Mozilla may be too old to support
- Negotiate authentication, and you should consider upgrading.
-
-
In order to obtain a Kerberos ticket, use the kinit command.
-
-
-
Installing the Koji cli
-
There is a single point of entry for most operations. The command is
- called 'koji' and is included in the main koji package.
-
-
Repos/webpage TBD
-
-
- The koji tool authenticates to the central server using Kerberos, so you will need
- to have a valid Kerberos ticket to use many features. However, many of the read-only
- commands will work without authentication.
-
-
Building a package
-
Builds are initiated with the command line tool.
- To build a package, the syntax is:
-
$ koji build <build target> <cvs URL>
-
-
For example:
-
$ koji build dist-fc7-scratch 'cvs://cvs.example.com/cvs/dist?rpms/kernel/FC-7#kernel-2_6_20-1_2925_fc7'
-
- The koji build command creates a build task in Koji. By default
- the tool will wait
- and print status updates until the build completes. You can override this with
- the --nowait option. To view other options to the build command use the
- --help option.
-
-
-
$ koji build --help
-
-
-
Build Options
-
- There are a few options to the build command. Here are some more detailed explanations
- of them:
-
-
-
-
--skip-tag
-
Normally the package is tagged after the build completes. This option causes
- the tagging step to be skipped. The package will be in the system, but untagged
- (you can later tag it with the tag-pkg command)
-
--scratch
-
This makes the build into a scratch build. The build will not be
- imported into the db, it will just be built. The rpms will land under
- <topdir>/scratch. Scratch builds are not tracked and can never
- be tagged, but can be convenient for testing. Scratch builds are
- typically removed from the filesystem after one week.
-
-
--nowait
-
As stated above, this prevents the cli from waiting on the build task.
-
--arch-override
-
This option allows you to override the base set of arches to build for.
- This option is really only for testing during the beta period, but it may
- be retained for scratch builds in the future.
-
-
-
Build Failures
-
If your package fails to build, you will see something like this.
-
- 420066 buildArch (kernel-2.6.18-1.2739.10.9.el5.jjf.215394.2.src.rpm,
- ia64): open (build-1.example.com) -> FAILED: BuildrootError:
- error building package (arch ia64), mock exited with status 10
-
-
-
You can figure out why the build failed by looking at the log files. If
- there is a build.log, start there. Otherwise, look at init.log
-
- In Koji, it is sometimes necessary to distinguish between the a package in general,
- a specific build of a package, and the various rpm files created by a build. When
- precision is needed, these terms should be interpreted as follows:
-
-
-
Package
-
The name of a source rpm. This refers to the package in general and not
- any particular build or subpackage. For example: kernel, glibc, etc.
-
Build
-
A particular build of a package. This refers to the entire build: all arches
- and subpackages. For example: kernel-2.6.9-34.EL, glibc-2.3.4-2.19.
-
RPM
-
A particular rpm. A specific arch and subpackage of a build.
- For example: kernel-2.6.9-34.EL.x86_64, kernel-devel-2.6.9-34.EL.s390,
- glibc-2.3.4-2.19.i686, glibc-common-2.3.4-2.19.ia64
-
-
-
-
Koji Components
-
- Koji is comprised of several components:
-
-
-
koji-hub is the center of all Koji operations. It is an XML-RPC server
- running under mod_python in Apache. koji-hub is passive in that it only
- receives XML-RPC calls and relies upon the build daemons and other
- components to initiate communication. koji-hub is the only component that
- has direct access to the database and is one of the two components that have
- write access to the file system.
-
-
kojid is the build daemon that runs on each of the build machines. Its
- primary responsibility is polling for incoming build requests and handling
- them accordingly. Koji also has support for tasks other than building.
- Creating install images is one example. kojid is responsible for handling
- these tasks as well.
-
-
kojid uses mock for building. It also creates a fresh buildroot for
- every build. kojid is written in Python and communicates with koji-hub via
- XML-RPC.
-
-
koji-web is a set of scripts that run in mod_python and use the Cheetah
- templating engine to provide an web interface to Koji. koji-web exposes a
- lot of information and also provides a means for certain operations, such as
- cancelling builds.
-
-
koji is a CLI written in Python that provides many hooks into
- Koji. It allows the user to query much of the data as well as perform
- actions such as build initiation.
-
-
kojirepod is a daemon that keeps the build root repodata
- updated.
-
-
-
-
Package Organization
-
Tags and Targets
-
Koji organizes packages using tags. In Koji a tag is roughly analogous to
- a beehive collection instance, but differ in a number of ways:
-
-
Tags are tracked in the database but not on disk
-
Tags support multiple inheritance
-
Each tag has its own list of valid packages (inheritable)
-
Package ownership can be set per-tag (inheritable)
-
Tag inheritance is more configurable
-
When you build you specify a target rather than a tag
-
-
- A build target specifies where a package should be built and how it
- should be tagged afterwards. This allows target names to remain fixed
- as tags change through releases. You can get a full list of build targets
- with the following command:
-
$ koji list-targets
-
- You can see just a single target with the --name option:
-
- This tells you a build for target dist-fc7 will use a buildroot with packages
- from the tag dist-fc7-build and tag the resulting packages as dist-fc7.
-
- You can get a list of tags with the following command:
-
$ koji list-tags
-
-
Package lists
-
- As mentioned above, each tag has its own list of packages that may be placed
- in the tag. To see that list for a tag, use the list-pkgs command:
- The first column is the name of the package, the second tells you which tag
- the package entry has been inherited from, and the third tells you the owner
- of the package.
-
Latest Builds
-
- To see the latest builds for a tag, use the latest-pkg command:
-
$ koji latest-pkg --all dist-fc7
-Build Tag Built by
----------------------------------------- -------------------- ----------------
-ConsoleKit-0.1.0-5.fc7 dist-fc7 davidz
-ElectricFence-2.2.2-20.2.2 dist-fc6 jkeating
-GConf2-2.16.0-6.fc7 dist-fc7 mclasen
-ImageMagick-6.2.8.0-3.fc6.1 dist-fc6-updates nmurray
-MAKEDEV-3.23-1.2 dist-fc6 nalin
-MySQL-python-1.2.1_p2-2 dist-fc7 katzj
-NetworkManager-0.6.5-0.3.cvs20061025.fc7 dist-fc7 caillon
-ORBit2-2.14.6-1.fc7 dist-fc7 mclasen
-
- The output gives you not only the latest builds, but which tag they have
- been inherited from and who built them (note: for builds imported from beehive
- the "built by" field may be misleading)
-
-
-
Exploring Koji
-
-
We've tried to make Koji self-documenting wherever possible. The command
- line tool will print a list of valid commands and each command supports
- --help. For example:
-
-
-$ koji help
-Koji commands are:
- build Build a package from source
- cancel-task Cancel a task
- help List available commands
- latest-build Print the latest rpms for a tag
- latest-pkg Print the latest builds for a tag
-...
-$ koji build --help
-usage: koji build [options] tag URL
-(Specify the --help global option for a list of other help options)
-
-options:
- -h, --help show this help message and exit
- --skip-tag Do not attempt to tag package
- --scratch Perform a scratch build
- --nowait Don't wait on build
-...
-
-
-
Getting Involved
-
- If you would like to be more involved with the Koji project...
-
-
Project data TBD
-
-
-
diff --git a/docs/Makefile b/docs/Makefile
index 43d8d68c..5709e83c 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,4 +1,177 @@
-install:
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make ' where is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
- rm -f *.o *.so *.pyc *~
+ rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Koji.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Koji.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/Koji"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Koji"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through platex and dvipdfmx..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+ @echo
+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/docs/Migrating_to_1.10.txt b/docs/Migrating_to_1.10.txt
deleted file mode 100644
index e934706c..00000000
--- a/docs/Migrating_to_1.10.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-Migrating to Koji 1.10
-======================
-
-// asciidoc formatted
-
-The 1.10 release of Koji includes a few changes that you should consider when
-migrating.
-
-DB Updates
-----------
-
-The new +tag_extra+ table tracks extra data for tags.
-
-There is a new entry in the +channels+ table and some additions and updates to
-the +archivetypes+ table.
-
-As in previous releases, we provide a migration script that updates the
-database.
-
- # psql koji koji >> 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
diff --git a/docs/source/HOWTO.rst b/docs/source/HOWTO.rst
new file mode 100644
index 00000000..ab7dec2a
--- /dev/null
+++ b/docs/source/HOWTO.rst
@@ -0,0 +1,342 @@
+==========
+Koji HOWTO
+==========
+
+Introduction
+============
+
+Koji is a system for building and tracking RPMs. It was designed with
+the following features in mind:
+
+**Security**
+
+- New buildroot for each build
+- nfs is used (mostly) read-only
+
+**Leverage other software**
+
+- Uses Yum and Mock open-source components
+- XML-RPC APIs for easy integration with other tools
+
+**Flexibility**
+
+- rich data model
+- active code base
+
+**Usability**
+
+- Web interface with Kerberos authentication
+- Thin, portable client
+- Users can create local buildroots
+
+**Reproducibility**
+
+- Buildroot contents are tracked in the database
+- Versioned data
+
+This HOWTO document covers the basic tasks that a developer needs to be
+able to accomplish with Koji.
+
+Getting started
+===============
+
+The web interface
+-----------------
+
+The primary interface for viewing Koji data is a web application. Most
+of the interface is read-only, but if you are logged in (see below) and
+have sufficient privileges there are some actions that can be performed
+though the web. For example:
+
+- Cancel a build
+- Resubmit a failed task
+
+Those with admin privileges will find additional actions, such as:
+
+- Create/Edit/Delete a tag
+- Create/Edit/Delete a target
+- Enable/Disable a build host
+
+The web site utilizes Kerberos authentication. In order to log in you
+will need a valid Kerberos ticket and your web browser will need to be
+configured to send the Kerberos information to the server.
+
+In Firefox or Mozilla, you will need to use the about:config page to set
+a few parameters. Use the search term 'negotiate' to filter the list.
+Change network.negotiate-auth.trusted-uris to the domain you want to
+authenticate against, e.g .example.com. You can leave
+network.negotiate-auth.delegation-uris blank, as it enables Kerberos
+ticket passing, which is not required. If you do not see those two
+config options listed, your version of Firefox or Mozilla may be too old
+to support Negotiate authentication, and you should consider upgrading.
+
+In order to obtain a Kerberos ticket, use the kinit command.
+
+Installing the Koji cli
+-----------------------
+
+There is a single point of entry for most operations. The command is
+called 'koji' and is included in the main koji package.
+
+Repos/webpage TBD
+
+The koji tool authenticates to the central server using Kerberos, so you
+will need to have a valid Kerberos ticket to use many features. However,
+many of the read-only commands will work without authentication.
+
+Building a package
+------------------
+
+Builds are initiated with the command line tool. To build a package, the
+syntax is:
+
+::
+
+ $ koji build
+
+For example:
+
+::
+
+ $ koji build dist-fc7-scratch 'cvs://cvs.example.com/cvs/dist?rpms/kernel/FC-7#kernel-2_6_20-1_2925_fc7'
+
+The ``koji build`` command creates a build task in Koji. By default the
+tool will wait and print status updates until the build completes. You
+can override this with the ``--nowait`` option. To view other options to
+the build command use the ``--help`` option.
+
+::
+
+ $ koji build --help
+
+Build Options
+-------------
+
+There are a few options to the build command. Here are some more
+detailed explanations of them:
+
+``--skip-tag``
+ Normally the package is tagged after the build completes. This
+ option causes the tagging step to be skipped. The package will be in
+ the system, but untagged (you can later tag it with the tag-pkg
+ command)
+``--scratch``
+ This makes the build into a scratch build. The build will not be
+ imported into the db, it will just be built. The rpms will land
+ under /scratch. Scratch builds are not tracked and can never
+ be tagged, but can be convenient for testing. Scratch builds are
+ typically removed from the filesystem after one week.
+``--nowait``
+ As stated above, this prevents the cli from waiting on the build
+ task.
+``--arch-override``
+ This option allows you to override the base set of arches to build
+ for. This option is really only for testing during the beta period,
+ but it may be retained for scratch builds in the future.
+
+Build Failures
+--------------
+
+If your package fails to build, you will see something like this.
+
+::
+
+ 420066 buildArch (kernel-2.6.18-1.2739.10.9.el5.jjf.215394.2.src.rpm,
+ ia64): open (build-1.example.com) -> FAILED: BuildrootError:
+ error building package (arch ia64), mock exited with status 10
+
+You can figure out why the build failed by looking at the log files. If
+there is a build.log, start there. Otherwise, look at init.log
+
+::
+
+ $ ls -1 /work/tasks/420066/*
+ /work/tasks/420066/build.log
+ /work/tasks/420066/init.log
+ /work/tasks/420066/mockconfig.log
+ /work/tasks/420066/root.log
+
+
+Filing Bugs
+-----------
+
+bug tracking TBD
+
+Koji Architecture
+=================
+
+Terminology
+-----------
+
+In Koji, it is sometimes necessary to distinguish between the a package
+in general, a specific build of a package, and the various rpm files
+created by a build. When precision is needed, these terms should be
+interpreted as follows:
+
+Package
+ The name of a source rpm. This refers to the package in general and
+ not any particular build or subpackage. For example: kernel, glibc,
+ etc.
+Build
+ A particular build of a package. This refers to the entire build:
+ all arches and subpackages. For example: kernel-2.6.9-34.EL,
+ glibc-2.3.4-2.19.
+RPM
+ A particular rpm. A specific arch and subpackage of a build. For
+ example: kernel-2.6.9-34.EL.x86\_64, kernel-devel-2.6.9-34.EL.s390,
+ glibc-2.3.4-2.19.i686, glibc-common-2.3.4-2.19.ia64
+
+Koji Components
+---------------
+
+Koji is comprised of several components:
+
+- **koji-hub** is the center of all Koji operations. It is an XML-RPC
+ server running under mod\_python in Apache. koji-hub is passive in
+ that it only receives XML-RPC calls and relies upon the build daemons
+ and other components to initiate communication. koji-hub is the only
+ component that has direct access to the database and is one of the
+ two components that have write access to the file system.
+- **kojid** is the build daemon that runs on each of the build machines.
+ Its primary responsibility is polling for incoming build requests and
+ handling them accordingly. Koji also has support for tasks other than
+ building. Creating install images is one example. kojid is
+ responsible for handling these tasks as well.
+
+ kojid uses mock for building. It also creates a fresh buildroot for
+ every build. kojid is written in Python and communicates with
+ koji-hub via XML-RPC.
+
+- **koji-web** is a set of scripts that run in mod\_python and use the
+ Cheetah templating engine to provide an web interface to Koji.
+ koji-web exposes a lot of information and also provides a means for
+ certain operations, such as cancelling builds.
+- **koji** is a CLI written in Python that provides many hooks into Koji.
+ It allows the user to query much of the data as well as perform
+ actions such as build initiation.
+- **kojirepod** is a daemon that keeps the build root repodata updated.
+
+Package Organization
+--------------------
+
+**Tags and Targets**
+
+Koji organizes packages using tags. In Koji a tag is roughly analogous
+to a beehive collection instance, but differ in a number of ways:
+
+- Tags are tracked in the database but not on disk
+- Tags support multiple inheritance
+- Each tag has its own list of valid packages (inheritable)
+- Package ownership can be set per-tag (inheritable)
+- Tag inheritance is more configurable
+- When you build you specify a *target* rather than a tag
+
+A build target specifies where a package should be built and how it
+should be tagged afterwards. This allows target names to remain fixed as
+tags change through releases. You can get a full list of build targets
+with the following command:
+
+::
+
+ $ koji list-targets
+
+You can see just a single target with the ``--name`` option:
+
+::
+
+ $ koji list-targets --name dist-fc7
+ Name Buildroot Destination
+ ---------------------------------------------------------------------------------------------
+ dist-fc7 dist-fc7-build dist-fc7
+
+This tells you a build for target dist-fc7 will use a buildroot with
+packages from the tag dist-fc7-build and tag the resulting packages as
+dist-fc7.
+
+You can get a list of tags with the following command:
+
+::
+
+ $ koji list-tags
+
+*Package lists*
+
+As mentioned above, each tag has its own list of packages that may be
+placed in the tag. To see that list for a tag, use the ``list-pkgs``
+command:
+
+::
+
+ $ koji list-pkgs --tag dist-fc7
+ Package Tag Extra Arches Owner
+ ----------------------- ----------------------- ---------------- ----------------
+ ElectricFence dist-fc6 pmachata
+ GConf2 dist-fc6 rstrode
+ lucene dist-fc6 dbhole
+ lvm2 dist-fc6 lvm-team
+ ImageMagick dist-fc6 nmurray
+ m17n-db dist-fc6 majain
+ m17n-lib dist-fc6 majain
+ MAKEDEV dist-fc6 clumens
+ ...
+
+The first column is the name of the package, the second tells you which
+tag the package entry has been inherited from, and the third tells you
+the owner of the package.
+
+**Latest Builds**
+
+To see the latest builds for a tag, use the ``latest-pkg`` command:
+
+::
+
+ $ koji latest-pkg --all dist-fc7
+ Build Tag Built by
+ ---------------------------------------- -------------------- ----------------
+ ConsoleKit-0.1.0-5.fc7 dist-fc7 davidz
+ ElectricFence-2.2.2-20.2.2 dist-fc6 jkeating
+ GConf2-2.16.0-6.fc7 dist-fc7 mclasen
+ ImageMagick-6.2.8.0-3.fc6.1 dist-fc6-updates nmurray
+ MAKEDEV-3.23-1.2 dist-fc6 nalin
+ MySQL-python-1.2.1_p2-2 dist-fc7 katzj
+ NetworkManager-0.6.5-0.3.cvs20061025.fc7 dist-fc7 caillon
+ ORBit2-2.14.6-1.fc7 dist-fc7 mclasen
+
+The output gives you not only the latest builds, but which tag they have
+been inherited from and who built them (note: for builds imported from
+beehive the "built by" field may be misleading)
+
+Exploring Koji
+--------------
+
+We've tried to make Koji self-documenting wherever possible. The command
+line tool will print a list of valid commands and each command supports
+``--help``. For example:
+
+::
+
+ $ koji help
+ Koji commands are:
+ build Build a package from source
+ cancel-task Cancel a task
+ help List available commands
+ latest-build Print the latest rpms for a tag
+ latest-pkg Print the latest builds for a tag
+ ...
+ $ koji build --help
+ usage: koji build [options] tag URL
+ (Specify the --help global option for a list of other help options)
+
+ options:
+ -h, --help show this help message and exit
+ --skip-tag Do not attempt to tag package
+ --scratch Perform a scratch build
+ --nowait Don't wait on build
+ ...
+
+Getting Involved
+================
+
+If you would like to be more involved with the Koji project...
+
+Project data TBD
diff --git a/docs/source/conf.py b/docs/source/conf.py
new file mode 100644
index 00000000..c3945fd8
--- /dev/null
+++ b/docs/source/conf.py
@@ -0,0 +1,261 @@
+# -*- coding: utf-8 -*-
+#
+# Koji documentation build configuration file, created by
+# sphinx-quickstart on Tue Nov 3 12:11:18 2015.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.doctest',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Koji'
+copyright = u'2015, Mike McLean, Mike B, Dennis Gilmore, Mathieu Bridon, Ian McLeod, Ralph Bean, Adam Miller'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.10.0'
+# The full version, including alpha/beta/rc tags.
+release = '1.10.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# " v documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Kojidoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('index', 'Koji.tex', u'Koji Documentation',
+ u'Mike McLean, Mike B, Dennis Gilmore, Mathieu Bridon, Ian McLeod, Ralph Bean, Adam Miller', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'koji', u'Koji Documentation',
+ [u'Mike McLean, Mike B, Dennis Gilmore, Mathieu Bridon, Ian McLeod, Ralph Bean, Adam Miller'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'Koji', u'Koji Documentation',
+ u'Mike McLean, Mike B, Dennis Gilmore, Mathieu Bridon, Ian McLeod, Ralph Bean, Adam Miller', 'Koji', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
diff --git a/docs/source/defining_hub_policies.rst b/docs/source/defining_hub_policies.rst
new file mode 100644
index 00000000..0c35b1f3
--- /dev/null
+++ b/docs/source/defining_hub_policies.rst
@@ -0,0 +1,256 @@
+=====================
+Defining Hub Policies
+=====================
+
+Defining a policy on the hub allows you fine control over certain activities
+in the system. At present, policy allows you to control:
+* tag/untag/move operations
+* allowing builds from srpm
+* allowing builds from expired repos
+* managing the package list for a tag
+* managing which channel a task goes to
+
+In the future, we expect to add more policy hooks for controlling more aspects
+of the system.
+
+Policy configuration is optional. If you don't define one, then by default:
+* tag/untag/move operations are governed by tag locks/permissions
+* builds from srpm are only allowed for admins
+* builds from expired repos are only allowed for admins
+* only admins may modify package lists
+* tasks go to the default channel
+
+Configuration
+=============
+
+The hub policy is configured in the ``hub.conf`` file, which is an ini-style
+configuration file. Policies are defined in the section named ``[policy]``.
+Each ``name = value`` pair defines the policy of that name. With multiple line
+policies, successive lines should be indented so that the parser treats them
+as part of the whole.
+
+Consider the following simple (and strict) example:
+
+::
+
+ [policy]
+ tag =
+ has_perm admin :: allow
+ tag *-candidate :: allow
+ all :: deny
+
+This policy section defines a single policy (named 'tag'). The policy is a
+series of rules, one per line. The rule lines must be indented. Each rule is
+a test and an action, separated by a double colon. The valid actions for
+current policies are 'allow' and 'deny'. There are many tests available,
+though not all of them are applicable for all policies. Each test is specified
+by giving the name of the test followed by any arguments the test accepts.
+
+Each rule in the policy is checked until a match is found. Upon finding a
+match, the action is applied. Our example above limits non-admins to tags
+ending in -candidate.
+
+Getting a bit more complicated
+The example above is very simple. The policy syntax also supports compound
+tests, negated tests, and nested tests. Consider the following example:
+
+::
+
+ [policy]
+ tag =
+ buildtag *epel* :: {
+ tag *epel* !! deny
+ }
+ tag *-updates :: {
+ operation move :: {
+ fromtag *-updates-candidate :: allow
+ fromtag *-updates-testing :: allow
+ all :: deny
+ }
+ operation tag && hastag *-updates-candidate *-updates-testing :: deny
+ }
+ all :: allow
+
+This policy sets up some rules concerning tags ending in -updates and tags
+containing epel, but is otherwise permissive.
+
+The first nested rule limits builds built from a tag matching ``epel`` to only
+such tags. Note the use of !! instead of :: negates the test.
+
+For tags matching ``*-updates``, a particular work-flow is enforced. Moving is
+only allowed if the move is coming from a tag matching ``*-updates-candidate``
+or ``*-updates-testing``. Conversely, a basic tag operation (not a move) is
+denied if the build also has such a tag (the policy requires a move instead).
+
+General format
+==============
+The general form of a basic policy line is one of the following
+
+::
+
+ test [params] [&& test [params] ...] :: action-if-true
+ test [params] [&& test [params] ...] !! action-if-false
+
+And for nested rules:
+
+::
+
+ test [params] [&& ...] [::|!!] {
+ test [params] [&& ...] [::|!!] action
+ test [params] [&& ...] [::|!!] {
+ ...
+ }
+ }
+
+Note that each closing brace must be on a line by itself.
+Using ``!!`` instead of ``::`` negates the entire test.
+Tests can only be joined with &&, the syntax does not support ``||``.
+
+Available policies
+==================
+The system currently looks for the following policies
+
+* tag : checked during tag/untag/move operations
+* build_from_srpm : checked when a build from srpm (not an SCM reference) is
+ requested.
+* build_from_repo_id : checked when a build from a specified repo id is
+ requested
+* package_list : checked when the package list for a tag is modified
+* channel : consulted when a task is created
+
+These policies are set by assigning a rule set to the given name in the policy
+section.
+
+Note that the use of tag policies does not bypass tag locks or permissions
+
+Note that an admin can bypass the tag policy by using ``--force``.
+
+Actions
+=======
+
+Most of the policies are simply allow/deny policies. They have two possible
+actions: ``allow`` or ``deny``.
+
+The channel policy is used to determine the channel for a task. It supports
+the following actions:
+
+``use ``
+ * use the given channel
+
+``req``
+ * use the requested channel
+ * generally this means the default, though some calls allow the client to
+ request a channel
+
+``parent``
+ * use the parent's channel
+ * only valid for child tasks
+ * recommend using the ``is_child_task`` test to be sure
+
+Available tests
+===============
+``true``
+ * always true. no arguments
+
+``all``
+ * an alias of true
+
+``false``
+ * always false. no arguments
+
+``none``
+ * an alias of false
+
+``operation``
+ * for tag operations, the operation is one of: tag, untag, move. This test
+ checks its arguments against the name of the operation and returns true if
+ there is a match. Accepts glob patterns.
+ * only applicable to the tag policy
+
+``package``
+ * Matches its arguments against the package name. Accepts glob patterns.
+
+``tag``
+ * matches its arguments against the tag name. Accepts glob patterns.
+ * for move operations, the tag name tested is the destination tag (see
+ fromtag)
+ * for untag operations, the tag name is null and this test will always be
+ false (see fromtag)
+ * for the build_from_* policies, tests the destination tag for the build
+ (which will be null is --skip-tag is used)
+
+``fromtag``
+ * matches against the tag name that a build is leaving. Accepts glob
+ patterns
+ * for tag operations, the tag name is null and this test will always be
+ false
+ * for move operations, the tag name test is the one that the build is
+ moving from
+ * for untag operations, tests the tag the build is being removed from
+ * only applicable to the tag policy
+
+``hastag``
+ * checks the current tags for the build in question against the arguments.
+
+``buildtag``
+
+ * checks the build tag name against the arguments
+ * for the build_from_* policies the build tag is determined by the build
+ target requested
+ * for the tag policies, determines the build tag from the build data,
+ which will by null for imported builds
+
+``skip_tag``
+ * checks to see if the --skip-tag option was used
+ * only applicable to the build_from_* policies
+
+``imported``
+ * checks to see if the build in question was imported
+ * takes no arguments
+ * true if any of the component rpms in the build lacks buildroot data
+ * only applicable to the tag policy
+
+``is_build_owner``
+ * Check if requesting user owns the build (not the same as package
+ ownership)
+ * take no arguments
+
+``user_in_group``
+ * matches the users groups against the arguments
+ * true if user is in /any/ matching group
+
+``has_perm``
+ * matches the user's permissions against the arguments
+ * true is user has /any/ matching permission
+
+``source``
+ * test the build source against the arguments
+ * for the build_from_* policies, this is the source specified for the build
+ * for the tag policy, this comes from the task corresponding to the build
+ (and will be null for imported builds)
+
+``policy``
+ * takes a single argument, which is the name of another policy to check
+ * checks the named policy. true if the resulting action is one of: yes,
+ true, allow
+ * additional policies are defined in the [policy] section, just like the
+ others
+
+``is_new_package``
+ * true if the package being added is new to the system
+ * intended for use with the package_list policy
+
+``is_child_task``
+ * true if the task is a child task
+ * for use with the channel policy
+
+``method``
+ * matches the task method name agaist glob pattern(s)
+ * true if the method name matches any of the patterns
+ * for use with the channel policy
+
+``user``
+ * checks the username against glob patterns
+ * true if any pattern matches
+ * the user matched is the user performing the action
+
diff --git a/docs/source/external_repo_server_bootstrap.rst b/docs/source/external_repo_server_bootstrap.rst
new file mode 100644
index 00000000..488f8ed8
--- /dev/null
+++ b/docs/source/external_repo_server_bootstrap.rst
@@ -0,0 +1,136 @@
+====================================
+External Repository Server Bootstrap
+====================================
+
+Bootstrapping a new External Repo Koji build environment
+========================================================
+
+These are the steps involved in pointing a new Koji server at external
+repositories so that it can be used for building. This assumes that the Koji
+hub is up, appropriate authentication methods have been configured, the Koji
+repo administration daemon (``kojira``) is properly configured and running,
+and at least one Koji builder (``kojid``) is properly configured and running.
+All koji cli commands assume that the user is a Koji ``admin``. If you need
+help with these tasks, see the :doc:`ServerHowTo `.
+
+* Create a new tag. ::
+
+ $ koji add-tag dist-foo
+
+* Create a build tag with the desired arches, and the previously created tag
+ as a parent. ::
+
+ $ koji add-tag --parent dist-foo --arches "i386 x86_64 ppc ppc64" dist-foo-build
+
+* Add an external repository to your build tag. Koji substitutes $arch for the
+ arches in your build tag. The ``$`` needs to be escaped for the shell to send
+ it though without interpreting it. See below for some additional examples of
+ external repo URLs. ::
+
+ $ koji add-external-repo -t dist-foo-build dist-foo-external-repo http://repo-server.example.com/path/to/repo/for/foo/\$arch/
+
+.. note::
+ If you are adding multiple external repos, koji assigns a priority to each
+ repo in FIFO order. This may cause updated packages to not be visible if a
+ repo with older packages is ranked at a higher priority (lower numeric
+ value). Use the ``-p`` flag to set specific repo priorities.
+
+.. note::
+ This uses $arch NOT $basearch
+
+* Create a build target that includes the tags you've already created. ::
+
+ $ koji add-target dist-foo dist-foo-build
+
+* Create a ''build'' and ''srpm-build'' group associated with your build tag. ::
+
+ $ koji add-group dist-foo-build build
+ $ koji add-group dist-foo-build srpm-build
+
+* Populate the ``build`` and ``srpm-build`` group with packages that will be
+ installed into the minimal buildroot. You can find out what the is in the
+ current groups for Fedora by running ``koji list-groups dist-f9-build``
+ against the Fedora Koji instance. This is probably a good starting point for
+ your minimal buildroot and srpm creation buildroot. If you are rebuilding
+ Fedora packages, it is recommended that you add all packages listed in the
+ Fedora Koji instance. ::
+
+ $ koji add-group-pkg dist-foo-build build .....
+
+* Add packages that you intend to build to your tag. ::
+
+ $ koji add-pkg --owner dist-foo .....
+
+* Wait for the repo to regenerate, and you should now be able to run a build
+ successfully.
+
+Regenerating your repo
+======================
+
+koji doesn't monitor external repositories for changes. new repositories
+will be generated when packages you build land in a tag that populates
+the buildroot or you manually regenerate the repository. you should be
+sure to regularly regenerate the repositories manually to pick up
+updates.
+
+::
+
+ $ koji regen-repo dist-foo-build
+
+Examples of urls to use for external Repositories
+=================================================
+
+all these examples use mirrors.kernel.org please find the closest mirror
+to yourself. Note that the Fedora minimal buildroots download ~100Mb
+then build dependencies on top. these are downloaded each build you can
+save alot of network bandwidth by using a local mirror or running
+through a caching proxy.
+
+NOTE: this uses $arch **NOT** $basearch
+
+Fedora 10
+---------
+
+::
+
+ http://mirrors.kernel.org/fedora/releases/10/Everything/\$arch/os/
+ http://mirrors.kernel.org/fedora/updates/10/\$arch/
+
+CentOS 5 and EPEL
+-----------------
+
+::
+
+ http://mirrors.kernel.org/centos/5/os/\$arch/
+ http://mirrors.kernel.org/centos/5/updates/\$arch/
+ http://mirrors.kernel.org/fedora-epel/5/\$arch/
+
+Example tags and targets
+========================
+
+In the simplest setup, where you just want to build against what is
+available in the external repositories, you may want to go with a simple
+layout of *dist-f\ **X**-build* tags inheriting one another, and
+*dist-f\ **X**-updates* tags and targets that inherit the
+*dist-f\ **X**-build* tag and have external repos attached to them. This
+way, a *dist-f\ **Y**-build* or *dist-f\ **Y**-updates* tag will not
+automatically inherit the external repos of your *dist-f\ **X*** tags.
+
+Tags
+----
+
+::
+
+ dist-f10-updates - This is where the external repos for f10 release and f10 updates are attached
+ `- dist-f10-build - This is the f10 build target with the 'build' and 'srpm-build' group inherited from dist-f9-build,
+ | so that your buildroot gets populated but you do not have to maintain these groups for each
+ | seperate release.
+ `- dist-f9-build - etc.
+ `- dist-f8-build - etc.
+
+Targets
+-------
+
+Each *dist-f\ **X**-build* tag has a *dist-f\ **X**-updates* child tag,
+and each *dist-f\ **X**-updates* tag has a corresponding
+*dist-f\ **X**-updates-candidate* build target.
diff --git a/docs/source/image_build.rst b/docs/source/image_build.rst
new file mode 100644
index 00000000..0debe9f1
--- /dev/null
+++ b/docs/source/image_build.rst
@@ -0,0 +1,943 @@
+=======================
+Building Images in Koji
+=======================
+
+Image Building
+==============
+
+Koji is capable of building many different types of images or appliances. They
+broadly fall into a few categories: LiveCDs, Disk Images, and Containers. All
+types of images end up with a Name-Version-Release just like an RPM build.
+What you need to provide Koji to perform a build varies by category, and the
+specifics will be explained below.
+
+For additional questions and information, ask around in ``#koji`` on FreeNode
+IRC and sign up to the right mailing lists as the `Koji project website`_
+dictates.
+
+Kickstart First
+===============
+
+No matter which type of image you want to build, you need to feed Koji a
+`kickstart`_ file, so we touch on how to create them and how to get them to Koji
+first. Once you have a kickstart to try out, look over the kickstart-specific
+caveats for each image type in the later sections.
+
+Kickstart Reference
+-------------------
+
+If you're new to automated installations, you should read the `Anaconda
+Kickstart Guide`_ first.
+
+Getting your Kickstart to Koji
+------------------------------
+
+For scratch builds, you can get away with just using the ``--kickstart``
+parameter, which accepts a path (relative or absolute) to your kickstart file
+on disk. For non-scratch builds though, the kickstart file needs to live in a
+remote Source Control Manager (SCM) such as git or Subversion. To access that,
+you need to pass the ``--ksurl`` parameter, which accepts a wacky string in
+this form:
+
+::
+
+ git://git.fedorahosted.org/git/spin-kickstarts.git?fedora22#68c40eb7
+
+Here we pointed to a repository hosted at
+``git://git.fedorahosted.org/git/spin-kickstarts.git``. Note the ``?`` in
+there, this delimiter separates the host URL with a directory structure to
+look in for the kickstart file. In other words, if you were to clone the
+repository, you should expect to see these (sub)directories laid out below the
+root of the clone. The important thing to realize is the behavior of
+``--kickstart`` changes if ``--ksurl`` is specified. Instead of indicating a
+path to a kickstart file, you just indicate a filename. The file itself is not
+specified in the fragment of the string between ``?`` and ``#`` that is passed
+to ``--ksurl``, Koji still uses the ``--kickstart`` option for that. After the
+directory structure comes a ``#``, which indicates the start of the commit ID.
+This is the commit Koji will reset the repository to after cloning. If you
+created a git repository which had just the spec file template in it, your SCM
+URL would have the ``?`` and ``#`` right next to each other.
+
+If we passed ``--ksurl`` the string above, and gave
+``--kickstart "server-ec2.ks"``, then Koji would do the following:
+
+* Clone the repository locally
+* Call ``git reset --hard 68c40eb7``
+* Search in the "fedora22" subdirectory of the clone for a file called
+ ``server-ec2.ks``, and pass that to Anaconda
+* Perform an automated install
+
+.. _building-livecds:
+
+Building LiveCDs
+================
+
+Let's describe building LiveCDs and the mechanics behind it.
+
+Getting Started
+---------------
+
+What you need before proceeding:
+
+* a name for your LiveCD, and a version number
+* a Koji build target
+* what architectures you want
+* a flattened kickstart file
+* you may also need yum repositories generated by release engineering if you
+ require signed packages be installed into the LiveCD
+* the livecd permission in Koji
+
+The Koji command that creates a LiveCD is called ``spin-livecd``. It calls out
+to `livecd-tools`_ in a mock chroot to construct the LiveCD. To run a LiveCD
+build, use the spin-livecd command like so:
+
+::
+
+$ koji spin-livecd --release 4 fedora-workstation 23 f23-image-build fedora-workstation.ks
+
+In this example a LiveCD will be created with the N-V-R of
+fedora-workstation-23-4. If ``--release`` was not included an incrementing
+value would be computed by Koji instead. spin-livecd takes a minimum of 5
+arguments:
+
+Name
+ the name of the image, without versioning information. Examples could be
+ ``fedora`` or ``fedora-workstation``.
+
+Version
+ an arbitrary version string. For Fedora images, this usually matches the
+ release version, such as 21, 22, or 23.
+
+Build Target
+ just like RPM builds Koji must be told which target to use. This controls
+ what tag the image will be tagged into, and what packages are available to
+ install into the image.
+
+Architecture
+ only x86_64 or i386 is supported
+
+Kickstart File
+ this is a recipe file that performs drives the construction of the image.
+
+Use ``--help`` to discover more options to ``spin-livecd``. You can override
+the Release field with ``--release``, or ``--repo`` to override what yum repo
+is used to provide packages to install to the image. Note that regardless of
+what repo you use, it must contain RPMs built by Koji, otherwise you will get
+an error. (unless you are building a scratch image)
+
+Mechanics
+---------
+
+The way LiveCDs are created in Koji is fairly straightforward. A chroot is
+initialized and populated with the packages and their dependencies from the
+``livecd-build`` package group. Next, the kickstart file is copied into it if
+it was provided from local storage. If not, it is checked out into it from an
+SCM. It is then modified to use the repo associated with the build tag for the
+target specified in the command unless the ``--repo`` option was given. Both
+the original and the modified kickstart files are saved as part of the output
+for the task for later review. A `livecd-creator`_ command is executed using the
+mock('--chroot', ...) method.
+
+.. note::
+ This process runs as root. This produces the desired image which is
+ uploaded to /mnt/koji/images//$imageID if it is not a scratch image.
+
+.. _caveats-for-livecds:
+
+Caveats for LiveCDs
+-------------------
+
+There are some known caveats with using the spin-livecd command that users
+should be aware of.
+
+%include macros in the kickstart
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A word of caution about kickstart files and the ``%include`` macro.
+`livecd-creator`_ is smart enough to search the current directory of the
+submitted kickstart file if it has %include macros. If the kickstart specified
+to koji is from local storage, only that kickstart file will be copied into
+the chroot, and this creates a problem if it has ``%include`` macros, because
+the other kickstart files it needs will be inaccessible. This issue is not
+present when the kickstart file is retrieved from a remote SCM (such as the
+spin-kickstarts git repo), because the entire repository is checked out.
+Presumably it will include any other kickstart files the specified one is
+including in the same directory. A workaround for the issue would be to use
+``ksflatten`` (from pykickstart) on kickstart files with ``%include`` macros
+that are going to be submitted to koji from the user's local disk.
+
+Package Groups in the Kickstart File
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Package Groups in the kickstart file cause a problem if the Koji repos do not
+define them, which they most likely don't since Koji's comps.xml is based on
+the "groups" set up from the CLI. `livecd-creator`_'s behavior is to ignore
+package groups that are not defined in the repo it is using, so this can be
+troublesome when creating the image since packages could be left out. There
+are a couple possible workarounds:
+
+* do not use package groups in the kickstart file and just specify a huge list
+ of packages
+* use ``--repo`` and specify a repo that does have a comps.xml that defines
+ the groups it uses
+
+Only Include RPMs Built in Koji
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The image building tasks will fail if your image tries to include a package
+that was not built in your build system. This is because the package does not
+have any origin information stored in Koji's database. The repos defined in the
+kickstart will automatically be overridden with the repo of the build tag for
+the build target, unless you use the ``--repo`` option. Since only packages
+you have built (or include from an external repo) should be there, you should
+never have this problem unless you use ``--repo``.
+
+No Signed or Debuginfo RPMs in Koji's Build Tags
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you need signed RPMs or debuginfo RPMs, you will run into trouble because
+Koji does not keep those in its build tag repos. The only work around for this
+is to create a repo yourself that includes these RPMs and then use ``--repo``.
+This will force the image to take RPMs from that repo. Remember, the task will
+fail if Koji detects RPMs were installed that were not built in the build
+system.
+
+%post Section in Kickstart
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+While livecd-tools does support building on SELinux disabled hosts, you can run
+into denials when booting if you create and use new files in the ``%post``
+section of your kickstart file. If you do, you should either set the labels
+appropriately at the end of the ``%post`` section, or instigate an autorelabel
+at boot time.
+
+Troubleshooting
+---------------
+
+If your build fails, you will be notified on the command line. In the output
+will be a URL to the Koji UI, visit that and click on the red subtask link.
+From that page review ``root.log`` and ``livecd.log`` for errors. Often errors
+are caused by packages being missing, or malformed kickstart files. The log
+files are at the bottom of the page. If you're stuck, contact Release
+Engineering.
+
+Build System Preparation
+------------------------
+
+This section assumes you have know-how required to install and configure a new
+instance of Koji, and that you have already done so. You can learn how to do so
+:doc:`here ` if you need to. Please ensure you are using the
+latest version of the software and that your database schema is updated as
+well. You should also have some familiarity with how `livecd-creator`_ works.
+This section only covers preparation for LiveCD builds.
+
+Follow this procedure step by step to get things prepared they way they need to
+be.
+
+#. ``koji add-host-to-channel livecd``
+ add a builder to the livecd channel
+#. ``koji grant-permission livecd ``
+ grant the permission to build an image type to a user. This step is
+ optional since admins have all permissions.
+#. You will need a tag and target to build the images from. The yum repo
+ generated for the build tag of the target is what Koji will use to populate
+ the LiveCDs with by default. (the alternative is to use the ``--repo``
+ option, more on that later)
+#. ``koji add-group livecd-build``
+ add the livecd-build group
+#. ``koji add-group-pkg livecd-build ...``
+ add packages to the livecd-build group. These package lists vary has
+ packages and dependencies change. As of October, 2015 for Fedora 23 the
+ needed packages for each image type are:
+
+ * bash, coreutils, fedora-logos, fedora-release, livecd-tools,
+ policycoreutils, python-dbus, sed, selinux-policy-targeted,
+ shadow-utils, squashfs-tools, sssd-client, tar, unzip, util-linux,
+ which, yum
+
+
+Building Disk Images
+====================
+
+Disk images are files that represent virtual disks. They have a partition table
+and filesystems on them, and are available in a variety of formats: qcow2,
+vmdk, ova, Hyper-V, raw, "base" container images, and more.
+
+Getting Started
+---------------
+
+What you need:
+
+* a name for your LiveCD, and a version number
+* what architectures you want
+* a Koji build target
+* kickstart file
+* installation tree
+* you may also need yum repositories generated by Rel-Eng if you require signed
+ packages be installed into the image
+
+The Koji command to build a disk image is called ``image-build``. The
+``image-build`` command uses `ImageFactory`_ and `Oz`_ to start a VM guest and
+perform an automated Anaconda installation. Here is a (lengthy) example for
+building a disk image.
+
+::
+
+ $ koji image-build --repo 'http://alt.fedoraproject.org/pub/alt/releases/22/Cloud/$arch/os/' --kickstart fedora-server.ks --scratch --distro Fedora-22 --format qcow2 fedora-server-kvm 22 'http://alt.fedoraproject.org/pub/alt/releases/22/Cloud/$arch/os/' x86_64
+
+This example builds a scratch qcow2 disk image using packages from an
+additional yum repository. Without this option the yum repo to populate the
+build root would be used instead. If this was the first image with the N-V of
+fedora-server-kvm-22, then the N-V-R would be fedora-server-kvm-22-1, because
+Koji uses an incrementing number for the release if you do not provide one.
+Like all Koji commands, use ``--help`` to see more options that are available.
+
+For Docker, Koji only supports Base Images right now using a kickstart file as
+described above. In the future it will support layered images, but not before
+some Docker requirements are met, and Koji is maintaining a Registry of its
+own. This scoping effort is ongoing.
+
+``image-build`` takes a minimum of 5 positional arguments, and 2 options must
+be specified. They are reviewed in the list below, with the positional
+arguments first.
+
+Name
+ the name of the image, without versioning information. Examples could be
+ ``fedora-server`` or ``fedora-workstation``.
+
+Version
+ an arbitrary version string. For Fedora images, this usually matches the
+ release version, such as 22 or 23.
+
+Build Target
+ just like RPM builds Koji must be told which target to use. This controls
+ what tag the image will be tagged into, and what packages are available to
+ install into the image.
+
+Installation Tree URL
+ this is a URL to a location you can install an operating system from. It is
+ the same place you would direct a PXE-booted system to go. In 99% of cases
+ this location is provided by Release Engineering. It should have an
+ "isolinux" subdirectory and yum metadata somewhere within.
+
+Architecture
+ only x86_64 or i386 is supported, and you can specify both on the command
+ line. This will cause two subtasks to be run, allowing you to build for
+ both arches in parallel. If either fail, the whole build will fail.
+
+Kickstart File
+ this is a recipe file that performs drives the construction of the image.
+ Pass in the path to a kickstart file, which must be flattened.
+
+Kickstart URL
+ in a non-scratch build, you'll need this too. For more details, see the
+ Getting your Kickstart to Koji section.
+
+Distro
+ a string that indicates what OS is being built. These always follow the
+ convention of "Fedora-X", where X is the release number.
+
+Since this command can get very long, a configuration file can drive the task
+as well, using the ``--config`` option. It accepts a path to a configuration
+file written in the Python ConfigParser format (like a Windows .ini). The
+options are all named the same with one caveat, see below. Here's what one
+could look like:
+
+::
+
+ [image-build]
+ name = fedora-server-docker
+ version = 22
+ target = f22-candidate
+ install_tree = http://alt.fedoraproject.org/pub/alt/releases/22/Cloud/$arch/os/
+ arches = x86_64
+
+ format = qcow2,rhevm-ova,vsphere-ova
+ distro = Fedora-22
+ repo = http://alt.fedoraproject.org/pub/alt/releases/22/Cloud/$arch/os/
+ disk_size = 20
+
+ ksversion = DEVEL
+ kickstart = fedora-22-server-docker.ks
+ ksurl = git://git.fedorahosted.org/git/spin-kickstarts.git?fedora22#68c40eb7
+ specfile = git://git.fedorahosted.org/git/spin-kickstarts.git?spec_templates/fedora22#68c40eb7
+
+A few notes on the syntax:
+
+* it allows for comments too, the lines start with a hash (#)
+* options on the command line that can be used multiple times can accept
+ values here as comma-separated strings
+* options with a hyphen need to use an underscore instead. ``--disk-size`` for
+ example would be disk_size in the config file
+
+OVA Features
+------------
+
+If you're building OVAs, either for RHEVM or vSphere, you can specify OVA
+options with a special section in the configuration file. It looks something
+like this:
+
+::
+
+ [ova-options]
+ vsphere_product_version=22
+ rhevm_description=Fedora Cloud 22
+ vsphere_product_vendor_name=Fedora Project
+ ovf_memory_mb=6144
+ rhevm_default_display_type=1
+ vsphere_product_name=Fedora Cloud 22
+ ovf_cpu_count=4
+ rhevm_os_descriptor=Fedora-22
+
+or this:
+
+::
+
+ [ova-options]
+ vsphere_ova_format = vagrant-virtualbox
+ rhevm_ova_format = vagrant-libvirt
+ vagrant_sync_directory = /home/vagrant/sync
+
+The second one is actually the secret sauce for generating an image for use in
+Vagrant. At this time, you would need rename the image file extension from .ova
+to .box, but otherwise this should work fine.
+
+Kickstart Preparation
+---------------------
+
+Kickstarts for the image-build command have some specific requirements which
+are covered in this section.
+
+Required Kickstart Arguments
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Anaconda of course requires many commands to be defined in the kickstart file.
+If you're starting from scratch you should review the reference linked above,
+or use an existing kickstart file in the spin-kickstarts git repo. It is
+critically important that the installation be completely automated, if
+Anaconda has to prompt for input for any reason, the build will fail because
+you cannot send input to the guest. Some of the kickstart commands are optional
+to Anaconda, but are required in Koji for your build to succeed. Here's the
+list and the reasons why.
+
+zerombr
+ You must tell Anaconda to wipe out the MBR in the virtual block device, if
+ you don't Anaconda will ask you.
+
+clearpart --all --initlabel
+ Anaconda has to be told to wipe out all data on the virtual block device we
+ install on otherwise it will ask for confirmation to do so. Since it is
+ blank anyway this is harmless.
+
+reboot
+ When the installation completes, the guest is rebooted. `ImageFactory`_ is
+ specifically looking for this behavior to conclude the installation
+ completed. Anaconda's default behavior is to wait for a key press to reboot
+ the system, but this is impossible from outside of Koji.
+
+locking the root account
+ You have to lock the root account (rootpw --lock) or create a non-root user
+ (user), otherwise Anaconda will prompt for one.
+
+Do not use the url command
+ The repo commands are overridden by Koji to point to internal Koji repos,
+ or what you specified on the command line with ``--repo``, it does not
+ override the url command if you provided it. Anaconda has a behavior where
+ it will prefer packages from the repositories given with the url command
+ over those with the repo command, and this is generally not what you want.
+ If Koji sees an RPM was installed that was not built in the system, it will
+ fail the build.
+
+Recommended Kickstart Arguments
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Often you want a ``%post`` section in your kickstart to perform
+post-installation configuration steps. Review that section of the reference
+and note that you can specify ``--log`` and ``--interpreter``. Both of these
+are recommended (but not required) to assist with the development and debugging
+process. Here are some other recommendations:
+
+* You probably want the network to use dhcp, sshd to be started, and port 22
+ opened in the firewall to allow access as well.
+* If you're building an image that will be shipped with a product, SELinux
+ should be enabled.
+* Images that will be used in cloud deployments like OpenStack or EC2 should
+ have ``cloud-init`` in the package list.
+* It is discouraged to have root passwords in plaintext in your kickstart file.
+* If your %post section is written in bash, consider setting -x.
+* For images that have multiple partitions, use the ``--asprimary`` option for
+ the part command that defines the root file system. This will ensure it is
+ the first partition on the image, which is a requirement in some cloud
+ environments like EC2.
+
+Troubleshooting
+---------------
+
+If your disk image build fails, follow the link in the command line output
+that takes you to the task page in the Koji web UI. Click on the failed
+createImage subtask in red. On that page review the screenshot.ppm file if it
+was provided, or oz.log. Most failures are from Anaconda rejecting a malformed
+kickstart file, which will be indicated in the screenshot. Your installation
+must be completely automatic, there can be no interactivity at all, otherwise
+Anaconda will sit there indefinitely until Koji (actually ImageFactory) kills
+the task.
+
+It is very easy to write a kickstart file with bugs or that results in a system
+that does not boot. This section will present a series of questions to ask
+yourself and examples to help diagnose where the problem lies. Once you know
+that, it should be easier to understand what you can do to inspect further.
+
+There are 4 steps in the process:
+
+#. create a guest
+#. perform an automated installation in the guest
+#. boot the guest and extract the list of installed RPMs
+#. upload and archive the disk image of the guest
+
+Is it a problem with guest creation?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There have been unusual cases where libvirt, ImageFactory, or Oz was
+misconfigured and guests could not be started properly. A misconfiguration with
+Puppet or whatever Fedora Infrastructure is up to can cause this. So far the
+errors have been clear in the task output, look either in the results string
+or oz.log. The bad news is that in this case you really can only inform Rel-Eng
+about the issue and wait for a resolution. The good news is these cases are
+very rare.
+
+Did the installation fail?
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The Anaconda installation can fail for many reasons: missing packages, network
+problems, or syntax errors in %post. Tasks will also fail if Anaconda prompts
+for input for any reason. If Koji detects a lack of disk activity in the guest
+for more than 5 minutes, it will fail the build and tear down the guest.
+Looking in oz.log may have the answer: dracut, anaconda, and yum logs are all
+printed there.
+
+These sorts of failures often have a screenshot taken and saved with the task
+output called screenshot.ppm. Viewing this will usually tell you what Anaconda
+is complaining about if the installer detected an issue or prompted for input.
+The string in the results output that says "No disk activity in 300 seconds,
+failing." This almost always means Anaconda hit an issue and either gave up or
+waited.
+
+If Anaconda claims it is missing packages, confirm they exist in the repos you
+are using with ``--repo``, if you are using that option. If you are not,
+confirm the builds you expect are in the tag inheritance for the target you are
+running. This is a lot like checking whether an RPM will build against the
+right libraries, except we're building an image instead.
+
+If you get the rare Anaconda dialog box that says something like "An unexpected
+error occurred", try using the ``text`` command in kickstart, which will have
+Anaconda boot in text mode. Sometimes the Python traceback (or whatever the
+error condition is) will be printed there. I have also seen cases where
+text-mode yields a black screen, but booting in graphical mode (the default)
+does produce a useful dialog box. Issues like this stem from syntax errors in
+the kickstart file, or bugs in pykickstart itself. If you think it is a
+pykickstart bug, then someone in Rel-Eng needs to update pykickstart on the
+builders.
+
+Did the guest boot?
+^^^^^^^^^^^^^^^^^^^
+
+Koji waits 5 minutes for a guest to boot in this step. It unfortunately does
+not give a lot of insight to why a guest may not boot, so these are a tougher
+class of issues to work through. You can usually answer this question by
+looking in results string. If you see "Timed out waiting for guest to boot",
+then this is your problem. You can also confirm this in oz.log.
+
+For now, the best way to investigate an issue like this is to drive a guest
+installation locally using something like Gnome's Virtual Machine Manager
+(VMM). The steps to perform are:
+
+* Select a Network Install
+* For the Operating System Install URL use the same one you gave to Koji. It
+ will be something like
+ http://alt.fedoraproject.org/pub/alt/releases/22/Cloud/x86_64/os/
+* Set the Kickstart URL to where your kickstart file is. You may need to make
+ it available over http.
+* Bump the memory to 2048M for good measure
+* Launch the guest and let it complete installation
+* Open a VNC session and watch what happens when the guest attempts to boot.
+
+If the console is not providing enough information, we have to get more
+creative. Anaconda supports starting an SSH daemon while the installation is
+happening with the sshpw command in kickstart. Set that and comment out the
+reboot command. This will let the installation complete locally and wait for a
+keystroke to reboot the guest. At this point you should be able to ssh in and
+inspect the environment to figure out what is going on. You should also
+consider making use of the ``--log`` option to %post so that output from the
+script is saved somewhere.
+
+Another option would be to scp logs and other files off of the guest as part of
+the ``%post`` script.
+
+Other Guest Misconfigurations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If the guest boots but you're having problems accessing it I'd suggest
+following same procedure as when the guest fails to boot. This could be a
+result of firewall misconfigurations or SSH not being available for some
+reason. Usually in this case the build is succeeding in Koji, but there's
+something still fundamentally broken in the image. If the issue is something
+you can investigate while the guest is online (you can log in), then I'd
+suggest importing it locally using the libvirt.xml and the disk image provided
+in Koji's task output.
+
+You can also do investigative work in an offline mode by mounting the image
+locally or using something like libguestfs to poke around without starting the
+guest. The fast, dirty way to do it is by mounting it. This can often pollute
+your guest environment. Here's how to do it:
+
+* Download the image from Koji
+* If the image format is not raw, you have to convert it first with qemu-img.
+ Something like:
+ ::
+
+ $ qemu-img convert -O raw
+
+* Now mount it up using loopback devices. (as root) If your image has multiple
+ partitions in it, you may need to pass in a different mapped loopback device
+ like ``loop0p2``. Whichever one you think is the root partition or has the
+ issue you're trying to fix.
+ ::
+
+ # kpartx -av
+ # mount -o loop /dev/mapper/loop0p1 /mnt/my_directory
+
+Hopefully at this point you figure out the issue. To tear down the image you'll
+run commands as root like so:
+
+::
+
+ # umount /mnt/my_directory
+ # dmsetup remove loop0p1
+ # losetup -d /dev/loop0
+
+Again, if you used different loopback devices, substitute those in to the
+dmsetup and losetup commands.
+
+Build System Preparation
+------------------------
+
+Follow this guide if you're a Koji admin and would like to enable image
+building or want to set up some testing before enabling the integration.
+
+When moving to ImageFactory to do image builds Koji lost the ability to easily
+reproduce the build environment for images the way we do for RPMs using Mock.
+This section will document how to set up an image builder for Koji. This is a
+lengthy task, it will take first-timers about a week to have a useful instance,
+and it is painful because it requires a bare metal system be provisioned since
+`ImageFactory`_ provisions VMs to build the image. There is a significant
+performance penalty for using nested virtualization.
+
+Follow the steps below to set up your builder.
+
+.. note::
+ You do not have to stand up a complete Koji instance to test the way Koji
+ builds images. However, if you want to test image builds with an accurate
+ representation of how Koji does it, or you want to test code changes
+ related to image builds in Koji, you should follow all the steps below.
+
+ImageFactory/Oz Preparation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+#. Provision a system with at least 4G of memory with the current release of
+ RHEL 6 or later. Sometimes builders lag behind a month or two before taking
+ in updates, but this will still get you pretty close to where you want to
+ be. For Fedora, use the latest release.
+#. Install the following packages to the builder.
+ #. oz
+ #. imagefactory
+ #. imagefactory-plugins-TinMan
+ #. imagefactory-plugins-vSphere
+ #. imagefactory-plugins-ovfcommon
+ #. imagefactory-plugins-docker
+ #. imagefactory-plugins
+ #. imagefactory-plugins-OVA
+ #. imagefactory-plugins-RHEVM
+ #. python-psphere => 0.5
+ #. VMDKStream => 0.2
+ #. pykickstart
+#. Edit ``/etc/oz/oz.cfg``, and set the memory value in the ``[libvirt]``
+ section to at least 2048. Set ``safe_generation`` under ``[icicle]`` to yes.
+#. Run: ``mkdir -p ~root/.psphere/templates``, and then copy the following
+ code into ``~root/.psphere/config.yaml``. Do not worry about the server,
+ username, and password credentials; they are not used anywhere.
+
+ ::
+
+ general:
+ server: 10.16.120.224
+ username: Administrator
+ password: whatever
+ template_dir: ~/.psphere/templates/
+ logging:
+ destination: ~/.psphere/psphere.log
+ level: DEBUG # DEBUG, INFO, etc
+
+Start up the services and ImageFactory/Oz should be ready to go. You should
+read more about `how to use Oz`_ and `how to use ImageFactory`_. If you want
+to try calling `ImageFactory`_ as if from a Koji Builder (but not set up a
+whole Koji instance), you can use the code below to emulate that. If you want
+to test the Koji integration with a full Koji instance, proceed to the next
+section instead.
+
+::
+
+ #!/usr/bin/python -tt
+
+ import logging
+ import os.path
+ import random
+ import sys
+
+ from imgfac.BuildDispatcher import BuildDispatcher
+ from imgfac.PluginManager import PluginManager
+ from imgfac.ReservationManager import ReservationManager
+ plugin_mgr = PluginManager('/etc/imagefactory/plugins.d')
+ plugin_mgr.load()
+ from imgfac.ApplicationConfiguration import ApplicationConfiguration
+
+ # logging
+ handler = logging.StreamHandler(sys.stdout)
+ tlog = logging.getLogger()
+ tlog.setLevel(logging.DEBUG)
+ tlog.addHandler(handler)
+
+ # configuration
+ ks = open('oztest.ks').read()
+ workdir = '/tmp/koji/test'
+ config = {
+ #Oz specific
+ 'oz_data_dir': os.path.join(workdir, 'oz_data'),
+ 'oz_screenshot_dir': os.path.join(workdir, 'oz_screenshots'),
+ #IF specific
+ 'imgdir': os.path.join(workdir, 'scratch_images'),
+ 'tmpdir': os.path.join(workdir, 'oz-tmp'),
+ 'verbose' : True,
+ 'timeout': 3600,
+ 'output': 'log',
+ 'raw': False,
+ 'debug': True,
+ 'image_manager': 'file',
+ 'plugins': '/etc/imagefactory/plugins.d',
+ 'tdl_require_root_pw': False,
+ 'image_manager_args': {
+ 'storage_path': os.path.join(workdir, 'output_image')},
+ }
+ random.seed() # necessary to ensure a unique mac address
+ rm = ReservationManager()
+ rm._listen_port = random.randint(rm.MIN_PORT, rm.MAX_PORT)
+ ApplicationConfiguration(configuration=config)
+ params = {'install_script': ks}
+ template = """
+ test-appliance
+
+ Fedora
+ 22
+ x86_64
+
+ http://alt.fedoraproject.org/pub/alt/releases/22/Cloud/x86_64/os/
+
+
+ rpm -qa --qf '%{NAME},%{VERSION},%{RELEASE},%{ARCH},%{EPOCH},%{SIZE},%{SIGMD5},%{BUILDTIME}\n'
+
+
+ test-appliance OS
+
+ 16G
+
+
+ """
+ bd = BuildDispatcher()
+
+ # build the image
+ base = bd.builder_for_base_image(template, parameters=params)
+ base.base_thread.join()
+ tlog.removeHandler(handler)
+
+This script is run as root with no arguments. It uses ``oztest.ks`` in your
+local directory as the kickstart you want to try to use. The URL in the XML
+template is where the RPM packages will be installed from, and what the guest
+will be booted with.
+
+Koji Preparation
+^^^^^^^^^^^^^^^^
+
+#. :doc:`Install Koji ` if you need it. This will easily be the
+ most time-consuming part of the process; my first time took 3 days to get
+ it working properly. Follow the guide closely, and go with the SSL
+ authentication method. SSL is a lot easier to set up locally. You will need
+ to install every Koji component (except koji-vmd) on the same system.
+ Proceed to the next step after you've had a successful Kojira repository
+ generated.
+#. At this point, you have a system that should be ready to build images. We
+ just have to do some Koji configuration so that your instance is pulling
+ content from Koji. Replace the base tag names with whatever fits your
+ conventions.
+
+ #. Add tags, tag inheritance, new pkg (with pkg owner), new external repo, and regen the repo
+
+ ::
+
+ koji add-tag fedora22
+ koji add-tag jay-fedora22
+ koji add-tag jay-fedora22-override --parent jay-1-fedora22
+ koji add-tag jay-fedora22-build --arches x86_64 --parent jay-fedora22-override
+ koji add-tag jay-fedora22-candidate --parent jay-fedora22
+ koji add-tag-inheritance --priority 40 jay-fedora22-build fedora22
+ koji add-pkg --owner kojiadmin jay-fedora22 fedora-server-ec2 fedora-server-kvm
+ koji add-external-repo -t fedora::20 fedora22 'http://alt.fedoraproject.org/pub/alt/releases/22/Cloud/$arch/os/'
+ koji add-target jay-fedora22-candidate jay-fedora22-build
+ koji regen-repo jay-fedora22-build
+ #. Grab a kickstart file from an image task in Koji that relates to what you want to test.
+ #. Finally, kick off a build!
+
+ ::
+
+ koji image-build fedora-server-ec2 22 --distro Fedora-22 jay-fedora22-candidate --kickstart fedora-server-starter-ec2.ks 'http://alt.fedoraproject.org/pub/alt/releases/22/Cloud/$arch/os/'
+
+
+Building Appliances
+===================
+
+This section is here for the sake of legacy. Unless you are trying to build
+ARM images, you should use the image-build command described in the previous
+section.
+
+.. note::
+ The spin-appliance command, described herein, is deprecated.
+
+Getting Started
+---------------
+
+Here's what you need before proceeding:
+
+* a name for your Appliance, and a version number
+* a Koji build target
+* what architectures you want
+* a flattened kickstart file
+* you may also need yum repositories generated by release engineering if you
+ require signed packages be installed into the appliance
+* the appliance permission in Koji
+
+The Koji command that creates an Appliance is called ``spin-appliance``. It
+calls out to appliance-creator in a mock chroot to construct the Appliance.
+To run an Appliance build, use the spin-appliance command like so:
+
+::
+
+ $ koji spin-appliance --release 4 fedora-workstation 23 f23-build fedora-workstation.ks
+
+In this example an Appliance will be created with the N-V-R of
+``fedora-workstation-23-4``. If ``--release`` was not included an incrementing
+value would be computed by Koji instead. spin-appliance takes a minimum of 5
+arguments:
+
+Name
+ the name of the image, without versioning information. Examples could be
+ ``fedora`` or ``fedora-workstation``.
+
+Version
+ an arbitrary version string. For Fedora images, this usually matches the
+ release version, such as 21, 22, or 23.
+
+Build Target
+ just like RPM builds Koji must be told which target to use. This controls
+ what tag the image will be tagged into, and what packages are available to
+ install into the image.
+
+Architecture
+ only arm, x86_64, or i386 are supported
+
+Kickstart File
+ this is a recipe file that performs drives the construction of the image.
+
+Use ``--help`` to discover more options to spin-appliance. You can override the
+Release field with ``--release``, or ``--repo`` to override what yum repo is
+used to provide packages to install to the image. Note that regardless of what
+repo you use, it must contain RPMs built by Koji, otherwise you will get an
+error. (unless you are building a scratch image)
+
+Mechanics
+---------
+
+The way Appliances are created in Koji is the same as :ref:`building-livecds`.
+
+Caveats for Appliances
+----------------------
+
+Caveats for using ``spin-appliance`` are the same as using ``spin-livecd`` to
+:ref:`caveats-for-livecds`.
+
+Troubleshooting
+---------------
+
+If your build fails, you will be notified on the command line. In the output
+will be a URL to the Koji UI, visit that and click on the red subtask link.
+From that page review ``root.log`` and ``appliance.log`` for errors. Often
+errors are caused by packages being missing, or malformed kickstart files. The
+log files are at the bottom of the page. If you're stuck, contact Release
+Engineering.
+
+Build System Preparation
+------------------------
+
+This section assumes you have know-how required to install and configure a new
+instance of Koji, and that you have already done so. You can learn how to do so
+:doc:`here ` if you need to. Please ensure you are using the
+latest version of the software and that your database schema is updated as
+well. You should also have some familiarity with how `appliance-creator`_
+works. This section only covers preparation for Appliance builds.
+
+Follow this procedure step by step to get things prepared they way they need
+to be.
+
+#. Add a builder to the appliance channel
+ ::
+
+ koji add-host-to-channel appliance
+
+#. Grant the permission to build an appliance to a user. This step is optional
+ since admins have all permissions.
+
+ ::
+
+ koji grant-permission appliance
+
+#. You will need a tag and target to build the images from. The yum repo
+ generated for the build tag of the target is what Koji will use to populate
+ the Appliances with by default. (the alternative is to use the ``--repo``
+ option, more on that later)
+
+#. Add the appliance-build group
+
+ ::
+
+ koji add-group appliance-build``
+
+#. Add packages to the appliance-build group. These package lists vary has
+ packages and dependencies change. As of October, 2015 for Fedora 24 the
+ needed packages for appliances:
+
+ * appliance-tools, bash, coreutils, grub, parted, perl, policycoreutils,
+ selinux-policy, shadow-utils, sssd-client
+
+ ::
+
+ koji add-group-pkg appliance-build ...
+
+.. _Koji project website: https://fedorahosted.org/koji/wiki
+.. _kickstart:
+ https://github.com/rhinstaller/pykickstart/blob/master/docs/kickstart-docs.rst
+.. _Anaconda Kickstart Guide:
+ https://github.com/rhinstaller/pykickstart/blob/master/docs/kickstart-docs.rst
+.. _livecd-tools: https://github.com/rhinstaller/livecd-tools/
+.. _livecd-creator: https://fedoraproject.org/wiki/FedoraLiveCD
+.. _ImageFactory: http://imgfac.org/
+.. _Oz: http://github.com/clalancette/oz
+.. _how to use Oz: https://github.com/clalancette/oz/wiki
+.. _how to use ImageFactory: http://imgfac.org/documentation/
+.. _appliance-creator: http://fedoraproject.org/wiki/Features/ApplianceTools
diff --git a/docs/source/index.rst b/docs/source/index.rst
new file mode 100644
index 00000000..a82566c3
--- /dev/null
+++ b/docs/source/index.rst
@@ -0,0 +1,279 @@
+.. Koji documentation master file, created by
+ sphinx-quickstart on Tue Nov 3 12:11:18 2015.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+================================
+Welcome to Koji's documentation!
+================================
+
+Koji
+====
+
+Koji is the software that builds `RPM packages for the Fedora project`_. It
+uses `Mock`_ to create chroot environments to perform builds. To download the
+source code, report bugs, join the mailing list etc., see the `Koji project
+website`_.
+
+Contents
+========
+
+.. toctree::
+ :maxdepth: 2
+
+ HOWTO
+ image_build
+ server_howto
+ defining_hub_policies
+ external_repo_server_bootstrap
+ image_build
+ misc
+ migrations
+ runs_here
+ server_bootstrap
+ server_howto
+ using_the_koji_build_system
+ writing_a_plugin
+ writing_koji_code
+
+HowTos
+======
+
+Setting up and using Koji on Fedora:
+
+* :doc:`Using the Koji build system `
+* :doc:`Run Your Own Koji Build Server `
+* :doc:`Building Images in Koji `
+* :doc:`Defining hub policies `
+
+Koji Architecture
+=================
+
+Terminology
+-----------
+In Koji it is sometimes necessary to distinguish between a package in general,
+a specific build of a package, and the various rpm files created by a build.
+When precision is needed, these terms should be interpreted as follows:
+
+Package
+ The name of a source rpm. This refers to the package in general and not
+ any particular build or subpackage. For example: kernel, glibc, etc.
+
+Build
+ A particular build of a package. This refers to the entire build: all
+ arches and subpackages. For example: kernel-2.6.9-34.EL, glibc-2.3.4-2.19.
+
+RPM
+ A particular rpm. A specific arch and subpackage of a build. For example:
+ kernel-2.6.9-34.EL.x86_64, kernel-devel-2.6.9-34.EL.s390,
+ glibc-2.3.4-2.19.i686, glibc-common-2.3.4-2.19.ia64
+
+Koji Components
+===============
+
+Koji is comprised of several components:
+
+Koji-Hub
+--------
+koji-hub is the center of all Koji operations. It is an XML-RPC server running
+under mod_wsgi in Apache. koji-hub is passive in that it only receives XML-RPC
+calls and relies upon the build daemons and other components to initiate
+communication. koji-hub is the only component that has direct access to the
+database and is one of the two components that have write access to the file
+system.
+
+Kojid
+-----
+kojid is the build daemon that runs on each of the build machines. Its primary
+responsibility is polling for incoming build requests and handling them
+accordingly. Essentially kojid asks koji-hub for work. Koji also has support
+for tasks other than building. Creating install images is one example. kojid
+is responsible for handling these tasks as well. kojid uses mock for building.
+It also creates a fresh buildroot for every build. kojid is written in Python
+and communicates with koji-hub via XML-RPC.
+
+Koji-Web
+--------
+koji-web is a set of scripts that run in mod_wsgi and use the Cheetah
+templating engine to provide a web interface to Koji. It acts as a client to
+koji-hub providing a visual interface to perform a limited amount of
+administration. koji-web exposes a lot of information and also provides a means
+for certain operations, such as cancelling builds.
+
+Koji-client
+-----------
+koji-client is a CLI written in Python that provides many hooks into Koji. It
+allows the user to query much of the data as well as perform actions such as
+adding users and initiating build requests.
+
+Kojira
+------
+kojira is a daemon that keeps the build root repodata updated. It is
+responsible for removing redundant build roots and cleaning up after a build
+request is completed.
+
+Package Organization
+====================
+
+Tags and Targets
+----------------
+
+Koji organizes packages using tags:
+
+* Tags are tracked in the database but not on disk
+* Tags support multiple inheritance
+* Each tag has its own list of valid packages (inheritable)
+* Package ownership can be set per-tag (inheritable)
+* Tag inheritance is more configurable
+* When you build you specify a target rather than a tag
+
+A build target specifies where a package should be built and how it should be
+tagged afterwards. This allows target names to remain fixed as tags change
+through releases. You can get a full list of build targets with the following
+command:
+
+::
+
+ $ koji list-targets
+
+You can see just a single target with the --name option:
+
+::
+
+ $ koji list-targets --name dist-fc7
+
+ Name Buildroot Destination
+ ---------------------------------------------------------------------------------------------
+ dist-fc7 dist-fc7-build dist-fc7
+
+This tells you a build for target dist-fc7 will use a buildroot with packages
+from the tag dist-fc7-build and tag the resulting packages as dist-fc7.
+
+You can get a list of tags with the following command:
+
+::
+
+ $ koji list-tags
+
+Package lists
+-------------
+
+As mentioned above, each tag has its own list of packages that may be placed in
+the tag. To see that list for a tag, use the list-pkgs command:
+
+::
+
+ $ koji list-pkgs --tag dist-fc7
+
+ Package Tag Extra Arches Owner
+ ----------------------- ----------------------- ---------------- ----------------
+ ElectricFence dist-fc6 pmachata
+ GConf2 dist-fc6 rstrode
+ lucene dist-fc6 dbhole
+ lvm2 dist-fc6 lvm-team
+ ImageMagick dist-fc6 nmurray
+ m17n-db dist-fc6 majain
+ m17n-lib dist-fc6 majain
+ MAKEDEV dist-fc6 clumens
+ [...]
+
+The first column is the name of the package, the second tells you which tag the
+package entry has been inherited from, and the third tells you the owner of the
+package.
+
+Latest Builds
+-------------
+
+To see the latest builds for a tag, use the latest-pkg command:
+
+::
+
+ $ koji latest-pkg --all dist-fc7
+
+ Build Tag Built by
+ ---------------------------------------- -------------------- ----------------
+ ConsoleKit-0.1.0-5.fc7 dist-fc7 davidz
+ ElectricFence-2.2.2-20.2.2 dist-fc6 jkeating
+ GConf2-2.16.0-6.fc7 dist-fc7 mclasen
+ ImageMagick-6.2.8.0-3.fc6.1 dist-fc6-updates nmurray
+ MAKEDEV-3.23-1.2 dist-fc6 nalin
+ MySQL-python-1.2.1_p2-2 dist-fc7 katzj
+ NetworkManager-0.6.5-0.3.cvs20061025.fc7 dist-fc7 caillon
+ ORBit2-2.14.6-1.fc7 dist-fc7 mclasen
+
+The output gives you not only the latest builds, but which tag they have been
+inherited from and who built them (note: for builds imported from beehive the
+"built by" field may be misleading).
+
+Documentation
+-------------
+
+We've tried to make Koji self-documenting wherever possible. The command line
+tool will print a list of valid commands and each command supports --help.
+For example:
+
+::
+
+ $ koji help
+
+ Koji commands are:
+ build Build a package from source
+ cancel-task Cancel a task
+ help List available commands
+ latest-build Print the latest rpms for a tag
+ latest-pkg Print the latest builds for a tag
+ [...]
+
+::
+
+ $ koji build --help
+
+ usage: koji build [options] tag URL
+ (Specify the --help global option for a list of other help options)
+
+ options:
+ -h, --help show this help message and exit
+ --skip-tag Do not attempt to tag package
+ --scratch Perform a scratch build
+ --nowait Don't wait on build
+ [...]
+
+You can see administrator-only command help with --admin. Most users will
+never use these additional commands, but if you're setting up your own Koji
+system, you may find them very useful.
+
+::
+
+ $ koji help --admin
+ Available commands:
+ add-external-repo Create an external repo and/or add one to a tag
+ add-group Add a group to a tag
+ add-group-pkg Add a package to a group's package listing
+ [...]
+
+Koji Deployments
+================
+
+Koji is also known to be used in many places, and we :doc:`track them on this
+page `. Feel free to add your entry. There is no additional
+obligation to you for doing so. :)
+
+Koji Contributor Guides
+=======================
+
+If you're interested in submitting patches, writing documentation, or filing
+bugs this section is for you. In time this will be the best place to learn
+how to get involved.
+
+* :doc:`Getting Started as a Developer `
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
+.. _Mock: http://fedoraproject.org/wiki/Projects/Mock
+.. _RPM packages for the Fedora project: http://koji.fedoraproject.org/koji/
+.. _Koji project website: https://fedorahosted.org/koji/wiki
diff --git a/docs/source/migrating_to_1.10.rst b/docs/source/migrating_to_1.10.rst
new file mode 100644
index 00000000..8002abbe
--- /dev/null
+++ b/docs/source/migrating_to_1.10.rst
@@ -0,0 +1,85 @@
+Migrating to Koji 1.10
+======================
+
+.. reStructured Text formatted
+
+The 1.10 release of Koji includes a few changes that you should consider when
+migrating.
+
+DB Updates
+----------
+
+The new ``tag_extra`` table tracks extra data for tags.
+
+There is a new entry in the ``channels`` table and some additions and updates to
+the ``archivetypes`` table.
+
+As in previous releases, we provide a migration script that updates the
+database.
+
+::
+
+ # psql koji koji DROP TABLE imageinfo_listing;
- koji=> DROP TABLE imageinfo;
- # rm -rf /mnt/koji/images
+::
+
+ koji=> DROP TABLE imageinfo_listing;
+ koji=> DROP TABLE imageinfo;
+ # rm -rf /mnt/koji/images
Command line changes
--------------------
-For clarity and consistency, all of the +-pkg+ commands have been renamed to
-+-build+ commands.
+For clarity and consistency, all of the ``-pkg`` commands have been renamed to
+``-build`` commands.
- latest-pkg -> latest-build
- move-pkg -> move-build
- tag-pkg -> tag-build
- untag-pkg -> untag-build
+::
+
+ latest-pkg -> latest-build
+ move-pkg -> move-build
+ tag-pkg -> tag-build
+ untag-pkg -> untag-build
For backwards compatibility, the old commands names are also recognized.
-A new command has been added, +remove-pkg+.
+A new command has been added, ``remove-pkg``.
Several commands have been modified to support images.
-The +spin-livecd+ and +spin-appliance+ commands now require additional
+The ``spin-livecd`` and ``spin-appliance`` commands now require additional
arguments. These arguments specify the name and version to use for the image.
@@ -93,20 +103,24 @@ New kojira options
The following options are new to kojira:
- max_delete_processes
- max_repo_tasks_maven
+::
+
+ max_delete_processes
+ max_repo_tasks_maven
Previously, kojira ran as a single process and repo deletions could potentially
slow things down (particularly for Maven-enabled repos). Now kojira spawns
-a separate process to handle these deletions. The +max_delete_processes+
+a separate process to handle these deletions. The ``max_delete_processes``
determines how many such processes it will launch at one time.
When Maven-enabled repos are in use, they can potentially take a very long time
to regenerate. If a number of these pile up it can severely slow down
-regeneration of non-Maven repos. The +max_repo_tasks_maven+ limits how many
+regeneration of non-Maven repos. The ``max_repo_tasks_maven`` limits how many
Maven repos kojira will attempt to regenerate at once.
Also the following kojira option has been removed:
- prune_batch_size
+::
+
+ prune_batch_size
diff --git a/docs/source/migrating_to_1.9.rst b/docs/source/migrating_to_1.9.rst
new file mode 100644
index 00000000..fbfb27c2
--- /dev/null
+++ b/docs/source/migrating_to_1.9.rst
@@ -0,0 +1,86 @@
+Migrating to Koji 1.9
+=====================
+
+.. reStructured Text formatted
+
+The 1.9 release of Koji includes a few changes that you should consider when
+migrating.
+
+DB Updates
+----------
+
+ImageFactory support introduced some new archive types. These have been added to
+the ``archivetypes`` table. The inaccurate ``vmx`` entry has been removed.
+
+As in previous releases, we provide a migration script that updates the
+database.
+
+::
+
+ # psql koji koji [ ...]
+
+Note: is a single entity, so denote multiple arches within quotes (e.g.
+'i386 i586 i686').
+
+Manually submitting a task
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Occasionally, you may need to manually submit a task to koji. One likely
+usage is to manually trigger a createRepo. To do this, use this command:
+
+::
+
+ koji make-task [options] [...]
+
+The make-task command is a bit of under-documented black magic. Task
+parameters are defined in kojihub.py. The easiest way I have found to
+figure out the right incantations for make-task is to query the *task*
+table in the koji database directly. Find a similar task to the one you
+want to create, and look in the request field for the parameters the
+task used, and mimic those.
+
+So, citing the createRepo case above, here is an example:
+
+::
+
+ kojiadmin@localhost$ koji make-task --channel=createrepo --priority=15 \
+ newRepo dist-foo-build
+
+Managing your tags
+~~~~~~~~~~~~~~~~~~
+
+Occasionally an unwanted package or version of a package will be built
+by koji. Don't fret. There are two mechanisms to handle rescinding a
+package or specific package version.
+
+- To remove a specific version of a package, you can untag it:
+
+::
+
+ koji untag-build [options] [...]
+
+ supports either %name or %name-%version-%release
+
+- To remove all versions of a package, you can untag it as above or you
+ can administratively block it from being listed in a tag:
+
+::
+
+ koji block-pkg [options] tag package [package2 ...]
+
+Spec file processing
+--------------------
+
+Macro processing
+~~~~~~~~~~~~~~~~
+
+Macros in the spec file are expanded before Requires and BuildRequires
+are processed. If there are any custom macros in the spec file, the
+package that drops those macros into /etc/rpm must be tagged under your
+dist-build tag
+
+%dist tags
+^^^^^^^^^^
+
+For packages that incorporate the %dist tags in their filename, they
+expect %dist to be defined in /etc/rpm/macros.dist, which was added in
+Fedora 7. For building on RHEL5/FC6 and earlier, koji needs the
+`http://buildsys.fedoraproject.org/buildgroups/
+buildsys-macros `__
+package tagged under the dist-build tag.
diff --git a/docs/source/runs_here.rst b/docs/source/runs_here.rst
new file mode 100644
index 00000000..12c4aa2c
--- /dev/null
+++ b/docs/source/runs_here.rst
@@ -0,0 +1,67 @@
+=========
+Runs Here
+=========
+
+List of locations that Koji is currently in use
+===============================================
+
+Please add yourself here if you run a local version of Koji. Please also
+describe what you are using it for.
+
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| # | Project | Site Name | Used for |
++=========+============================================================================+===================================================================+===========================================================================================================================================================================================================================================================================+
+| 0 | Grid and HPC Operations Center of A.U.Th | Not-Public | Building packages for local fabric needs. Maintenance of RPM repositories. Monitoring, messaging and information system software for `LCG `__. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 1 | pc V Pharmacy | Not-public | Compiling proprietary software across Fedora and RHEL. Both the software and any dependencies that are not available in Fedora and/or RHEL that may also be proprietary. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 2 | CERN | \* | CERN no longer runs their own Koji, but does make daily use of the one run by the Scientific Computing Center of A.U.Th. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 3 | `fedora.danny.cz `__ | the hub is not public yet | http://sharkcz.livejournal.com/3988.html |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 4 | `Ergo Project `__ | `Koji Web Interface `__ | Fast-Track repositories for Enterprise Linux and Fedora, FTBFS, `Blog posts on Koji `__ |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 5 | `NetNix Estonia OÜ `__ | Internal | Packaging commercial and in-house software for RHEL/CentOS/Fedora support. Multiple instances installed, locally and customer sites. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 6 | `Kolab Systems AG `__ | Not Public (yet) | Packaging for ISV products |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 7 | `Lebanon Evangelical School for Boys and Girls `__ | http://koji.lesbg.com/koji | Used to provide configuration RPMS for our three schools |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 8 | `Messinet Secure Services `__ | http://messinet.com/koji | Building and packaging to support local infrastructure as well as incorporate software not packaged at Fedora or RPMFusion. Most packaged software is available to all. See `Messinet Secure Services Fedora RPM Repository `__ for details. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 9 | `ACOSS France `__ | Not-public | Building and packaging on top of RHEL and CentOS 6 for newer software version. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 10 | `Virtual Bridges, Inc. `__ | Not-public | Building `VERDE LEAF `__ virtualization platform/distribution. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 11 | Caltech | http://koji.hep.caltech.edu/koji/ | multi-university CERN-based project |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 12 | Spacewalk | http://koji.spacewalkproject.org/koji/ | building Spacewalk for RHEL 5, 6, and Fedora 14, 15 |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 13 | `National Nanotechnology Network Grid `__ | http://koji.ngrid.ru/koji/ | GridNNN middleware |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| \| 14 | TomTom | non-public | used to build rpms that aren't available in the RHEL repos or EPEL |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| \| 15 | Amazon | non-public | used to build RPMS for the Amazon Linux AMI |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| \| 16 | Open Science Grid | http://koji-hub.batlab.org/koji/ | Used to build RPMs for the Open Science Grid software project. Software built here is deployed across 100+ universities and labs across the U.S. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| \| 17 | RussianFedora | http://koji.russianfedora.ru | Building add-on packages for the RFRemix. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| \| 18 | Scientific Linux | Not-public (yet) | Building Scientific Linux. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| \| 19 | Katello | http://koji.katello.org/koji/ | Building packages for Katello project |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| \| 20 | NIWA | non-public | Building packages for climate and forecasting project |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 21 | `Xenith Consulting Limited `__ | Not-Public | Banking, Telecommunications and Embedded Systems |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 22 | Abril Comunicações | non-public | Media / Entertainment Company. Building RPM packages for the Digital products |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 23 | The FireServer Project | http://www.fireserver.com.br | Building packages for FireServer Project |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 24 | Seneca Centre for Development of Open Technology | http://koji.pidora.ca (info at http://pidora.ca) | Pidora (Fedora Remix for Raspberry Pi) and some other projects. |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 25 | OpenVZ/Virtuozzo | `https://openvz.org/Virtuozzo `__ | Building OpenVZ packages |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| 26 | Cloud Linux | `http://koji.cloudlinux.com/ `__ | Building Cloud Linux packages |
++---------+----------------------------------------------------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
diff --git a/docs/source/server_bootstrap.rst b/docs/source/server_bootstrap.rst
new file mode 100644
index 00000000..86c35887
--- /dev/null
+++ b/docs/source/server_bootstrap.rst
@@ -0,0 +1,95 @@
+=====================
+Koji Server Bootstrap
+=====================
+
+Bootstrapping a new Koji build environment
+==========================================
+
+These are the steps involved in populating a new Koji server with
+packages so that it can be used for building. This assumes that the Koji
+hub is up, appropriate authentication methods have been configured, the
+Koji repo administration daemon (``kojira``) is properly configured and
+running, and at least one Koji builder (``kojid``) is properly
+configured and running. All koji cli commands assume that the user is a
+Koji *admin*. If you need help with these tasks, see the
+`ServerHowTo `__ .
+
+- Download all source rpms and binary rpms for the arches you're
+ interested in
+
+- Import all source rpms
+
+::
+
+ $ koji import /path/to/package1.src.rpm /path/to/package2.src.rpm ...
+
+If the files are on the same volume as /mnt/koji, you can use
+``koji import --link``, which hardlinks the files into place, avoiding
+the need to upload them to the hub and **very significantly** increasing
+import speed. When using ``--link``, you must run as root. It is
+**highly** recommended that you use ``--link``.
+
+- Import all binary rpms using the same method as above
+
+- Create a new tag
+
+::
+
+ $ koji add-tag dist-foo
+
+- Tag all of the packages you just imported into the tag you just
+ created
+
+You can use ``koji list-untagged`` to get a list of all of the packages
+you just imported.
+
+::
+
+ $ koji list-pkgs --quiet | xargs koji add-pkg --owner dist-foo
+ $ koji list-untagged | xargs -n 1 koji call tagBuildBypass dist-foo
+
+We call the *tagBuildBypass* method instead of using ``koji tag-pkg``
+because it doesn't require the builders to process *tagBuild* tasks one
+at a time, but does the tagging directly. This will save a significant
+amount of time, especially when tagging a large number of packages.
+
+- Create a build tag with the desired arches, and the previously
+ created tag as a parent
+
+::
+
+ $ koji add-tag --parent dist-foo --arches "i386 x86_64 ppc ppc64" dist-foo-build
+
+- Create a build target that includes the tags you've already created
+
+::
+
+ $ koji add-target dist-foo dist-foo-build
+
+- Create a *build* group associated with your build tag
+
+::
+
+ $ koji add-group dist-foo-build build
+
+- Populate the *build* group with packages that will be installed into
+ the minimal buildroot
+
+You can find out what the current build group for Fedora is by running
+``koji -s http://$ARCH.koji.fedoraproject.org/kojihub list-groups f17-build``
+against the Fedora Koji instance for your $ARCH. This is probably a good
+starting point for your minimal buildroot.
+
+::
+
+ $ koji add-group-pkg dist-foo-build build pkg1
+ $ koji add-group-pkg dist-foo-build build pkg2
+
+- regenerate the repo
+
+::
+
+ $ koji regen-repo dist-foo-build
+
+- Wait for the repo to regenerate, and you should now be able to run a
+ build successfully.
diff --git a/docs/source/server_howto.rst b/docs/source/server_howto.rst
new file mode 100644
index 00000000..026720d3
--- /dev/null
+++ b/docs/source/server_howto.rst
@@ -0,0 +1,1298 @@
+=============
+Server How To
+=============
+
+Setting Up a Koji Build System
+==============================
+
+The Koji components may **live** on separate resources as long as all resources
+are able to communicate. This document will cover how to setup each service
+individually, however, all services may **live** on the same resource.
+
+Knowledge Prerequisites
+=======================
+
+* Basic understanding of SSL and authentication via certificates and/or
+ Kerberos credentials
+* Basic knowledge about creating a database in PostgreSQL and importing a schema
+* Working with psql
+* Basic knowledge about Apache configuration
+* Basic knowledge about `dnf`_/`yum`_/`createrepo`_/`mock`_ - else you'll not
+ be able to debug problems!
+* Basic knowledge about using command line
+* Basic knowledge about RPM building
+* Simple usage of the Koji client
+* For an overview of yum, mock, Koji (and all its subcomponents), mash, and how
+ they all work together, see the excellent slides put together by `Steve
+ Traylen at CERN `_.
+
+Package Prerequisites
+=====================
+
+On the server (koji-hub/koji-web)
+---------------------------------
+* httpd
+* mod_ssl
+* postgresql-server
+* mod_wsgi
+
+On the builder (koji-builder)
+-----------------------------
+* mock
+* setarch (for some archs you'll require a patched version)
+* rpm-build
+* createrepo
+
+A note on filesystem space
+==========================
+Koji will consume copious amounts of disk space under the primary KojiDir
+directory (as set in the kojihub.conf file - defaults to ``/mnt/koji``).
+However, as koji makes use of mock on the backend to actually create build
+roots and perform the builds in those build roots, it might come to a surprise
+to users that a running koji server will consume large amounts of disk space
+under ``/var/lib/mock`` and ``/var/cache/mock`` as well. Users should either
+plan the disk and filesystem allocations for this, or plan to modify the
+default mock build directory in the kojid.conf file. If you change the
+location, ensure that the new directories are owned by the group "mock" and
+have 02755 permission.
+
+Koji Authentication Selection
+=============================
+Koji primarily supports Kerberos and SSL Certificate authentication. For basic
+koji command line access, plain user/pass combinations are possible. However,
+kojiweb does **not** support plain user/pass authentication and once either
+Kerberos or SSL Certificate authentication is enabled for kojiweb, the plain
+user/pass method will stop working entirely. For this reason we encourage
+skipping the plain user/pass method altogether and properly configuring either
+Kerberos or SSL Certification authentication from the start.
+
+The decision on how to authenticate users will affect all other actions you
+take in setting up koji. For this reason it is a decision best made up front.
+
+For Kerberos authentication
+ a working Kerberos environment (the user is assumed to either already have
+ this or know how to set it up themselves, instructions for it are not
+ included here) and the Kerberos credentials of the initial admin user will
+ be necessary to bootstrap the user database.
+
+For SSL authentication
+ SSL certificates for the xmlrpc server, for the various koji components,
+ and one for the admin user will need to be setup (the user need not know
+ how to create certificate chains already, we include the instructions for
+ this below).
+
+Setting up SSL Certificates for authentication
+----------------------------------------------
+
+Certificate generation
+^^^^^^^^^^^^^^^^^^^^^^
+Create the ``/etc/pki/koji`` directory and copy-and-paste the ssl.cnf listed
+here, and save it in the new directory. This configuration file is used along
+with the ``openssl`` command to generate the SSL certificates for the various
+koji components.
+
+``ssl.cnf``
+
+::
+
+
+ HOME = .
+ RANDFILE = .rand
+
+ [ca]
+ default_ca = ca_default
+
+ [ca_default]
+ dir = .
+ certs = $dir/certs
+ crl_dir = $dir/crl
+ database = $dir/index.txt
+ new_certs_dir = $dir/newcerts
+ certificate = $dir/%s_ca_cert.pem
+ private_key = $dir/private/%s_ca_key.pem
+ serial = $dir/serial
+ crl = $dir/crl.pem
+ x509_extensions = usr_cert
+ name_opt = ca_default
+ cert_opt = ca_default
+ default_days = 3650
+ default_crl_days = 30
+ default_md = sha256
+ preserve = no
+ policy = policy_match
+
+ [policy_match]
+ countryName = match
+ stateOrProvinceName = match
+ organizationName = match
+ organizationalUnitName = optional
+ commonName = supplied
+ emailAddress = optional
+
+ [req]
+ default_bits = 1024
+ default_keyfile = privkey.pem
+ distinguished_name = req_distinguished_name
+ attributes = req_attributes
+ x509_extensions = v3_ca # The extentions to add to the self signed cert
+ string_mask = MASK:0x2002
+
+ [req_distinguished_name]
+ countryName = Country Name (2 letter code)
+ countryName_default = AT
+ countryName_min = 2
+ countryName_max = 2
+ stateOrProvinceName = State or Province Name (full name)
+ stateOrProvinceName_default = Vienna
+ localityName = Locality Name (eg, city)
+ localityName_default = Vienna
+ 0.organizationName = Organization Name (eg, company)
+ 0.organizationName_default = My company
+ organizationalUnitName = Organizational Unit Name (eg, section)
+ commonName = Common Name (eg, your name or your server\'s hostname)
+ commonName_max = 64
+ emailAddress = Email Address
+ emailAddress_max = 64
+
+ [req_attributes]
+ challengePassword = A challenge password
+ challengePassword_min = 4
+ challengePassword_max = 20
+ unstructuredName = An optional company name
+
+ [usr_cert]
+ basicConstraints = CA:FALSE
+ nsComment = "OpenSSL Generated Certificate"
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid,issuer:always
+
+ [v3_ca]
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer:always
+ basicConstraints = CA:true
+
+Although it is not required, it is recommended that you edit the default values
+in the ``[req_distinguished_name]`` section of the configuration to match the
+information for your own server. This will allow you to accept most of the
+default values when generating certificates later. The other sections can be
+left unedited.
+
+Generate CA
+^^^^^^^^^^^
+
+The CA is the Certificate Authority. It's the key/cert pair used to sign all
+the other certificate requests. When configuring the various koji components,
+both the client CA and the server CA will be a copy of the CA generated here.
+The CA certificate will be placed in the ``/etc/pki/koji`` directory and the
+certificates for the other components will be placed in the
+``/etc/pki/koji/certs`` directory. The ``index.txt`` file which is created is
+a database of the certificates generated and can be used to view the
+information for any of the certificates simply by viewing the contents of
+``index.txt``.
+
+::
+
+ cd /etc/pki/koji/
+ mkdir {certs,private,confs}
+ touch index.txt
+ echo 01 > serial
+ openssl genrsa -out private/koji_ca_cert.key 2048
+ openssl req -config ssl.cnf -new -x509 -days 3650 -key private/koji_ca_cert.key \
+ -out koji_ca_cert.crt -extensions v3_ca
+
+The last command above will ask you to confirm a number of items about the
+certificate you are generating. Presumably you already edited the defaults for
+the country, state/province, locale, and organization in the ``ssl.cnf`` file
+and you only needed to hit enter. It's the organizational unit and the common
+name that we will be changing in the various certs we create. For the CA
+itself, these fields don't have a hard requirement. One suggestion for this
+certificate is to use the FQDN of the server.
+
+If you are trying to automate this process via a configuration management
+tool, you can create the cert in one command with a line like this:
+
+::
+
+ openssl req -config ssl.cnf -new -x509 \
+ -subj "/C=US/ST=Oregon/L=Portland/O=IT/CN=koji.example.com" \
+ -days 3650 -key private/koji_ca_cert.key -out koji_ca_cert.crt -extensions v3_ca
+
+Generate the koji component certificates and the admin certificate
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Each koji component needs its own certificate to identify it. Two of the
+certificates (kojihub and kojiweb) are used as server side certificates that
+authenticate the server to the client. For this reason, you want the common
+name on both of those certs to be the fully qualified domain name of the web
+server they are running on so that clients don't complain about the common
+name and the server not being the same. You can set the OU for these two
+certificates to be kojihub and kojiweb for identification purposes.
+
+For the other certificates (kojira, kojid, the initial admin account, and all
+user certificates), the cert is used to authenticate the client to the server.
+The common name for these certs should be set to the login name for that
+specific component. For example the common name for the kojira cert should be
+set to kojira so that it matches the username. The reason for this is that the
+common name of the cert will be matched to the corresponding user name in the
+koji database. If there is not a username in the database which matches the CN
+of the cert the client will not be authenticated and access will be denied.
+
+When you later use ``koji add-host`` to add a build machine into the koji
+database, it creates a user account for that host even though the user account
+doesn't appear in the user list. The user account created must match the
+common name of the certificate which that component uses to authenticate with
+the server. When creating the kojiweb certificate, you'll want to remember
+exactly what values you enter for each field as you'll have to regurgitate
+those into the /etc/koji-hub/hub.conf file as the ProxyDNs entry.
+
+When you need to create multiple certificates it may be convenient to create a
+loop or a script like the on listed below and run the script to create the
+certificates. You can simply adjust the number of kojibuilders and the name of
+the admin account as you see fit. For much of this guide, the admin account is
+called ``kojiadmin``.
+
+::
+
+ #!/bin/bash
+ # if you change your certificate authority name to something else you will
+ # need to change the caname value to reflect the change.
+ caname=koji
+
+ # user is equal to parameter one or the first argument when you actually
+ # run the script
+ user=$1
+
+ openssl genrsa -out private/${user}.key 2048
+ cat ssl.cnf | sed 's/insert_hostname/'${user}'/'> ssl2.cnf
+ openssl req -config ssl2.cnf -new -nodes -out certs/${user}.csr -key private/${user}.key
+ openssl ca -config ssl2.cnf -keyfile private/${caname}_ca_cert.key -cert ${caname}_ca_cert.crt \
+ -out certs/${user}.crt -outdir certs -infiles certs/${user}.csr
+ cat certs/${user}.crt private/${user}.key > ${user}.pem
+ mv ssl2.cnf confs/${user}-ssl.cnf
+
+Generate a PKCS12 user certificate (for web browser)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+This is only required for user certificates.
+
+::
+
+ openssl pkcs12 -export -inkey private/${user}.key -in certs/${user}.crt \
+ -CAfile ${caname}_ca_cert.crt -out certs/${user}_browser_cert.p12
+
+When generating certs for a user, the user will need the ``${user}.pem``, the
+``${caname}_ca_cert.crt``, and the ``${user}_browser_cert.p12`` files which
+were generated above. The ${user}.pem file would normally be installed as
+``~/.fedora.cert``, the ``${caname}_ca_cert.crt`` file would be installed as
+both ``~/.fedora-upload-ca.cert`` and ``~/.fedora-server-ca.cert``, and the
+user would import the ``${user}_brower_cert.p12`` into their web browser as a
+personal certificate.
+
+Copy certificates into ~/.koji for kojiadmin
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You're going to want to be able to send admin commands to the kojihub. In order
+to do so, you'll need to use the newly created certificates to authenticate
+with the hub. Create the kojiadmin user then copy the certificates for the koji
+CA and the kojiadmin user to ``~/.koji``:
+
+::
+
+ kojiadmin@localhost$ mkdir ~/.koji
+ kojiadmin@localhost$ cp /etc/pki/koji/kojiadmin.pem ~/.koji/client.crt # NOTE: It is IMPORTANT you use the PEM and NOT the CRT
+ kojiadmin@localhost$ cp /etc/pki/koji/koji_ca_cert.crt ~/.koji/clientca.crt
+ kojiadmin@localhost$ cp /etc/pki/koji/koji_ca_cert.crt ~/.koji/serverca.crt
+
+.. note::
+ See /etc/koji.conf for the current system wide koji client configuration.
+ Copy /etc/koji.conf to ~/.koji/config if you wish to change the config on a
+ per user basis.
+
+Setting up Kerberos for authentication
+--------------------------------------
+
+The initial configuration of a kerberos service is outside the scope of this
+document, however there are a few specific things required by koji.
+
+DNS
+^^^
+
+The koji builders (kojid) use DNS to find the kerberos servers for any given
+realm.
+
+::
+
+ _kerberos._udp IN SRV 10 100 88 kerberos.EXAMPLE.COM.
+
+The trailing dot denotes DNS root and is needed if FQDN is used.
+
+
+Principals and Keytabs
+^^^^^^^^^^^^^^^^^^^^^^
+
+It should be noted that in general you will need to use the fully qualified
+domain name of the hosts when generating the keytabs for services.
+
+You will need the following principals extracted to a keytab for a fully
+kerberized configuration, the requirement for a host key for the koji-hub is
+currently hard coded into the koji client.
+
+``host/kojihub@EXAMPLE.COM``
+ Used by the koji-hub server when communicating with the koji client
+
+``HTTP/kojiweb@EXAMPLE.COM``
+ Used by the koji-web server when performing a negotiated Kerberos
+ authentication with a web browser. This is a service principal for
+ Apache's mod_auth_kerb.
+
+``koji/kojiweb@EXAMPLE.COM``
+ Used by the koji-web server during communications with the koji-hub. This
+ is a user principal that will authenticate koji-web to Kerberos as
+ "koji/kojiweb@EXAMPLE.COM". Koji-web will proxy the mod_auth_kerb user
+ information to koji-hub (the ProxyPrincipals koji-hub config
+ option).
+
+``koji/kojira@EXAMPLE.COM``
+ Used by the kojira server during communications with the koji-hub
+
+``compile/builder1@EXAMPLE.COM``
+ Used on builder1 to communicate with the koji-hub
+
+PostgreSQL Server
+=================
+
+Once the authentication scheme has been setup your will need to install and
+configure a PostgreSQL server and prime the database which will be used to hold
+the koji users.
+
+Configuration Files
+-------------------
+
+* ``/var/lib/pgsql/data/pg_hba.conf``
+* ``/var/lib/pgsql/data/postgresql.conf``
+
+Install PostgreSQL
+------------------
+
+In Fedora 22 and Later versions use `dnf`_:
+
+::
+
+ # dnf install postgresql-server
+
+Or `yum`_ in Fedora 21 and earlier versions:
+
+::
+
+ # yum install postgresql-server
+
+Initialize PostgreSQL DB:
+-------------------------
+
+The following commands will initialize PostgreSQL and will start the database service
+
+::
+
+ root@localhost$ su - postgres -c "PGDATA=/var/lib/pgsql/data initdb"
+ root@localhost$ systemctl enable postgresql
+ root@localhost$ systemctl start postgresql
+
+Setup User Accounts:
+--------------------
+
+The following commands will setup the ``koji`` account and assign it a password
+
+::
+
+ root@localhost$ useradd koji
+ root@localhost$ passwd koji
+
+Setup PostgreSQL and populate schema:
+-------------------------------------
+
+The following commands will:
+
+* create the koji user within PostgreSQL
+* create the koji database within PostgreSQL
+* set a password for the koji user
+* create the koji schema using the provided
+ ``/usr/share/doc/koji*/docs/schema.sql`` file
+
+::
+
+ root@localhost$ su - postgres
+ postgres@localhost$ createuser --no-superuser --no-createrole --no-createdb koji
+ postgres@localhost$ createdb -O koji koji
+ postgres@localhost$ psql -c "alter user koji with encrypted password 'mypassword';"
+ postgres@localhost$ logout
+ root@localhost$ su - koji
+ koji@localhost$ psql koji koji < /usr/share/doc/koji*/docs/schema.sql
+ koji@localhost$ exit
+
+.. note::
+ When issuing the command to import the psql schema into the new database it
+ is important to ensure that the directory path
+ /usr/share/doc/koji*/docs/schema.sql remains intact and is not resolved to
+ a specific version of koji. In test it was discovered that when the path is
+ resolved to a specific version of koji then not all of the tables were
+ created correctly.
+
+.. note::
+ When issuing the command to import the psql schema into the new database it
+ is important to ensure that you are logged in as the koji database owner.
+ This will ensure all objects are owned by the koji database user. Upgrades
+ may be difficult if this was not done correctly.
+
+Authorize Koji-web and Koji-hub resources
+-----------------------------------------
+
+.. note::
+ In this example, Koji-web and Koji-hub are running on localhost.
+
+``/var/lib/pgsql/data/pg_hba.conf``
+ These settings need to be valid and inline with other services
+ configurations. Please note, the first matching auth line is used so this
+ line must be above any other potential matches. Add:
+
+ ::
+
+ #TYPE DATABASE USER CIDR-ADDRESS METHOD
+ host koji koji 127.0.0.1/32 trust
+ host koji koji ::1/128 trust
+
+ It may also be necessary to add an entry for your machine's external IP
+ address:
+
+ ::
+
+ host koji koji $IP_ADDRESS/32 trust
+
+ You can also use UNIX socket access. The DBHost variable must be unset to
+ use this method. Add:
+
+ ::
+
+ local koji apache trust
+ local koji koji trust
+
+ .. note::
+ To enforce password based logins to the database, change trust to md5.
+
+ ::
+
+ #TYPE DATABASE USER CIDR-ADDRESS METHOD
+ host koji koji 127.0.0.1/32 md5
+ host koji koji ::1/128 md5
+ host koji koji $IP_ADDRESS/32 md5
+
+ Make auth changes live:
+ You must reload the PostgreSQL configuration for these changes to become active.
+
+ ::
+
+ root@localhost$ systemctl reload postgresql
+
+Bootstrapping the initial koji admin user into the PostgreSQL database
+----------------------------------------------------------------------
+
+The initial admin user must be manually added to the user database using sql
+commands. Once added and given admin privilege, you may add additional users
+and change privileges of those users via the koji command line tool's
+administrative commands.
+
+However, if you decided to use the simple user/pass method of authentication,
+then any password setting/changing must be done manually via sql commands as
+there is no password manipulation support exposed through the koji tools.
+
+The sql commands you need to use vary by authentication mechanism.
+
+Set User/Password Authentication
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ root@localhost$ su - koji
+ koji@localhost$ psql
+ koji=> insert into users (name, password, status, usertype) values ('admin-user-name', 'admin-password-in-plain-text', 0, 0);
+
+Kerberos authentication
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The process is very similar to user/pass except you would replace the first
+insert above with this:
+
+::
+
+ root@localhost$ su - koji
+ koji@localhost$ psql
+ koji=> insert into users (name, krb_principal, status, usertype) values ('admin-user-name', 'admin@EXAMPLE.COM', 0, 0);
+
+SSL Certificate authentication
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There is no need for either a password or a Kerberos principal, so this will
+suffice:
+
+::
+
+ root@localhost$ su - koji
+ koji@localhost$ psql
+ koji=> insert into users (name, status, usertype) values ('admin-user-name', 0, 0);
+
+Give yourself admin permissions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following command will give the user admin permissions. In order to do
+this you will need to know the ID of the user.
+
+::
+
+ koji=> insert into user_perms (user_id, perm_id, creator_id) values (, 1, );
+
+.. note::
+ If you do not know the ID of the admin user, you can get the ID by running the query:
+
+::
+
+ koji=> select * from users;
+
+You can't actually log in and perform any actions until kojihub is up and
+running in your web server. In order to get to that point you still need to
+complete the authentication setup and the kojihub configuration. If you wish
+to access koji via a web browser, you will also need to get kojiweb up and
+running.
+
+Set Database To Listen On All Addresses
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The koji-hub service will attempt to connect to the database server in the
+manner you configure. If you use the system hostname, then the database will
+need to be avalible on that address. To configure this please perform the
+following:
+
+#. Edit /var/lib/pgsql/data/postgresql.conf
+#. Set listen_address
+
+ ::
+
+ listen_addresses = '*'
+#. Reload the postgresql service
+
+ ::
+ systemctl restart postgresql
+
+Koji Hub
+========
+
+.. note::
+ Koji 1.7 and greater uses mod_wsgi. Any mod_python configurations will
+ need to be migrated.
+
+Koji-hub is the center of all Koji operations. It is an XML-RPC server running
+under mod_wsgi in the Apache httpd. koji-hub is passive in that it only
+receives XML-RPC calls and relies upon the build daemons and other components
+to initiate communication. Koji-hub is the only component that has direct
+access to the database and is one of the two components that have write access
+to the file system.
+
+Configuration Files
+-------------------
+
+* ``/etc/koji-hub/hub.conf``
+* ``/etc/httpd/conf/httpd.conf``
+* ``/etc/httpd/conf.d/kojihub.conf``
+* ``/etc/httpd/conf.d/ssl.conf`` (when using ssl auth)
+
+Install koji-hub
+----------------
+
+In Fedora 22 and later versions use `dnf`_:
+
+::
+
+ # dnf install koji-hub httpd mod_ssl
+
+Or with `yum`_ in Fedora 21 and earlier versions:
+
+::
+
+ # yum install koji-hub httpd mod_ssl
+
+Required Configuration
+----------------------
+
+/etc/httpd/conf/httpd.conf
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The apache web server has two places that it sets maximum requests a server
+will handle before the server restarts. The xmlrpc interface in kojihub is a
+python application, and processes can sometimes grow outrageously large when it
+doesn't reap memory often enough. As a result, it is strongly recommended that
+you set both instances of MaxRequestsPerChild in httpd.conf to something
+reasonable in order to prevent the server from becoming overloaded and crashing
+(at 100 the httpd processes will grow to about 75MB resident set size before
+respawning).
+
+::
+
+
+ ...
+ MaxRequestsPerChild 100
+
+
+ ...
+ MaxRequestsPerChild 100
+
+
+/etc/httpd/conf.d/kojihub.conf
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The koji-hub package provides this configuration file. You will need to modify
+it based on your authentication type. Instructions are contained within the
+file and should be simple to follow.
+
+/etc/httpd/conf.d/ssl.conf
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If using SSL you will also need to add the needed SSL options for apache. These
+options should point to where the certificates are located on the hub.
+
+::
+
+ SSLCertificateFile /etc/pki/koji/certs/kojihub.crt
+ SSLCertificateKeyFile /etc/pki/koji/certs/kojihub.key
+ SSLCertificateChainFile /etc/pki/koji/koji_ca_cert.crt
+ SSLCACertificateFile /etc/pki/koji/koji_ca_cert.crt
+ SSLVerifyClient require
+ SSLVerifyDepth 10
+
+/etc/koji-hub/hub.conf
+^^^^^^^^^^^^^^^^^^^^^^
+
+This file contains the configuration information for the hub. You will need to
+edit this configuration to point Koji Hub to the database you are using and to
+setup Koji Hub to utilize the authentication scheme you selected in the
+beginning.
+
+::
+
+ DBName = koji
+ DBUser = koji
+ DBPass = mypassword
+ DBHost = db.example.com
+ KojiDir = /mnt/koji
+ LoginCreatesUser = On
+ KojiWebURL = http://kojiweb.example.com/koji
+
+If kojihub is running on the same server as the koji db, then DBHost should be
+set to 127.0.0.1
+
+Authentication Configuration
+----------------------------
+
+/etc/koji-hub/hub.conf
+^^^^^^^^^^^^^^^^^^^^^^
+
+If using Kerberos, these settings need to be valid and inline with other
+services configurations.
+
+::
+
+ AuthPrincipal host/kojihub@EXAMPLE.COM
+ AuthKeytab /etc/koji.keytab
+ ProxyPrincipals koji/kojiweb@EXAMPLE.COM
+ HostPrincipalFormat compile/%s@EXAMPLE.COM
+
+If using SSL auth, these settings need to be valid and inline with other
+services configurations for kojiweb to allow logins.
+
+ProxyDNs should be set to the DN of the kojiweb certificate. The exact format
+depends on your mod_ssl version.
+
+For mod_ssl < 2.3.11 use:
+
+::
+
+ DNUsernameComponent = CN
+ ProxyDNs = /C=US/ST=Massachusetts/O=Example Org/OU=kojiweb/CN=example/emailAddress=example@example.com
+
+However, for mod_ssl >= 2.3.11 use:
+
+::
+
+ DNUsernameComponent = CN
+ ProxyDNs = CN=example.com,OU=kojiweb,O=Example Org,ST=Massachusetts,C=US
+
+.. note::
+ More details on this format change, including handling of special
+ characters, can be found in the `Apache mod_ssl documentation`_. See
+ LegacyDNStringFormat there.
+
+Koji filesystem skeleton
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Above in the ``kojihub.conf`` file we set KojiDir to ``/mnt/koji``. For
+certain reasons, if you change this, you should make a symlink from
+``/mnt/koji`` to the new location (note: this is a bug and should be fixed
+eventually). However, before other parts of koji will operate properly, we
+need to create a skeleton filesystem structure for koji as well as make the
+file area owned by apache so that the xmlrpc interface can write to it as
+needed.
+
+::
+
+ cd /mnt
+ mkdir koji
+ cd koji
+ mkdir {packages,repos,work,scratch}
+ chown apache.apache *
+
+SELinux Configuration
+^^^^^^^^^^^^^^^^^^^^^
+
+If running in Enforcing mode
+ * you will need to allow apache to connect to the postgreSQL server
+ * you will need to allow apache to write some files to disk
+
+Even if you are not currently running in Enforcing mode, it is still
+recommended to configure the SELinux settings so that there are no future
+issues with SELinux if Enforcing mode is enabled later on.
+
+::
+
+ root@localhost$ setsebool -P httpd_can_network_connect_db=1 allow_httpd_anon_write=1
+ root@localhost$ chcon -R -t public_content_rw_t /mnt/koji/*
+
+If you've placed ``/mnt/koji`` on an NFS share you may also need to set
+``httpd_use_nfs``.
+
+Check Your Configuration
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+At this point, you can now restart apache and you should have at least minimal
+operation. The admin user should be able to connect via the command line
+client, add new users, etc. It's possible at this time to undertake initial
+administrative steps such as adding users and hosts to the koji database.
+
+So we will need a working client to test with.
+
+Koji cli - The standard client
+==============================
+
+The koji cli is the standard client. It can perform most tasks and is essential
+to the successful use of any koji environment.
+
+Ensure that your client is configured to work with your server. The system-wide
+koji client configuration file is ``/etc/koji.conf``, and the user-specific one
+is in ``~/.koji/config``. You may also use the ``-c`` option when using the
+Koji client to specify an alternative configuration file.
+
+If you are using SSL for authentication, you will need to edit the Koji client
+configuration to tell it which URLs to use for the various Koji components and
+where their SSL certificates can be found.
+
+For a simple test, all we need is the ``server`` and authentication sections.
+
+::
+
+ [koji]
+
+ ;url of XMLRPC server
+ server = http://koji-hub.example.com/kojihub
+
+ ;url of web interface
+ weburl = http://koji-web.example.com/koji
+
+ ;url of package download site
+ topurl = http://koji-filesystem.example.com/kojifiles
+
+ ;path to the koji top directory
+ topdir = /mnt/koji
+
+ ; configuration for Kerberos authentication
+
+ ;the service name of the principal being used by the hub
+ ;krbservice = host
+
+ ; configuration for SSL athentication
+
+ ;client certificate
+ cert = ~/.koji/client.crt
+
+ ;certificate of the CA that issued the client certificate
+ ca = ~/.koji/clientca.crt
+
+ ;certificate of the CA that issued the HTTP server certificate
+ serverca = ~/.koji/serverca.crt
+
+The following command will test your login to the hub:
+
+::
+
+ root@localhost$ koji moshimoshi
+
+Koji Web - Interface for the Masses
+===================================
+
+.. note::
+ Koji 1.7 and greater uses mod_wsgi. Any mod_python configurations will
+ need to be migrated.
+
+Koji-web is a set of scripts that run in mod_wsgi and use the Cheetah
+templating engine to provide an web interface to Koji. koji-web exposes a lot
+of information and also provides a means for certain operations, such as
+cancelling builds.
+
+Configuration Files
+-------------------
+
+* ``/etc/httpd/conf.d/kojiweb.conf``
+* ``/etc/httpd/conf.d/ssl.conf``
+* ``/etc/kojiweb/web.conf``
+
+Install Koji-Web
+----------------
+
+For Fedora 22 and later versions use `dnf`_:
+
+::
+
+ # dnf install koji-web mod_ssl
+
+Or with `yum`_ for Fedora 21 and earlier versions:
+
+::
+
+ # yum install koji-web mod_ssl
+
+Required Configuration
+----------------------
+
+/etc/httpd/conf.d/kojiweb.conf
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The koji-web package provides this configuration file. You will need to modify
+it based on your authentication type. Instructions are contained within the
+file and should be simple to follow.
+
+.. note::
+ RHEL 5's mod_python publisher does not support non-basic auth, so Kerberos
+ authentication does not currently work in EPEL 5's Koji-web. See
+ `BZ #682319 `_.
+
+/etc/httpd/conf.d/ssl.conf
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you are using SSL you will need to add the needed SSL options for apache.
+
+::
+
+ SSLVerifyClient require
+ SSLVerifyDepth 10
+
+/etc/kojiweb/web.conf
+^^^^^^^^^^^^^^^^^^^^^
+
+You will need to edit the kojiweb configuration file to tell kojiweb which URLs
+it should use to access the hub, the koji packages and its own web interface.
+You will also need to tell kojiweb where it can find the SSL certificates for
+each of these components. If you are using SSL authentication, the "WebCert"
+line below must contain both the public **and** private key. You will also want
+to change the last line in the example below to a unique password.
+
+::
+
+ [web]
+ SiteName = koji
+ # KojiTheme =
+
+ # Necessary urls
+ KojiHubURL = https://koji-hub.example.com/kojihub
+ KojiFilesURL = http://koji-filesystem.example.com/kojifiles
+
+ ## Kerberos authentication options
+ ; WebPrincipal = koji/web@EXAMPLE.COM
+ ; WebKeytab = /etc/httpd.keytab
+ ; WebCCache = /var/tmp/kojiweb.ccache
+
+ ## SSL authentication options
+ ; WebCert = /etc/pki/koji/koji-web.pem
+ ; ClientCA = /etc/pki/koji/ca_cert.crt
+ ; KojiHubCA = /etc/pki/koji/ca_cert.crt
+
+ LoginTimeout = 72
+
+ # This must be set before deployment
+ #Secret = CHANGE_ME
+
+ LibPath = /usr/share/koji-web/lib
+
+Filesystem Configuration
+------------------------
+
+You'll need to make ``/mnt/koji/`` web-accessible, either here, on the hub, or
+on another web server altogether.
+
+This URL will go into various clients such as:
+* ``/etc/kojiweb/web.conf`` as KojiFilesURL
+* ``/etc/kojid/kojid.conf`` as topurl
+* ``/etc/koji.conf`` as topurl
+
+::
+
+ Alias /kojifiles/ /mnt/koji/
+
+ Options Indexes
+ AllowOverride None
+ # Apache < 2.4
+ # Order allow,deny
+ # Allow from all
+ # Apache >= 2.4
+ Require all granted
+
+
+Wherever you configure this, please go back and set it correctly in
+``/etc/kojiweb/web.conf`` now.
+
+Web interface now operational
+-----------------------------
+
+At this point you should be able to point your web browser at the kojiweb URL
+and be presented with the koji interface. Many operations should work in read
+only mode at this point, and any configured users should be able to log in.
+
+Koji Daemon - Builder
+=====================
+
+Kojid is the build daemon that runs on each of the build machines. Its primary
+responsibility is polling for incoming build requests and handling them
+accordingly. Koji also has support for tasks other than building such as
+creating livecd images or raw disk images, and kojid is responsible for
+handling these tasks as well. The kojid service uses mock for creating pristine
+build environments and creates a fresh one for every build, ensuring that
+artifacts of build processes cannot contaminate each other. All of kojid is
+written in Python and communicates with koji-hub via XML-RPC.
+
+Configuration Files
+-------------------
+
+* ``/etc/kojid/kojid.conf`` - Koji Daemon Configuration
+* ``/etc/sysconfig/kojid`` - Koji Daemon Switches
+
+Install kojid
+-------------
+
+For Fedora 22 and later versions use `dnf`_:
+
+::
+
+ # dnf install koji-builder
+
+Or with `yum`_ in Fedora 21 and earlier versions:
+
+::
+
+ # yum install koji-builder
+
+Required Configuration
+----------------------
+
+Add the host entry for the koji builder to the database
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You will now need to add the koji builder to the database so that they can be
+utilized by kojij hub. Make sure you do this before you start kojid for the
+first time, or you'll need to manually remove entries from the sessions and
+users table before it can be run successfully.
+
+::
+
+ kojiadmin@localhost$ koji add-host kojibuilder1.example.com i386 x86_64
+
+The first argument used after the ``add-host`` command should the hostname of
+the builder. The second argument is used to specify the architecture which the
+builder uses.
+
+
+/etc/kojid/kojid.conf
+^^^^^^^^^^^^^^^^^^^^^
+
+The configuration file for each koji builder must be edited so that the line
+below points to the URL for the koji hub. The user tag must also be edited to
+point to the username used to add the koji builder.
+
+::
+
+ ; The URL for the xmlrpc server
+ server=http://hub.example.com/kojihub
+
+ ; the username has to be the same as what you used with add-host
+ ; in this example follow as below
+ user = kojibuilder1.example.com
+
+The koji filesystem may also be needed over http. Set this as it was
+configured about.
+
+::
+
+ # The URL for the file access
+ topurl=http://koji-filesystem.example.com/kojifiles
+
+This item may be changed, but may not be the same as KojiDir on the
+``kojihub.conf`` file (although it can be something under KojiDir, just not
+the same as KojiDir)
+
+::
+
+ ; The directory root for temporary storage
+ workdir=/tmp/koji
+
+The root of the koji build directory (ie, ``/mnt/koji``) must be mounted on the
+builder. A Read-Only NFS mount is the easiest way to handle this.
+
+::
+
+ # The directory root where work data can be found from the koji hub
+ topdir=/mnt/koji
+
+Authentication Configuration (SSL certificates)
+-----------------------------------------------
+
+/etc/kojid/kojid.conf
+^^^^^^^^^^^^^^^^^^^^^
+
+If you are using SSL, these settings need to be edited to point to the
+certificates you generated at the beginning of the setup process.
+
+::
+
+ ;client certificate
+ ; This should reference the builder certificate we created on the kojihub CA, for kojibuilder1.example.com
+ ; ALSO NOTE: This is the PEM file, NOT the crt
+ cert = /etc/kojid/kojid.pem
+
+ ;certificate of the CA that issued the client certificate
+ ca = /etc/kojid/koji_ca_cert.crt
+
+ ;certificate of the CA that issued the HTTP server certificate
+ serverca = /etc/kojid/koji_ca_cert.crt
+
+It is important to note that if your builders are hosted on seperate machines
+from koji hub and koji web, you will need to scp the certificates mentioned in
+the above configuration file from the ``/etc/kojid/`` directory on koji hub to
+the ``/etc/koji/`` directory on the local machine so that the builder can be
+authenticated.
+
+Authentication Configuration (Kerberos)
+---------------------------------------
+
+/etc/kojid/kojid.conf
+^^^^^^^^^^^^^^^^^^^^^
+
+If using Kerberos, these settings need to be valid and inline with other
+services configurations.
+
+::
+
+ ; the username has to be the same as what you used with add-host
+ ;user =
+
+ host_principal_format=compile/%s@EXAMPLE.COM
+
+By default it will look for the Kerberos keytab in ``/etc/kojid/kojid.keytab``
+
+.. note::
+ Kojid will not attempt kerberos authentication to the koji-hub unless the
+ username field is commented out
+
+Optional Configuration SourceCodeManagement
+-------------------------------------------
+
+/etc/kojid/kojid.conf
+^^^^^^^^^^^^^^^^^^^^^
+
+The pattern is as follows:
+ hostname:/path/match:checkout /common?, hostname2:/path/match:checkout /common?
+
+``checkout /common? is 'true' unless set to false``
+
+::
+
+ allowed_scms=scm-server.example.com:/repo/base/repos*/:false
+
+Once the code is checked out kojid will run the following:
+
+::
+
+ make sources
+ mv *.spec /SPECS
+ mv * /SOURCES
+ rpmbuild -bs /SPECS/*.spec
+
+Add the host to the createrepo channel
+--------------------------------------
+
+Channels are a way to control which builders process which tasks. By default
+hosts are added to the ''default'' channel. At least some build hosts also
+needs to be added to the ''createrepo'' channel so there will be someone to
+process repo creation tasks initiated by kojira.
+
+::
+
+ kojiadmin@localhost$ koji add-host-to-channel kojibuilder1.example.com createrepo
+
+A note on capacity
+------------------
+
+The default capacity of a host added to the host database is 2. This means that
+once the load average on that machine exceeds 2, kojid will not accept any
+additional tasks. This is separate from the maxjobs item in the configuration
+file. Before kojid will accept a job, it must pass both the test to ensure the
+load average is below capacity and that the current number of jobs it is
+already processing is less than maxjobs. However, in today's modern age of quad
+core and higher CPUs, a load average of 2 is generally insufficient to fully
+utilize hardware.
+
+::
+
+ koji edit-host --capacity=16 kojibuilder1.example.com
+
+The koji-web interface also offers the ability to edit this value to admin
+accounts.
+
+Start Kojid
+-----------
+
+Once the builder has been added to the database you must start kojid
+
+::
+
+ root@localhost$ service kojid start
+
+Check ``/var/log/kojid.log`` to verify that kojid has started successfully. If
+the log does not show any errors then the koji builder should be up and ready.
+You can check this by pointing your web browser to the web interface and
+clicking on the hosts tab. This will show you a list of builders in the
+database and the status of each builder.
+
+Kojira - Dnd|Yum repository creation and maintenance
+====================================================
+
+Configuration Files
+-------------------
+
+* ``/etc/kojira/kojira.conf`` - Kojira Daemon Configuration
+* ``/etc/sysconfig/kojira`` - Kojira Daemon Switches
+
+Install kojira
+---------------
+For Fedora 22 and later versions use `dnf`_:
+
+::
+
+ # dnf install koji-utils
+
+Or with `yum`_ in Fedora 21 and earlier versions:
+
+::
+
+ # yum install koji-utils
+
+Required Configuration
+----------------------
+
+Add the user entry for the kojira user
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The kojira user requires the ``repo`` permission to function.
+
+::
+
+ kojiadmin@localhost$ koji add-user kojira
+ kojiadmin@localhost$ koji grant-permission repo kojira
+
+``/etc/kojira/kojira.conf``
+ This needs to point at your koji-hub.
+
+ ::
+
+ ; The URL for the xmlrpc server
+ server=http://koji-hub.example.com/kojihub
+
+
+Additional Notes
+^^^^^^^^^^^^^^^^
+* Kojira needs read-write access to ``/mnt/koji``.
+* There should only be one instance of kojira running at any given time.
+* It is not recommended that kojira run on the builders, as builders only
+ should require read-only access to ``/mnt/koji``.
+* Kojira may need to be restarted when new tags are added in order to detect
+ those tags correctly.
+
+Authentication Configuration
+----------------------------
+
+/etc/kojira/kojira.conf
+^^^^^^^^^^^^^^^^^^^^^^^
+
+**If using SSL,** these settings need to be valid.
+
+::
+
+ ;client certificate
+ ; This should reference the kojira certificate we created above
+ cert = /etc/pki/koji/kojira.pem
+
+ ;certificate of the CA that issued the client certificate
+ ca = /etc/pki/koji/koji_ca_cert.crt
+
+ ;certificate of the CA that issued the HTTP server certificate
+ serverca = /etc/pki/koji/koji_ca_cert.crt
+
+**If using Kerberos,** these settings need to be valid.
+
+::
+
+ ; For Kerberos authentication
+ ; the principal to connect with
+ principal=koji/kojira@EXAMPLE.COM
+ ; The location of the keytab for the principal above
+ keytab=/etc/kojira.keytab
+
+``/etc/sysconfig/kojira``
+ The local user kojira runs as needs to be able to read and write to
+ ``/mnt/koji/repos/``. If the volume that directory resides on is
+ root-squashed or otherwise unmodifiable by root, you can set ``RUNAS=`` to
+ a user that has the required privileges.
+
+Start Kojira
+------------
+
+::
+
+ root@localhost$ service kojira start
+
+Check ``/var/log/kojira/kojira.log`` to verify that kojira has started
+successfully.
+
+Bootstrapping the Koji build environment
+========================================
+
+For instructions on importing packages and preparing Koji to run builds, see
+:doc:`Server Bootstrap `.
+
+For instructions on using External Repos and preparing Koji to run builds, see
+:doc:`External Repo Server Bootstrap `.
+
+Useful scripts and config files for setting up a Koji instance are available
+`here `_.
+
+Minutia and Miscellany
+======================
+Please see :doc:`KojiMisc ` for additional details and notes about
+operating a koji server.
+
+.. _dnf: https://fedoraproject.org/wiki/Dnf
+.. _yum: https://fedoraproject.org/wiki/Yum
+.. _createrepo: http://createrepo.baseurl.org/
+.. _mock: https://fedoraproject.org/wiki/Mock
+.. _Apache mod_ssl documentation:
+ https://httpd.apache.org/docs/trunk/mod/mod_ssl.html#ssloptions
diff --git a/docs/source/using_the_koji_build_system.rst b/docs/source/using_the_koji_build_system.rst
new file mode 100644
index 00000000..ebf7aa22
--- /dev/null
+++ b/docs/source/using_the_koji_build_system.rst
@@ -0,0 +1,544 @@
+===========================
+Using the koji build system
+===========================
+
+
+Using Koji in Fedora
+====================
+
+The `Koji Build System `__ is Fedora's RPM buildsystem. Packagers
+use the koji client to request package builds and get information about
+the buildsystem. Koji runs on top of Mock to build RPM packages for
+specific architectures and ensure that they build correctly.
+
+There is also a `simplified Chinese
+edition `__.
+
+Installing Koji
+---------------
+
+Installing the Koji CLI
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Everything you need to use Koji (and be a Fedora contributor) can be
+installed in a single step:
+
+::
+
+ dnf install fedora-packager
+
+fedora-packager provides useful scripts to help maintain and setup your
+koji environment. Additionally, it includes dependencies on the Koji
+CLI, so it will be installed when you install ``fedora-packager``. The
+command is called ``koji`` and is included in the main koji package. By
+default the koji tool authenticates to the central server using
+Kerberos. However SSL and username/password authentications are
+available. You will need to have a valid authentication token to use
+many features. However, many of the read-only commands will work without
+authentication.
+
+Fedora Account System (FAS2) Setup
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In order to interface with the koji server, maintainers will need to run
+
+::
+
+ /usr/bin/fedora-packager-setup
+
+Each user on a system will need to run fedora-packager-setup if they
+wish to use Koji to build Fedora packages. Each user has their own
+certificates that authenticate them.
+
+.. raw:: mediawiki
+
+ {{admon/tip|Plague users rejoice!|For existing users of plague (the old build system that preceded Koji), fedora-packager-setup will use your existing certificates. If you did not have plague before, it will get the server CA certs and tell you where to get your user cert.}}
+
+Fedora Certificates
+'''''''''''''''''''
+
+Koji uses three certificates:
+
+``~/.fedora.cert`` (specific to the Fedora Maintainer) : This cert is
+generated from running ``fedora-cert -n``. It should have been generated
+when you became maintainer. You may need to refresh it when it expires
+by running ``fedora-cert -n`` again. You can check if it has expired
+with ``fedora-cert -v``.
+
+the following are downloaded automatically by fedora-packager-setup and
+dont need to be manually setup
+
+``~/.fedora-upload-ca.cert`` (The certificate for the Certificate
+Authority used to sign the user keys.) : It can be manually downloaded
+from
+`here `__
+or ``fedora-packager-setup or fedora-cert -n`` should fetch it. using
+the CLI is prefered.
+``~/.fedora-server-ca.cert`` (The certificate for the Certificate
+Authority used to sign the build system's server keys.) : It can be
+downloaded manually from
+`here `__
+or ``fedora-packager-setup`` should fetch it. This certificate may also
+be needed to let `https koji `__ URLs
+resolve without untrusted-CA warnings.
+
+.. raw:: mediawiki
+
+ {{admon/warning|RHEL6 cert bug|If you're using RHEL6, an incompatibility between RHEL6's openssl and nss causes certificates downloaded from fas to fail to work with some fedpkg tools. [[https://bugzilla.redhat.com/show_bug.cgi?id=631000 Bug 631000 rhel6 openssl creates PKCS#8 encoded PEM RSA private key files, nss can't read them]]. The cert can be made compatible using this command: (openssl x509 -in ~/.fedora.cert -text; echo; openssl rsa -in ~/.fedora.cert) > fedora.cert.new}}
+
+Koji Config
+^^^^^^^^^^^
+
+The global local client configuration file for koji is
+``/etc/koji.conf``. You should not need to change this from the defaults
+for building Fedora packages.These will allow you to use the primary
+build system as well as secondary arch build systems.
+
+The web interface
+-----------------
+
+.. raw:: mediawiki
+
+ {{admon/tip|Optional|The web interface is optional. You may skip to the
+ next section if you like.}}
+
+The primary interface for viewing Koji data is a web application. It is
+available at http://koji.fedoraproject.org/koji/ . Most of the interface
+is read-only, but with sufficient privileges, you can log in and perform
+some additional actions. For example:
+
+- Cancel a build
+- Resubmit a failed task
+- Setup a notification
+
+Those with admin privileges will find additional actions, such as:
+
+- Create/Edit/Delete a tag
+- Create/Edit/Delete a target
+- Enable/Disable a build host
+
+The web site utilizes SSL authentication. In order to log in you will
+need a valid SSL certificate and your web browser will need to be
+configured to trust the SSL cert. Instructions on how to do this are
+printed when running ``fedora-packager-setup --with-browser-cert``.
+
+.. raw:: mediawiki
+
+ {{admon/warning|Using the certificate directly downloaded from the FAS web
+ interface|If you have generated and downloaded the certificate
+ ~/.fedora.cert directly from FAS using the form referenced
+ above, you need to convert it into a format that the browser can understand
+ using the following command:
+ openssl pkcs12 -export -in ~/.fedora.cert -CAfile ~/.fedora-upload-ca.cert -out ~/fedora-browser-cert.p12,
+ where .fedora-upload-ca.cert can be downloaded from the URL
+ referenced above.}}
+
+Installing SSL Certificates in Firefox
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. raw:: mediawiki
+
+ {{admon/note|Optional|You only need to check these instructions if you are intending to authenticate with the web interface with Firefox. Authenticating with the web interface is optional.}}
+
+Once you have created your FAS account, generated your certificate in
+the form posted in the link above and ran
+``fedora-packager-setup --with-browser-cert``, you will need to import
+it into your web browser. You can do this in Firefox by doing the
+following:
+
+1. Launch Firefox and click on the **Edit** menu from the toolbar
+
+2. Select **Preferences** in the sub-menu which appears.
+
+3. This should open the **Preferences** window where you can switch to
+the **Advanced** section
+
+4. In the **Advanced** section switch to the **Encryption** tab
+
+5. Click on the **View Certificates** button and the Certificates window
+will appear
+
+6. Switch to the **Your Certificates** tab and click on the **Import**
+button
+
+7. Point to where your Fedora Certificate is located and click **Open**
+(fedora-packager-setup will have told you where it was saved and will
+have asked you to set a password for the cert)
+
+You should now be able to see your Fedora Certificate listed under
+**Your Certificates** and you should be able to authenticate with the
+koji web interface.
+
+Installing SSL Certificates in Chromium
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. raw:: mediawiki
+
+ {{admon/note|Optional|You only need to check these instructions if you are intending to authenticate with the web interface with Chromium. Authenticating with the web interface is optional.}}
+
+Chromium uses the NSS Shared DB, you will need the nss-tools package
+installed.
+
+::
+
+ pk12util -d sql:$HOME/.pki/nssdb -i fedora-browser-cert.p12
+
+Notifications
+^^^^^^^^^^^^^
+
+When authenticated with the Koji web interface, you can setup a
+notification requests to make sure you do not miss when a package you
+care about gets built. Login and scroll to the bottom of the page, there
+you should find a *`Add a
+notification `__*
+link and a list of your configured notifications.
+
+Building with fedpkg targets
+----------------------------
+
+Every push is automatically tagged via git. All you have done to build
+the package is to run,
+
+::
+
+ fedpkg build
+
+This will trigger a build request for the branch. Easy!
+
+It is also possible to target a specific koji tag as follows:
+
+::
+
+ fedpkg build --target TARGET
+
+for example, if building on rawhide against a special tag created by
+rel-eng for updating API for many packages, e.g. ``dist-f14-python`` you
+would use the following:
+
+::
+
+ fedpkg build --target 'dist-f14-python'
+
+Chained builds
+^^^^^^^^^^^^^^
+
+.. raw:: mediawiki
+
+ {{Admon/warning | chain-builds only work when building on the devel/ branch (aka rawhide). To chain-build packages to update a released OS version, [https://fedoraproject.org/wiki/Bodhi/BuildRootOverrides set up an override using bodhi] requesting packages to be included in the proper buildroot.}}
+
+Sometimes you want to make sure than one build succeeded before
+launching the next one, for example when you want to rebuild a package
+against a just rebuilt dependency. In that case you can use a chain
+build with:
+
+``fedpkg chain-build libwidget libgizmo``
+
+The current package is added to the end of the CHAIN list. Colons (:)
+can be used in the CHAIN parameter to define groups of packages.
+Packages in any single group will be built in parallel and all packages
+in a group must build successfully and populate the repository before
+the next group will begin building. For example:
+
+``fedpkg chain-build libwidget libaselib : libgizmo :``
+
+will cause libwidget and libaselib to be built in parallel, followed by
+libgizmo and then the currect directory package. If no groups are
+defined, packages will be built sequentially.
+
+If a build fail, following builds are cancelled but the builds that
+already succeeded are pushed to the repository.
+
+Scratch Builds
+--------------
+
+Sometimes it is useful to be able to build a package against the
+buildroot but without actually including it in the release. This is
+called a scratch build. The following section covers using koji directly
+as well as the fedpkg tool to do scratch builds. To create a scratch
+build from changes you haven't committed, do the following:
+
+::
+
+ rpmbuild -bs foo.spec
+ koji build --scratch rawhide foo.srpm
+
+From the latest git commit:
+
+::
+
+ koji build --scratch rawhide 'git url'
+
+Warning: Scratch builds will *not* work correctly if your .spec file
+does something different depending on the value of %fedora, %fc9, and so
+on. Macro values like these are set by the *builder*, not by koji, so
+the value of %fedora will be for whatever created the source RPM, and
+*not* what it's being built on. Non-scratch builds get around this by
+first re-building the source RPM.
+
+If you have committed the changes to git and you are in the current
+branch, you can do a scratch build with fedpkg tool which wraps the koji
+command line tool with the appropriate options:
+
+::
+
+ fedpkg scratch-build
+
+if you want to do a scratch build for a specific architecture, you can
+type:
+
+::
+
+ fedpkg scratch-build-
+
+ can be a comma separated list of several architectures.
+
+finally is possible to combine the scratch-build command with a specific
+koji tag in the form:
+
+::
+
+ fedpkg scratch-build --target TARGET
+
+fedpkg scratch-build --help or koji build --help for more information.
+
+Build Failures
+--------------
+
+If your package fails to build, you will see something like this:
+
+::
+
+ 420066 buildArch kernel-2.6.18-1.2739.10.9.el5.jjf.215394.2.src.rpm,
+ ia64): open (build-1.example.com) -> FAILED: BuildrootError:
+ error building package (arch ia64), mock exited with status 10
+
+You can figure out why the build failed by looking at the log files. If
+there is a build.log, start there. Otherwise, look at init.log.
+
+Logs can be found via the web interface in the Task pages for the failed
+task. Alternatively the koji client can be used to view the logs via the
+``watch-logs`` command. See the help output for more details.
+
+Advanced use of Koji
+--------------------
+
+We've tried to make Koji self-documenting wherever possible. The command
+line tool will print a list of valid commands and each command supports
+--help. For example:
+
+::
+
+ $ koji help
+
+ Koji commands are:
+ build Build a package from source
+ cancel-task Cancel a task
+ help List available commands
+ latest-build Print the latest rpms for a tag
+ latest-pkg Print the latest builds for a tag
+ [...]
+
+::
+
+ $ koji build --help
+
+ usage: koji build [options] tag URL
+ (Specify the --help global option for a list of other help options)
+
+ options:
+ -h, --help show this help message and exit
+ --skip-tag Do not attempt to tag package
+ --scratch Perform a scratch build
+ --nowait Don't wait on build
+ [...]
+
+Using koji to generate a mock config to replicate a buildroot
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+koji can be used to replicate a build root for local debugging
+
+::
+
+ koji mock-config --help
+ Usage: koji mock-config [options] name
+ (Specify the --help global option for a list of other help options)
+
+ Options:
+ -h, --help show this help message and exit
+ --arch=ARCH Specify the arch
+ --tag=TAG Create a mock config for a tag
+ --task=TASK Duplicate the mock config of a previous task
+ --buildroot=BUILDROOT
+ Duplicate the mock config for the specified buildroot
+ id
+ --mockdir=DIR Specify mockdir
+ --topdir=DIR Specify topdir
+ --topurl=URL url under which Koji files are accessible
+ --distribution=DISTRIBUTION
+ Change the distribution macro
+ -o FILE Output to a file
+
+for example to get the latest buildroot for dist-f12-build run
+
+::
+
+ koji mock-config --tag dist-f12-build --arch=x86_64 --topurl=http://kojipkgs.fedoraproject.org/ dist-f12
+
+you will need to pass in --topurl=http://kojipkgs.fedoraproject.org/ to
+any mock-config command to get a working mock-config from fedoras koji.
+
+Using Koji to control tasks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+List tasks:
+
+::
+
+ koji list-tasks
+
+List only tasks requested by you:
+
+::
+
+ koji list-tasks --mine
+
+requeue an already-processed task: general syntax is: koji resubmit
+[options] taskID
+
+::
+
+ koji resubmit 3
+
+Building a Package with the command-line tool
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Instead of using the fedpkg target, you can also directly use the
+command\_line tool, koji.
+
+To build a package, the syntax is:
+
+::
+
+ $ koji build
+
+For example:
+
+::
+
+ $ koji build dist-f14 'git url'
+
+The koji build command creates a build task in Koji. By default the tool
+will wait and print status updates until the build completes. You can
+override this with the --nowait option.
+
+.. raw:: html
+
+
+
+NOTE: For fedora koji, the git url MUST be based on
+pkgs.fedoraproject.org. Other arbitrary git repos cannot be used for
+builds.
+
+Koji tags and packages organization
+-----------------------------------
+
+Terminology
+^^^^^^^^^^^
+
+In Koji, it is sometimes necessary to distinguish between a package in
+general, a specific build of a package, and the various rpm files
+created by a build. When precision is needed, these terms should be
+interpreted as follows:
+
+- Package: The name of a source rpm. This refers to the package in
+ general and not any particular build or subpackage. For example:
+ kernel, glibc, etc.
+- Build: A particular build of a package. This refers to the entire
+ build: all arches and subpackages. For example: kernel-2.6.9-34.EL,
+ glibc-2.3.4-2.19.
+- RPM: A particular rpm. A specific arch and subpackage of a build. For
+ example: kernel-2.6.9-34.EL.x86\_64, kernel-devel-2.6.9-34.EL.s390,
+ glibc-2.3.4-2.19.i686, glibc-common-2.3.4-2.19.ia64
+
+Tags and targets
+^^^^^^^^^^^^^^^^
+
+Koji organizes packages using tags. In Koji a tag is roughly a
+collection of packages:
+
+- Tags support inheritance
+- Each tag has its own list of valid packages (inheritable)
+- Package ownership can be set per-tag (inheritable)
+- When you build you specify a target rather than a tag
+
+A build target specifies where a package should be built and how it
+should be tagged afterwards. This allows target names to remain fixed as
+tags change through releases.
+
+Koji commands for tags
+^^^^^^^^^^^^^^^^^^^^^^
+
+Targets
+'''''''
+
+You can get a full list of build targets with the following command:
+
+::
+
+ $ koji list-targets
+
+You can see just a single target with the --name option:
+
+::
+
+ $ koji list-targets --name dist-f14
+
+ Name Buildroot Destination
+ ---------------------------------------------------------------------------------------------
+ dist-f14 dist-f14-build dist-f14
+
+This tells you a build for target dist-f14 will use a buildroot with
+packages from the tag dist-f14-build and tag the resulting packages as
+dist-f14.
+
+Watch out: You probably don't want to build against dist-rawhide. If
+Fedora N is the latest one out, to build to the next one, choose
+dist-f{N+1}.
+
+Tags
+''''
+
+You can get a list of tags with the following command:
+
+::
+
+ $ koji list-tags
+
+Packages
+''''''''
+
+As mentioned above, each tag has its own list of packages that may be
+placed in the tag. To see that list for a tag, use the list-pkgs
+command:
+
+::
+
+ $ koji list-pkgs --tag dist-f14
+
+The first column is the name of the package, the second tells you which
+tag the package entry has been inherited from, and the third tells you
+the owner of the package.
+
+Latest Builds
+'''''''''''''
+
+To see the latest builds for a tag, use the latest-pkg command:
+
+::
+
+ $ koji latest-pkg --all dist-f14
+
+The output gives you not only the latest builds, but which tag they have
+been inherited from and who built them.
+
+`Category:Package Maintainers `__
diff --git a/docs/source/writing_a_plugin.rst b/docs/source/writing_a_plugin.rst
new file mode 100644
index 00000000..3611302b
--- /dev/null
+++ b/docs/source/writing_a_plugin.rst
@@ -0,0 +1,190 @@
+=========================
+How to write Koji plugins
+=========================
+
+
+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
diff --git a/docs/source/writing_koji_code.rst b/docs/source/writing_koji_code.rst
new file mode 100644
index 00000000..4dbf7929
--- /dev/null
+++ b/docs/source/writing_koji_code.rst
@@ -0,0 +1,631 @@
+=================
+Writing Koji Code
+=================
+
+Getting Started Hacking on Koji
+===============================
+
+
+This page gives an overview of the Koji code and then describes what
+needs to change if you want to add a new type of task. A new task could
+be for a new content type, or assembling the results of multiple builds
+together, or something else that helps your workflow. New contributors
+to Koji should leave this page knowing where to begin and have enough
+understanding of Koji's architecture to be able to estimate how much
+work is still ahead of them.
+
+Task Flow
+=========
+
+A task starts with a user submitting it with the Koji client, which is a
+command line interface. This contacts the hub, an apache-based server
+application. It leaves a row in the database that represents a "free"
+task, one that has not been assigned to a builder. Periodically, the
+builders asynchronously ping the hub asking if there are any tasks
+available, and at some point one will be given the new task. The hub
+marks this in the database, and the builder begins executing the task (a
+build).
+
+Upon completion, the builder uploads the results to the hub, including
+logs, binaries, environment information, and whatever else the task
+handler for the build dictated. The hub moves the results to a permanent
+shared storage solution, and marks the task as completed (or failed).
+During this whole time, the webUI can be used to check up on progress.
+So the flow of work is:
+
+::
+
+ Client -> Hub -> Builder -> Hub
+
+If you wanted to add a new build type or task that was tightly
+integrated in Koji's data model, you would need to modify the CLI, Hub,
+Builder, and WebUI at a minimum. Alternatively, you could do this with a
+plugin, which is far simpler but less flexible.
+
+Component Overview
+==================
+
+Koji is comprised of several components, this section goes into details
+for each one, and what you potentially may need to change. Every
+component is written in Python, so you will need to know that language
+beyond a beginner level.
+
+Koji-client
+-----------
+
+koji-client is a command line interface that provides many hooks into
+Koji. It allows the user to query much of the data as well as perform
+actions such as adding users and initiating build requests.
+
+Option Handling
+~~~~~~~~~~~~~~~
+
+The code is in ``cli/koji``. It uses ``OptionParsers`` extensively with
+interspersed arguments disabled. That means these two commands are not
+interpreted the same:
+
+::
+
+ $ koji -u admin -p password tag-build some-tag --force some-build
+ $ koji tag-build -u admin -p password some-tag --force some-build
+
+The second one will generate an error, because -u and -p are not options
+for tag-build, they must show up before that because they are global
+options that can be used with any subcommand. There will be two
+``OptionParsers`` used with each command. The first is used to pick up
+arguments to ``koji`` itself, and the second for the subcommand
+specified. When the first one executes (see ``get_options()``) it will
+figure out the subcommand and come up with a function name based on it.
+
+The convention is to prepend the word ``handle_`` before it, and change
+all hyphens to underscores. If a command does not require an account
+with Koji, the function handle will prepended with ``anon_handle_``
+instead. The code will dynamically call the derived function handle
+which is where the second ``OptionParser`` is used to parse the
+remaining options. To have your code log into Koji (you're writing a
+handle\_ function), use the ``activate_session`` function. All function
+signatures in the client code will get a session object, which is your
+interface to the hub.
+
+Profiles
+~~~~~~~~
+
+It is possible to run the Koji client with different configuration
+profiles so that you can interact with multiple Koji instances easily.
+The ``--profile`` option to the Koji command itself enables this. You
+should have a ``~/.koji/config`` already, if not just copy from
+``/etc/koji.conf`` to get a start. The profile command accepts an
+argument that matches a section in that config file. So if your config
+file had this:
+
+::
+
+ [Fedora]
+ authtype = ssl
+ server = http://koji.fedoraproject.org/kojihub
+ topdir = /mnt/koji
+ weburl = http://koji.fedoraproject.org/koji
+ #pkgurl = http://koji.fedoraproject.org/packages
+ cert = ~/.fedora.cert
+ ca = ~/.fedora-upload-ca.cert
+ serverca = ~/.fedora-server-ca.cert
+
+ [MyKoji]
+ server = http://koji.mydomain.com/kojihub
+ authtype = kerberos
+ topdir = /mnt/koji
+ weburl = http://koji.mydomain.com/koji
+ topurl = http://download.mydomain.com/kojifiles
+
+you could pass Fedora or MyKoji to --profile.
+
+Creating Tasks
+~~~~~~~~~~~~~~
+
+Once options are processed and understood, a task needs to be created on
+the hub so that a builder can come along and take it. This is
+accomplished with the ``maskTask`` method (defined on the Hub, so call
+it on the ``session`` object). The name of the task should match the
+name given to the task handler in the builder, which is explained later
+on.
+
+Be sure to process the channel, priority, background, and watch/nowatch
+parameters too, which should be available to most new tasks. They'll be
+buried in the first argument to your handler function, which captures
+the options passed to the base Koji command.
+
+If the client needs to make locally-available artifacts (config files,
+sources, kickstarts) accessible to the builder, it must be uploaded to
+the hub. This is the case with uploading SRPMs or kickstarts. You can
+easily upload this content with the ``session.uploadWrapper`` method.
+You can create progress bars as necessary with this snippet:
+
+::
+
+ if _running_in_bg() or task_opts.noprogress:
+ callback = None
+ else:
+ callback = _progress_callback
+ serverdir = _unique_path('cli-image') # create a unique path on the hub
+ session.uploadWrapper(somefile, serverdir, callback=callback)
+
+Task Arguments
+~~~~~~~~~~~~~~
+
+If you define a new task for Koji, you'll want the task submission
+output to have the options ordered usefully. This output is
+automatically generated, but sometimes it does not capture the more
+important arguments you want displayed.
+
+::
+
+ Created task 10001810
+ Watching tasks (this may be safely interrupted)...
+ 10001810 thing (noarch): free
+ 10001810 thing (noarch): free -> closed
+ 0 free 0 open 1 done 0 failed
+
+ 10001810 thing (noarch) completed successfully
+
+In this (fake) example, you can see that "noarch" is the only option
+being displayed, but maybe you want something more than just the task
+architecture displayed, like some other options that were passed in. You
+can fix this behavior in ``koji/__init__.py`` in the \_taskLabel
+function. Here you can define the string(s) to display when Koji
+receives status on a task. That is the return value.
+
+Koji-Hub
+--------
+
+koji-hub is the center of all Koji operations. It is an XML-RPC server
+running under mod\_wsgi in Apache. koji-hub is passive in that it only
+receives XML-RPC calls and relies upon the build daemons and other
+components to initiate communication. koji-hub is the only component
+that has direct access to the database and is one of the two components
+that have write access to the file system. If you want to make changes
+to the webUI (new pages or themes), you are looking in the wrong
+section, there is a separate component for that.
+
+Implementation Details
+~~~~~~~~~~~~~~~~~~~~~~
+
+The **hub/kojihub.py** file is where the server-side code lives. If you
+need to fix any server problems or want to add any new tasks, you will
+need to modify this file. Changes to the database schema will almost
+certainly require code changes too. This file gets deployed to
+**/usr/share/koji-hub/kojihub.py**, whenever you make changes to that
+remember to restart **httpd**. Also there are cases where httpd looks
+for an existing .pyc file and takes it as-is, instead of re-compiling it
+when the code is changed.
+
+In the code there are two large classes: **RootExports** and
+**HostExports**. RootExports exposes methods using XMLRPC for any client
+that connects to the server. The Koji CLI makes use of this quite a bit.
+If you want to expose a new API to any remote system, add your code
+here. The HostExports class does the same thing except it will ensure
+the requests are only coming from builders. Attempting to use an API
+exposed here with the CLI will fail. If your work requires the builders
+to call a new API, you should implement it here. Any other function
+defined in this file is inaccessible by remote hosts. It is generally a
+good practice to have the exposed APIs do very little work, and pass off
+control to internal functions to do the heavy lifting.
+
+Database Interactions
+~~~~~~~~~~~~~~~~~~~~~
+
+Database interactions are done with raw query strings, not with any kind
+of modern ORM. Consider using context objects from the Koji contexts
+library for thread-safe interactions. The database schema is captured in
+the **docs** directory in the root of a git clone. A visualization of
+the schema is not available at the time of this writing.
+
+If you plan to introduce schema changes, please update both
+``schema.sql`` and provide a migration script if necessary.
+
+Troubleshooting
+~~~~~~~~~~~~~~~
+
+The hub runs in an Apache service, so you will need to look in Apache
+logs for error messages if you are encountering 500 errors or the
+service is failing to start. Specifically you want to check in:
+
+- /var/log/httpd/error\_log
+- /var/log/httpd/ssl\_error\_log
+
+If you need more specific tracebacks and debugging data, consider
+changing the debugging setting in **/etc/koji-hub/hub.conf**. Be advised
+the hub is very verbose with this setting on, your logs will take up
+gigabytes of space within several days.
+
+Kojid
+-----
+
+kojid is the build daemon that runs on each of the build machines. Its
+primary responsibility is polling for incoming build requests and
+handling them accordingly. Essentially kojid asks koji-hub for work.
+Koji also has support for tasks other than building. Creating install
+images is one example. kojid is responsible for handling these tasks as
+well. kojid uses mock for building. It also creates a fresh buildroot
+for every build. kojid is written in Python and communicates with
+koji-hub via XML-RPC.
+
+Implementation Details
+~~~~~~~~~~~~~~~~~~~~~~
+
+The daemon runs as a service on a host that is traditionally not the
+same as the hub or webUI. This is a good security practice because the
+service runs as root, and executes untrusted code to produce builds on a
+regular basis. Keeping the Hub separate limits the damage a malicious
+package can do to the build system as a whole. For the same reason, the
+filesystem that the hub keeps built software on should be mounted
+Read-Only on the build host. It should call APIs on the hub that are
+exposed through the ``HostExports`` class in the hub code. Whenever the
+builder accepts a task, it forks a process to carry out the build.
+
+An initscript/unit-file is available for kojid, so it can be stopped and
+started like a normal service. Remember to do this when you deploy
+changes!
+
+TaskHandlers
+^^^^^^^^^^^^
+
+All tasks in kojid have a ``TaskHandler`` class that defines what to do
+when the task is picked up from the hub. The base class is defined in
+``koji/tasks.py`` where a lot of useful utility methods are available.
+An example is ``uploadFile``, which is used to upload logs and built
+binaries from a completed build to the hub since the shared filesystem
+is read only.
+
+The daemon code lives in ``builder/kojid``, which is deployed to
+/usr/sbin/kojid. In there you'll notice that each task handler class has
+a ``Methods`` member and ``_taskWeight`` member. These must be defined,
+and the former is used to match the name of a waiting task (on the hub)
+with the task handler code to execute. Each task handler object must
+have a ``handler`` method defined, which is the entry point for the
+forked process when a builder accepts a task.
+
+Tasks can have subtasks, which is a typical model when a build can be
+run on multiple architectures. In this case, developers should write 2
+task handlers: one handles the build for exact one architecture, and one
+that assembles the results of those tasks into a single build, and sends
+status information to the hub. You can think of the latter handler as
+the parent task.
+
+All task handler objects have a ``session`` object defined, which is the
+interface to use for communications with the hub. So, parent tasks
+should kick off child tasks using the session object's subtask method
+(which is part of HostExports). It should then call ``self.wait`` with
+``all=True`` to wait for the results of the child tasks.
+
+Here's a stub of what a new build task might look like:
+
+::
+
+ class BuildThingTask(BaseTaskHandler):
+ Methods = ['thing']
+ _taskWeight = 0.5
+
+ def handler(self, a, b, arches, options):
+ subtasks = {}
+ for arch in arches:
+ subtasks[arch] = session.host.subtask(method='thingArch', a, b, arch)
+ results = self.wait(subtasks.values(), all=True)
+ # parse results and put rows in database
+ # put files in their final resting place
+ return 'Build successful'
+
+ class BuildThingArchTask(BaseTaskHandler):
+ Methods = ['thingArch']
+ _taskWeight = 2.0
+
+ def handler(self, a, b, arch):
+ # do the build, capture results in a variable
+ self.uploadFile('/path/to/some/log')
+ self.uploadFile('/path/to/binary/file')
+ return result
+
+Source Control Managers
+^^^^^^^^^^^^^^^^^^^^^^^
+
+If you your build needs to check out code from a Source Control Manager
+(SCM) such as git or subversion, you can use SCM objects defined in
+``koji/daemon.py``. They take a specially formed URL as an argument to
+the constructor. Here's an example use. The second line is important, it
+makes sure the SCM is in the whitelist of SCMs allowed in
+``/etc/kojid/kojid.conf``.
+
+::
+
+ scm = SCM(url)
+ scm.assert_allowed(self.options.allowed_scms)
+ directory = scm.checkout('/checkout/path', session, uploaddir, logfile)
+
+Checking out takes 4 arguments: where to checkout, a session object
+(which is how authentication is handled), a directory to upload the log
+to, and a string representing the log file name. Using this method Koji
+will checkout (or clone) a remote repository and upload a log of the
+standard output to the task results.
+
+Build Root Objects
+^^^^^^^^^^^^^^^^^^
+
+It is encouraged to build software in mock chroots if appropriate. That
+way Koji can easily track precise details about the environment in which
+the build was executed. In ``builder/kojid`` a BuildRoot class is
+defined, which provides an interface to execute mock commands. Here's an
+example of their use:
+
+::
+
+ broot = BuildRoot(self.session, self.options, build_tag, arch, self.id)
+
+A session object, task options, and a build tag should be passed in
+as-is. You should also specify the architecture and the task ID. If you
+ever need to pass in specialized options to mock, look in the
+ImageTask.makeImgBuildRoot method to see how they are defined and passed
+in to the BuildRoot constructor.
+
+Troubleshooting
+~~~~~~~~~~~~~~~
+
+The daemon writes a log file to ``/var/log/kojid.log``. Debugging output
+can be turned on in ``/etc/kojid/kojid.conf``.
+
+Koji-Web
+--------
+
+koji-web is a set of scripts that run in mod\_wsgi and use the Cheetah
+templating engine to provide a web interface to Koji. It acts as a
+client to koji-hub providing a visual interface to perform a limited
+amount of administration. koji-web exposes a lot of information and also
+provides a means for certain operations, such as cancelling builds.
+
+The web pages are derived from Cheetah templates, the syntax of which
+you can read up on
+`here `__. These
+templates are the ``chtml`` files sitting in ``www/kojiweb``. You'll
+notice quickly that these templates are referencing variables, but where
+do they come from?
+
+The ``www/kojiweb/index.py`` file provides them. There are several
+functions named after the templates they support, and in each one a
+dictionary called ``values`` is populated. This is how data is gathered
+about the task, build, archive, or whatever the page is about. Take your
+time with ``taskinfo.chtml`` in particular, as the conditionals there
+have gotten quite long. If you are adding a new task to Koji, you will
+need to extend this at a minimum. A new type of build task would require
+this, and possibly another that is specific to viewing the archived
+information about the build. (taskinfo vs. buildinfo)
+
+If your web page needs to display the contents of a list or dictionary,
+use the ``$printMap`` function to help with that. It is often sensible
+to define a function that easily prints options and values in a
+dictionary. An example of this is in taskinfo.chtml.
+
+::
+
+ #def printOpts($opts)
+ #if $opts
+ Options:
+ $printMap($opts, ' ')
+ #end if
+ #end def
+
+Finally, if you need to expand the drop-down menus of "method" types
+when searching for tasks in the WebUI, you will need to add them to the
+``_TASKS`` list in ``www/kojiweb/index.py``. Add values where
+appropriate to ``_TOPLEVEL_TASKS`` and ``_PARENT_TASKS`` as well so that
+parent-child relationships show up correctly too.
+
+Remember whenever you update a template or index.py, you will need to
+deploy and restart apache/httpd!
+
+Troubleshooting
+~~~~~~~~~~~~~~~
+
+Like the hub, this component is backed by apache, so you should follow
+the same techniques for debugging Koji-Web as
+`Koji-Hub <#Troubleshooting>`__.
+
+Kojira
+------
+
+kojira is a daemon that keeps the build root repodata updated. It is
+responsible for removing redundant build roots and cleaning up after a
+build request is completed.
+
+Building and Deploying Changes
+==============================
+
+The root of the git clone for Koji code contains a ``Makefile`` that has
+a few targets to make building and deployment a little easier. Among
+them are:
+
+- tarball: create a bz2 tarball that could be consumed in an rpm build
+- rpm: create Koji rpms. The NVRs will be defined by the spec file,
+ which is also in the same directory. The results will appear in a
+ ``noarch`` directory.
+- test-rpm: like rpm, but append the Release field with a date and time
+ stamp for easy upgrade-deployment
+
+Plugins
+=======
+
+This section is copied from the ``docs/Writing_a_plugin.md`` file.
+
+Koji supports different types of plugins, three of which are captured
+here. Depending on what you are trying to do, there are different ways
+to write a Koji plugin.
+
+Koji Builder Plugins
+--------------------
+
+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 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``
+
+Hub Plugins
+-----------
+
+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
+
+What's happening?
+
+- 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
+ correct permissions are available.
+
+Save your plugin as e.g \`mymethod.py\`, then install it in the Koji Hub
+plugins folder, which is ``/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')
+
+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.
+
+Event Plugin
+------------
+
+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 too, 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
+
+So what is this doing?
+
+- 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``
+
+Patch Review
+============
+
+If you have a patch to submit, please send it to
+koji-devel@lists.fedoraproject.org. Here are some guidelines on
+producing preferable patches.
+
+- Please do not "patch bomb". Keep them manageable, perhaps providing a
+ patch for each component that is getting changes.
+- Adhere to `PEP8 `__
+- Provide patches a feature at a time, not a pile of several. Please
+ follow the same practice for bugs.
+- Consider using ``git-send-email``, or just attach the patches to the
+ email
+- Patches should apply cleanly to HEAD of the intended branch
+- Please maintain backward-compatibility up to RHEL 5 (which means
+ Python 2.4)
+
+There are only 3-5 people with commit access that regularly watch the
+mailing list, so responses may take a couple days if we're all occupied.