예제 #1
0
    def test_delete_expired_coprs(self, f_users, f_mock_chroots, f_coprs,
                                  f_builds, f_db):
        query = self.db.session.query(models.Copr)

        # nothing is deleted at the beginning
        assert len([c for c in query.all() if c.deleted]) == 0

        # one is to be deleted in the future
        self.c1.delete_after_days = 2
        # one is already to be deleted
        self.c2.delete_after = datetime.datetime.now() - datetime.timedelta(
            days=1)

        # and one is not to be temporary at all (c3)

        ComplexLogic.delete_expired_projects()
        self.db.session.commit()

        query = self.db.session.query(models.Copr)
        assert len(query.all()) == 3  # we only set deleted=true

        # some builds are not finished, nothing deleted yet
        assert len([c for c in query.all() if c.deleted]) == 0

        b = self.db.session.query(models.Build).get(3)
        b.canceled = True

        ComplexLogic.delete_expired_projects()
        self.db.session.commit()
        # some builds are not finished, nothing deleted yet
        assert len([c for c in query.all() if c.deleted]) == 1

        # test that build is deleted as well
        assert not self.db.session.query(models.Build).get(3)
예제 #2
0
def clean_expired_projects():
    """
    Clean all the expired temporary projects.  This command is meant to be
    executed by cron.
    """

    with db_session_scope():
        ComplexLogic.delete_expired_projects()
예제 #3
0
    def wrapper(username, coprname, **kwargs):
        if username.startswith("@"):
            group_name = username[1:]
            copr = ComplexLogic.get_group_copr_safe(group_name, coprname)
        else:
            copr = ComplexLogic.get_copr_safe(username, coprname)

        return f(copr, **kwargs)
예제 #4
0
    def wrapper(username, coprname, **kwargs):
        if username.startswith("@"):
            group_name = username[1:]
            copr = ComplexLogic.get_group_copr_safe(group_name, coprname)
        else:
            copr = ComplexLogic.get_copr_safe(username, coprname)

        return f(copr, **kwargs)
예제 #5
0
파일: misc.py 프로젝트: danvratil/copr
 def wrapper(**kwargs):
     coprname = kwargs.pop("coprname")
     if "group_name" in kwargs:
         group_name = kwargs.pop("group_name")
         copr = ComplexLogic.get_group_copr_safe(group_name, coprname, with_mock_chroots=True)
     else:
         username = kwargs.pop("username")
         copr = ComplexLogic.get_copr_safe(username, coprname, with_mock_chroots=True)
     return f(copr, **kwargs)
예제 #6
0
 def wrapper(**kwargs):
     coprname = kwargs.pop("coprname")
     if "group_name" in kwargs:
         group_name = kwargs.pop("group_name")
         copr = ComplexLogic.get_group_copr_safe(group_name,
                                                 coprname,
                                                 with_mock_chroots=True)
     else:
         username = kwargs.pop("username")
         copr = ComplexLogic.get_copr_safe(username,
                                           coprname,
                                           with_mock_chroots=True)
     return f(copr, **kwargs)
예제 #7
0
def list_projects_by_group(group_name, page=1):
    group = ComplexLogic.get_group_by_name_safe(group_name)
    query = CoprsLogic.get_multiple_by_group_id(group.id)

    paginator = Paginator(query, query.count(), page)

    coprs = paginator.sliced_query

    return render_template("coprs/show/group.html",
                           user=flask.g.user,
                           coprs=coprs,
                           paginator=paginator,
                           tasks_info=ComplexLogic.get_queues_size(),
                           group=group)
예제 #8
0
    def test_delete_project_that_is_pinned(self, f_users, f_coprs, f_db):
        pc1 = models.PinnedCoprs(id=1,
                                 copr_id=self.c2.id,
                                 user_id=self.u2.id,
                                 position=1)
        pc2 = models.PinnedCoprs(id=2,
                                 copr_id=self.c3.id,
                                 user_id=self.u2.id,
                                 position=2)
        self.db.session.add_all([pc1, pc2])

        ComplexLogic.delete_copr(self.c2, admin_action=True)
        assert set(CoprsLogic.get_multiple_by_username(
            self.u2.name)) == {self.c3}
        assert set(PinnedCoprsLogic.get_by_owner(self.u2)) == {pc2}
예제 #9
0
def get_build_config(ownername, projectname, chrootname):
    copr = get_copr(ownername, projectname)
    chroot = ComplexLogic.get_copr_chroot_safe(copr, chrootname)
    if not chroot:
        raise ObjectNotFound('Chroot not found.')
    config = to_build_config_dict(chroot)
    return flask.jsonify(config)
예제 #10
0
def process_copr_repeat_build(build_id, copr):
    build = ComplexLogic.get_build_safe(build_id)
    if not flask.g.user.can_build_in(build.copr):
        flask.flash("You are not allowed to repeat this build.")
    form = forms.BuildFormRebuildFactory.create_form_cls(build.chroots)(
        build_id=build_id,
        enable_net=build.enable_net,
    )
    # remove all checkboxes by default
    for ch in build.chroots:
        field = getattr(form, ch.name)
        field.data = False
    chroot_to_build = request.args.get("chroot")
    app.logger.debug("got param chroot: {}".format(chroot_to_build))
    if chroot_to_build:
        # set single checkbox if chroot query arg was provided
        if hasattr(form, chroot_to_build):
            getattr(form, chroot_to_build).data = True
    else:
        # set checkbox on the failed chroots
        chroots_to_select = set(ch.name for ch in build.get_chroots_by_status([
            helpers.StatusEnum('failed'),
            helpers.StatusEnum('canceled'),
        ]))

        for ch in build.chroots:
            if ch.name in chroots_to_select:
                getattr(form, ch.name).data = True
    return flask.render_template("coprs/detail/add_build/rebuild.html",
                                 copr=copr,
                                 build=build,
                                 form=form)
예제 #11
0
def delete_project(ownername, projectname):
    copr = get_copr(ownername, projectname)
    copr_dict = to_dict(copr)
    form = forms.APICoprDeleteForm(meta={'csrf': False})

    if form.validate_on_submit() and copr:
        try:
            ComplexLogic.delete_copr(copr)
        except (ActionInProgressException, InsufficientRightsException) as err:
            db.session.rollback()
            raise err
        else:
            db.session.commit()
    else:
        raise BadRequest(form.errors)
    return flask.jsonify(copr_dict)
