diff --git a/inventory/group_vars/fedora_nightlies b/inventory/group_vars/fedora_nightlies new file mode 100644 index 0000000000..c5289eb229 --- /dev/null +++ b/inventory/group_vars/fedora_nightlies @@ -0,0 +1,17 @@ +# we need this for our fedora-messaging consumer as it is not allowed +# to create queues on the infra AMQP broker, by broker config +fedora_nightlies_amqp_passive: true + +# fedora-messaging job scheduler settings: most of these are the same +# for prod and stg as they both must listen for prod messages. Only +# the queue names differs +fedora_nightlies_amqp_url: "amqps://openqa:@rabbitmq.fedoraproject.org/%2Fpubsub" +fedora_nightlies_amqp_cacert: /etc/fedora-messaging/cacert.pem +fedora_nightlies_amqp_key: /etc/pki/fedora-messaging/openqa-key.pem +fedora_nightlies_amqp_cert: /etc/pki/fedora-messaging/openqa-cert.pem +fedora_nightlies_amqp_queue: "openqa_fedora_nightlies" +fedora_nightlies_amqp_routing_keys: ["org.fedoraproject.prod.openqa.job.done", "org.fedoraproject.prod.pungi.compose.status.change"] + +# fedora-messaging email error reporting settings +fedora_nightlies_amqp_mailto: ["adamwill@fedoraproject.org"] +fedora_nightlies_amqp_smtp: bastion diff --git a/inventory/inventory b/inventory/inventory index 6caa75c913..19c6b2c892 100644 --- a/inventory/inventory +++ b/inventory/inventory @@ -567,6 +567,9 @@ openqa01.iad2.fedoraproject.org [checkcompose_stg] #openqa-lab01.iad2.fedoraproject.org +[fedora_nightlies] +openqa01.iad2.fedoraproject.org + [resultsdb:children] resultsdb_stg resultsdb_prod diff --git a/playbooks/groups/openqa.yml b/playbooks/groups/openqa.yml index 069da3caea..84bd1e73f8 100644 --- a/playbooks/groups/openqa.yml +++ b/playbooks/groups/openqa.yml @@ -196,12 +196,13 @@ # relvalconsumer isn't particularly related to openQA in any way, we # just put that role on these boxes. There's nowhere more obviously -# correct for it, really. +# correct for it, really. Ditto fedora_nightlies roles: - { role: openqa/server, tags: ['openqa_server'] } - { role: openqa/dispatcher, tags: ['openqa_dispatcher'] } - { role: check-compose, tags: ['check-compose'], when: "checkcompose_env_suffix is defined" } - { role: relvalconsumer, tags: ['relvalconsumer'], when: "relvalconsumer_env_suffix is defined" } + - { role: fedora_nightlies, tags: ['fedora_nightlies'], when: "fedora_nightlies_amqp_queue is defined" } handlers: - import_tasks: "{{ handlers_path }}/restart_services.yml" diff --git a/roles/fedora_nightlies/defaults/main.yml b/roles/fedora_nightlies/defaults/main.yml new file mode 100644 index 0000000000..e974df5473 --- /dev/null +++ b/roles/fedora_nightlies/defaults/main.yml @@ -0,0 +1,9 @@ +fedora_nightlies_amqp_passive: false +fedora_nightlies_amqp_url: "amqps://fedora:@rabbitmq.fedoraproject.org/%2Fpublic_pubsub" +fedora_nightlies_amqp_cacert: /etc/fedora-messaging/cacert.pem +fedora_nightlies_amqp_key: /etc/fedora-messaging/fedora-key.pem +fedora_nightlies_amqp_cert: /etc/fedora-messaging/fedora-cert.pem +fedora_nightlies_amqp_routing_keys: ["org.fedoraproject.prod.openqa.job.done", "org.fedoraproject.prod.pungi.compose.status.change"] +fedora_nightlies_amqp_mailfrom: "root@{{ external_hostname }}" +fedora_nightlies_amqp_smtp: localhost +fedora_nightlies_disabled: false diff --git a/roles/fedora_nightlies/files/fedora_nightlies.conf.httpd b/roles/fedora_nightlies/files/fedora_nightlies.conf.httpd new file mode 100644 index 0000000000..8bcc8f8b47 --- /dev/null +++ b/roles/fedora_nightlies/files/fedora_nightlies.conf.httpd @@ -0,0 +1,3 @@ + + Alias /nightlies.html /var/www/fedora_nightlies/nightlies.html + diff --git a/roles/fedora_nightlies/handlers/main.yml b/roles/fedora_nightlies/handlers/main.yml new file mode 100644 index 0000000000..3a1025227c --- /dev/null +++ b/roles/fedora_nightlies/handlers/main.yml @@ -0,0 +1,5 @@ +# Restart handler for our fedora-messaging consumers +- name: Conditionally restart fedora_nightlies consumer service + command: /usr/local/bin/conditional-restart.sh fm-consumer@fedora_nightlies + listen: + - restart fedora_nightlies diff --git a/roles/fedora_nightlies/tasks/main.yml b/roles/fedora_nightlies/tasks/main.yml new file mode 100644 index 0000000000..84f944f5e9 --- /dev/null +++ b/roles/fedora_nightlies/tasks/main.yml @@ -0,0 +1,156 @@ +# This role runs a fedora-messaging consumer to run fedora_nightlies, +# a static site generator that produces a page with links to the +# latest and last-known-good nightly compose images for Branched and +# Rawhide. +# +# Required vars +# - fedora_nightlies_amqp_queue +## string - Message queue name for the consumer. To use the +## fedora-messaging scheduler with public authentication +## on the Fedora production AMQP broker (which is what +## you'd typically want), you only need to set this. +## This should be a unique and private string; the +## official recommendation is to use a random UUID +## generated by uuidgen. +# +# Required vars with defaults +# - fedora_nightlies_amqp_passive +## bool - If true, passive_declares will be set true in all the +## fedora-messaging consumer configuration files. This +## is needed for private authentication on the Fedora +## brokers. +## default - False +# - fedora_nightlies_amqp_url +## string - AMQP broker URL for fedora-messaging event creator. +## The role default for this is the Fedora production +## broker with the shared 'fedora' username. +# - fedora_nightlies_amqp_cacert +## string - CA certificate file to use for authenticating with +## AMQP broker for fedora-messaging event creator. +## The role default for this is the CA cert file for the +## Fedora production broker. +# - fedora_nightlies_amqp_cert +## string - Certificate file to use for authenticating with AMQP +## broker for fedora-messaging event creator. The role +## default for this is the certificate file for the +## public 'fedora' account on the Fedora production +## broker. +# - fedora_nightlies_amqp_key +## string - Private key file to use for authenticating with AMQP +## broker for fedora-messaging event creator. The role +## default for this is the key file for the public +## 'fedora' account on the Fedora production broker. +# - fedora_nightlies_amqp_routing_keys +## list - List of routing key names for the fedora-messaging +## creator to subscribe to. The role default for this +## is the appropriate keys for the Fedora production +## broker. +# - fedora_nightlies_amqp_mailfrom +## string - From email address for error report emails. Defaults +## to "root@{{ external_hostname }}". Only relevant if +## fedora_nightlies_amqp_mailto is set. +# - fedora_nightlies_amqp_smtp +## string - Hostname of SMTP server to use for sending error +## emails. Defaults to 'localhost'. Only relevant if +## fedora_nightlies_amqp_mailto is set. +# - fedora_nightlies_disabled +## bool - If true, don't enable the consumer service. This is +## mainly just for temporary use if something's broken. +## default - False +# +# Optional vars +# - fedora_nightlies_amqp_mailto +## list - List of email addresses to email errors to. If set, +## the email log handler will be configured. +# - deployment_type +## string - Fedora Infrastructure thing; for this role, applies an +## infra-specific tweak to httpd config. Don't set it outside +## Fedora infra. + + +- name: Install required packages + package: + # 'relval' itself is needed as we call it directly for size + # checking + name: ['python3-fedfind', 'fedora-messaging', 'python3-pip', 'python3-setuptools', 'python3-openqa_client'] + state: present + tags: + - packages + +- name: Check out fedora_nightlies + git: + repo: https://pagure.io/fedora_nightlies.git + dest: /root/fedora_nightlies + register: gitfn + +- name: Check if fedora_nightlies is installed for current Python + command: "pip show fedora_nightlies" + register: instfn + changed_when: "1 != 1" + failed_when: "1 != 1" + check_mode: no + +- name: Install fedora_nightlies + command: "python3 setup.py install" + args: + chdir: /root/fedora_nightlies + when: "gitfn is changed or instfn.rc != 0" + notify: + - restart fedora_nightlies + +- name: Create /etc/pki/fedora-messaging + file: + dest: /etc/pki/fedora-messaging + mode: 0775 + owner: root + group: root + state: directory + when: "deployment_type is defined" + tags: + - config + +# We always use the openQA production cert and key here for now; we +# don't really need a separate identity for fedora_nightlies. +- name: Deploy the Fedora infra fedora-messaging cert (openQA production) + copy: + src: "{{ private }}/files/rabbitmq/production/pki/issued/openqa.crt" + dest: /etc/pki/fedora-messaging/openqa-cert.pem + mode: 0644 + owner: root + group: root + when: "deployment_type is defined" + tags: + - config + +# This is kinda icky, as there's no intrinsic reason the group geekotest +# should exist so far as this role is concerned. But as we run this role +# on the same box as openQA, in fact we need to keep the ownership in +# line. This needs making cleaner somehow. +- name: Deploy the Fedora infra fedora-messaging key + copy: + src: "{{ private }}/files/rabbitmq/production/pki/private/openqa.key" + dest: /etc/pki/fedora-messaging/openqa-key.pem + mode: 0640 + owner: root + group: geekotest + when: "deployment_type is defined" + tags: + - config + +- name: Configure fedora-messaging fedora_nightlies + template: src=fedora_nightlies.toml.j2 dest=/etc/fedora-messaging/fedora_nightlies.toml owner=root group=root mode=0640 + notify: + - restart fedora_nightlies + tags: + - config + +- name: Enable and start fedora-messaging fedora_nightlies + service: name=fm-consumer@fedora_nightlies enabled=yes state=started + when: not fedora_nightlies_disabled|bool + +- name: Set up Apache config + copy: src=fedora_nightlies.conf.httpd dest=/etc/httpd/conf.d/fedora_nightlies.conf owner=root group=root mode=0644 + notify: + - reload httpd + tags: + - config diff --git a/roles/fedora_nightlies/templates/fedora_nightlies.toml.j2 b/roles/fedora_nightlies/templates/fedora_nightlies.toml.j2 new file mode 100644 index 0000000000..44a8114ad0 --- /dev/null +++ b/roles/fedora_nightlies/templates/fedora_nightlies.toml.j2 @@ -0,0 +1,118 @@ +# fedora-messaging consumer configuration file for fedora_nightlies +# (nightly image static site generator). See fedora_nightlies main.yml +# comments for details on the variables that must be set here. +# +# This file is in the TOML format. + +amqp_url = "{{ fedora_nightlies_amqp_url }}" +{% if fedora_nightlies_amqp_passive|bool %} +passive_declares = true +{% endif %} +callback = "fedora_nightlies:NightlyConsumer" + +[tls] +ca_cert = "{{ fedora_nightlies_amqp_cacert }}" +keyfile = "{{ fedora_nightlies_amqp_key }}" +certfile = "{{ fedora_nightlies_amqp_cert }}" + +[client_properties] +app = "Fedora nightly image static site generator (fedora_nightlies)" +app_url = "https://pagure.io/fedora_nightlies" +app_contacts_email = ["adamwill@fedoraproject.org", "qa-devel@lists.fedoraproject.org"] + +[exchanges."amq.topic"] +type = "topic" +durable = true +auto_delete = false +arguments = {} + +[queues."{{ fedora_nightlies_amqp_queue }}"] +durable = false +auto_delete = true +exclusive = true +arguments = {} + +[[bindings]] +queue = "{{ fedora_nightlies_amqp_queue }}" +exchange = "amq.topic" +routing_keys = [{% for key in fedora_nightlies_amqp_routing_keys %}"{{ key }}",{% endfor %}] +# need this to receive messages from ZMQ->AMQP bridge +[[bindings]] +queue = "{{ fedora_nightlies_amqp_queue }}" +exchange = "zmq.topic" +routing_keys = [{% for key in fedora_nightlies_amqp_routing_keys %}"{{ key }}",{% endfor %}] + +[consumer_config] +# JSON data file location. If not set, default +# /var/lib/fedora_nightlies/nightlies.json will be used +#datafile = "/tmp/nightlies.json" +# HTML output file location. If not set, default +# /var/www/fedora_nightlies/nightlies.html will be used +#htmlfile = "/tmp/nightlies.html" + +[qos] +prefetch_size = 0 +prefetch_count = 25 + +[log_config] +version = 1 +disable_existing_loggers = true + +[log_config.formatters.simple] +format = "[%(levelname)s %(name)s] %(message)s" + +[log_config.handlers.console] +class = "logging.StreamHandler" +formatter = "simple" +stream = "ext://sys.stdout" + +{% if fedora_nightlies_amqp_mailto is defined %} +[log_config.handlers.email] +class = "logging.handlers.SMTPHandler" +formatter = "simple" +level = "ERROR" +mailhost = "{{ fedora_nightlies_amqp_smtp }}" +fromaddr = "{{ fedora_nightlies_amqp_mailfrom }}" +toaddrs = [{% for key in fedora_nightlies_amqp_mailto %}"{{ key }}",{% endfor %}] +subject = "fedora_nightlies error" +{% endif %} + +[log_config.loggers.NightlyConsumer] +level = "INFO" +propagate = false +{% if fedora_nightlies_amqp_mailto is defined %} +handlers = ["console", "email"] +{% else %} +handlers = ["console"] +{% endif %} + +[log_config.loggers.fedora_messaging] +level = "INFO" +propagate = false +{% if fedora_nightlies_amqp_mailto is defined %} +handlers = ["console", "email"] +{% else %} +handlers = ["console"] +{% endif %} + +[log_config.loggers.twisted] +level = "INFO" +propagate = false +{% if fedora_nightlies_amqp_mailto is defined %} +handlers = ["console", "email"] +{% else %} +handlers = ["console"] +{% endif %} + +[log_config.loggers.pika] +level = "WARNING" +propagate = false +handlers = ["console"] + +[log_config.root] +level = "ERROR" +{% if fedora_nightlies_amqp_mailto is defined %} +handlers = ["console", "email"] +{% else %} +handlers = ["console"] +{% endif %}