Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add rabbitmq msg for announcer #1845

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 88 additions & 17 deletions factory-package-news/announcer.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
#!/usr/bin/python

from __future__ import print_function

import httplib
import re
from urlparse import urlparse, urljoin
import smtplib
from email.mime.text import MIMEText
import os
import osc
import sys
import email.utils
import argparse
import logging
import yaml
import json
import pika
from xdg.BaseDirectory import save_data_path
from collections import namedtuple

Expand All @@ -21,12 +26,12 @@
'sender': 'noreply@opensuse.org',
'to': 'opensuse-factory@opensuse.org',
'relay': 'relay.suse.de',
'url' : "http://download.opensuse.org/tumbleweed/iso/",
'iso' : "openSUSE-Tumbleweed-DVD-x86_64-Current.iso",
'name' : 'factory-announcer',
'subject' : 'New Tumbleweed snapshot {version} released!',
'changesfile' : "Changes.{version}.txt",
'bodytemplate' : """
'url': "http://download.opensuse.org/tumbleweed/iso/",
'iso': "openSUSE-Tumbleweed-DVD-x86_64-Current.iso",
'name': 'factory-announcer',
'subject': 'New Tumbleweed snapshot {version} released!',
'changesfile': "Changes.{version}.txt",
'bodytemplate': """
Please note that this mail was generated by a script.
The described changes are computed based on the x86_64 DVD.
The full online repo contains too many changes to be listed here.
Expand All @@ -43,21 +48,85 @@

}

def _load_config(handle = None):

def send_amqp_message(version, config):
""" Sends a rabbitmq message notifying about a new iso release

This function sends a message over the openSUSE rabbitmq message bus
notifying about a new ISO being released. The message topic is::

opensuse.release.iso.publish

The message's body contains the name of the release iso, the link to the
base url and the name of the changesfile.

Args:
version (str): version string of the iso
config (namedtuple): configuration for this opensuse release, must
contain the following keys: iso, url, changesfile

Returns:
Nothing
"""
amqp_url = osc.conf.config.get('ttm_amqp_url')
if amqp_url is None:
logger.error("No ttm_amqp_url configured in oscrc - No message will be"
" sent")
return

topic = 'opensuse.release.iso.publish'
payload = {key: config[key] for key in config
if key in ("iso", "url", "changesfile")}
payload["version"] = version
body = json.dumps(payload)

# copy-pasta from totest-manager.py:
# send amqp event
tries = 7 # arbitrary
for t in range(tries):
try:
notify_connection = pika.BlockingConnection(
pika.URLParameters(amqp_url))
notify_channel = notify_connection.channel()
notify_channel.exchange_declare(exchange='pubsub',
exchange_type='topic',
passive=True, durable=True)
notify_channel.basic_publish(exchange='pubsub',
routing_key=topic, body=body)
notify_connection.close()
break
except pika.exceptions.ConnectionClosed as e:
logger.warn("Sending AMQP event did not work: {!s}. Retrying try "
"{!s} out of {!s}".format(e, t, tries))
else:
logger.error("Could not send out AMQP event for {!s} tries, aborting."
.format(tries))


def _load_config(handle=None):
d = config_defaults
y = yaml.safe_load(handle) if handle is not None else {}
return namedtuple('Config', sorted(d.keys()))(*[ y.get(p, d[p]) for p in sorted(d.keys()) ])
return namedtuple('Config', sorted(d.keys()))(*[y.get(p, d[p]) for p in sorted(d.keys())])


parser = argparse.ArgumentParser(description="Announce new snapshots")
parser.add_argument("--dry", action="store_true", help="dry run")
parser.add_argument("--debug", action="store_true", help="debug output")
parser.add_argument("--verbose", action="store_true", help="verbose")
parser.add_argument("--from", dest='sender', metavar="EMAIL", help="sender email address")
parser.add_argument("--from", dest='sender', metavar="EMAIL",
help="sender email address")
parser.add_argument("--to", metavar="EMAIL", help="recepient email address")
parser.add_argument("--relay", metavar="RELAY", help="SMTP relay server address")
parser.add_argument("--version", metavar="VERSION", help="announce specific version")
parser.add_argument("--config", metavar="FILE", type=argparse.FileType(), help="YAML config file to override defaults")
parser.add_argument("--dump-config", action="store_true", help="dump built in YAML config")
parser.add_argument("--relay", metavar="RELAY",
help="SMTP relay server address")
parser.add_argument("--version", metavar="VERSION",
help="announce specific version")
parser.add_argument("--config", metavar="FILE",
type=argparse.FileType(),
help="YAML config file to override defaults")
parser.add_argument("--dump-config", action="store_true",
help="dump built in YAML config")
parser.add_argument("--no-amqp-msg", action="store_true",
help="don't send a rabbitmq message")

options = parser.parse_args()

Expand All @@ -67,7 +136,7 @@ def _load_config(handle = None):
format='%(asctime)s - %(module)s:%(lineno)d - %(levelname)s - %(message)s')

if options.dump_config:
print yaml.dump(config_defaults, default_flow_style=False)
print(yaml.dump(config_defaults, default_flow_style=False))
sys.exit(0)

config = _load_config(options.config)
Expand Down Expand Up @@ -101,7 +170,7 @@ def _load_config(handle = None):

m = re.search(r'(?:Snapshot|Build)([\d.]+)-Media', loc)
if m is None:
raise Exception("failed to parse %s"%loc)
raise Exception("failed to parse %s" % loc)

version = m.group(1)
logger.debug("found version %s", version)
Expand Down Expand Up @@ -145,8 +214,8 @@ def _load_config(handle = None):
msg['Message-ID'] = email.utils.make_msgid()

if options.dry:
print "sending ..."
print msg.as_string()
print("sending ...")
print(msg.as_string())
else:
logger.info("announcing version {}".format(version))
s = smtplib.SMTP(options.relay)
Expand All @@ -157,3 +226,5 @@ def _load_config(handle = None):
os.symlink(version, tmpfn)
os.rename(tmpfn, current_fn)

if not options.no_amqp_msg:
send_amqp_message(version, config)