예제 #12
0
def copr_fork_post(copr):
    form = forms.CoprForkFormFactory.create_form_cls(
        copr=copr, user=flask.g.user, groups=flask.g.user.user_groups)()
    if form.validate_on_submit():
        dstgroup = ([
            g for g in flask.g.user.user_groups if g.at_name == form.owner.data
        ] or [None])[0]
        if flask.g.user.name != form.owner.data and not dstgroup:
            return generic_error("There is no such group: {}".format(
                form.owner.data))

        fcopr, created = ComplexLogic.fork_copr(copr,
                                                flask.g.user,
                                                dstname=form.name.data,
                                                dstgroup=dstgroup)
        if created:
            msg = (
                "Forking project {} for you into {}. Please be aware that it may take a few minutes "
                "to duplicate a backend data.".format(copr.full_name,
                                                      fcopr.full_name))
        elif not created and form.confirm.data == True:
            msg = (
                "Updating packages in {} from {}. Please be aware that it may take a few minutes "
                "to duplicate a backend data.".format(copr.full_name,
                                                      fcopr.full_name))
        else:
            return render_copr_fork(copr, form, confirm=True)

        db.session.commit()
        flask.flash(msg)

        return flask.redirect(url_for_copr_details(fcopr))
    return render_copr_fork(copr, form)
예제 #13
0
def group_copr_add(group_name):
    group = ComplexLogic.get_group_by_name_safe(group_name)
    form = forms.CoprFormFactory.create_form_cls()()

    return flask.render_template("coprs/group_add.html",
                                 form=form,
                                 group=group)
예제 #14
0
def group_copr_new(group_name):
    group = ComplexLogic.get_group_by_name_safe(group_name)
    form = forms.CoprFormFactory.create_form_cls(group=group)()

    if form.validate_on_submit():
        try:
            copr = coprs_logic.CoprsLogic.add(
                flask.g.user,
                name=form.name.data,
                homepage=form.homepage.data,
                contact=form.contact.data,
                repos=form.repos.data.replace("\n", " "),
                selected_chroots=form.selected_chroots,
                description=form.description.data,
                instructions=form.instructions.data,
                disable_createrepo=form.disable_createrepo.data,
                build_enable_net=form.build_enable_net.data,
                unlisted_on_hp=form.unlisted_on_hp.data,
                group=group,
                persistent=form.persistent.data,
            )
        except (exceptions.DuplicateException, exceptions.NonAdminCannotCreatePersistentProject) as e:
            flask.flash(str(e), "error")
            return flask.render_template("coprs/group_add.html", form=form, group=group)

        db.session.add(copr)
        db.session.commit()
        after_the_project_creation(copr, form)

        return flask.redirect(url_for_copr_details(copr))
    else:
        return flask.render_template("coprs/group_add.html", form=form, group=group)
예제 #15
0
def coprs_by_user(username=None, page=1):
    user = users_logic.UsersLogic.get(username).first()
    if not user:
        return page_not_found("User {0} does not exist.".format(username))

    pinned = [pin.copr for pin in PinnedCoprsLogic.get_by_user_id(user.id)
              ] if page == 1 else []
    query = CoprsLogic.get_multiple_owned_by_username(username)
    query = CoprsLogic.filter_without_ids(query, [copr.id for copr in pinned])
    query = CoprsLogic.filter_without_group_projects(query)
    query = CoprsLogic.set_query_order(query, desc=True)

    paginator = helpers.Paginator(query, query.count(), page)
    coprs = paginator.sliced_query

    # flask.g.user is none when no user is logged - showing builds from everyone
    users_builds = builds_logic.BuildsLogic.get_recent_tasks(flask.g.user, 4)

    data = builds_logic.BuildsLogic.get_small_graph_data('30min')

    return flask.render_template("coprs/show/user.html",
                                 user=user,
                                 coprs=coprs,
                                 pinned=pinned,
                                 paginator=paginator,
                                 tasks_info=ComplexLogic.get_queue_sizes(),
                                 users_builds=users_builds,
                                 graph=data)
예제 #16
0
def dist_git_upload_completed():
    app.logger.debug(flask.request.json)
    build_id = flask.request.json.get("build_id")

    try:
        build = ComplexLogic.get_build_safe(build_id)
    except ObjectNotFound:
        return flask.jsonify({"updated": False})

    collected_branch_chroots = []
    for branch, git_hash in flask.request.json.get("branch_commits",
                                                   {}).items():
        branch_chroots = BuildsLogic.get_buildchroots_by_build_id_and_branch(
            build_id, branch)
        for ch in branch_chroots:
            ch.status = StatusEnum("pending")
            ch.git_hash = git_hash
            db.session.add(ch)
            collected_branch_chroots.append((ch.task_id))

    final_source_status = StatusEnum("succeeded")
    for ch in build.build_chroots:
        if ch.task_id not in collected_branch_chroots:
            final_source_status = StatusEnum("failed")
            ch.status = StatusEnum("failed")
            db.session.add(ch)

    build.source_status = final_source_status
    db.session.add(build)
    db.session.commit()

    BuildsLogic.delete_local_source(build)
    return flask.jsonify({"updated": True})
예제 #17
0
def process_rebuild(copr, build_id, view, url_on_success):
    source_build = ComplexLogic.get_build_safe(build_id)
    form = forms.BuildFormRebuildFactory.create_form_cls(copr.active_chroots)()

    if form.validate_on_submit():
        try:
            build_options = {
                "enable_net": form.enable_net.data,
                "timeout": form.timeout.data,
            }

            BuildsLogic.create_new_from_other_build(
                flask.g.user,
                copr,
                source_build,
                chroot_names=form.selected_chroots,
                **build_options)

        except (ActionInProgressException, InsufficientRightsException) as e:
            flask.flash(str(e), "error")
            db.session.rollback()
        else:
            flask.flash("New build has been created", "success")

            db.session.commit()

        return flask.redirect(url_on_success)
    else:
        return render_add_build(copr, form, view)
