Blame pagure/lib/lib_ci.py

Pierre-Yves Chibon 5776fd
# -*- coding: utf-8 -*-
Pierre-Yves Chibon f377a8
Pierre-Yves Chibon f377a8
"""
Pierre-Yves Chibon f377a8
 (c) 2016 - Copyright Red Hat Inc
Pierre-Yves Chibon f377a8
Pierre-Yves Chibon f377a8
 Authors:
Pierre-Yves Chibon f377a8
   Lubomír Sedlář <lubomir.sedlar@gmail.com></lubomir.sedlar@gmail.com>
Pierre-Yves Chibon f377a8
   Farhaan Bukhsh <farhaan.bukhsh@gmail.com></farhaan.bukhsh@gmail.com>
Pierre-Yves Chibon f377a8
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon f377a8
Pierre-Yves Chibon f377a8
"""
Pierre-Yves Chibon f377a8
Pierre-Yves Chibon 67d1cc
from __future__ import unicode_literals, absolute_import
Aurélien Bompard dcf6f6
Pierre-Yves Chibon 22a554
# pylint: disable=too-many-locals
Clement Verna f5181b
import logging
Pierre-Yves Chibon cdc7ec
import time
Pierre-Yves Chibon 5776fd
import pagure.exceptions
Pierre-Yves Chibon 930073
import pagure.lib.query
Pierre-Yves Chibon 5776fd
Clement Verna f5181b
from pagure.config import config as pagure_config
Pierre-Yves Chibon d9a239
Clement Verna f5181b
_log = logging.getLogger(__name__)
Pierre-Yves Chibon 5776fd
Pierre-Yves Chibon 5776fd
BUILD_STATS = {
Pierre-Yves Chibon c48ff3
    "SUCCESS": ("Build #%s successful", pagure_config["FLAG_SUCCESS"], 100),
Pierre-Yves Chibon c48ff3
    "FAILURE": ("Build #%s failed", pagure_config["FLAG_FAILURE"], 0),
Pierre-Yves Chibon c48ff3
    "ABORTED": ("Build #%s aborted", "error", 0),
Pierre-Yves Chibon c48ff3
    "BUILDING": ("Build #%s in progress", pagure_config["FLAG_PENDING"], 0),
Pierre-Yves Chibon 5776fd
}
Pierre-Yves Chibon 5776fd
Pierre-Yves Chibon 5776fd
Patrick Uiterwijk 3f97f6
def process_jenkins_build(session, project, build_id, iteration=0):
Pierre-Yves Chibon 5776fd
    """  Gets the build info from jenkins and flags that particular
Pierre-Yves Chibon 5776fd
    pull-request.
Pierre-Yves Chibon 5776fd
    """
Pierre-Yves Chibon 5776fd
    import jenkins
Pierre-Yves Chibon 9c2953
Pierre-Yves Chibon 5a469e
    # This import is needed as pagure.lib relies on Project.ci_hook to be
Pierre-Yves Chibon 5a469e
    # defined and accessible and this happens in pagure.hooks.pagure_ci
Pierre-Yves Chibon 5a469e
    from pagure.hooks import pagure_ci  # noqa: E402,F401
Pierre-Yves Chibon 5a469e
Farhaan Bukhsh e4a06d
    # Jenkins Base URL
Pierre-Yves Chibon 9c2953
    _log.info("Querying jenkins at: %s", project.ci_hook.ci_url)
Pierre-Yves Chibon 9c6dee
    jenk = jenkins.Jenkins(
Pierre-Yves Chibon 9c6dee
        project.ci_hook.ci_url,
Pierre-Yves Chibon 9c6dee
        username=project.ci_hook.ci_username or None,
Pierre-Yves Chibon 9c6dee
        password=project.ci_hook.ci_password or None,
Pierre-Yves Chibon 9c6dee
    )
Clement Verna 5434db
    jenkins_name = project.ci_hook.ci_job
