Skip to content
Draft
Show file tree
Hide file tree
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
14 changes: 7 additions & 7 deletions client/create_repo_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
]

if len(sys.argv) != 3:
print 'Usage: {program} <orga> <repository>'.format(program=sys.argv[0])
print('Usage: {program} <orga> <repository>'.format(program=sys.argv[0]))
sys.exit(1)

orga, repository = sys.argv[1:]
Expand All @@ -53,13 +53,13 @@
# https://developer.github.com/v3/#pagination
try:
repo = get('https://api.github.com/repos/{orga}/{repository}')
print fmt('Repository exists: {repository}')
except subprocess.CalledProcessError, exc:
print(fmt('Repository exists: {repository}'))
except subprocess.CalledProcessError as exc:
if "404 Not Found" in exc.output:
print fmt('Creating repository: {repository}')
print(fmt('Creating repository: {repository}'))
post('https://api.github.com/orgs/{orga}/repos', {'name': repository})
else:
print exc.output
print(exc.output)
sys.exit(1)

wait()
Expand All @@ -77,10 +77,10 @@
'config': {'url': url, 'content_type': 'json', },
'events': ['push', 'pull_request'], }
if url not in existing_hooks:
print fmt('Adding hook: {url}')
print(fmt('Adding hook: {url}'))
post('https://api.github.com/repos/{orga}/{repository}/hooks', config)
wait()
else:
print fmt('Updating existing hook: {url}')
print(fmt('Updating existing hook: {url}'))
patch('https://api.github.com/repos/{orga}/{repository}/hooks/%s' % existing_hooks[url], config)
wait()
63 changes: 34 additions & 29 deletions rpm/boss-launcher-webhook.spec
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@ Source: %{name}-%{version}.tar.gz

BuildArch: noarch

BuildRequires: python-setuptools
BuildRequires: python-rpm-macros
BuildRequires: python3-setuptools
BuildRequires: python3-rpm-macros

Requires(post): boss-standard-workflow-common
Requires(post): python-boss-skynet >= 0.6.6
Requires: python-Django
Requires: python-boss-common >= 0.27.10
Requires: python-djangorestframework
Requires: python-requests
Requires: python-xml
Requires: python2-django-filter
Requires(post): python3-boss-skynet >= 0.6.6
Requires: python3-Django
Requires: python3-boss-common >= 0.27.10
Requires: python3-djangorestframework
Requires: python3-requests
Requires: python3-xml
Requires: python3-django-filter
Requires: python3-mysqlclient
Requires: uwsgi-python3
Recommends: boss-participant-create_project
Recommends: boss-participant-auto_promote

Summary: VCS webhook handler

Expand All @@ -37,60 +41,61 @@ This package provides the service to generate source from git inside an OBS sour

%package -n obs-service-webhook
Requires: obs-source_service
Requires: python-argparse
Requires: python-requests
Requires: python3-argparse
Requires: python3-requests
Summary: OBS source service to manage webhooks
%description -n obs-service-webhook
This package provides the service to update webhooks from OBS. It ensures that only users who have access to a package can update the webhook for that package.

%package -n boss-participant-trigger_service
Requires(post): boss-standard-workflow-common
Requires(post): python-boss-skynet >= 0.6.6
Requires: osc
Requires: python-boss-common >= 0.27.10
Requires: python-lxml
Requires: python-yaml
Requires(post): python3-boss-skynet >= 0.6.6
Requires: osc3
Requires: python3-boss-common >= 0.27.10
Requires: python3-lxml
Requires: python3-pyaml
Summary: BOSS participant to handle webhooks
%description -n boss-participant-trigger_service
This package provides the participant that handles creating and/or triggering _service files in OBS, in response to webhook triggers

%package -n boss-participant-create_project
Requires(post): boss-standard-workflow-common
Requires(post): python-boss-skynet >= 0.6.6
Requires(post): python3-boss-skynet >= 0.6.6
Requires: boss-launcher-webhook
Requires: osc
Requires: python-boss-common >= 0.27.10
Requires: python-lxml
Requires: osc3
Requires: python3-boss-common >= 0.27.10
Requires: python3-lxml
Summary: BOSS participant to handle webhooks
%description -n boss-participant-create_project
This package provides the participant that handles creating project files in OBS, in response to webhook triggers
It must run on the webhook server as it accesses the database.

%package -n boss-participant-get_src_state
Requires(post): boss-standard-workflow-common
Requires(post): python-boss-skynet >= 0.6.6
Requires: python-boss-common >= 0.27.10
Requires(post): python3-boss-skynet >= 0.6.6
Requires: python3-boss-common >= 0.27.10
Summary: BOSS participant to handle webhooks
%description -n boss-participant-get_src_state
This package provides the participant that checks that there is src is ready to build in OBS projects. Usually this means the service has succeeded.