예제 #18
0
def copr_rebuild_package(copr, package_name):
    package = ComplexLogic.get_package_safe(copr.main_dir, package_name)
    data = package.source_json_dict

    if package.source_type_text == "scm":
        form = forms.BuildFormScmFactory
        f = render_add_build_scm
        view_suffix = "_scm"
    elif package.source_type_text == "pypi":
        form = forms.BuildFormPyPIFactory
        f = render_add_build_pypi
        view_suffix = "_pypi"
    elif package.source_type_text == "custom":
        form = forms.BuildFormCustomFactory
        f = render_add_build_custom
        view_suffix = "_custom"
    else:
        flask.flash(
            "Package {} has not the default source which is required for rebuild. Please configure some source"
            .format(package_name, copr.full_name))
        return flask.redirect(
            helpers.copr_url("coprs_ns.copr_edit_package",
                             copr,
                             package_name=package_name))

    form = form(copr.active_chroots, package)(data=data)
    return f(copr,
             form,
             view="coprs_ns.copr_new_build" + view_suffix,
             package=package)
예제 #19
0
def build_detail(build_id):
    build = ComplexLogic.get_build_safe(build_id)

    chroots = {}
    results_by_chroot = {}
    for chroot in build.build_chroots:
        chroots[chroot.name] = chroot.state
        results_by_chroot[chroot.name] = chroot.result_dir_url

    built_packages = None
    if build.built_packages:
        built_packages = build.built_packages.split("\n")

    output = {
        "output": "ok",
        "status": build.state,
        "project": build.copr.name,
        "owner": build.copr.user.name,
        "results": build.results,
        "built_pkgs": built_packages,
        "src_version": build.pkg_version,
        "chroots": chroots,
        "submitted_on": build.submitted_on,
        "started_on": build.min_started_on,
        "ended_on": build.max_ended_on,
        "src_pkg": build.pkgs,
        "submitted_by": build.user.name,
        "results_by_chroot": results_by_chroot
    }
    return flask.jsonify(output)
예제 #20
0
def group_copr_new(group_name):
    group = ComplexLogic.get_group_by_name_safe(group_name)
    form = forms.CoprFormFactory.create_form_cls(group=group)()

    if form.validate_on_submit():
        copr = coprs_logic.CoprsLogic.add(
            flask.g.user,
            name=form.name.data,
            homepage=form.homepage.data,
            contact=form.contact.data,
            repos=form.repos.data.replace("\n", " "),
            selected_chroots=form.selected_chroots,
            description=form.description.data,
            instructions=form.instructions.data,
            disable_createrepo=form.disable_createrepo.data,
            build_enable_net=form.build_enable_net.data,
            group=group)

        db.session.add(copr)
        db.session.commit()
        after_the_project_creation(copr, form)

        return flask.redirect(url_for_copr_details(copr))
    else:
        return flask.render_template("coprs/group_add.html",
                                     form=form,
                                     group=group)
예제 #21
0
def webhooks_hello(copr_id, uuid):
    # For the documentation of the data we receive see:
    # https://developer.github.com/v3/activity/events/types/#pushevent
    try:
        copr = ComplexLogic.get_copr_by_id_safe(copr_id)
    except ObjectNotFound:
        return page_not_found("Project does not exist")

    if copr.webhook_secret != uuid:
        return access_restricted("This webhook is not valid")

    try:
        request_json = flask.request.json
        clone_url = request_json["repository"]["clone_url"]
    except KeyError:
        return "Bad Request", 400
    if "commits" in request_json:
        commits = request_json["commits"]
    else:
        commits = []

    packages = PackagesLogic.get_for_webhook_rebuild(copr_id, uuid, clone_url, commits)

    for package in packages:
        BuildsLogic.rebuild_package(package)

    db.session.commit()

    return "OK", 200
예제 #22
0
def copr_rebuild_all_packages(copr):
    form = forms.RebuildAllPackagesFormFactory(
        copr.active_chroots, [package.name for package in copr.packages])()

    if flask.request.method == "POST" and form.validate_on_submit():
        try:
            packages = []
            for package_name in form.packages.data:
                packages.append(
                    ComplexLogic.get_package_safe(copr.main_dir, package_name))

            PackagesLogic.batch_build(flask.g.user,
                                      copr,
                                      packages,
                                      form.selected_chroots,
                                      enable_net=form.enable_net.data)

        except (ObjectNotFound, ActionInProgressException, NoPackageSourceException, \
                InsufficientRightsException, MalformedArgumentException) as e:
            db.session.rollback()
            flask.flash(str(e), "error")
        else:
            db.session.commit()
            flask.flash("Batch build successfully started.", "success")
            return flask.redirect(helpers.url_for_copr_builds(copr))

    return flask.render_template("coprs/detail/packages_rebuild_all.html",
                                 view="coprs_ns.copr_rebuild_all_packages",
                                 form=form,
                                 copr=copr)
예제 #23
0
def copr_edit_package(copr, package_name, source_type_text=None, **kwargs):
    package = ComplexLogic.get_package_safe(copr.main_dir, package_name)
    data = package.source_json_dict
    data["webhook_rebuild"] = package.webhook_rebuild
    data["chroot_blacklist"] = package.chroot_blacklist_raw
    data["max_builds"] = package.max_builds

    if package.has_source_type_set and not source_type_text:
        source_type_text = package.source_type_text
    elif not source_type_text:
        source_type_text = "scm"

    form_classes = {
        "scm": forms.PackageFormScm,
        "pypi": forms.PackageFormPyPI,
        "rubygems": forms.PackageFormRubyGems,
        "custom": forms.PackageFormCustom,
    }
    form = {k: v(formdata=None) for k, v in form_classes.items()}

    if "form" in kwargs:
        form[source_type_text] = kwargs["form"]
    elif package.has_source_type_set:
        form[package.source_type_text] = form_classes[
            package.source_type_text](data=data)

    return flask.render_template("coprs/detail/edit_package.html",
                                 package=package,
                                 copr=copr,
                                 source_type_text=source_type_text,
                                 view="coprs_ns.copr_edit_package",
                                 form_scm=form["scm"],
                                 form_pypi=form["pypi"],
                                 form_rubygems=form["rubygems"],
                                 form_custom=form['custom'])