Pierre-Yves Chibon 2824fb
    _log.info(
Pierre-Yves Chibon 9c2953
        "Querying jenkins for project: %s, build: %s", jenkins_name, build_id
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon d67005
    try:
Pierre-Yves Chibon d67005
        build_info = jenk.get_build_info(jenkins_name, build_id)
Pierre-Yves Chibon d67005
    except jenkins.NotFoundException:
Pierre-Yves Chibon 9c2953
        _log.debug("Could not find build %s at: %s", build_id, jenkins_name)
Pierre-Yves Chibon d67005
        raise pagure.exceptions.PagureException(
Pierre-Yves Chibon 9c2953
            "Could not find build %s at: %s" % (build_id, jenkins_name)
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 2824fb
Pierre-Yves Chibon 9c2953
    if build_info.get("building") is True:
Pierre-Yves Chibon 7143ee
        if iteration < 5:
Pierre-Yves Chibon 9c2953
            _log.info("Build is still going, let's wait a sec and try again")
Pierre-Yves Chibon 7143ee
            time.sleep(1)
Pierre-Yves Chibon 7143ee
            return process_jenkins_build(
Patrick Uiterwijk 3f97f6
                session, project, build_id, iteration=iteration + 1
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon 7143ee
        _log.info(
Pierre-Yves Chibon 7143ee
            "We've been waiting for 5 seconds and the build is still "
Pierre-Yves Chibon 9c2953
            "not finished, so let's keep going."
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon cdc7ec
Pierre-Yves Chibon 9c2953
    result = build_info.get("result")
Pierre-Yves Chibon 9c2953
    if not result and build_info.get("building") is True:
Pierre-Yves Chibon 9c2953
        result = "BUILDING"
Pierre-Yves Chibon 7143ee
Pierre-Yves Chibon 9c2953
    _log.info("Result from jenkins: %s", result)
Pierre-Yves Chibon 9c2953
    url = build_info["url"]
Pierre-Yves Chibon 9c2953
    _log.info("URL from jenkins: %s", url)
Pierre-Yves Chibon 5776fd
Pierre-Yves Chibon 5776fd
    pr_id = None
Pierre-Yves Chibon 9c2953
    for action in build_info["actions"]:
Pierre-Yves Chibon 9c2953
        for cause in action.get("causes", []):
Pierre-Yves Chibon 5776fd
            try:
Pierre-Yves Chibon 9c2953
                pr_id = int(cause["note"])
Pierre-Yves Chibon 5776fd
            except (KeyError, ValueError):
Pierre-Yves Chibon 5776fd
                continue
Pierre-Yves Chibon 5776fd
Pierre-Yves Chibon 5776fd
    if not pr_id:
Pierre-Yves Chibon 9c2953
        raise pagure.exceptions.NoCorrespondingPR("No corresponding PR found")
Pierre-Yves Chibon 5776fd
Pierre-Yves Chibon cdc7ec
    if not result or result not in BUILD_STATS:
Pierre-Yves Chibon d67005
        raise pagure.exceptions.PagureException(
Pierre-Yves Chibon 9c2953
            "Unknown build status: %s" % result
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 5776fd
Pierre-Yves Chibon 930073
    request = pagure.lib.query.search_pull_requests(
Pierre-Yves Chibon 9c2953
        session, project_id=project.id, requestid=pr_id
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 5776fd
Pierre-Yves Chibon 5776fd
    if not request:
Pierre-Yves Chibon 9c2953
        raise pagure.exceptions.PagureException("Request not found")
Pierre-Yves Chibon 5776fd
Pierre-Yves Chibon 7143ee
    comment, state, percent = BUILD_STATS[result]
Pierre-Yves Chibon c48ff3
    comment = comment % build_id
Farhaan Bukhsh a877eb
    # Adding build ID to the CI type
Pierre-Yves Chibon c48ff3
    username = "%s" % project.ci_hook.ci_type
Pierre-Yves Chibon 7143ee
    if request.commit_stop:
Pierre-Yves Chibon 9c2953
        comment += " (commit: %s)" % (request.commit_stop[:8])
Pierre-Yves Chibon 7143ee
Pierre-Yves Chibon 7143ee
    uid = None
Pierre-Yves Chibon 7143ee
    for flag in request.flags:
Pierre-Yves Chibon 9c2953
        if (
Pierre-Yves Chibon 9c2953
            flag.status == pagure_config["FLAG_PENDING"]
Pierre-Yves Chibon 9c2953
            and flag.username == username
Pierre-Yves Chibon 9c2953
        ):
Pierre-Yves Chibon 7143ee
            uid = flag.uid
Pierre-Yves Chibon 7143ee
            break
Pierre-Yves Chibon 5776fd
Pierre-Yves Chibon 7143ee
    _log.info("Flag's UID: %s", uid)
Pierre-Yves Chibon 930073
    pagure.lib.query.add_pull_request_flag(
Pierre-Yves Chibon 5776fd
        session,
Pierre-Yves Chibon 5776fd
        request=request,
Farhaan Bukhsh a877eb
        username=username,
Pierre-Yves Chibon 5776fd
        percent=percent,
Pierre-Yves Chibon 5776fd
        comment=comment,
Pierre-Yves Chibon 5776fd
        url=url,
Pierre-Yves Chibon 7143ee
        status=state,
Pierre-Yves Chibon 7143ee
        uid=uid,
Farhaan Bukhsh 04671b
        user=project.user.username,
Pierre-Yves Chibon d22583
        token=None,
Pierre-Yves Chibon 5776fd
    )
Farhaan Bukhsh 04671b
    session.commit()
Clement Verna f5181b
Clement Verna f5181b
Pierre-Yves Chibon fd1956
def trigger_jenkins_build(
Pierre-Yves Chibon 9c6dee
    project_path,
Pierre-Yves Chibon 9c6dee
    url,
Pierre-Yves Chibon 9c6dee
    job,
Pierre-Yves Chibon 9c6dee
    token,
Pierre-Yves Chibon 9c6dee
    branch,
Pierre-Yves Chibon 9c6dee
    branch_to,
Pierre-Yves Chibon 9c6dee
    cause,
Pierre-Yves Chibon 9c6dee
    ci_username=None,
Pierre-Yves Chibon 9c6dee
    ci_password=None,
Pierre-Yves Chibon fd1956
):
Clement Verna f5181b
    """ Trigger a build on a jenkins instance."""
Clement Verna f5181b
    try:
Clement Verna f5181b
        import jenkins
Clement Verna f5181b
    except ImportError:
Pierre-Yves Chibon 9c2953
        _log.error("Pagure-CI: Failed to load the jenkins module, bailing")
Clement Verna f5181b
        return
Clement Verna f5181b
Pierre-Yves Chibon 9c2953
    _log.info("Jenkins CI")
Clement Verna f5181b
Pierre-Yves Chibon 9c2953
    repo = "%s/%s" % (pagure_config["GIT_URL_GIT"].rstrip("/"), project_path)
Clement Verna f5181b
Pierre-Yves Chibon fd1956
    data = {
Pierre-Yves Chibon fd1956
        "cause": cause,
Pierre-Yves Chibon fd1956
        "REPO": repo,
Pierre-Yves Chibon fd1956
        "BRANCH": branch,
Pierre-Yves Chibon fd1956
        "BRANCH_TO": branch_to,
Pierre-Yves Chibon fd1956
    }
Clement Verna f5181b
Pierre-Yves Chibon 9c6dee
    server = jenkins.Jenkins(
Pierre-Yves Chibon 9c6dee
        url, username=ci_username or None, password=ci_password or None
Pierre-Yves Chibon 9c6dee
    )
Pierre-Yves Chibon 2824fb
    _log.info(
Pierre-Yves Chibon 9c2953
        "Pagure-CI: Triggering at: %s for: %s - data: %s", url, job, data
Pierre-Yves Chibon 9c2953
    )
Clement Verna f5181b
    try:
Pierre-Yves Chibon 9c2953
        server.build_job(name=job, parameters=data, token=token)
Pierre-Yves Chibon 9c2953
        _log.info("Pagure-CI: Build triggered")
Clement Verna f5181b
    except Exception as err:
Pierre-Yves Chibon 9c2953
        _log.info("Pagure-CI:An error occured: %s", err)