%package -n boss-participant-auto_promote
Requires(post): boss-standard-workflow-common
Requires(post): python-boss-skynet >= 0.6.6
Requires(post): python3-boss-skynet >= 0.6.6
Requires: boss-launcher-webhook
Requires: python-boss-common >= 0.27.10
Requires: python3-boss-common >= 0.27.10
Summary: BOSS participant to handle webhooks
%description -n boss-participant-auto_promote
This package provides the participant that handles promotion of gated projects, in response to webhook triggers

It must run on the webhook server as it accesses the database.

%prep
%setup -q %{name}-%{version}

%build
%python2_build
%python3_build

%install
%python2_install
%python3_install
make PREFIX=%{_prefix} DESTDIR=%{buildroot} install


Expand Down Expand Up @@ -139,8 +144,8 @@ fi
%config(noreplace) %{svdir}/delete_webhook.conf
%config(noreplace) %{svdir}/handle_webhook.conf
%config(noreplace) %{svdir}/relay_webhook.conf
%{python_sitelib}/webhook_launcher
%{python_sitelib}/*egg-info
%{python3_sitelib}/webhook_launcher
%{python3_sitelib}/*egg-info
%{_datadir}/webhook_launcher
%{_datadir}/boss-skynet/delete_webhook.py*
%{_datadir}/boss-skynet/handle_webhook.py*
Expand Down
2 changes: 1 addition & 1 deletion src/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def launch_log(*args, **kwargs):
", ".join(repr(x) for x in args),
", ".join("\n%s=%s" % (k, repr(v)) for k, v in kwargs.items()),
] if x)
print "launch(%s)" % params
print("launch(%s)" % params)
return DEFAULT


Expand Down
12 changes: 6 additions & 6 deletions src/participants/auto_promote.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"""

from boss.obs import BuildServiceParticipant
from urllib2 import HTTPError
from urllib.error import HTTPError
import os

from boss.bz.config import parse_bz_config
Expand Down Expand Up @@ -86,7 +86,7 @@ def handle_wi(self, wid):
gated_project = f.gated_project

if not project or not gated_project:
print "Nothing to do, no project or gated_project in the fields"
print("Nothing to do, no project or gated_project in the fields")
wid.result = True
return

Expand All @@ -101,21 +101,21 @@ def handle_wi(self, wid):
description = "%s @ %s" % (
webhook.tag or webhook.rev_or_head, str(webhook))
comment = ""
print "Requesting actions: %s\ndesc: %s" % (actions, description)
print("Requesting actions: %s\ndesc: %s" % (actions, description))
try:
result = self.obs.createRequest(
options_list=actions, description=description,
comment=comment, supersede=True,
opt_sourceupdate="cleanup")
except HTTPError as e:
print "%s\n%s" % (e, e.read())
print("%s\n%s" % (e, e.read()))
result = None

if not result:
raise RuntimeError(
"Something went wrong while creating project %s" % project)

print "Created submit request from %s/%s to %s/%s : %s" % (project, package, gated_project, package, description)
print("Created submit request from %s/%s to %s/%s : %s" % (project, package, gated_project, package, description))
else:
print "No gated Project matching gated_project: %s" % (gated_project)
print("No gated Project matching gated_project: %s" % (gated_project))
wid.result = True
20 changes: 10 additions & 10 deletions src/participants/create_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

from boss.obs import BuildServiceParticipant
import osc
from urlparse import urlparse
from urllib.parse import urlparse
import os
from lxml import etree
import json
Expand Down Expand Up @@ -135,14 +135,14 @@ def handle_wi(self, wid):
# TODO: deduce project name from "official" mappings of the same repo
# for now just short circuit here
wid.result = True
print "No project given. Continuing"
print("No project given. Continuing")
return

# events for official projects that are gated get diverted to a side
# project
prjobj = Project.get_matching(project, self.obs.apiurl)
if prjobj and prjobj.gated:
print "%s is gated" % prjobj
print("%s is gated" % prjobj)
linked_project = project
f.gated_project = project
project += ":gate:%s" % package
Expand All @@ -169,17 +169,17 @@ def handle_wi(self, wid):
linked_project = ":".join(prj_parts[0:-3])
fea = "%s#%s" % (prj_parts[-2], prj_parts[-1])
# Go through each bugzilla we support
for (bugzillaname, bugzilla) in self.bzs.iteritems():
for (bugzillaname, bugzilla) in self.bzs.items():
for match in bugzilla['compiled_re'].finditer(fea):
bugnum = match.group('key')
try:
summary = bugzilla['interface'].bug_get(
bugnum)['summary']
desc = bugzilla['interface'].comment_get(
bugnum, 0)['text']
except BugzillaError, error:
except BugzillaError as error:
if error.code == 101:
print "Bug %s not found" % bugnum
print("Bug %s not found" % bugnum)
else:
raise
if project not in project_list:
Expand Down Expand Up @@ -214,17 +214,17 @@ def handle_wi(self, wid):
if not result:
raise RuntimeError(
"Something went wrong while creating project %s" % project)
print "Created project %s" % project
print("Created project %s" % project)
else:
print "Didn't need to create project %s" % project
print("Didn't need to create project %s" % project)

wid.result = True

try:
self._set_blame_emails(
project, package, get_or_none(LastSeenRevision, mapping_id=f.pk))
except Exception, exc:
print "Ignoring exception: %s" % exc
except Exception as exc:
print("Ignoring exception: %s" % exc)
pass

def _set_blame_emails(self, project, package, lsr):
Expand Down
8 changes: 4 additions & 4 deletions src/participants/get_src_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ def handle_wi(self, wid):
if f.project and f.package:
project = f.project
package = f.package
print "setting %s/%s from fields" % (project, package)
print("setting %s/%s from fields" % (project, package))

if p.project and p.package:
project = p.project
package = p.package
print "setting %s/%s from params" % (project, package)
print("setting %s/%s from params" % (project, package))

err = []
if not project:
Expand All @@ -101,8 +101,8 @@ def handle_wi(self, wid):
raise RuntimeError(
"Missing mandatory field or parameter: %s" % ", ".join(err))

print "Checking service for %s/%s" % (project, package)
print("Checking service for %s/%s" % (project, package))
f.service_state = self.obs.getServiceState(project, package)
print "State : %s" % f.service_state
print("State : %s" % f.service_state)
if f.service_state == "succeeded":
wid.result = True
13 changes: 9 additions & 4 deletions src/participants/handle_webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,18 @@ def handle_wi(self, wid):
if wid.fields.payload is None:
raise RuntimeError("Missing mandatory field: payload")

md5 = hashlib.md5(json.dumps(wid.fields.payload.as_dict(),
sort_keys=True)).hexdigest()
md5 = hashlib.md5(
json.dumps(wid.fields.payload.as_dict(),
sort_keys=True).encode('utf8')).hexdigest()
now = time.time()
# purge seen hashes
# purge seen hashes. Find then purge to avoid
# RuntimeError: dictionary changed size during iteration
aged = []
for seen_md5, seen_time in self.seen.items():
if now - seen_time > 30:
del self.seen[seen_md5]
aged.append(seen_md5)
for seen_md5 in aged:
del self.seen[seen_md5]

if md5 in self.seen:
print("Ignoring duplicate webhook (possible resend or "
Expand Down
14 changes: 7 additions & 7 deletions src/participants/trigger_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@
"""

from boss.obs import BuildServiceParticipant
from urlparse import urlparse
from urllib.parse import urlparse
from osc import core
from StringIO import StringIO
from io import StringIO
from lxml import etree
import urllib2
import urllib.request, urllib.error, urllib.parse
import yaml
import re

Expand Down Expand Up @@ -110,7 +110,7 @@ def make_constraint(package):
for elem in ["disk", "memory"]:
if elem in constraint:
node = etree.SubElement(hardware, elem)
etree.SubElement(node, "size", unit="G").text = unicode(constraint[elem])
etree.SubElement(node, "size", unit="G").text = str(constraint[elem])

return etree.tostring(constraints, pretty_print=True)

Expand Down Expand Up @@ -263,9 +263,9 @@ def handle_wi(self, wid):
u = core.makeurl(self.obs.apiurl,
['source', project, package, "_constraints"])
core.http_PUT(u, data=constraint_xml)
print "New _constraints file:\n%s" % constraint_xml
print("New _constraints file:\n%s" % constraint_xml)
else:
print "No _constraints for %s" % package
print("No _constraints for %s" % package)

# Start with an empty XML doc
try: # to get any existing _service file.
Expand All @@ -274,7 +274,7 @@ def handle_wi(self, wid):
print("Trying to get _service file for %s/%s" % (project, package))
services_xml = self.obs.getFile(
project, package, "_service", expand=0)
except urllib2.HTTPError as e:
except urllib.error.HTTPError as e:
print("Exception %s trying to get _service file for %s/%s" %
(e, project, package))
if e.code == 404:
Expand Down
3 changes: 2 additions & 1 deletion src/webhook_launcher/app/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from django.contrib import admin, messages
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.db import models
from django.forms import TextInput
from django.http import HttpResponseRedirect
Expand All @@ -32,6 +32,7 @@
VCSNameSpace, VCSService, WebHookMapping
)
from webhook_launcher.app.payload import get_payload
from functools import reduce


class LastSeenRevisionInline(admin.StackedInline):
Expand Down
Loading