예제 #24
0
def reschedule_build_chroot():
    response = {}
    if "build_id" in flask.request.json and "chroot" in flask.request.json:
        build = ComplexLogic.get_build_safe(flask.request.json["build_id"])
    else:
        response["result"] = "bad request"
        response["msg"] = "Request missing  `build_id` and/or `chroot`"
        return flask.jsonify(response)

    if build:
        if build.canceled:
            response["result"] = "noop"
            response["msg"] = "build was cancelled, ignoring"
        else:
            chroot = flask.request.json["chroot"]
            build_chroot = build.chroots_dict_by_name.get(chroot)
            run_statuses = set([StatusEnum("starting"), StatusEnum("running")])
            if build_chroot and build_chroot.status in run_statuses:
                log.info("rescheduling build {} chroot: {}".format(build.id, build_chroot.name))
                BuildsLogic.update_state_from_dict(build, {
                    "chroot": chroot,
                    "status": StatusEnum("pending")
                })
                db.session.commit()
                response["result"] = "done"
            else:
                response["result"] = "noop"
                response["msg"] = "build is not in running states, ignoring"

    else:
        response["result"] = "noop"
        response["msg"] = "Build {} wasn't found".format(flask.request.json["build_id"])

    return flask.jsonify(response)
예제 #25
0
def edit_project_chroot(ownername, projectname, chrootname):
    copr = get_copr(ownername, projectname)
    data = rename_fields(get_form_compatible_data())
    form = forms.ModifyChrootForm(data, meta={'csrf': False})
    chroot = ComplexLogic.get_copr_chroot_safe(copr, chrootname)

    if not form.validate_on_submit():
        raise BadRequest(form.errors)

    buildroot_pkgs = repos = comps_xml = comps_name = with_opts = without_opts = None
    if "buildroot_pkgs" in data:
        buildroot_pkgs = form.buildroot_pkgs.data
    if "repos" in data:
        repos = form.repos.data
    if "with_opts" in data:
        with_opts = form.with_opts.data
    if "without_opts" in data:
        without_opts = form.without_opts.data
    if form.upload_comps.has_file():
        comps_xml = form.upload_comps.data.stream.read()
        comps_name = form.upload_comps.data.filename
    if form.delete_comps.data:
        CoprChrootsLogic.remove_comps(flask.g.user, chroot)
    CoprChrootsLogic.update_chroot(flask.g.user,
                                   chroot,
                                   buildroot_pkgs,
                                   repos,
                                   comps=comps_xml,
                                   comps_name=comps_name,
                                   with_opts=with_opts,
                                   without_opts=without_opts)
    db.session.commit()
    return flask.jsonify(to_dict(chroot))
예제 #26
0
def copr_package_icon(copr, package_name):
    try:
        package = ComplexLogic.get_package_safe(copr.main_dir, package_name)
    except ObjectNotFound:
        return send_file("static/status_images/bad_url.png", mimetype='image/png')

    return send_build_icon(package.last_build())
예제 #27
0
def copr_edit_package(copr, package_name, source_type_text=None, **kwargs):
    package = ComplexLogic.get_package_safe(copr, package_name)
    data = package.source_json_dict
    data["webhook_rebuild"] = package.webhook_rebuild

    if package.has_source_type_set and not source_type_text:
        source_type_text = package.source_type_text
    elif not source_type_text:
        source_type_text = "git_and_tito"

    form_classes = {
        "git_and_tito": forms.PackageFormTito,
        "mock_scm": forms.PackageFormMock,
        "pypi": forms.PackageFormPyPI,
        "rubygems": forms.PackageFormRubyGems,
    }
    form = {k: v(formdata=None) for k, v in form_classes.items()}

    if "form" in kwargs:
        form[source_type_text] = kwargs["form"]
    elif package.has_source_type_set:
        if package.source_type_text == "git_and_tito" and "git_dir" in data:
            data["git_directory"] = data["git_dir"]  # @FIXME workaround
        form[package.source_type_text] = form_classes[
            package.source_type_text](data=data)

    return flask.render_template("coprs/detail/edit_package.html",
                                 package=package,
                                 copr=copr,
                                 source_type_text=source_type_text,
                                 view="coprs_ns.copr_edit_package",
                                 form_tito=form["git_and_tito"],
                                 form_mock=form["mock_scm"],
                                 form_pypi=form["pypi"],
                                 form_rubygems=form["rubygems"])
예제 #28
0
파일: __init__.py 프로젝트: schlupov/copr
def get_copr(ownername=None, projectname=None):
    request = flask.request
    ownername = ownername or request.form.get(
        "ownername") or request.json["ownername"]
    projectname = projectname or request.form.get(
        "projectname") or request.json["projectname"]
    return ComplexLogic.get_copr_by_owner_safe(ownername, projectname)
예제 #29
0
def copr_rebuild_package(copr, package_name):
    package = ComplexLogic.get_package_safe(copr, package_name)
    data = package.source_json_dict

    if package.source_type_text == "git_and_tito":
        data["git_directory"] = data["git_dir"]  # @FIXME workaround
        form = forms.BuildFormTitoFactory
        f = render_add_build_tito
        view_suffix = "_tito"
    elif package.source_type_text == "mock_scm":
        form = forms.BuildFormMockFactory
        f = render_add_build_mock
        view_suffix = "_mock"
    elif package.source_type_text == "pypi":
        form = forms.BuildFormPyPIFactory
        f = render_add_build_pypi
        view_suffix = "_pypi"
    else:
        flask.flash(
            "Package {} has not the default source which is required for rebuild. Please configure some source"
            .format(package_name, copr.full_name))
        return flask.redirect(
            helpers.copr_url("coprs_ns.copr_edit_package",
                             copr,
                             package_name=package_name))

    form = form(copr.active_chroots)(data=data)
    return f(copr,
             form,
             view="coprs_ns.copr_new_build" + view_suffix,
             package=package)
