def edit_project(ownername, projectname): copr = get_copr(ownername, projectname) data = rename_fields(get_form_compatible_data()) form = forms.CoprModifyForm(data, meta={'csrf': False}) if not form.validate_on_submit(): raise BadRequest(form.errors) validate_chroots(get_input_dict(), MockChrootsLogic.get_multiple()) for field in form: if field.data is None or field.name in ["csrf_token", "chroots"]: continue if field.name not in data.keys(): continue setattr(copr, field.name, field.data) if form.chroots.data: CoprChrootsLogic.update_from_names(flask.g.user, copr, form.chroots.data) try: CoprsLogic.update(flask.g.user, copr) if copr.group: # load group.id _ = copr.group.id db.session.commit() except (ActionInProgressException, InsufficientRightsException, NonAdminCannotDisableAutoPrunning) as ex: db.session.rollback() raise ex return flask.jsonify(to_dict(copr))
def copr_modify(copr): form = forms.CoprModifyForm(csrf_enabled=False) if not form.validate_on_submit(): raise LegacyApiError("Invalid request: bad request parameters") # .raw_data needs to be inspected to figure out whether the field # was not sent or was sent empty if form.description.raw_data and len(form.description.raw_data): copr.description = form.description.data if form.instructions.raw_data and len(form.instructions.raw_data): copr.instructions = form.instructions.data if form.repos.raw_data and len(form.repos.raw_data): copr.repos = form.repos.data if form.disable_createrepo.raw_data and len( form.disable_createrepo.raw_data): copr.disable_createrepo = form.disable_createrepo.data try: CoprsLogic.update(flask.g.user, copr) db.session.commit() except (exceptions.ActionInProgressException, exceptions.InsufficientRightsException) as e: db.session.rollback() raise LegacyApiError("Invalid request: {}".format(e)) output = { 'output': 'ok', 'description': copr.description, 'instructions': copr.instructions, 'repos': copr.repos, } return flask.jsonify(output)
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)
def copr_modify(copr): form = forms.CoprModifyForm(csrf_enabled=False) if not form.validate_on_submit(): raise LegacyApiError("Invalid request: bad request parameters") # .raw_data needs to be inspected to figure out whether the field # was not sent or was sent empty if form.description.raw_data and len(form.description.raw_data): copr.description = form.description.data if form.instructions.raw_data and len(form.instructions.raw_data): copr.instructions = form.instructions.data if form.repos.raw_data and len(form.repos.raw_data): copr.repos = form.repos.data if form.disable_createrepo.raw_data and len(form.disable_createrepo.raw_data): copr.disable_createrepo = form.disable_createrepo.data try: CoprsLogic.update(flask.g.user, copr) db.session.commit() except (exceptions.ActionInProgressException, exceptions.InsufficientRightsException) as e: db.session.rollback() raise LegacyApiError("Invalid request: {}".format(e)) output = { 'output': 'ok', 'description': copr.description, 'instructions': copr.instructions, 'repos': copr.repos, } return flask.jsonify(output)
def test_update_raises_if_copr_has_unfinished_actions(self, f_users, f_coprs, f_actions, f_db): self.c1.name = "foo" with pytest.raises(ActionInProgressException): CoprsLogic.update(self.u1, self.c1) self.db.session.rollback()
def test_api_create_copr_ok_all(self, f_users, f_mock_chroots, f_db): self.db.session.add_all([self.u1, self.mc1]) self.tc.post("/api/new/") content = { "name": self.copr_name, self.mc1.name: "y", "repos": self.repos, "initial_pkgs": self.initial_pkgs, "description": self.description, "instructions": self.instructions } content_encoded = json.dumps(content) with pytest.raises(sqlalchemy.orm.exc.NoResultFound): CoprsLogic.get(None, self.u1.name, self.copr_name).one() r = self.post_api_with_auth("/api/coprs/{}/new/".format(self.u1.name), content_encoded) response = json.loads(r.data) assert "New project was successfully created" in response["message"] copr = self.models.Copr.query.filter( self.models.Copr.name == self.copr_name).one() assert copr.name == self.copr_name assert [self.mc1.name] == [c.name for c in copr.active_chroots] assert copr.repos == self.repos assert copr.owner.id == self.u1.id assert copr.description == self.description assert copr.instructions == self.instructions
def test_api_create_copr_ok_all(self, f_users, f_mock_chroots, f_db): self.db.session.add_all([self.u1, self.mc1]) self.tc.post("/api/new/") content = { "name": self.copr_name, self.mc1.name: "y", "repos": self.repos, "initial_pkgs": self.initial_pkgs, "description": self.description, "instructions": self.instructions } content_encoded = json.dumps(content) with pytest.raises(sqlalchemy.orm.exc.NoResultFound): CoprsLogic.get(self.u1.name, self.copr_name).one() r = self.post_api_with_auth( "/api/coprs/{}/new/".format(self.u1.name), content_encoded ) response = json.loads(r.data.decode("utf-8")) assert "New project was successfully created" in response["message"] copr = self.models.Copr.query.filter(self.models.Copr.name == self.copr_name).one() assert copr.name == self.copr_name assert [self.mc1.name] == [c.name for c in copr.active_chroots] assert copr.repos == self.repos assert copr.owner.id == self.u1.id assert copr.description == self.description assert copr.instructions == self.instructions
def test_legal_flag_doesnt_block_copr_functionality(self, f_users, f_coprs, f_db): self.db.session.add( self.models.Action(object_type="copr", object_id=self.c1.id, action_type=ActionTypeEnum("legal-flag")) ) self.db.session.commit() # test will fail if this raises exception CoprsLogic.raise_if_unfinished_blocking_action(self.c1, "ha, failed")
def test_project_delete_fail_unfinished_project_action( self, f_users, f_mock_chroots, f_coprs, f_users_api, f_db): CoprsLogic.create_delete_action(self.c1) self.db.session.commit() href = "/api_2/projects/{}".format(self.c1.id) r0 = self.request_rest_api_with_auth(href, method="delete") assert r0.status_code == 400
def test_re_enable_auto_createrepo_produce_action(self, f_users, f_coprs, f_mock_chroots, f_db): self.db.session.add_all( [self.u1, self.c1, self.mc1, self.mc2, self.mc3]) username = self.u1.name coprname = self.c1.name copr_id = self.c1.id chroot = self.mc1.name # 1.ensure ACR enabled self.db.session.commit() c1_actual = CoprsLogic.get(self.u1.name, self.c1.name).one() assert c1_actual.auto_createrepo # 1. disabling ACR self.test_client.post("/coprs/{0}/{1}/update/".format( username, coprname), data={ "name": coprname, chroot: "y", "id": copr_id, "disable_createrepo": True }, follow_redirects=True) self.db.session.commit() # check current status c1_actual = CoprsLogic.get(username, coprname).one() assert not c1_actual.auto_createrepo # no actions issued before assert len(ActionsLogic.get_many().all()) == 0 # 2. enabling ACR self.test_client.post("/coprs/{0}/{1}/update/".format( username, coprname), data={ "name": coprname, chroot: "y", "id": copr_id, "disable_createrepo": "false" }, follow_redirects=True) self.db.session.commit() c1_actual = CoprsLogic.get(username, coprname).one() # ACR enabled assert c1_actual.auto_createrepo # added action assert len(ActionsLogic.get_many().all()) > 0 action = ActionsLogic.get_many( action_type=ActionTypeEnum("createrepo")).one() data_dict = json.loads(action.data) assert data_dict["username"] == username assert data_dict["projectname"] == coprname
def projects(self): # @FIXME We get into circular import when this import is on module-level from coprs.logic.coprs_logic import CoprsLogic return [{ "full_name": p.full_name, "url": copr_url("coprs_ns.copr_detail", p, _external=True) } for p in CoprsLogic.filter_by_user_name( CoprsLogic.get_multiple(), self.user.name)]
def __call__(self, form, field): if self.group: existing = CoprsLogic.exists_for_group( self.group, field.data).first() else: existing = CoprsLogic.exists_for_user( self.user, field.data).first() if existing and str(existing.id) != form.id.data: raise wtforms.ValidationError(self.message.format(field.data))
def test_legal_flag_doesnt_block_copr_functionality(self, f_users, f_coprs, f_db): self.db.session.add(self.models.Action( object_type="copr", object_id=self.c1.id, action_type=ActionTypeEnum("legal-flag"))) self.db.session.commit() # test will fail if this raises exception CoprsLogic.raise_if_unfinished_blocking_action(self.c1, "ha, failed")
def __call__(self, form, field): if self.group: existing = CoprsLogic.exists_for_group(self.group, field.data).first() else: existing = CoprsLogic.exists_for_user(self.user, field.data).first() if existing and str(existing.id) != form.id.data: raise wtforms.ValidationError(self.message.format(field.data))
def test_project_delete_fail_unfinished_project_action( self, f_users, f_mock_chroots, f_coprs, f_users_api, f_db): CoprsLogic.create_delete_action(self.c1) self.db.session.commit() href = "/api_2/projects/{}".format(self.c1.id) r0 = self.request_rest_api_with_auth( href, method="delete" ) assert r0.status_code == 400
def test_copr_logic_add_sends_create_gpg_key_action(self, f_users, f_mock_chroots, f_db): name = u"project_1" selected_chroots = [self.mc1.name] CoprsLogic.add(self.u1, name, selected_chroots) 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.u1.name assert data["projectname"] == name
def coprs_migration_report(username=None): if not username and not flask.g.user: return generic_error("You are not logged in") elif not username: username = flask.g.user.name user = UsersLogic.get(username).first() coprs = CoprsLogic.filter_without_group_projects(CoprsLogic.get_multiple_owned_by_username(username)).all() for group in UsersLogic.get_groups_by_fas_names_list(user.user_teams).all(): coprs.extend(CoprsLogic.get_multiple_by_group_id(group.id).all()) return render_migration_report(coprs, user=user)
def test_re_enable_auto_createrepo_produce_action( self, f_users, f_coprs, f_mock_chroots, f_db): self.db.session.add_all( [self.u1, self.c1, self.mc1, self.mc2, self.mc3]) username = self.u1.name coprname = self.c1.name copr_id = self.c1.id chroot = self.mc1.name # 1.ensure ACR enabled self.db.session.commit() c1_actual = CoprsLogic.get(self.u1.name, self.c1.name).one() assert c1_actual.auto_createrepo # 1. disabling ACR self.test_client.post( "/coprs/{0}/{1}/update/".format(username, coprname), data={"name": coprname, chroot: "y", "id": copr_id, "disable_createrepo": True}, follow_redirects=True ) self.db.session.commit() # check current status c1_actual = CoprsLogic.get(username, coprname).one() assert not c1_actual.auto_createrepo # no actions issued before assert len(ActionsLogic.get_many().all()) == 0 # 2. enabling ACR self.test_client.post( "/coprs/{0}/{1}/update/".format(username, coprname), data={"name": coprname, chroot: "y", "id": copr_id, "disable_createrepo": "false"}, follow_redirects=True ) self.db.session.commit() c1_actual = CoprsLogic.get(username, coprname).one() # ACR enabled assert c1_actual.auto_createrepo # added action assert len(ActionsLogic.get_many().all()) > 0 action = ActionsLogic.get_many(action_type=ActionTypeEnum("createrepo")).one() data_dict = json.loads(action.data) assert data_dict["username"] == username assert data_dict["projectname"] == coprname
def copr_modify(copr): form = forms.CoprModifyForm(meta={'csrf': False}) if not form.validate_on_submit(): raise LegacyApiError("Invalid request: {0}".format(form.errors)) # .raw_data needs to be inspected to figure out whether the field # was not sent or was sent empty if form.description.raw_data and len(form.description.raw_data): copr.description = form.description.data if form.instructions.raw_data and len(form.instructions.raw_data): copr.instructions = form.instructions.data if form.repos.raw_data and len(form.repos.raw_data): copr.repos = form.repos.data if form.disable_createrepo.raw_data and len( form.disable_createrepo.raw_data): copr.disable_createrepo = form.disable_createrepo.data if "unlisted_on_hp" in flask.request.form: copr.unlisted_on_hp = form.unlisted_on_hp.data if "build_enable_net" in flask.request.form: copr.build_enable_net = form.build_enable_net.data if "auto_prune" in flask.request.form: copr.auto_prune = form.auto_prune.data if "use_bootstrap_container" in flask.request.form: copr.use_bootstrap_container = form.use_bootstrap_container.data if "chroots" in flask.request.form: coprs_logic.CoprChrootsLogic.update_from_names(flask.g.user, copr, form.chroots.data) try: CoprsLogic.update(flask.g.user, copr) if copr.group: # load group.id _ = copr.group.id db.session.commit() except (exceptions.ActionInProgressException, exceptions.InsufficientRightsException, exceptions.NonAdminCannotDisableAutoPrunning) as e: db.session.rollback() raise LegacyApiError("Invalid request: {}".format(e)) output = { 'output': 'ok', 'description': copr.description, 'instructions': copr.instructions, 'repos': copr.repos, 'chroots': [c.name for c in copr.mock_chroots], } return flask.jsonify(output)
def coprs_migration_report(username=None): if not username and not flask.g.user: return generic_error("You are not logged in") elif not username: username = flask.g.user.name user = UsersLogic.get(username).first() coprs = CoprsLogic.filter_without_group_projects( CoprsLogic.get_multiple_owned_by_username(username)).all() for group in UsersLogic.get_groups_by_fas_names_list( user.user_teams).all(): coprs.extend(CoprsLogic.get_multiple_by_group_id(group.id).all()) return render_migration_report(coprs, user=user)
def get_project_list(ownername=None, **kwargs): if not ownername: query = CoprsLogic.get_multiple() elif ownername.startswith("@"): group_name = ownername[1:] query = CoprsLogic.get_multiple() query = CoprsLogic.filter_by_group_name(query, group_name) else: query = CoprsLogic.get_multiple_owned_by_username(ownername) query = CoprsLogic.filter_without_group_projects(query) # @TODO ordering doesn't work correctly - try order by models.Copr.name DESC paginator = Paginator(query, models.Copr, **kwargs) projects = paginator.map(to_dict) return flask.jsonify(items=projects, meta=paginator.meta)
def api_coprs_by_owner(username=None): """ Return the list of coprs owned by the given user. username is taken either from GET params or from the URL itself (in this order). :arg username: the username of the person one would like to the coprs of. """ username = flask.request.args.get("username", None) or username if username is None: raise LegacyApiError("Invalid request: missing `username` ") release_tmpl = "{chroot.os_release}-{chroot.os_version}-{chroot.arch}" if username.startswith("@"): group_name = username[1:] query = CoprsLogic.get_multiple() query = CoprsLogic.filter_by_group_name(query, group_name) else: query = CoprsLogic.get_multiple_owned_by_username(username) query = CoprsLogic.join_builds(query) query = CoprsLogic.set_query_order(query) repos = query.all() output = {"output": "ok", "repos": []} for repo in repos: yum_repos = {} for build in repo.builds: # FIXME in new api! for chroot in repo.active_chroots: release = release_tmpl.format(chroot=chroot) yum_repos[release] = fix_protocol_for_backend( os.path.join(build.copr.repo_url, release + '/')) break output["repos"].append({ "name": repo.name, "additional_repos": repo.repos, "yum_repos": yum_repos, "description": repo.description, "instructions": repo.instructions, "persistent": repo.persistent, "unlisted_on_hp": repo.unlisted_on_hp, "auto_prune": repo.auto_prune, }) return flask.jsonify(output)
def main(): updated_packages = get_updated_packages(get_updates_messages()) loginfo('Updated packages according to datagrepper: {0}'.format(updated_packages)) for row in get_copr_package_info_rows(): source_json = json.loads(row.source_json) source_package_name = source_json['pypi_package_name'].lower() source_python_versions = source_json['python_versions'] latest_build_version = row.pkg_version loginfo('candidate package for rebuild: {0}, package_id: {1}, copr_id: {2}'.format(source_package_name, row.package_id, row.copr_id)) if source_package_name in updated_packages: new_updated_version = updated_packages[source_package_name] logdebug('source_package_name: {0}, latest_build_version: {1}, new_updated_version {2}'.format(source_package_name, latest_build_version, new_updated_version)) if not latest_build_version or not re.match(new_updated_version, latest_build_version): # if the last build's package version is "different" from new remote package version, rebuild try: copr = CoprsLogic.get_by_id(row.copr_id)[0] except Exception as e: logexception(e) continue if args.backend.lower() == 'pypi': loginfo('Launching pypi build for package of source name: {0}, package_id: {1}, copr_id: {2}, user_id: {3}'.format(source_package_name, row.package_id, copr.id, copr.user.id)) build = BuildsLogic.create_new_from_pypi(copr.user, copr, source_package_name, new_updated_version, source_python_versions, chroot_names=None) else: raise Exception('Unsupported backend {0} passed as command-line argument'.format(args.backend)) db.session.commit() loginfo('Launched build id {0}'.format(build.id))
def api_coprs_search_by_project(project=None): """ Return the list of coprs found in search by the given text. project is taken either from GET params or from the URL itself (in this order). :arg project: the text one would like find for coprs. """ project = flask.request.args.get("project", None) or project if not project: raise LegacyApiError("No project found.") try: query = CoprsLogic.get_multiple_fulltext(project) repos = query.all() output = {"output": "ok", "repos": []} for repo in repos: output["repos"].append({ "username": repo.user.name, "coprname": repo.name, "description": repo.description }) except ValueError as e: raise LegacyApiError("Server error: {}".format(e)) return flask.jsonify(output)
def main(): updated_packages = get_updated_packages(get_updates_messages()) loginfo('Updated packages according to datagrepper: {0}'.format(updated_packages)) for row in get_copr_package_info_rows(): source_json = json.loads(row.source_json) package = package_from_source(args.backend.lower(), source_json) latest_build_version = row.pkg_version loginfo('candidate package for rebuild: {0}, package_id: {1}, copr_id: {2}'.format(package.name, row.package_id, row.copr_id)) if package.name in updated_packages: new_updated_version = updated_packages[package.name] logdebug('name: {0}, latest_build_version: {1}, new_updated_version {2}'.format(package.name, latest_build_version, new_updated_version)) # if the last build's package version is "different" from new remote package version, rebuild if not latest_build_version or not re.match(new_updated_version, latest_build_version): try: copr = CoprsLogic.get_by_id(row.copr_id)[0] except Exception as e: logexception(e) continue loginfo('Launching {} build for package of source name: {}, package_id: {}, copr_id: {}, user_id: {}' .format(args.backend.lower(), package.name, row.package_id, copr.id, copr.user.id)) build = package.build(copr, new_updated_version) db.session.commit() loginfo('Launched build id {0}'.format(build.id))
def test_regression_monitor_no_copr_returned(self, f_db, f_users, f_mock_chroots): # https://bugzilla.redhat.com/show_bug.cgi?id=1165284 # commit users to the database self.db.session.commit() copr_name = u"temp" # trying to get monitor page for non-existing project res = self.tc.get("/coprs/{}/{}/monitor/".format( self.u1.name, copr_name)) assert res.status_code == 404 tmp_copr = models.Copr(name=copr_name, owner=self.u1) cc = models.CoprChroot() cc.mock_chroot = self.mc1 tmp_copr.copr_chroots.append(cc) self.db.session.add_all([tmp_copr, cc]) self.db.session.commit() res = self.tc.get("/coprs/{}/{}/monitor/".format( self.u1.name, copr_name)) assert res.status_code == 200 self.db.session.add(CoprsLogic.delete_unsafe(self.u1, tmp_copr)) self.db.session.commit() res = self.tc.get("/coprs/{}/{}/monitor/".format( self.u1.name, copr_name)) assert res.status_code == 404
def test_regression_monitor_no_copr_returned(self, f_db, f_users, f_mock_chroots): # https://bugzilla.redhat.com/show_bug.cgi?id=1165284 # commit users to the database self.db.session.commit() copr_name = u"temp" # trying to get monitor page for non-existing project res = self.tc.get("/coprs/{}/{}/monitor/".format(self.u1.name, copr_name)) assert res.status_code == 404 tmp_copr = models.Copr(name=copr_name, user=self.u1) cc = models.CoprChroot() cc.mock_chroot = self.mc1 tmp_copr.copr_chroots.append(cc) self.db.session.add_all([tmp_copr, cc]) self.db.session.commit() res = self.tc.get("/coprs/{}/{}/monitor/".format(self.u1.name, copr_name)) assert res.status_code == 200 self.db.session.add(CoprsLogic.delete_unsafe(self.u1, tmp_copr)) self.db.session.commit() res = self.tc.get("/coprs/{}/{}/monitor/".format(self.u1.name, copr_name)) assert res.status_code == 404
def api_coprs_search_by_project(project=None): """ Return the list of coprs found in search by the given text. project is taken either from GET params or from the URL itself (in this order). :arg project: the text one would like find for coprs. """ project = flask.request.args.get("project", None) or project if not project: raise LegacyApiError("Invalid request") try: query = CoprsLogic.get_multiple_fulltext(project) repos = query.all() output = {"output": "ok", "repos": []} for repo in repos: output["repos"].append({"username": repo.user.name, "coprname": repo.name, "description": repo.description}) except ValueError as e: raise LegacyApiError("Server error: {}".format(e)) return flask.jsonify(output)
def search_projects(query, **kwargs): try: search_query = CoprsLogic.get_multiple_fulltext(query) paginator = Paginator(search_query, models.Copr, **kwargs) projects = paginator.map(to_dict) except ValueError as ex: raise BadRequest(str(ex)) return flask.jsonify(items=projects, meta=paginator.meta)
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)
def coprs_show(page=1): query = CoprsLogic.get_multiple(include_unlisted_on_hp=False) 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)
def test_pinned_projects(self, f_users, f_coprs, f_db): assert set(CoprsLogic.get_multiple_by_username( self.u2.name)) == {self.c2, self.c3} assert set(PinnedCoprsLogic.get_by_owner(self.u2)) == set() 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]) assert set(PinnedCoprsLogic.get_by_owner(self.u2)) == {pc1, pc2} assert set(CoprsLogic.get_multiple_by_username( self.u2.name)) == {self.c2, self.c3}
def api_coprs_by_owner(username=None): """ Return the list of coprs owned by the given user. username is taken either from GET params or from the URL itself (in this order). :arg username: the username of the person one would like to the coprs of. """ username = flask.request.args.get("username", None) or username if username is None: raise LegacyApiError("Invalid request: missing `username` ") release_tmpl = "{chroot.os_release}-{chroot.os_version}-{chroot.arch}" if username.startswith("@"): group_name = username[1:] query = CoprsLogic.get_multiple() query = CoprsLogic.filter_by_group_name(query, group_name) else: query = CoprsLogic.get_multiple_owned_by_username(username) query = CoprsLogic.join_builds(query) query = CoprsLogic.set_query_order(query) repos = query.all() output = {"output": "ok", "repos": []} for repo in repos: yum_repos = {} for build in repo.builds: if build.results: for chroot in repo.active_chroots: release = release_tmpl.format(chroot=chroot) yum_repos[release] = fix_protocol_for_backend( os.path.join(build.results, release + '/')) break output["repos"].append({"name": repo.name, "additional_repos": repo.repos, "yum_repos": yum_repos, "description": repo.description, "instructions": repo.instructions}) return flask.jsonify(output)
def test_build_post_json_on_project_during_action( self, f_users, f_coprs, f_db, f_mock_chroots, f_mock_chroots_many, f_build_many_chroots, f_users_api): CoprsLogic.create_delete_action(self.c1) chroot_name_list = [c.name for c in self.c1.active_chroots] metadata = { "project_id": 1, "srpm_url": "http://example.com/mypkg.src.rpm", "chroots": chroot_name_list } self.db.session.commit() r0 = self.request_rest_api_with_auth( "/api_2/builds", method="post", content=metadata, ) assert r0.status_code == 400
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)
def rss(limit=200): """ Simple route that returns all projects name, description, link to selected project as rss feed except projects hidden from homepage """ coprs = CoprsLogic.get_multiple(include_unlisted_on_hp=False).order_by( models.Copr.id.desc()).limit(limit) answer = render_template("rss/rss.xml", coprs=coprs) return Response(answer, mimetype="text/xml")
def test_build_post_json_on_project_during_action(self, f_users, f_coprs, f_db, f_mock_chroots, f_mock_chroots_many, f_build_many_chroots, f_users_api): CoprsLogic.create_delete_action(self.c1) chroot_name_list = [c.name for c in self.c1.active_chroots] metadata = { "project_id": 1, "srpm_url": "http://example.com/mypkg.src.rpm", "chroots": chroot_name_list } self.db.session.commit() r0 = self.request_rest_api_with_auth( "/api_2/builds", method="post", content=metadata, ) assert r0.status_code == 400
def rss_all(limit=200): """ Simple route that returns all projects name, description, link to selected project as rss feed """ coprs = CoprsLogic.get_all().order_by(models.Copr.id.desc()).limit(limit) answer = render_template("rss/rss.xml", coprs=coprs) return Response(answer, mimetype="text/xml")
def playground_list(): """ Return list of coprs which are part of playground """ query = CoprsLogic.get_playground() repos = query.all() output = {"output": "ok", "repos": []} for repo in repos: output["repos"].append({"username": repo.owner.name, "coprname": repo.name, "chroots": [chroot.name for chroot in repo.active_chroots]}) jsonout = flask.jsonify(output) jsonout.status_code = 200 return jsonout
def test_project_get_one_with_chroots(self, f_users, f_mock_chroots, f_coprs, f_db): p_id_list = [p.id for p in self.basic_coprs_list] for p_id in p_id_list: href = "/api_2/projects/{}?show_chroots=True".format(p_id) r = self.tc.get(href) assert r.status_code == 200 obj = json.loads(r.data.decode("utf-8")) assert obj["project"]["id"] == p_id assert obj["_links"]["self"]["href"] == href project = CoprsLogic.get_by_id(p_id).one() assert len(obj["project_chroots"]) == len(project.copr_chroots)
def test_build_post_multipart_on_project_during_action( self, f_users, f_coprs, f_builds, f_db, f_mock_chroots, f_mock_chroots_many, f_build_many_chroots, f_users_api): CoprsLogic.create_delete_action(self.c1) chroot_name_list = [c.name for c in self.c1.active_chroots] metadata = { "project_id": 1, "enable_net": True, "chroots": chroot_name_list } data = { "metadata": json.dumps(metadata), "srpm": (BytesIO(b'my file contents'), 'hello world.src.rpm') } self.db.session.commit() r0 = self.request_rest_api_with_auth( "/api_2/builds", method="post", content_type="multipart/form-data", data=data) assert r0.status_code == 400
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)) query = CoprsLogic.get_multiple_owned_by_username(username) 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, 5) return flask.render_template("coprs/show/user.html", user=user, coprs=coprs, paginator=paginator, tasks_info=ComplexLogic.get_queues_size(), users_builds=users_builds)
def test_raise_if_cant_delete(self, f_users, f_fas_groups, f_coprs): # Project owner should be able to delete his project CoprsLogic.raise_if_cant_delete(self.u2, self.c2) # Admin should be able to delete everything CoprsLogic.raise_if_cant_delete(self.u1, self.c2) # A user can't remove someone else's project with pytest.raises(InsufficientRightsException): CoprsLogic.raise_if_cant_delete(self.u2, self.c1) # Group member should be able to remove group project self.u2.openid_groups = {"fas_groups": ["somegroup"]} self.u3.openid_groups = {"fas_groups": ["somegroup"]} self.c2.group = UsersLogic.get_group_by_fas_name_or_create("somegroup") CoprsLogic.raise_if_cant_delete(self.u3, self.c2) # Once a member is kicked from a group, he can't delete # a project even though he originally created it self.u2.openid_groups = {"fas_groups": []} with pytest.raises(InsufficientRightsException): CoprsLogic.raise_if_cant_delete(self.u2, self.c2)
def coprs_by_owner(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)) query = CoprsLogic.get_multiple_owned_by_username(username) 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, 5) return flask.render_template("coprs/show/user.html", user=user, coprs=coprs, paginator=paginator, tasks_info=ComplexLogic.get_queues_size(), users_builds=users_builds)
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)
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}
def test_build_post_multipart_on_project_during_action( self, f_users, f_coprs, f_builds, f_db, f_mock_chroots, f_mock_chroots_many, f_build_many_chroots, f_users_api): CoprsLogic.create_delete_action(self.c1) chroot_name_list = [c.name for c in self.c1.active_chroots] metadata = { "project_id": 1, "enable_net": True, "chroots": chroot_name_list } data = { "metadata": json.dumps(metadata), "srpm": (BytesIO(b'my file contents'), 'hello world.src.rpm') } self.db.session.commit() r0 = self.request_rest_api_with_auth( "/api_2/builds", method="post", content_type="multipart/form-data", data=data ) assert r0.status_code == 400
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 )
def playground_list(): """ Return list of coprs which are part of playground """ query = CoprsLogic.get_playground() repos = query.all() output = {"output": "ok", "repos": []} for repo in repos: output["repos"].append({ "username": repo.owner_name, "coprname": repo.name, "chroots": [chroot.name for chroot in repo.active_chroots] }) jsonout = flask.jsonify(output) jsonout.status_code = 200 return jsonout
def all_coprs(): return CoprsLogic.get_all()
def api_new_copr(username): """ Receive information from the user on how to create its new copr, check their validity and create the corresponding copr. :arg name: the name of the copr to add :arg chroots: a comma separated list of chroots to use :kwarg repos: a comma separated list of repository that this copr can use. :kwarg initial_pkgs: a comma separated list of initial packages to build in this new copr """ form = forms.CoprFormFactory.create_form_cls()(csrf_enabled=False) # are there any arguments in POST which our form doesn't know? # TODO: don't use WTFform for parsing and validation here if any([post_key not in form.__dict__.keys() for post_key in flask.request.form.keys()]): raise LegacyApiError("Unknown arguments passed (non-existing chroot probably)") elif form.validate_on_submit(): infos = [] group = ComplexLogic.get_group_by_name_safe(username[1:]) if username[0] == "@" else None try: copr = CoprsLogic.add( name=form.name.data.strip(), repos=" ".join(form.repos.data.split()), user=flask.g.user, selected_chroots=form.selected_chroots, description=form.description.data, instructions=form.instructions.data, check_for_duplicates=False, auto_createrepo=True, group=group, ) infos.append("New project was successfully created.") if form.initial_pkgs.data: pkgs = form.initial_pkgs.data.split() for pkg in pkgs: builds_logic.BuildsLogic.add( user=flask.g.user, pkgs=pkg, copr=copr) infos.append("Initial packages were successfully " "submitted for building.") output = {"output": "ok", "message": "\n".join(infos)} db.session.commit() except exceptions.DuplicateException as err: db.session.rollback() raise LegacyApiError(str(err)) else: errormsg = "Validation error\n" if form.errors: for field, emsgs in form.errors.items(): errormsg += "- {0}: {1}\n".format(field, "\n".join(emsgs)) errormsg = errormsg.replace('"', "'") raise LegacyApiError(errormsg) return flask.jsonify(output)
def all_coprs(): """ Return all coprs without those which are deleted. """ return CoprsLogic.get_all()
def group_coprs_migration_report(group_name=None): group = ComplexLogic.get_group_by_name_safe(group_name) coprs = CoprsLogic.get_multiple_by_group_id(group.id) return render_migration_report(coprs, group=group)