Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ktdreyer/koji-ansible

Ansible modules to manage Koji resources
https://github.com/ktdreyer/koji-ansible

Last synced: 7 days ago
JSON representation

Ansible modules to manage Koji resources

Awesome Lists containing this project

README

        

koji-ansible
============

.. image:: https://github.com/ktdreyer/koji-ansible/workflows/tests/badge.svg
:target: https://github.com/ktdreyer/koji-ansible/actions

.. image:: https://codecov.io/gh/ktdreyer/koji-ansible/branch/master/graph/badge.svg
:target: https://codecov.io/gh/ktdreyer/koji-ansible

.. image:: https://img.shields.io/badge/dynamic/json?style=flat&label=galaxy&prefix=v&url=https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/index/ktdreyer/koji_ansible/&query=highest_version.version
:target: https://galaxy.ansible.com/ui/repo/published/ktdreyer/koji_ansible/

Ansible modules to manage `Koji `_ resources.

This is not about installing Koji. Instead, it is a way to declaratively
define things within Koji, where you might normally use the koji CLI.

koji_tag
--------

The ``koji_tag`` module can create, update, and delete tags within Koji. It can
also manage the tag inheritance, packages list and groups list for a tag.

.. code-block:: yaml

- name: Create a koji tag for the ceph product
koji_tag:
name: ceph-3.1-rhel-7
arches: x86_64
state: present
packages:
kdreyer:
- ansible
- ceph
- ceph-ansible
groups:
srpm-build:
- rpm-build
- fedpkg

koji_target
-----------

The ``koji_target`` module can create, update, and delete targets within Koji.

.. code-block:: yaml

- name: Create a koji build target for Fedora 34
koji_target:
name: f34-candidate
build_tag: f34-build
dest_tag: f34-updates-candidate
state: present

koji_external_repo
------------------

The ``koji_external_repo`` module can create, update, and delete `external
repositories `_
within Koji.

.. code-block:: yaml

- name: Create an external repo for CentOS "CR"
koji_external_repo:
name: centos7-cr
url: http://mirror.centos.org/centos/7/cr/$arch/
state: present

You can then configure these repositories (and their priorities) on each of
your Koji tags with the ``external_repos`` parameter to the ``koji_tag``
module.

koji_cg
-------

The ``koji_cg`` module can grant or revoke access to a `content generator
`_ for a user account.

This user account must already exist in Koji's database. For example, you may
run an authenticated ``koji hello`` command to create the account database
entry.

.. code-block:: yaml

- name: Grant access to the rcm/debbuild account
koji_cg:
koji: mykoji
name: debian
user: rcm/debbuild
state: present

Your Koji Hub must be version 1.19 or newer in order to use the new
`listCGs `_ RPC.

koji_btype
----------

The ``koji_btype`` module can add new build types. These are typically in
support of `content generators
`_.

(Koji only supports adding new build types, not deleting them.)

.. code-block:: yaml

- name: Add debian build type to Koji
koji_btype:
koji: mykoji
name: debian
state: present

koji_archivetype
----------------

The ``koji_archivetype`` module can add new archive types. This allows Koji to
recognize new build archive files, for example ``.dsc`` files. These are
typically in support of `content generators
`_.

(Koji only supports adding new archive types, not deleting them.)

Your Koji Hub must be version 1.20 or newer in order to use the new
`addArchiveType `_ RPC.

.. code-block:: yaml

- name: Add dsc archive type
koji_archivetype:
name: dsc
description: Debian source control file
extensions: dsc
state: present

koji_host
---------

The ``koji_host`` module can add new hosts and manage existing hosts.

Koji only supports adding new hosts, not deleting them. Once they're defined,
you can enable or disable the hosts with ``state: enabled`` or ``state:
disabled``.

.. code-block:: yaml

- name: Add new builder1 host
koji_host:
name: builder1.example.com
arches: [x86_64]
state: enabled
channels:
- default
- createrepo

If you specify channels that do not yet exist, Ansible will create them. For
example, if you are setting up a new builder host for `OSBS
`_, you can specify ``container`` in the list of
channels, and Ansible will automatically create that new "container" channel
when it configures the host.