예제 #30
0
파일: api_general.py 프로젝트: nos1609/copr
def build_detail(build_id):
    build = ComplexLogic.get_build_safe(build_id)

    chroots = {}
    results_by_chroot = {}
    for chroot in build.build_chroots:
        chroots[chroot.name] = chroot.state
        results_by_chroot[chroot.name] = chroot.result_dir_url

    built_packages = None
    if build.built_packages:
        built_packages = build.built_packages.split("\n")

    output = {
        "output": "ok",
        "status": build.state,
        "project": build.copr.name,
        "owner": build.copr.owner.name,
        "results": build.results,
        "built_pkgs": built_packages,
        "src_version": build.pkg_version,
        "chroots": chroots,
        "submitted_on": build.submitted_on,
        "started_on": build.min_started_on,
        "ended_on": build.ended_on,
        "src_pkg": build.pkgs,
        "submitted_by": build.user.name,
        "results_by_chroot": results_by_chroot
    }
    return flask.jsonify(output)
예제 #31
0
 def factory(**build_options):
     source_build = ComplexLogic.get_build_safe(build_id)
     BuildsLogic.create_new_from_other_build(
         flask.g.user, copr, source_build,
         chroot_names=form.selected_chroots,
         **build_options
     )
예제 #32
0
def process_rebuild(copr, build_id, view, url_on_success):
    source_build = ComplexLogic.get_build_safe(build_id)
    form = forms.BuildFormRebuildFactory.create_form_cls(copr.active_chroots)()

    if form.validate_on_submit():
        try:
            build_options = {
                "enable_net": form.enable_net.data,
                "timeout": form.timeout.data,
            }

            BuildsLogic.create_new_from_other_build(
                flask.g.user, copr, source_build,
                chroot_names=form.selected_chroots,
                **build_options
            )

        except (ActionInProgressException, InsufficientRightsException) as e:
            flask.flash(str(e), "error")
            db.session.rollback()
        else:
            flask.flash("New build has been created", "success")

            db.session.commit()

        return flask.redirect(url_on_success)
    else:
        return render_add_build(copr, form, view)
예제 #33
0
def process_copr_repeat_build(build_id, copr):
    build = ComplexLogic.get_build_safe(build_id)
    if not flask.g.user.can_build_in(build.copr):
        flask.flash("You are not allowed to repeat this build.")
    form = forms.BuildFormRebuildFactory.create_form_cls(build.chroots)(
        build_id=build_id, enable_net=build.enable_net,
    )
    # remove all checkboxes by default
    for ch in build.chroots:
        field = getattr(form, ch.name)
        field.data = False
    chroot_to_build = request.args.get("chroot")
    app.logger.debug("got param chroot: {}".format(chroot_to_build))
    if chroot_to_build:
        # set single checkbox if chroot query arg was provided
        if hasattr(form, chroot_to_build):
            getattr(form, chroot_to_build).data = True
    else:
        # set checkbox on the failed chroots
        chroots_to_select = set(ch.name for ch in build.get_chroots_by_status([
            helpers.StatusEnum('failed'), helpers.StatusEnum('canceled'),
        ]))

        for ch in build.chroots:
            if ch.name in chroots_to_select:
                getattr(form, ch.name).data = True
    return flask.render_template(
        "coprs/detail/add_build/rebuild.html",
        copr=copr, build=build, form=form)
예제 #34
0
def copr_edit_chroot(copr, chrootname):
    form = forms.ModifyChrootForm(meta={'csrf': False})
    chroot = ComplexLogic.get_copr_chroot_safe(copr, chrootname)

    if not form.validate_on_submit():
        raise LegacyApiError("Invalid request: {0}".format(form.errors))
    else:
        buildroot_pkgs = repos = comps_xml = comps_name = None
        if "buildroot_pkgs" in flask.request.form:
            buildroot_pkgs = form.buildroot_pkgs.data
        if "repos" in flask.request.form:
            repos = form.repos.data
        if form.upload_comps.has_file():
            comps_xml = form.upload_comps.data.stream.read()
            comps_name = form.upload_comps.data.filename
        if form.delete_comps.data:
            coprs_logic.CoprChrootsLogic.remove_comps(flask.g.user, chroot)
        coprs_logic.CoprChrootsLogic.update_chroot(flask.g.user,
                                                   chroot,
                                                   buildroot_pkgs,
                                                   repos,
                                                   comps=comps_xml,
                                                   comps_name=comps_name)
        db.session.commit()

    output = {
        "output": "ok",
        "message": "Edit chroot operation was successful.",
        "chroot": chroot.to_dict(),
    }
    return flask.jsonify(output)
예제 #35
0
def build_detail(build_id):
    build = ComplexLogic.get_build_safe(build_id)

    chroots = {}
    results_by_chroot = {}
    for chroot in build.build_chroots:
        chroots[chroot.name] = chroot.state
        results_by_chroot[chroot.name] = chroot.result_dir_url

    built_packages = None
    if build.built_packages:
        built_packages = build.built_packages.split("\n")

    output = {
        "output": "ok",
        "status": build.state,
        "project": build.copr_name,
        "project_dirname": build.copr_dirname,
        "owner": build.copr.owner_name,
        "results":
        build.copr.repo_url,  # TODO: in new api return build results url
        "built_pkgs": built_packages,
        "src_version": build.pkg_version,
        "chroots": chroots,
        "submitted_on": build.submitted_on,
        "started_on": build.min_started_on,
        "ended_on": build.max_ended_on,
        "src_pkg": build.pkgs,
        "submitted_by": build.user.name
        if build.user else None,  # there is no user for webhook builds
        "results_by_chroot": results_by_chroot
    }
    return flask.jsonify(output)
예제 #36
0
def reschedule_build_chroot():
    response = {}
    if "build_id" in flask.request.json and "chroot" in flask.request.json:
        build = ComplexLogic.get_build_safe(flask.request.json["build_id"])
    else:
        response["result"] = "bad request"
        response["msg"] = "Request missing  `build_id` and/or `chroot`"
        return flask.jsonify(response)

    if build:
        if build.canceled:
            response["result"] = "noop"
            response["msg"] = "build was cancelled, ignoring"
        else:
            chroot = flask.request.json["chroot"]
            build_chroot = build.chroots_dict_by_name.get(chroot)
            run_statuses = set([StatusEnum("starting"), StatusEnum("running")])
            if build_chroot and build_chroot.status in run_statuses:
                log.info("rescheduling build {} chroot: {}".format(build.id, build_chroot.name))
                BuildsLogic.update_state_from_dict(build, {
                    "chroot": chroot,
                    "status": StatusEnum("pending")
                })
                db.session.commit()
                response["result"] = "done"
            else:
                response["result"] = "noop"
                response["msg"] = "build is not in running states, ignoring"

    else:
        response["result"] = "noop"
        response["msg"] = "Build {} wasn't found".format(flask.request.json["build_id"])

    return flask.jsonify(response)
