commit 93a5d6425c8bf7a8270e27742d1328053f9fc98d
Author: Nicolas Chauvet <kwizart(a)gmail.com>
Date: Mon Sep 6 21:23:19 2021 +0200
Update koji-hub
roles/koji_hub/files/00-mpm.conf | 18 +++
roles/koji_hub/files/kojira.conf | 24 ++++
roles/koji_hub/tasks/main.yml | 177 +++++++++++++++++-------
roles/koji_hub/templates/fedmsg-koji-plugin.py | 109 +++++++++++----
roles/koji_hub/templates/hub.conf.j2 | 24 +++-
5 files changed, 266 insertions(+), 86 deletions(-)
---
diff --git a/roles/koji_hub/files/00-mpm.conf b/roles/koji_hub/files/00-mpm.conf
new file mode 100644
index 0000000..18c219a
--- /dev/null
+++ b/roles/koji_hub/files/00-mpm.conf
@@ -0,0 +1,18 @@
+# Select the MPM module which should be used by uncommenting exactly
+# one of the following LoadModule lines:
+
+# prefork MPM: Implements a non-threaded, pre-forking web server
+# See:
http://httpd.apache.org/docs/2.4/mod/prefork.html
+#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
+
+# worker MPM: Multi-Processing Module implementing a hybrid
+# multi-threaded multi-process web server
+# See:
http://httpd.apache.org/docs/2.4/mod/worker.html
+#
+LoadModule mpm_worker_module modules/mod_mpm_worker.so
+
+# event MPM: A variant of the worker MPM with the goal of consuming
+# threads only for connections with active processing
+# See:
http://httpd.apache.org/docs/2.4/mod/event.html
+#
+#LoadModule mpm_event_module modules/mod_mpm_event.so
diff --git a/roles/koji_hub/files/kojira.conf b/roles/koji_hub/files/kojira.conf
index 39990d7..759d504 100644
--- a/roles/koji_hub/files/kojira.conf
+++ b/roles/koji_hub/files/kojira.conf
@@ -27,6 +27,30 @@ with_src=no
; prevent kojira from flooding the build system with newRepo tasks
max_repo_tasks=6
+repo_tasks_limit=8
+
+;how soon (in seconds) to clean up expired repositories. 1 week default
+;keep repos for 3 days
+deleted_repo_lifetime = 259200
+
+;how soon (in seconds) to clean up dist repositories.
+;we want this super long so we don't delete latest repos
+;just set this to 6 months for now.
+dist_repo_lifetime = 7257600
+
+; If True, monitor external repos and trigger the appropriate Koji repo
+; regenerations when they change.
+; Note that you need to have your database set to use UTC, as otherwise
+; you can end with weird behaviour. For details see
+;
https://pagure.io/koji/issue/2159
+check_external_repos = True
+
+; Writable path could be set here. In such case, kojira will write a
+; list of currently monitored tags there with simple statistics in
+; every cycle. File would contain information about how long these
+; tags are expired and what is the computed score for them. This can
+; be used to debug and check in realtime the actual performance.
+queue_file = /mnt/koji/kojira/queue
;configuration for SSL athentication
diff --git a/roles/koji_hub/tasks/main.yml b/roles/koji_hub/tasks/main.yml
index 27826b8..772c623 100644
--- a/roles/koji_hub/tasks/main.yml
+++ b/roles/koji_hub/tasks/main.yml
@@ -13,6 +13,7 @@
- koji-containerbuild-hub
- mod_ssl
- mod_wsgi
+ - mod_auth_gssapi
- git
- gnupg2
tags:
@@ -53,6 +54,14 @@
#
https://lists.fedoraproject.org/pipermail/buildsys/2015-April/004636.html
when: env == 'staging'
+- name: set the apache mpm to use event MPM
+ copy: src=00-mpm.conf dest=/etc/httpd/conf.modules.d/00-mpm.conf
+ notify:
+ - reload proxyhttpd
+ tags:
+ - config
+ - koji_hub
+
- name: hub config
template: src=hub.conf.j2 dest=/etc/koji-hub/hub.conf owner=apache group=apache
mode=600
tags:
@@ -81,75 +90,142 @@
- selinux
- koji_hub
-- name: koji fedmsg plugin
- template: src=fedmsg-koji-plugin.py
dest=/usr/lib/koji-hub-plugins/fedmsg-koji-plugin.py
- notify:
- - reload httpd
+- name: install fedora-messaging as a dependency for the plugin (rhel7)
+ package: name={{ item }} state=present
+ with_items:
+ - python2-fedora-messaging
+ - python2-koji-sidetag-plugin-hub
+ tags:
+ - packages
+ - koji_hub
+ - fedora-messaging
+ when: ansible_distribution == "RedHat" and
ansible_distribution_major_version|int == 7
+
+- name: install fedora-messaging as a dependency for the plugin (fedora)
+ package: name={{ item }} state=present
+ with_items:
+ - python3-fedora-messaging
+ tags:
+ - packages
+ - koji_hub
+ - fedora-messaging
+ when: ansible_distribution == "Fedora"
+
+- name: create the config folder for fedora-messaging
+ file: path=/etc/fedora-messaging/ owner=root group=root mode=0755 state=directory
+ tags:
+ - koji_hub
+ - fedora-messaging
+
+- name: install the configuration file for fedora-messaging
+ template:
+ src=fedora-messaging.toml
+ dest=/etc/fedora-messaging/config.toml
tags:
- config
- koji_hub
+ - fedora-messaging
-#
-# install production certs and keys
-#
-- name: install kojiweb_cert_key.pem
- copy: src={{ private }}/files/koji/kojiweb_cert_key.pem
dest=/etc/pki/tls/private/kojiweb_cert_key.pem owner=apache mode=600
- notify:
- - reload httpd
+- name: create folder where we'll place the certs
+ file: path=/etc/pki/rabbitmq/kojicert/ owner=root group=root mode=0755 state=directory
tags:
- config
- koji_hub
- when: env != 'staging' and ansible_hostname.startswith('koji')
+ - fedora-messaging
-- name: install production koji_cert.pem
- copy: src={{ private }}/files/koji/koji_cert.pem dest=/etc/pki/tls/certs/koji_cert.pem
owner=apache mode=600
- notify:
- - reload httpd
+- name: deploy koji/rabbitmq certificate
+ copy: src={{ item.src }}
+ dest=/etc/pki/rabbitmq/kojicert/{{ item.dest }}
+ owner={{ item.owner }} group=root mode={{ item.mode }}
+ with_items:
+ - src: "{{private}}/files/rabbitmq/{{env}}/pki/issued/koji{{ env_suffix
}}.crt"
+ dest: koji.crt
+ owner: apache
+ mode: 0644
+ - src: "{{private}}/files/rabbitmq/{{env}}/pki/private/koji{{ env_suffix
}}.key"
+ dest: koji.key
+ owner: apache
+ mode: "600"
+ - src: "{{private}}/files/rabbitmq/{{env}}/pki/ca.crt"
+ dest: koji.ca
+ owner: apache
+ mode: 0644
tags:
- config
- koji_hub
- when: env != 'staging' and ansible_hostname.startswith('koji')
+ - fedora-messaging
-- name: install production koji_key.pem
- copy: src={{ private }}/files/koji/koji_key.pem dest=/etc/pki/tls/private/koji_key.pem
owner=apache mode=600
+# Since we're in freeze we'll have different plugins in prod and stg
+- name: koji fedora-messaging plugin - installed as fedmsg-koji-plugin
+ template:
+ src: fedmsg-koji-plugin.py
+ dest: /usr/lib/koji-hub-plugins/fedmsg-koji-plugin.py
+ mode: 644
notify:
- reload httpd
tags:
- config
- koji_hub
- when: env != 'staging' and ansible_hostname.startswith('koji')
+ - fedora-messaging
+
+
+- name: install the configuration file for the sidetag plugin
+ copy:
+ src: sidetag.conf
+ dest: /etc/koji-hub/plugins/sidetag.conf
+ tags:
+ - koji_hub
#
-# install production s390 certs and keys
+# rpmautospec plugin
#
-- name: install s390 kojiweb_cert_key.pem
- copy: src={{ private }}/files/koji/s390.koji.fedoraproject.org_key_and_cert.pem
dest=/etc/pki/tls/private/kojiweb_cert_key.pem owner=apache mode=600
- notify:
- - reload httpd
+
+- name: uninstall koji hub rpmautospec plugin
+ package: name={{ item }} state=absent
+ with_items:
+ - koji-hub-plugin-rpmautospec
+ tags:
+ - packages
+ - koji_hub
+ - rpmautospec
+
+- name: remove obsolete configuration for rpmautospec
+ file:
+ path: "/etc/koji-hub/plugins/{{ item }}"
+ state: absent
+ loop:
+ - rpmautospec.conf
+ - rpmautospec.conf.rpmnew
+ - rpmautospec.conf.rpmsave
+ - rpmautospec.conf.rpmorig
tags:
- - config
- koji_hub
- when: ansible_hostname.startswith('s390')
+ - rpmautospec
+
+#
+# install keytabs
+#
-- name: install s390 production koji_cert.pem
- copy: src={{ private }}/files/koji/s390_koji_cert.pem
dest=/etc/pki/tls/certs/koji_cert.pem owner=apache mode=600
+- name: install koji-hub keytab
+ copy: src={{ private }}/files/keytabs/{{ env }}/koji-hub-{{ fedmsg_koji_instance }}
dest=/etc/koji-hub/koji-hub.keytab
+ owner=apache group=apache mode=0600
notify:
- reload httpd
tags:
- config
- koji_hub
- when: ansible_hostname.startswith('s390')
-- name: install s390 production koji_key.pem
- copy: src={{ private }}/files/koji/s390_koji_key.pem
dest=/etc/pki/tls/private/koji_key.pem owner=apache mode=600
+- name: install GSSAPI keytab
+ copy: src={{ private }}/files/keytabs/{{ env }}/koji-gssapi
dest=/etc/koji-hub/gssapi.keytab
+ owner=apache group=apache mode=0600
notify:
- reload httpd
tags:
- config
- koji_hub
- when: ansible_hostname.startswith('s390')
+
#
-# install production arm certs and keys
+# install production certs and keys
#
- name: install arm kojiweb_cert_key.pem
copy: src={{ private }}/files/koji/arm.koji.fedoraproject.org_key_and_cert.pem
dest=/etc/pki/tls/private/kojiweb_cert_key.pem owner=apache mode=600
@@ -215,21 +291,6 @@
tags:
- config
- koji_hub
- when: ansible_hostname.startswith('koji') or
ansible_hostname.startswith('s390') or ansible_hostname.startswith('arm')
-
-- name: updatecrl script
- copy: src=updatecrl.sh dest=/usr/local/bin/updatecrl.sh owner=root mode=755
- tags:
- - config
- - koji_hub
- - cron
-
-- name: updatecrl cronjob
- copy: src=updatecrl.cron dest=/etc/cron.d/updatecrl owner=root mode=644
- tags:
- - config
- - cron
- - koji_hub
- name: koji web common config files
copy: src={{ item }} dest=/etc/httpd/conf.d/{{ item }} owner=root group=root
@@ -265,6 +326,7 @@
tags:
- config
- koji_hub
+ - sslciphers
notify: reload httpd
when: env == "staging"
@@ -273,6 +335,7 @@
tags:
- config
- koji_hub
+ - sslciphers
notify: reload httpd
when: env != "staging"
@@ -295,6 +358,8 @@
tags:
- config
- koji_hub
+ notify:
+ - restart kojira
- name: make an empty /mnt/rpmfusion_koji for stg.
file: state=directory path=/mnt/rpmfusion_koji/koji owner=root group=root
@@ -327,12 +392,18 @@
- selinux
- koji_hub
+- name: set sebooleans so koji can run the fedora-messaging plugin
+ seboolean: name=httpd_execmem state=true persistent=true
+ tags:
+ - selinux
+ - koji_hub
+
- name: set sebooleans so koji can anon write
seboolean: name=httpd_anon_write state=true persistent=true
tags:
- selinux
- koji_hub
- when: ansible_distribution == "CentOS" and
ansible_distribution_major_version|int == 7
+ when: ansible_distribution == "RedHat" and
ansible_distribution_major_version|int == 7
- name: Set httpd to run on boot
service: name=httpd enabled=yes
@@ -343,12 +414,12 @@
- service
- koji_hub
-- name: Make sure kojira is set to not run on boot (controlled by keepalived)
- service: name=kojira enabled=no
+- name: Make sure kojira is set to run on boot
+ service: name=kojira enabled=yes
tags:
- service
- koji_hub
- when: env != 'staging' and ansible_hostname.startswith('koji')
+ when: ansible_hostname.startswith('koji02')
- name: install cert for oscar (garbage collector) user
copy: src={{ private }}/files/koji/gc/oscar_key_and_cert.pem
dest=/etc/koji-gc/client.crt
diff --git a/roles/koji_hub/templates/fedmsg-koji-plugin.py
b/roles/koji_hub/templates/fedmsg-koji-plugin.py
index 2ba4ffc..69e01f9 100644
--- a/roles/koji_hub/templates/fedmsg-koji-plugin.py
+++ b/roles/koji_hub/templates/fedmsg-koji-plugin.py
@@ -1,25 +1,27 @@
-# Koji callback for sending notifications about events to the fedmsg messagebus
-# Copyright (c) 2009-2012 Red Hat, Inc.
+# Koji callback for sending notifications about events to the fedmsg message bus
+# Copyright (c) 2009-2019 Red Hat, Inc.
+#
+# Source:
https://pagure.io/koji-fedmsg-plugin/
#
# Authors:
# Ralph Bean <rbean(a)redhat.com>
# Mike Bonnet <mikeb(a)redhat.com>
+import logging
+import re
+import time
+
from koji.context import context
from koji.plugin import callbacks
from koji.plugin import callback
from koji.plugin import ignore_error
-
-import fedmsg
+import fedora_messaging.api
+import fedora_messaging.exceptions
import kojihub
-import re
-import pprint
-
-# Talk to the fedmsg-relay
-fedmsg.init(name='relay_inbound', cert_prefix='koji', active=True)
MAX_KEY_LENGTH = 255
+log = logging.getLogger(__name__)
def camel_to_dots(name):
@@ -27,18 +29,45 @@ def camel_to_dots(name):
return re.sub('([a-z0-9])([A-Z])', r'\1.\2', s1).lower()
+def serialize_datetime_in_task(task):
+ date_fields = [
+ "completion_time", "create_time", "start_time",
"buildtime",
+ "creation_ts", "creation_time",
+ ]
+ for date_key in date_fields:
+ if task.get(date_key) is None:
+ continue
+ if isinstance(task[date_key], (float, int)):
+ continue
+ task[date_key] = time.mktime(task[date_key].timetuple())
+
+
def get_message_body(topic, *args, **kws):
msg = {}
if topic == 'package.list.change':
msg['tag'] = kws['tag']['name']
msg['package'] = kws['package']['name']
+ msg['action'] = kws['action']
+ if 'owner' in kws:
+ msg['owner'] =
kojihub.get_user(kws['owner'])['name']
+ else:
+ msg['owner'] = None
+ msg['block'] = kws.get('block', None)
+ msg['extra_arches'] = kws.get('extra_arches', None)
+ msg['force'] = kws.get('force', None)
+ msg['update'] = kws.get('update', None)
elif topic == 'task.state.change':
info = kws['info']
+ serialize_datetime_in_task(info)
# Stuff in information about descendant tasks
task = kojihub.Task(info['id'])
- info['children'] = task.getChildren()
+ info['children'] = []
+ for child_orig in task.getChildren():
+ child = child_orig.copy()
+ serialize_datetime_in_task(child)
+ info['children'].append(child)
# Send the whole info dict along because it might have useful info.
# For instance, it contains the mention of what format createAppliance
@@ -68,6 +97,7 @@ def get_message_body(topic, *args, **kws):
msg['name'] = info['name']
msg['version'] = info['version']
msg['release'] = info['release']
+ msg['epoch'] = info.get('epoch')
msg['attribute'] = kws['attribute']
msg['old'] = kws['old']
msg['new'] = kws['new']
@@ -112,19 +142,29 @@ def get_message_body(topic, *args, **kws):
msg['tag_id'] = kws['repo']['tag_id']
msg['repo_id'] = kws['repo']['id']
elif topic == 'rpm.sign':
- msg['attribute'] = kws['attribute']
- msg['old'] = kws['old']
- msg['new'] = kws['new']
- msg['info'] = kws['info']
+ if 'attribute' in kws:
+ # v1.10.1 and earlier
+ msg['attribute'] = kws['attribute']
+ msg['old'] = kws['old']
+ msg['new'] = kws['new']
+ msg['info'] = kws['info']
+ else:
+ # v1.11.0 (and maybe higher, but who knows)
+ msg['sigkey'] = kws['sigkey']
+ msg['sighash'] = kws['sighash']
+ msg['build'] = kws['build']
+ msg['rpm'] = kws['rpm']
+ serialize_datetime_in_task(msg['build'])
+ serialize_datetime_in_task(msg['rpm'])
return msg
# This callback gets run for every koji event that starts with "post"
@callback(*[
- c for c in callbacks.keys()
+ c for c in list(callbacks.keys())
if c.startswith('post') and c not in [
- 'postImport', # This is kind of useless; also noisy.
+ 'postImport', # This is kind of useless; also noisy.
# This one is special, and is called every time, so ignore it.
# Added here
https://pagure.io/koji/pull-request/148
'postCommit',
@@ -156,37 +196,41 @@ def queue_message(cbtype, *args, **kws):
# We need this to distinguish between messages from primary koji
# and the secondary hubs off for s390 and ppc.
- body['instance'] = '{{ fedmsg_koji_instance }}'
+ body['instance'] = 'primary'
# Don't publish these uninformative rpm.sign messages if there's no actual
# sigkey present. Koji apparently adds a dummy sig value when rpms are
# first imported and there's no need to spam the world about that.
- if topic == 'rpm.sign' and body.get('info', {}).get('sigkey')
== '':
+ if topic == 'rpm.sign' and (body.get('info',
{}).get('sigkey') == '' or
+ body.get('sigkey') == ''):
+ return
+
+ # Also, do not want to send a message on volume_id changes
+ if topic == 'build.state.change' and body.get('attribute') ==
'volume_id':
return
# Last thing to do before publishing: scrub some problematic fields
# These fields are floating points which get json-encoded differently on
# rhel and fedora.
problem_fields = ['weight', 'start_ts', 'create_ts',
'completion_ts']
+
def scrub(obj):
if isinstance(obj, list):
return [scrub(item) for item in obj]
if isinstance(obj, dict):
return dict([
- (k, scrub(v)) for k, v in obj.items() if k not in problem_fields
+ (k, scrub(v))
+ for k, v in list(obj.items())
+ if k not in problem_fields
])
return obj
body = scrub(body)
-{% if env != 'staging' %}
- # Send the messages immediately.
- fedmsg.publish(topic=topic, msg=body, modname='buildsys')
-{% else %}
# Queue the message for later.
# It will only get sent after postCommit is called.
messages = getattr(context, 'fedmsg_plugin_messages', [])
- messages.append(dict(topic=topic, msg=body, modname='buildsys'))
+ messages.append(dict(topic=topic, msg=body))
context.fedmsg_plugin_messages = messages
@@ -195,6 +239,19 @@ def queue_message(cbtype, *args, **kws):
@ignore_error
def send_messages(cbtype, *args, **kws):
messages = getattr(context, 'fedmsg_plugin_messages', [])
+
for message in messages:
- fedmsg.publish(**message)
-{% endif %}
+ try:
+ msg = fedora_messaging.api.Message(
+ topic="buildsys.{}".format(message['topic']),
+ body=message['msg']
+ )
+ fedora_messaging.api.publish(msg)
+ except fedora_messaging.exceptions.PublishReturned as e:
+ log.warning(
+ "Fedora Messaging broker rejected message %s: %s", msg.id, e
+ )
+ except fedora_messaging.exceptions.ConnectionException as e:
+ log.warning("Error sending message %s: %s", msg.id, e)
+ except Exception:
+ log.exception("Un-expected error sending fedora-messaging
message")
diff --git a/roles/koji_hub/templates/hub.conf.j2 b/roles/koji_hub/templates/hub.conf.j2
index fdbe56d..1b00e2b 100644
--- a/roles/koji_hub/templates/hub.conf.j2
+++ b/roles/koji_hub/templates/hub.conf.j2
@@ -30,11 +30,7 @@ ProxyDNs =
emailAddress=rpmfusion-buildsys(a)rpmfusion.org,CN=kojiweb,O=RPM Fusion
## Other options ##
LoginCreatesUser = On
-{% if inventory_hostname.startswith('koji') %}
KojiWebURL =
https://koji.rpmfusion.org/koji
-{% elif inventory_hostname.startswith('arm-koji') %}
-KojiWebURL =
http://arm.koji.rpmfusion.org/koji
-{% endif %}
# The domain name that will be appended to Koji usernames
# when creating email notifications
EmailDomain =
rpmfusion.org
@@ -46,6 +42,12 @@ DisableNotifications = True
## subclasses of koji.GenericError).
# KojiDebug = On
+## If MissingPolicyOk is on, and given policy is not set up,
+## policy test will pass as ok. If 'deny' result is desired, set it
+## to off
+# MissingPolicyOk = True
+MissingPolicyOk = False
+
## Determines how much detail about exceptions is reported to the client (via faults)
## Meaningful values:
## normal - a basic traceback (format_exception)
@@ -68,9 +70,8 @@ DisableNotifications = True
#Plugins = darkserver-plugin
Plugins = runroot_hub hub_containerbuild
-{% if inventory_hostname.startswith('koji') %}
-[policy]
+[policy]
tag =
has_perm secure-boot && package kernel shim grub2 fedora-release fedora-repos
pesign :: allow
@@ -107,12 +108,21 @@ channel =
all :: use default
+
build_from_srpm =
has_perm admin :: allow
+ tag *-infra-candidate && has_perm infra :: allow
all :: deny
build_from_repo_id=
has_perm admin :: allow
all :: deny
-{% endif %}
+sidetag =
+ tag f36-*-build :: allow
+ tag f35-*-build :: allow
+ tag f34-*-build :: allow
+ tag f33-*-build :: allow
+ tag el8-*-build :: allow
+ tag el7-*-build :: allow
+ all :: deny