koji_user
---------

The ``koji_user`` module can add new users and manage existing users and
permissions.

Koji only supports adding new users, not deleting them. Once they're defined,
you can enable or disable the users with ``state: enabled`` or ``state:
disabled``.

.. code-block:: yaml

- name: Add new kdreyer user
koji_user:
name: kdreyer
state: enabled
permissions: [admin]

koji_tag_inheritance
--------------------

The ``koji_tag`` module (above) is all-or-nothing when it comes to managing
tag inheritance. When you set inheritance with ``koji_tag``, the module will
delete any inheritance relationships that are not defined there.

In some cases you may want to declare *some* inheritance relationships within
Ansible without clobbering other existing inheritance relationships. For
example, `MBS `_
will dynamically manage some inheritance relationships of tags, and you do not
want Ansible to fight MBS.

To declare inheritance relationships with finer granularity, you may use the
``koji_tag_inheritance`` module.

.. code-block:: yaml

- name: set devtoolset-7 as a parent of ceph nautilus
koji_tag_inheritance:
parent_tag: sclo7-devtoolset-7-rh-release
child_tag: storage7-ceph-nautilus-el7-build
priority: 25

This will only mange that single parent-child relationship between the two
tags, and it will not delete any other inheritance relationships.

Another approach is to have MBS operate on a dedicated "-modules" tag and then
inherit from that, so that you do not have to use this Ansible module.

koji_tag_packages
-----------------

The ``koji_tag`` module (above) is all-or-nothing when it comes to managing
packages. When you set packages with ``koji_tag``, the module will
delete any packages that are not defined there.

In some cases you may want to declare *some* packages within
Ansible without clobbering existing packages. For example, if you have a
separate tool that might add or remove packages from tags dynamically, you do
not want Ansible to fight that other tooling.

To declare packages with finer granularity, you may use the
``koji_tag_packages`` module.

.. code-block:: yaml

- name: ensure ceph packages are present and ownership set
koji_tag_packages:
tag: ceph-3.1-rhel-7
packages:
kdreyer:
- ceph
aschoen:
- ansible
state: present

- name: ensure koji packages are absent
koji_tag_packages:
tag: ceph-3.1-rhel-7
packages:
kdreyer:
- koji
state: absent

This will only mange the packages defined and will not change any other
packages on the tag.

koji_call
---------

The ``koji_call`` module allows you to send raw RPCs to the Koji hub. This
exposes the entire `Koji API `_ to
you directly.

Why would you use this module instead of the higher level modules like
``koji_tag``, ``koji_target``, etc? This ``koji_call`` module has two main
uses-cases:

1. You may want to do something that the higher level modules do not yet
support. It can be easier to use this module to quickly prototype out your
ideas for what actions you need, and then write the Python code to do it in
a better way later. If you find that you need to use koji_call to achieve
functionality that is not yet present in the other koji-ansible modules,
please file a Feature Request issue in `GitHub
`_ with your use case.
2. You want to write some tests that verify Koji's data at a very low level.
For example, you may want to write an integration test to verify that
you've set up your Koji configuration in the way you expect.

Note that this module will always report "changed: true" every time, because
it simply sends the RPC to the Koji Hub on every ansible run. This module
cannot understand if your chosen RPC actually "changes" anything.

.. code-block:: yaml

- name: make a raw API call:
koji_call:
name: getTag
args: [f34-build]
register: call_result

- debug:
var: call_result.data

This will print the tag information for the `Fedora 34 -build tag
`_. It is similar
to running ``koji taginfo f34-build`` on the command-line.

Koji profiles
-------------

You must tell koji-ansible which `Koji client profile
`_ to use.

Here is an example of setting a profile explicitly on the task:

.. code-block:: yaml

- name: Create a koji tag for the ceph product
koji_tag:
koji: kojidev
name: ceph-3.1-rhel-7
arches: x86_64
state: present