예제 #37
0
def webhooks_hello(copr_id, uuid):
    # For the documentation of the data we receive see:
    # https://developer.github.com/v3/activity/events/types/#pushevent
    try:
        copr = ComplexLogic.get_copr_by_id_safe(copr_id)
    except ObjectNotFound:
        return page_not_found("Project does not exist")

    if copr.webhook_secret != uuid:
        return access_restricted("This webhook is not valid")

    try:
        request_json = flask.request.json
        clone_url = request_json["repository"]["clone_url"]
    except KeyError:
        return "Bad Request", 400
    if "commits" in request_json:
        commits = request_json["commits"]
    else:
        commits = []

    packages = PackagesLogic.get_for_webhook_rebuild(copr_id, uuid, clone_url,
                                                     commits)

    for package in packages:
        BuildsLogic.rebuild_package(package)

    db.session.commit()

    return "OK", 200
예제 #38
0
def group_copr_new(group_name):
    group = ComplexLogic.get_group_by_name_safe(group_name)
    form = forms.CoprFormFactory.create_form_cls(group=group)()

    if form.validate_on_submit():
        copr = coprs_logic.CoprsLogic.add(
            flask.g.user,
            name=form.name.data,
            homepage=form.homepage.data,
            contact=form.contact.data,
            repos=form.repos.data.replace("\n", " "),
            selected_chroots=form.selected_chroots,
            description=form.description.data,
            instructions=form.instructions.data,
            disable_createrepo=form.disable_createrepo.data,
            build_enable_net=form.build_enable_net.data,
            group=group
        )

        db.session.add(copr)
        db.session.commit()
        after_the_project_creation(copr, form)

        return flask.redirect(url_for_copr_details(copr))
    else:
        return flask.render_template("coprs/group_add.html", form=form, group=group)
예제 #39
0
def copr_edit_package(copr, package_name, source_type=None, **kwargs):
    package = ComplexLogic.get_package_safe(copr, package_name)
    data = package.source_json_dict
    data["webhook_rebuild"] = package.webhook_rebuild

    if package.source_type and not source_type:
        source_type = package.source_type_text
    elif not source_type:
        source_type = "git_and_tito"

    form_classes = {
        "git_and_tito": forms.PackageFormTito,
        "mock_scm": forms.PackageFormMock,
        "pypi": forms.PackageFormPyPI,
    }
    form = {k: v(formdata=None) for k, v in form_classes.items()}

    if "form" in kwargs:
        form[kwargs["form"].source_type.data] = kwargs["form"]
    elif package.source_type:
        if package.source_type_text == "git_and_tito" and "git_dir" in data:
            data["git_directory"] = data["git_dir"]  # @FIXME workaround
        form[package.source_type_text] = form_classes[package.source_type_text](data=data)

    return flask.render_template("coprs/detail/package_edit.html", package=package, copr=copr,
                                 source_type=source_type, view="coprs_ns.copr_edit_package",
                                 form_tito=form["git_and_tito"], form_mock=form["mock_scm"], form_pypi=form["pypi"])
예제 #40
0
def list_projects_by_group(group_name, page=1):
    group = ComplexLogic.get_group_by_name_safe(group_name)
    query = CoprsLogic.get_multiple_by_group_id(group.id)

    paginator = Paginator(query, query.count(), page)

    coprs = paginator.sliced_query

    return render_template(
        "coprs/show/group.html",
        user=flask.g.user,
        coprs=coprs,
        paginator=paginator,
        tasks_info=ComplexLogic.get_queues_size(),
        group=group
    )
예제 #41
0
 def factory(**build_options):
     source_build = ComplexLogic.get_build_safe(build_id)
     BuildsLogic.create_new_from_other_build(
         flask.g.user,
         copr,
         source_build,
         chroot_names=form.selected_chroots,
         **build_options)
예제 #42
0
def process_delete(copr, url_on_error, url_on_success):
    form = forms.CoprDeleteForm()
    if form.validate_on_submit():

        try:
            ComplexLogic.delete_copr(copr)
        except (exceptions.ActionInProgressException,
                exceptions.InsufficientRightsException) as e:

            db.session.rollback()
            flask.flash(str(e), "error")
            return flask.redirect(url_on_error)
        else:
            db.session.commit()
            flask.flash("Project has been deleted successfully.")
            return flask.redirect(url_on_success)
    else:
        return render_template("coprs/detail/settings/delete.html", form=form, copr=copr)
예제 #43
0
def copr_createrepo(copr_id):
    copr = ComplexLogic.get_copr_by_id_safe(copr_id)

    chroots = [c.name for c in copr.active_chroots]
    actions_logic.ActionsLogic.send_createrepo(
        username=('@'+copr.group.name if copr.is_a_group_project else copr.user.name), coprname=copr.name,
        chroots=chroots)

    db.session.commit()
    flask.flash("Repository metadata will be regenerated in a few minutes ...")
    return flask.redirect(url_for_copr_details(copr))
예제 #44
0
def cancel_build(build_id):
    build = ComplexLogic.get_build_safe(build_id)

    try:
        builds_logic.BuildsLogic.cancel_build(flask.g.user, build)
        db.session.commit()
    except exceptions.InsufficientRightsException as e:
        raise LegacyApiError("Invalid request: {}".format(e))

    output = {'output': 'ok', 'status': "Build canceled"}
    return flask.jsonify(output)
예제 #45
0
def copr_delete_build(username, coprname, build_id):
    build = ComplexLogic.get_build_safe(build_id)

    try:
        builds_logic.BuildsLogic.delete_build(flask.g.user, build)
    except (InsufficientRightsException, ActionInProgressException) as e:
        flask.flash(str(e), "error")
    else:
        db.session.commit()
        flask.flash("Build has been deleted successfully.", "success")

    return flask.redirect(url_for_copr_builds(build.copr))
