diff --git a/pagure/consumer.py b/pagure/consumer.py index 738ead4..5725240 100644 --- a/pagure/consumer.py +++ b/pagure/consumer.py @@ -44,7 +44,6 @@ class Integrator(fedmsg.consumers.FedmsgConsumer): for cfg in jenkins_hook.get_configs(project, jenkins_hook.Service.PAGURE): repo = msg['pullrequest'].get('remote_git') or get_repo(cfg, msg) - print repo self.log.info("Trigger on %s PR #%s from %s: %s", project, pr_id, repo, branch) diff --git a/pagure/hooks/jenkins_hook.py b/pagure/hooks/jenkins_hook.py index 348ee44..d22f05d 100644 --- a/pagure/hooks/jenkins_hook.py +++ b/pagure/hooks/jenkins_hook.py @@ -9,6 +9,7 @@ """ import os +import uuid import sqlalchemy as sa import pygit2 @@ -29,26 +30,28 @@ class PagureCI(BASE): id = sa.Column(sa.Integer, primary_key=True) project_id = sa.Column( - sa.Integer, + sa.Integer, sa.ForeignKey('projects.id', onupdate='CASCADE'), nullable=False, unique=False, index=True) active = sa.Column(sa.Boolean, nullable=False, default=False) - + display_name = sa.Column(sa.String(64), nullable=False, default='Jenkins') name = sa.Column(sa.String(64)) pagure_name = sa.Column(sa.String(255)) - pagure_url = sa.Column(sa.String(255)) + pagure_url = sa.Column(sa.String(255), nullable=False, + default='https://pagure.io/') pagure_token = sa.Column(sa.String(64)) jenkins_name = sa.Column(sa.String(255)) - jenkins_url = sa.Column(sa.String(255)) + jenkins_url = sa.Column(sa.String(255), nullable=False, + default='http://jenkins.fedorainfracloud.org/') jenkins_token = sa.Column(sa.String(64)) hook_token = sa.Column(sa.String(64), - nullable=True, - unique=True, - index=True) + nullable=True, + unique=True, + index=True) project = relation( 'Project', @@ -58,27 +61,14 @@ class PagureCI(BASE): 'hook_pagure_ci', cascade="delete, delete-orphan", single_parent=True) ) - def __init__(self, name = None, display_name = None, owner = None, - pagure_name = None, pagure_url = None, pagure_token = None, - jenkins_name = None, jenkins_url = None, jenkins_token = None, - hook_token = None, active = False): - self.name = name - self.display_name = display_name - self.owner = owner - self.pagure_name = pagure_name - self.pagure_url = pagure_url - self.pagure_token = pagure_token - - self.jenkins_name = jenkins_name - self.jenkins_url = jenkins_url - self.jenkins_token = jenkins_token - - self.hook_token = hook_token - self.active = active + + def __init__(self): + self.hook_token = uuid.uuid4().hex def __repr__(self): return ''.format(self) + class ConfigNotFound(Exception): pass @@ -93,7 +83,8 @@ def get_configs(project_name, service): :raises ConfigNotFound: when no configuration matches """ - cfg = BASE.metadata.bind.query(PagureCI).filter(service == project_name).all() + cfg = BASE.metadata.bind.query(PagureCI).filter( + service == project_name).all() if len(cfg) == 0: raise ConfigNotFound(project_name) return cfg @@ -128,21 +119,21 @@ class JenkinsForm(wtf.Form): default='http://jenkins.fedorainfracloud.org/') jenkins_token = TextField('Jenkins token', [validators.Required()]) - active = BooleanField('Active',[validators.Optional()]) + active = BooleanField('Active', [validators.Optional()]) class Hook(BaseHook): ''' Jenkins hooks. ''' - name = 'Jenkins Hook' + name = 'Pagure CI' description = 'This hook help to set up CI for the project'\ ' the changes made by the pushes to the git repository.' form = JenkinsForm db_object = PagureCI backref = 'pagure_ci_hook' form_fields = [ - 'display_name','name', 'pagure_name', 'pagure_url', 'pagure_token', 'jenkins_name', - 'jenkins_url', 'jenkins_token','active' + 'display_name', 'name', 'pagure_name', 'pagure_url', 'pagure_token', 'jenkins_name', + 'jenkins_url', 'jenkins_token', 'active' ] @classmethod @@ -160,7 +151,7 @@ class Hook(BaseHook): repo_obj = pygit2.Repository(repopath) # Configure the hook - #repo_obj.config.set_multivar(dbobj) + # repo_obj.config.set_multivar(dbobj) # Install the hook itself hook_file = os.path.join(hook_files, 'jenkins_hook.py') @@ -181,5 +172,5 @@ class Hook(BaseHook): repopath = get_repo_path(project) #hook_path = os.path.join(repopath, 'hooks', 'post-receive.irc') - #if os.path.exists(hook_path): - #os.unlink(hook_path) + # if os.path.exists(hook_path): + # os.unlink(hook_path) diff --git a/pagure/lib/pagure_ci.py b/pagure/lib/pagure_ci.py index d4ddf9d..8157c5f 100644 --- a/pagure/lib/pagure_ci.py +++ b/pagure/lib/pagure_ci.py @@ -15,10 +15,9 @@ import jenkins os.environ.setdefault('INTEGRATOR_SETTINGS', '/etc/poormanci.conf') -app = flask.Flask(__name__) -app.config.from_object('pagure.default_config') -app.config.from_envvar('INTEGRATOR_SETTINGS', silent=True) -app.logger.setLevel(logging.INFO) + +APP.config.from_envvar('INTEGRATOR_SETTINGS', silent=True) +APP.logger.setLevel(logging.INFO) PAGURE_URL = '{base}api/0/{repo}/pull-request/{pr}/flag' JENKINS_TRIGGER_URL = '{base}job/{project}/buildWithParameters' @@ -28,7 +27,7 @@ db_session = None def connect_db(): global db_session - engine = create_engine(app.config['DB_URL'], convert_unicode=True) + engine = create_engine(APP.config['DB_URL'], convert_unicode=True) db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) @@ -68,7 +67,7 @@ def process_build(logger, cfg, build_id): # Comment in Pagure logger.info('Updating %s PR %d: %s', cfg.pagure_name, pr_id, result) try: - post_flag(logger, "Jenkins", cfg.pagure_url, cfg.pagure_token, + post_flag(logger, cfg.display_name, cfg.pagure_url, cfg.pagure_token, cfg.pagure_name, pr_id, result, url) except KeyError as exc: logger.warning('Unknown build status', exc_info=exc) @@ -95,22 +94,33 @@ def post_data(logger, *args, **kwargs): if resp.status_code < 200 or resp.status_code >= 300: logger.error('Network request failed: %d: %s', resp.status_code, resp.text) -@app.errorhandler(403) -def forbidden(e): - return flask.render_template('forbidden.html'), 403 +@APP.route('/hooks//build-finished', methods=['POST']) +def hook_finished(token): + try: + data = json.loads(flask.request.get_data()) + cfg = jenkins_hook.get_configs(data['name'], jenkins_hook.Service.JENKINS)[0] + build_id = data['build']['number'] + if token != cfg.hook_token: + raise ValueError('Token mismatch') + except (TypeError, ValueError, KeyError, jenkins_hook.ConfigNotFound) as exc: + APP.logger.error('Error processing jenkins notification', exc_info=exc) + return ('Bad request...\n', 400, {'Content-Type': 'text/plain'}) + APP.logger.info('Received jenkins notification') + process_build(APP.logger, cfg, build_id) + return ('', 204) def cleanup_url(url): """Make sure there is trailing slash.""" return url.rstrip('/') + '/' -@app.before_request +@APP.before_request def before_request(): if db_session is None: connect_db() -@app.teardown_appcontext +@APP.teardown_appcontext def shutdown_session(exception=None): db_session.remove() diff --git a/pagure/templates/plugin.html b/pagure/templates/plugin.html index 0d6d3ff..2fbdc1f 100644 --- a/pagure/templates/plugin.html +++ b/pagure/templates/plugin.html @@ -1,32 +1,27 @@ -{% from "_formhelper.html" import render_field_in_row %} - -{% if full %} -{% extends "repo_master.html" %} - -{% block title %}{{ select.capitalize() }} {{ plugin.name }} - {{ repo.name }}{% endblock %} -{% set tag = "home" %} -{% endif %} - - -{% block repo %} -{% if full %} -