The ``koji: kojidev`` setting means Ansible will search
``~/.koji/config.d/*.conf`` and ``/etc/koji.conf.d/*.conf`` for the
``[kojidev]`` config section and perform the tag management on that Koji hub
listed there.

To avoid specifying this ``koji:`` argument on every task, you can set the
``KOJI_PROFILE`` environment variable when running ``ansible-playbook``.
koji-ansible will fall back to using ``KOJI_PROFILE`` for the tasks that have
no explicit ``koji:`` argument::

KOJI_PROFILE=kojidev ansible-playbook -v my-koji-playbook.yaml

Installing from Ansible Galaxy
------------------------------

We distribute koji-ansible through the `Ansible Galaxy
`_.

If you are using Ansible 2.9 or greater, you can `install
`_
koji-ansible like so::

ansible-galaxy collection install ktdreyer.koji_ansible

This will install the latest Git snapshot automatically. Use ``--force``
upgrade your installed version to the latest version.

Using this Ansible Galaxy Collection inside a role
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Here is an example of a simple playbook and role that uses this collection.
``playbook.yml`` calls one role named ``my-koji-project``::

top
├── playbook.yml
└── roles
└── my-koji-project
├── collections
│   └── requirements.yml
├── meta
│   └── main.yml
└── tasks
└── main.yml

The ``playbook.yml`` file is a small playbook that simply loads our role::

- name: Test a role that uses koji-ansible
hosts: localhost
gather_facts: false
roles:
- my-koji-project

The ``roles/my-koji-project/collections/requirements.yml`` file should require
this collection (and a specific version, as described above)::

collections:
- name: ktdreyer.koji_ansible

The ``roles/my-koji-project/meta/main.yml`` file tells Ansible to load any
custom modules in this role from the ``ktdreyer.koji_ansible`` collection
namespace::

collections:
- ktdreyer.koji_ansible

Lastly you can add your role's tasks as usual to ``roles/my-koji-project/tasks/main.yml``::

- name: create the "my-product-1.0" tag
koji_tag:
name: my-product-1.0

Role and collection dependencies must be installed separately. This is true even if
the dependencies are defined in the same requirements.yml.

For role dependencies::

ansible-galaxy install -r requirements.yml

For collection dependencies::

ansible-galaxy collection install -r requirements.yml

Running from a Git clone
------------------------

Instead of using the Ansible Collection tarball, you can use this project
directly from a Git clone. This is useful when hacking on the code.

These modules import ``common_koji`` from the ``module_utils`` directory.

One easy way to arrange your Ansible files is to symlink the ``library`` and
``module_utils`` directories into the directory with your playbook.

For example, if you have a ``koji.yml`` playbook that you run with
``ansible-playbook``, it should live alongside these ``library`` and
``module_utils`` directories::

top
├── koji.yml
├── module_utils
└── library

and you should run the playbook like so::

ansible-playbook koji.yml

Investigating changes that happened outside Ansible
---------------------------------------------------

Koji tracks a history of everything in its database. You can view this history
with the ``koji list-history`` and ``koji list-tag-history`` sub-commands.

For example, let's say that you wake up one morning to find that your Ansible
playbook for your tags no longer matches up with what is configured live in
Koji. Did someone else on your team make a change with the CLI without editing
the playbook or notifying you? Who did it, and when? Use ``koji list-history
--tag=my-tag`` to see the entire list of changes for your tag in the database.
After a friendly chat with the person who made the change, you can work
together to record the change within your Ansible playbook so your sources of
truth remain consistent.

Generating a playbook from a live Koji instance
-----------------------------------------------

Do you have a Koji hub that has many tags, targets, and other settings that
were crafted by hand over the years? You can use the
``./utils/generate-playbook`` script to query your Koji hub and write an
Ansible playbook that describes some or all of the tags. You can then store
this YAML in Git. Other things beyond tags and targets (like content
generators or users) are not yet supported.

This ``generate-playbook`` utility's output may not be the most elegant way to
manage your Koji tags. There will be lots of repetition, because it will not
use any Ansible variables, etc. The purpose of this utility is simply to help
you get up and running quickly with koji-ansible.

TODO
----

* Unit tests