예제 #46
0
def copr_delete_package(copr, package_id):
    package = ComplexLogic.get_package_by_id_safe(package_id)

    try:
        PackagesLogic.delete_package(flask.g.user, package)
    except (InsufficientRightsException, ActionInProgressException) as e:
        flask.flash(str(e), "error")
    else:
        db.session.commit()
        flask.flash("Package has been deleted successfully.", "success")

    return flask.redirect(helpers.copr_url("coprs_ns.copr_packages", copr))
예제 #47
0
def api_copr_delete(copr):
    """ Deletes selected user's project
    """
    form = forms.CoprDeleteForm(csrf_enabled=False)
    httpcode = 200

    if form.validate_on_submit() and copr:
        try:
            ComplexLogic.delete_copr(copr)
        except (exceptions.ActionInProgressException,
                exceptions.InsufficientRightsException) as err:

            db.session.rollback()
            raise LegacyApiError(str(err))
        else:
            message = "Project {} has been deleted.".format(copr.name)
            output = {"output": "ok", "message": message}
            db.session.commit()
    else:
        raise LegacyApiError("Invalid request")

    return flask.jsonify(output)
예제 #48
0
def copr_modify_chroot(copr, chrootname):
    form = forms.ModifyChrootForm(csrf_enabled=False)
    # chroot = coprs_logic.MockChrootsLogic.get_from_name(chrootname, active_only=True).first()
    chroot = ComplexLogic.get_copr_chroot_safe(copr, chrootname)

    if not form.validate_on_submit():
        raise LegacyApiError("Invalid request: bad request parameters")
    else:
        coprs_logic.CoprChrootsLogic.update_chroot(flask.g.user, chroot, form.buildroot_pkgs.data)
        db.session.commit()

    output = {'output': 'ok', 'buildroot_pkgs': chroot.buildroot_pkgs}
    return flask.jsonify(output)
예제 #49
0
def render_package_edit(copr, package_name, view, form_tito=None, form_mock=None):
    package = ComplexLogic.get_package_safe(copr, package_name)
    if not form_tito:
        data = package.source_json_dict
        if "git_dir" in data:
            data["git_directory"] = data["git_dir"]  # @FIXME workaround
        form_tito = forms.PackageFormTitoFactory.create_form_cls()(data=data)

    if not form_mock:
        data = package.source_json_dict
        form_mock = forms.PackageFormMockFactory.create_form_cls()(data=data)

    return flask.render_template("coprs/detail/package_edit.html", package=package, copr=copr, form_tito=form_tito,
                                 form_mock=form_mock, view=view)
예제 #50
0
파일: coprs_chroots.py 프로젝트: 0-T-0/copr
def render_chroot_edit(copr, chroot_name):
    chroot = ComplexLogic.get_copr_chroot_safe(copr, chroot_name)

    # todo: get COPR_chroot, not mock chroot, WTF?!
    # form = forms.ChrootForm(buildroot_pkgs=copr.buildroot_pkgs(chroot))

    form = forms.ChrootForm(buildroot_pkgs=chroot.buildroot_pkgs)
    # FIXME - test if chroot belongs to copr
    if flask.g.user.can_build_in(copr):
        return render_template("coprs/detail/edit_chroot.html",
                               form=form, copr=copr, chroot=chroot)
    else:
        raise AccessRestricted(
            "You are not allowed to modify chroots in project {0}."
            .format(copr.name))
예제 #51
0
def copr_build_redirect(build_id):
    build = ComplexLogic.get_build_safe(build_id)
    copr = build.copr
    if copr.is_a_group_project:
        return flask.redirect(url_for(
            "coprs_ns.group_copr_build",
            group_name=build.copr.group.name,
            coprname=build.copr.name,
            build_id=build_id))
    else:
        return flask.redirect(url_for(
            "coprs_ns.copr_build",
            username=build.copr.user.name,
            coprname=build.copr.name,
            build_id=build_id))
예제 #52
0
def generate_repo_file(username, coprname, name_release, repofile):
    """ Generate repo file for a given repo name.
        Reponame = username-coprname """
    # This solution is used because flask splits off the last part after a
    # dash, therefore user-re-po resolves to user-re/po instead of user/re-po
    # FAS usernames may not contain dashes, so this construction is safe.

    # support access to the group projects using @-notation
    # todo: remove when yum/dnf plugin is updated to use new url schema
    if username.startswith("@"):
        return group_generate_repo_file(group_name=username[1:], coprname=coprname,
                                        name_release=name_release, repofile=repofile)

    copr = ComplexLogic.get_copr_safe(username, coprname)
    return render_generate_repo_file(copr, name_release)
예제 #53
0
def render_copr_package_rebuild(copr, package_name, view):
    package = ComplexLogic.get_package_safe(copr, package_name)
    data = package.source_json_dict

    if package.source_type_text == "git_and_tito":
        data["git_directory"] = data["git_dir"]  # @FIXME workaround
        form = forms.BuildFormTitoFactory
        f = render_add_build_tito
        view_suffix = "_tito"
    elif package.source_type_text == "mock_scm":
        form = forms.BuildFormMockFactory
        f = render_add_build_mock
        view_suffix = "_mock"

    form = form.create_form_cls(copr.active_chroots)(data=data)
    return f(copr, form, view=view + view_suffix)
예제 #54
0
def coprs_show(page=1):
    query = CoprsLogic.get_multiple()
    query = CoprsLogic.set_query_order(query, desc=True)

    paginator = helpers.Paginator(query, query.count(), page)

    coprs = paginator.sliced_query

    # flask.g.user is none when no user is logged - showing builds from everyone
    # TODO: builds_logic.BuildsLogic.get_recent_tasks(flask.g.user, 5) takes too much time, optimize sql
    # users_builds = builds_logic.BuildsLogic.get_recent_tasks(flask.g.user, 5)
    users_builds = builds_logic.BuildsLogic.get_recent_tasks(None, 5)

    return flask.render_template("coprs/show/all.html",
                                 coprs=coprs,
                                 paginator=paginator,
                                 tasks_info=ComplexLogic.get_queues_size(),
                                 users_builds=users_builds)