{{ plugin.name }} settings

+{% from "_formhelper.html" import render_field_in_row %} {% if full %} {% extends "repo_master.html" %} {% block title %}{{ select.capitalize() }} {{ plugin.name }} - {{ repo.name }}{% endblock %} {% set tag = "home" %} {% endif %} {% block repo %} {% +if full %} +

{{ plugin.name }} settings

{% endif %} -
- {{ plugin.description | markdown | noJS | safe }} + {{ plugin.description | markdown | noJS | safe }} {% if post_token and (plugin.name == 'Pagure CI') %} +
+ + +
+ {% endif %} - {% for field in fields %} - {{ render_field_in_row(field) }} - {% endfor %} + {% for field in fields %} {{ render_field_in_row(field) }} {% endfor %}

{{ form.csrf_token }}

-
+ + {% endblock %} diff --git a/pagure/ui/app.py b/pagure/ui/app.py index 7e4996f..7aff6de 100644 --- a/pagure/ui/app.py +++ b/pagure/ui/app.py @@ -671,21 +671,3 @@ def ssh_hostkey(): return flask.render_template( 'doc_ssh_keys.html', ) - - -@APP.route('/hooks//build-finished', methods=['POST']) -def hook_finished(token): - print "Hello" - try: - data = json.loads(flask.request.get_data()) - cfg = jenkins_hook.get_configs(data['name'], jenkins_hook.Service.JENKINS)[0] - build_id = data['build']['number'] - print data , cfg, build_id - if token != cfg.hook_token: - raise ValueError('Token mismatch') - except (TypeError, ValueError, KeyError, jenkins_hook.ConfigNotFound) as exc: - APP.logger.error('Error processing jenkins notification', exc_info=exc) - return ('Bad request...\n', 400, {'Content-Type': 'text/plain'}) - APP.logger.info('Received jenkins notification') - pagure_ci.process_build(APP.logger, cfg, build_id) - return ('', 204) diff --git a/pagure/ui/plugins.py b/pagure/ui/plugins.py index c7f5a17..0de4a79 100644 --- a/pagure/ui/plugins.py +++ b/pagure/ui/plugins.py @@ -21,6 +21,8 @@ import pagure.forms from pagure import APP, SESSION, login_required, is_repo_admin from pagure.lib.model import BASE from pagure.exceptions import FileNotFoundException +from pagure.hooks.jenkins_hook import PagureCI + # pylint: disable=E1101 @@ -85,7 +87,15 @@ def view_plugin(repo, plugin, username=None, full=True): plugin = get_plugin(plugin) fields = [] new = True + post_token = None dbobj = plugin.db_object() + + post_token_obj = BASE.metadata.bind.query(PagureCI).filter( + PagureCI.pagure_name == repo.name).first() + + if hasattr(post_token_obj, 'hook_token'): + post_token = getattr(post_token_obj, 'hook_token') + if hasattr(repo, plugin.backref): dbobj = getattr(repo, plugin.backref) # There should always be only one, but let's double check @@ -95,18 +105,13 @@ def view_plugin(repo, plugin, username=None, full=True): else: dbobj = plugin.db_object() - print dir(dbobj) - - form = plugin.form(obj=dbobj) for field in plugin.form_fields: fields.append(getattr(form, field)) - print "validate:", form.validate_on_submit(), dir(form), form.errors + if form.validate_on_submit(): form.populate_obj(obj=dbobj) - if dbobj.__tablename__ == 'hook_pagure_ci': - dbobj.hook_token = uuid.uuid4().hex - + if new: dbobj.project_id = repo.id SESSION.add(dbobj) @@ -128,7 +133,7 @@ def view_plugin(repo, plugin, username=None, full=True): username=username, plugin=plugin, form=form, - dbobj=dbobj, + post_token=post_token, fields=fields) if form.active.data: @@ -162,5 +167,5 @@ def view_plugin(repo, plugin, username=None, full=True): username=username, plugin=plugin, form=form, - dbobj=dbobj, + post_token=post_token, fields=fields) diff --git a/setup.py b/setup.py index 1dbf3c4..02d354b 100644 --- a/setup.py +++ b/setup.py @@ -55,4 +55,8 @@ setup( packages=['pagure'], include_package_data=True, install_requires=get_requirements(), + entry_points=""" + [moksha.consumer] + integrator = pagure.consumer:Integrator + """ )