예제 #55
0
    def test_fork_copr_sends_actions(self, mc_flask_g, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
        mc_flask_g.user.name = self.u2.name
        fc1, created = ComplexLogic.fork_copr(self.c1, self.u2, u"dstname")
        self.db.session.commit()

        actions = ActionsLogic.get_many(ActionTypeEnum("gen_gpg_key")).all()
        assert len(actions) == 1
        data = json.loads(actions[0].data)
        assert data["username"] == self.u2.name
        assert data["projectname"] == "dstname"

        actions = ActionsLogic.get_many(ActionTypeEnum("fork")).all()
        assert len(actions) == 1
        data = json.loads(actions[0].data)
        assert data["user"] == self.u2.name
        assert data["copr"] == "dstname"

        last_build, forked_build = self.c1.packages[0].builds[1], fc1.builds[0]
        assert data["builds_map"] == {str(forked_build.id): str(last_build.result_dir_name)}
예제 #56
0
def copr_fork_post(copr):
    form = forms.CoprForkFormFactory.create_form_cls(copr=copr, user=flask.g.user, groups=flask.g.user.user_groups)()
    if form.validate_on_submit():
        dstgroup = ([g for g in flask.g.user.user_groups if g.at_name == form.owner.data] or [None])[0]
        if flask.g.user.name != form.owner.data and not dstgroup:
            return generic_error("There is no such group: {}".format(form.owner.data))

        fcopr = CoprsLogic.get_by_group_id(dstgroup.id, form.name.data).first() if dstgroup \
            else CoprsLogic.filter_without_group_projects(CoprsLogic.get(flask.g.user.name, form.name.data)).first()

        if not fcopr:
            fcopr = ComplexLogic.fork_copr(copr, flask.g.user, dstname=form.name.data, dstgroup=dstgroup)
            db.session.commit()

            flask.flash("Forking project {} for you into {}. Please be aware that it may take a few minutes "
                        "to duplicate a backend data.".format(copr.full_name, fcopr.full_name))

        return flask.redirect(url_for_copr_details(fcopr))
    return render_copr_fork(copr, form)
예제 #57
0
def coprs_fulltext_search(page=1):
    fulltext = flask.request.args.get("fulltext", "")
    try:
        query = coprs_logic.CoprsLogic.get_multiple_fulltext(fulltext)
    except ValueError as e:
        flask.flash(str(e), "error")
        return flask.redirect(flask.request.referrer or
                              flask.url_for("coprs_ns.coprs_show"))

    paginator = helpers.Paginator(query, query.count(), page,
                                  additional_params={"fulltext": fulltext})

    coprs = paginator.sliced_query
    return render_template(
        "coprs/show/fulltext.html",
        coprs=coprs,
        paginator=paginator,
        fulltext=fulltext,
        tasks_info=ComplexLogic.get_queues_size(),
    )
예제 #58
0
def starting_build():
    """
    Check if the build is not cancelled and set it to running state
    """

    result = {"can_start": False}

    if "build_id" in flask.request.json and "chroot" in flask.request.json:
        build = ComplexLogic.get_build_safe(flask.request.json["build_id"])
        chroot = flask.request.json.get("chroot")

        if build and chroot and not build.canceled:
            log.info("mark build {} chroot {} as starting".format(build.id, chroot))
            BuildsLogic.update_state_from_dict(build, {
                "chroot": chroot,
                "status": StatusEnum("starting")
            })
            db.session.commit()
            result["can_start"] = True

    return flask.jsonify(result)
예제 #59
0
def process_copr_repeat_build(build_id, copr):
    build = ComplexLogic.get_build_safe(build_id)
    if not flask.g.user.can_build_in(build.copr):
        flask.flash("You are not allowed to repeat this build.")

    if build.source_type == helpers.BuildSourceEnum('srpm_upload'):
        # If the original build's source is 'srpm_upload', we will show only the
        # original build's chroots and skip import.
        available_chroots = build.chroots

    else:
        # For all other sources, we will show all chroots enabled in the project
        # and proceed with import.
        available_chroots = copr.active_chroots

    form = forms.BuildFormRebuildFactory.create_form_cls(available_chroots)(
        build_id=build_id, enable_net=build.enable_net)

    # remove all checkboxes by default
    for ch in available_chroots:
        field = getattr(form, ch.name)
        field.data = False
    chroot_to_build = request.args.get("chroot")
    app.logger.debug("got param chroot: {}".format(chroot_to_build))
    if chroot_to_build:
        # set single checkbox if chroot query arg was provided
        if hasattr(form, chroot_to_build):
            getattr(form, chroot_to_build).data = True
    else:
        build_chroot_names = set(ch.name for ch in build.chroots)
        build_failed_chroot_names = set(ch.name for ch in build.get_chroots_by_status([
            helpers.StatusEnum('failed'), helpers.StatusEnum('canceled'),
        ]))
        for ch in available_chroots:
            # check checkbox on all the chroots that have not been (successfully) built before
            if (ch.name not in build_chroot_names) or (ch.name in build_failed_chroot_names):
                getattr(form, ch.name).data = True
    return flask.render_template(
        "coprs/detail/add_build/rebuild.html",
        copr=copr, build=build, form=form)
예제 #60
0
def copr_fork_post(copr):
    form = forms.CoprForkFormFactory.create_form_cls(copr=copr, user=flask.g.user, groups=flask.g.user.user_groups)()
    if form.validate_on_submit():
        dstgroup = ([g for g in flask.g.user.user_groups if g.at_name == form.owner.data] or [None])[0]
        if flask.g.user.name != form.owner.data and not dstgroup:
            return generic_error("There is no such group: {}".format(form.owner.data))

        fcopr, created = ComplexLogic.fork_copr(copr, flask.g.user, dstname=form.name.data, dstgroup=dstgroup)
        if created:
            msg = ("Forking project {} for you into {}. Please be aware that it may take a few minutes "
                   "to duplicate a backend data.".format(copr.full_name, fcopr.full_name))
        elif not created and form.confirm.data == True:
            msg = ("Updating packages in {} from {}. Please be aware that it may take a few minutes "
                   "to duplicate a backend data.".format(copr.full_name, fcopr.full_name))
        else:
            return render_copr_fork(copr, form, confirm=True)

        db.session.commit()
        flask.flash(msg)

        return flask.redirect(url_for_copr_details(fcopr))
    return render_copr_fork(copr, form)