├── .pep8 ├── doc ├── requirements.txt ├── pkgdb.dia ├── pkgdb2.png ├── _templates │ └── pkgdb-logo.html ├── pkgdb1_shortcomings ├── api.rst ├── _static │ └── site.css ├── contributing.rst ├── index.rst ├── deployment.rst ├── contributors.rst ├── pkgdb_api_design ├── groups.rst ├── new_branch_request_graph ├── Makefile └── development.rst ├── pkgdb2 ├── static │ ├── EOL.png │ ├── Active.png │ ├── Denied.png │ ├── arrow.png │ ├── link.png │ ├── small.gif │ ├── wheel.png │ ├── Approved.png │ ├── Obsolete.png │ ├── Removed.png │ ├── watch_20.png │ ├── small_asc.gif │ ├── small_desc.gif │ ├── icon_koschei.png │ ├── Awaiting Review.png │ ├── images │ │ ├── header-bg.png │ │ ├── animated-overlay.gif │ │ ├── ui-icons_217bc0_256x240.png │ │ ├── ui-icons_2e83ff_256x240.png │ │ ├── ui-icons_3c6eb4_256x240.png │ │ ├── ui-icons_454545_256x240.png │ │ ├── ui-icons_469bdd_256x240.png │ │ ├── ui-icons_666666_256x240.png │ │ ├── ui-icons_6da8d5_256x240.png │ │ ├── ui-icons_cd0a0a_256x240.png │ │ ├── ui-icons_d8e7f3_256x240.png │ │ ├── ui-icons_db3279_256x240.png │ │ ├── ui-icons_f9bd01_256x240.png │ │ ├── ui-icons_ffffff_256x240.png │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ ├── ui-bg_flat_0_eeeeee_40x100.png │ │ ├── ui-bg_flat_55_fbec88_40x100.png │ │ ├── ui-bg_flat_55_ffffff_40x100.png │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_glass_75_d0e5f5_1x400.png │ │ ├── ui-bg_glass_85_dfeffc_1x400.png │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ ├── ui-bg_gloss-wave_55_5c9ccc_500x100.png │ │ ├── ui-bg_inset-hard_100_f5f8f9_1x100.png │ │ ├── ui-bg_inset-hard_100_fcfdfd_1x100.png │ │ ├── ui-bg_highlight-soft_25_3c6eb4_1x100.png │ │ ├── ui-bg_highlight-soft_50_dddddd_1x100.png │ │ ├── ui-bg_highlight-soft_75_dddddd_1x100.png │ │ └── ui-bg_highlight-soft_100_f6f6f6_1x100.png │ ├── packagedb-logo.png │ ├── Under Development.png │ ├── fedora-infra-icon_review.png │ ├── toggle.css │ └── jquery.flot.categories.js ├── templates │ ├── msg.html │ ├── acl_request.html │ ├── admin.html │ ├── acl_give.html │ ├── collection_new.html │ ├── collection_edit.html │ ├── package_give.html │ ├── admin_namespaces.html │ ├── request_branch.html │ ├── branch_selection.html │ ├── request_unretire.html │ ├── package_new.html │ ├── opensearch.html │ ├── collection.html │ ├── index.html │ ├── list_packagers.html │ ├── actions_update_ro.html │ ├── _formhelpers.html │ ├── package_anitya.html │ ├── list_collections.html │ ├── acl_pending.html │ ├── list_logs.html │ ├── packager.html │ ├── actions_update.html │ ├── package_request.html │ ├── package_timeline.html │ ├── stats.html │ ├── list_packages.html │ ├── acl_update.html │ ├── api.html │ └── list_actions.html ├── lib │ ├── exceptions.py │ └── notifications.py ├── proxy.py ├── doc_utils.py ├── mail_logging.py ├── ui │ └── packagers.py └── api │ └── __init__.py ├── devel └── ansible │ ├── playbook.yml │ └── roles │ ├── core │ └── tasks │ │ └── main.yml │ ├── db │ └── tasks │ │ └── main.yml │ └── dev │ └── tasks │ └── main.yml ├── runtests.sh ├── MANIFEST.in ├── .gitignore ├── test_requirements.txt ├── nosetests ├── requirements.txt ├── createdb.py ├── alembic ├── script.py.mako ├── versions │ ├── 353d208dd699_drop_package_shouldo.py │ ├── 2947b3065e9a_add_the_monitor_field.py │ ├── 1f179f37f12b_add_a_koschei_settings_to_the_package_.py │ ├── 1adacdcd3910_refactor_the_monitoring_flag.py │ ├── 187e9f9ec178_expand_fas_name_to_255_chars.py │ ├── 7fa622e911d_update_log_on_delete.py │ ├── 33d905fb1f55_date_updated_for_collections.py │ ├── 2eef3c8402d0_lower_case_table_name.py │ ├── 80939061434_update_unique_constraints_on_admin_.py │ ├── 27924040e3ad_artifacts.py │ └── 563dd24698a7_add_the_allow_retire_field_to_the_.py └── env.py ├── fedmsg.d └── pkgdb.py ├── utility ├── pkgdb2.conf ├── pkgdb2.wsgi ├── alembic.ini └── pkgdb2.cfg.sample ├── Vagrantfile ├── setup.py ├── runserver.py ├── tests ├── test_flask_api.py ├── test_pkgdb.py ├── test_collection.py ├── test_orphan_group.py └── test_flask_ui_packagers.py └── README.rst /.pep8: -------------------------------------------------------------------------------- 1 | [pep8] 2 | ignore = E265 3 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx 2 | cloud_sptheme 3 | -------------------------------------------------------------------------------- /doc/pkgdb.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fedora-infra/pkgdb2/HEAD/doc/pkgdb.dia -------------------------------------------------------------------------------- /doc/pkgdb2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fedora-infra/pkgdb2/HEAD/doc/pkgdb2.png -------------------------------------------------------------------------------- /doc/_templates/pkgdb-logo.html: -------------------------------------------------------------------------------- 1 |
12 | This page summarize all the actions an admin can do 13 |
14 | 15 |12 | This page lists all the namespaces currently in the DB. 13 |
14 | 15 || {{ namespace }} | 19 |20 | 26 | | 27 |
12 | Status :
14 | {{ collection.status }}
15 | (
16 | edit
17 | )
18 |
| Name: | 23 |{{ collection.name }} | 24 |
| Version: | 27 |{{ collection.version }} | 28 |
| Branch-name: | 31 |{{ collection.branchname }} | 32 |
| Description: | 35 |{{ collection.description }} | 36 |
| Dist-tag: | 39 |{{ collection.dist_tag }} | 40 |
| Allows package retirement | 43 |{{ collection.allow_retire }} | 44 |
| Created on | 47 |{{ collection.date_created.strftime('%Y-%m-%d %H:%M:%S') }} | 48 |
| Last update on | 51 |{{ collection.date_updated.strftime('%Y-%m-%d %H:%M:%S') }} | 52 |
14 | The Package Database is a central repository of package information in 15 | {{ config['PROJECT_NAME'] }}. You will eventually be able to find and change all the 16 | metainformation about a package by searching the database. The current 17 | implementation is focused on the data that package developers and release 18 | engineers need to create packages and spin them into a distribution. 19 |
20 | 21 |22 | 24 | 27 | 28 |
29 | 30 || Package | 34 |Summary | 35 |Branches | 36 |
|---|---|---|
| 41 | {{ pkg.namespace }}/{{ pkg.name }} 42 | | 43 |{{ pkg.summary }} | 44 |45 | {% for listing in pkg.listings | sort(attribute="collection.branchname", reverse=True) 46 | %} {% if listing.collection.status != 'EOL' %} 47 | {{ listing.collection.branchname }} 48 | {% endif %}{% endfor %} 49 | | 50 |
| 15 | {% if page > 1 %} 16 | 17 | < Previous 18 | 19 | {% else %} 20 | < Previous 21 | {% endif %} 22 | | 23 |{{ page }} / {{ total_page }} | 24 |25 | {% if page < total_page %} 26 | 27 | Next > 28 | 29 | {% else %} 30 | Next > 31 | {% endif %} 32 | | 33 | 34 |
No packagers found in the database.
57 | {% endif %} 58 || User: | {{ admin_action.user }} |
| Package: | 16 |17 | {% if admin_action.package %} 18 | 21 | {{ admin_action.package.name }} 22 | 23 | {% else %} 24 | {{ admin_action.info_data['pkg_name'] }} 25 | {% endif %} 26 | | 27 |
| Action: | {{ admin_action.action }} |
| To branch: | {{ admin_action.collection.branchname }} |
| Status | {{ admin_action.status }} |
| Message | {{ admin_action.message }} |
| Ticket | 36 |37 | 38 | {{ admin_action.info_data['pkg_review_url'] }} 39 | 40 | | 41 |
| Monitoring status | 44 |45 | {{ admin_action.info_data.get('monitoring_status', 'True') }} 46 | | 47 |
| Koschei integration | 50 |51 | {{ admin_action.info_data.get('koschei', 'False') }} 52 | | 53 |
32 | This package could not be found in 33 | anitya. 34 |
35 |36 | 38 | Add it yourself! 39 | 40 |
41 | {% else %} 42 || Project | 45 |46 | {{ config['PKGDB2_ANITYA_URL'] }}/project/{{ data['id'] }} 47 | | 48 |
|---|---|
| Homepage | 51 |{{ data['homepage'] }} | 52 |
| Backend | 55 |{{ data['backend'] }} | 56 |
| Latest versions | 59 |{{ data['version'] }} | 60 |
| All versions found | 63 |{{ data['versions'] | join(', ') }} | 64 |
| 28 | {% if page > 1%} 29 | 31 | < Previous 32 | 33 | {% else %} 34 | < Previous 35 | {% endif %} 36 | | 37 |{{ page }} / {{ total_page }} | 38 |39 | {% if page < total_page %} 40 | 42 | Next > 43 | 44 | {% else %} 45 | Next > 46 | {% endif %} 47 | | 48 |
| 55 | Branch name 56 | | 57 |58 | Name 59 | | 60 |61 | Release 62 | | 63 |64 | Status 65 | | 66 |
|---|---|---|---|
| 70 | 72 | {{ collection. branchname }} 73 | | 74 |75 | {{ collection.name }} 76 | | 77 |78 | {{ collection.version }} 79 | | 80 |81 | {{ collection.status }} 82 | | 83 |
| User | 37 |Package | 38 |Collection | 39 |ACL | 40 |Status | 41 ||
|---|---|---|---|---|---|
| 45 | 47 | {{ pending_acl['user'] | avatar(32) | safe }} 48 | {{ pending_acl['user'] }} 49 | 50 | | 51 |52 | 55 | {{ pending_acl['package'] }} 56 | 57 | | 58 |{{ pending_acl['collection'] }} | 59 |{{ pending_acl['acl'] }} | 60 |{{ pending_acl['status'] }} | 61 |62 | 66 | 67 | 68 | | 69 |
74 | No pending ACLs for you 75 |
76 | {% endif %} 77 | 78 | {% endblock %} 79 | -------------------------------------------------------------------------------- /doc/groups.rst: -------------------------------------------------------------------------------- 1 | Group maintainership 2 | ==================== 3 | 4 | PkgDB2 integrates the possibility for FAS group to get ``watchcommits``, 5 | ``watchbugzilla`` and ``commit`` ACLs. 6 | 7 | .. note:: Please note that FAS group cannot get ``approveacls`` permissions. 8 | This is to prevent anyone in the group to approve him/herself and drop 9 | the ACLs for everybody else. 10 | 11 | 12 | There are some requirements for the FAS group: 13 | 14 | * name must end with ``-sig`` 15 | * must be of type ``pkgdb`` 16 | * must require people to be in the ``packager`` group 17 | * must have a mailing list address 18 | * must require sponsoring 19 | 20 | 21 | One requirement for the mailing list address: 22 | 23 | * The mailing list address given to the FAS group must have a corresponding 24 | bugzilla account 25 | 26 | 27 | .. note:: If you wish to share you ACLs with a FAS group, open a new ticket on 28 | the `infrastructure pagure.io tracker| 37 | {% if page > 1%} 38 | 41 | < Previous 42 | 43 | {% else %} 44 | < Previous 45 | {% endif %} 46 | | 47 |{{ page }} / {{ total_page }} | 48 |49 | {% if page < total_page %} 50 | 53 | Next > 54 | 55 | {% else %} 56 | Next > 57 | {% endif %} 58 | | 59 |
| 68 | {{ log.change_time.strftime('%Y-%m-%d %H:%M:%S') }} 69 | | 70 |71 | {{ log.description }} 72 | | 73 |
78 | Sorry, but the page you are requesting is unavailable.
79 |
80 | Back to the list
81 |
82 |
No logs found in the database.
85 | {% endif %} 86 | 87 | 88 | {% endblock %} 89 | 90 | {% block jscripts %} 91 | {{ super() }} 92 | 96 | 103 | {% endblock %} 104 | -------------------------------------------------------------------------------- /pkgdb2/doc_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013 Red Hat, Inc. 4 | # 5 | # This copyrighted material is made available to anyone wishing to use, 6 | # modify, copy, or redistribute it subject to the terms and conditions 7 | # of the GNU General Public License v.2, or (at your option) any later 8 | # version. This program is distributed in the hope that it will be 9 | # useful, but WITHOUT ANY WARRANTY expressed or implied, including the 10 | # implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR 11 | # PURPOSE. See the GNU General Public License for more details. You 12 | # should have received a copy of the GNU General Public License along 13 | # with this program; if not, write to the Free Software Foundation, 14 | # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 | # 16 | # Any Red Hat trademarks that are incorporated in the source 17 | # code or documentation are not subject to the GNU General Public 18 | # License and may only be used or replicated with the express permission 19 | # of Red Hat, Inc. 20 | # 21 | 22 | ''' 23 | Provide utility function to convert rst in docstring of functions into html 24 | ''' 25 | 26 | import docutils 27 | import docutils.examples 28 | import textwrap 29 | 30 | import markupsafe 31 | 32 | 33 | def modify_rst(rst): 34 | """ Downgrade some of our rst directives if docutils is too old. """ 35 | 36 | ## We catch Exception if we want :-p 37 | # pylint: disable=W0703 38 | try: 39 | # The rst features we need were introduced in this version 40 | minimum = [0, 9] 41 | version = [int(cpt) for cpt in docutils.__version__.split('.')] 42 | 43 | # If we're at or later than that version, no need to downgrade 44 | if version >= minimum: 45 | return rst 46 | except Exception: # pragma: no cover 47 | # If there was some error parsing or comparing versions, run the 48 | # substitutions just to be safe. 49 | pass 50 | 51 | # On Fedora this will never work as the docutils version is to recent 52 | # Otherwise, make code-blocks into just literal blocks. 53 | substitutions = { # pragma: no cover 54 | '.. code-block:: javascript': '::', 55 | } 56 | for old, new in substitutions.items(): # pragma: no cover 57 | rst = rst.replace(old, new) 58 | 59 | return rst # pragma: no cover 60 | 61 | 62 | def modify_html(html): 63 | """ Perform style substitutions where docutils doesn't do what we want. 64 | """ 65 | 66 | substitutions = { 67 | '': '',
68 | '': '',
69 | }
70 | for old, new in substitutions.items():
71 | html = html.replace(old, new)
72 |
73 | return html
74 |
75 |
76 | def load_doc(endpoint):
77 | """ Utility to load an RST file and turn it into fancy HTML. """
78 |
79 | rst = unicode(textwrap.dedent(endpoint.__doc__))
80 |
81 | rst = modify_rst(rst)
82 |
83 | api_docs = docutils.examples.html_body(rst)
84 |
85 | api_docs = modify_html(api_docs)
86 |
87 | api_docs = markupsafe.Markup(api_docs)
88 | return api_docs
89 |
--------------------------------------------------------------------------------
/pkgdb2/templates/packager.html:
--------------------------------------------------------------------------------
1 | {% extends "master.html" %}
2 |
3 | {% block title %} {{ super() }} {% endblock %}
4 |
5 | {%block tag %}packagers{% endblock %}
6 |
7 | {% block content %}
8 |
9 |
10 | | Point of contact: | 30 |{{ packages | length }} | 31 |
|---|---|
| Co-maintainer: | 34 |{{ packages_co | length}} | 35 |
| Watched: | 38 |{{ packages_watch | length}} | 39 |
18 | As current admin of the package {{ package.name }} you have the possibility 19 | for 7 days to block a branch request for EPEL branches. 20 |
21 | {% endif %} 22 | {% if tag %} 23 | {% if admin_action.action != 'request.package' %} 24 |25 | During the 7 days following the request, you can 'Block' the new branch 26 | process by setting the request to Blocked 27 | or 'Approve' it by setting it to Awaiting Review 28 | to inform admins that they can now review this request. 29 |
30 | {% endif %} 31 | 97 | {% endblock %} 98 | -------------------------------------------------------------------------------- /doc/new_branch_request_graph: -------------------------------------------------------------------------------- 1 | 2 | 3 | +--------------------+ +------------------------+ +----------------+ 4 | | New branch +---------------------->| New Fedora branch +----------->| APPROVED |<--------+ 5 | | request | | request | +----------------+ | 6 | +---------+----------+ +------------------------+ | 7 | | | 8 | | | 9 | | +----+---------+ +--------------+ | 10 | | | Review by +------->| OBSOLETE | | 11 | | | submitter | +--------------+ | 12 | | +--------------+ | 13 | | ^ | 14 | v | | 15 | +---------------------+ +---+-------+ +---------------------+ +-----------+ | 16 | | New EPEL branch +----->| PENDING +----->| Review by package +------------>| BLOCKED | | 17 | | request | +-----+-----+ | admin | +-----------+ | 18 | +---------------------+ | +---------+-----------+ | 19 | | | | 20 | | | | 21 | | | | 22 | After a week | v | 23 | | +---------------------+ +--------------------+ | 24 | +----------->| AWAITING REVIEW +------------->| Review by admins +----+ 25 | +---------------------+ | | 26 | +---+----------------+ 27 | | 28 | | 29 | v 30 | +----------+ 31 | | DENIED | 32 | +----------+ 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /pkgdb2/lib/notifications.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013 Red Hat, Inc. 4 | # 5 | # This copyrighted material is made available to anyone wishing to use, 6 | # modify, copy, or redistribute it subject to the terms and conditions 7 | # of the GNU General Public License v.2, or (at your option) any later 8 | # version. This program is distributed in the hope that it will be 9 | # useful, but WITHOUT ANY WARRANTY expressed or implied, including the 10 | # implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR 11 | # PURPOSE. See the GNU General Public License for more details. You 12 | # should have received a copy of the GNU General Public License along 13 | # with this program; if not, write to the Free Software Foundation, 14 | # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 | # 16 | # Any Red Hat trademarks that are incorporated in the source 17 | # code or documentation are not subject to the GNU General Public 18 | # License and may only be used or replicated with the express permission 19 | # of Red Hat, Inc. 20 | # 21 | 22 | """ This is a temporary shim that allows fedmsg to be an optional dependency of 23 | pkgdb. If fedmsg is installed, these function calls will try to actually send 24 | messages. If it is not installed, it will return silently. 25 | 26 | :Author: Ralph Bean| 42 | {% if page > 1%} 43 | 46 | < Previous 47 | 48 | {% else %} 49 | < Previous 50 | {% endif %} 51 | | 52 |{{ page }} / {{ total_page }} | 53 |54 | {% if page < total_page %} 55 | 58 | Next > 59 | 60 | {% else %} 61 | Next > 62 | {% endif %} 63 | | 64 |
| 73 | {{ log.change_time.strftime('%Y-%m-%d %H:%M:%S') }} 74 | | 75 |76 | {{ log.description }} 77 | | 78 |
83 | Sorry, but the page you are requesting is unavailable.
84 |
86 | Back to the list
87 |
88 |
No logs found in the database.
91 | {% endif %} 92 | 93 | 94 | {% endblock %} 95 | 96 | {% block jscripts %} 97 | {{ super() }} 98 | 102 | 135 | {% endblock %} 136 | -------------------------------------------------------------------------------- /tests/test_collection.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013 Red Hat, Inc. 4 | # 5 | # This copyrighted material is made available to anyone wishing to use, 6 | # modify, copy, or redistribute it subject to the terms and conditions 7 | # of the GNU General Public License v.2, or (at your option) any later 8 | # version. This program is distributed in the hope that it will be 9 | # useful, but WITHOUT ANY WARRANTY expressed or implied, including the 10 | # implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR 11 | # PURPOSE. See the GNU General Public License for more details. You 12 | # should have received a copy of the GNU General Public License along 13 | # with this program; if not, write to the Free Software Foundation, 14 | # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 | # 16 | # Any Red Hat trademarks that are incorporated in the source 17 | # code or documentation are not subject to the GNU General Public 18 | # License and may only be used or replicated with the express permission 19 | # of Red Hat, Inc. 20 | # 21 | 22 | ''' 23 | pkgdb tests for the Collection object. 24 | ''' 25 | 26 | __requires__ = ['SQLAlchemy >= 0.8'] 27 | import pkg_resources 28 | 29 | import unittest 30 | import sys 31 | import os 32 | 33 | sys.path.insert(0, os.path.join(os.path.dirname( 34 | os.path.abspath(__file__)), '..')) 35 | 36 | from pkgdb2.lib import model 37 | from tests import Modeltests, create_collection 38 | 39 | 40 | class Collectiontests(Modeltests): 41 | """ Collection tests. """ 42 | 43 | def test_init_collection(self): 44 | """ Test the __init__ function of Collection. """ 45 | create_collection(self.session) 46 | self.assertEqual(5, len(model.Collection.all(self.session))) 47 | 48 | def test_repr_collection(self): 49 | """ Test the __repr__ function of Collection. """ 50 | create_collection(self.session) 51 | collections = sorted( 52 | model.Collection.all(self.session), key=lambda x: x.branchname) 53 | self.assertEqual(collections[0].branchname, 'el4') 54 | self.assertEqual(collections[1].branchname, 'el6') 55 | self.assertEqual("Collection(u'Fedora', u'17', u'Active', " 56 | "owner:u'toshio')", 57 | collections[2].__repr__()) 58 | self.assertEqual(collections[3].branchname, 'f18') 59 | 60 | def test_search(self): 61 | """ Test the search function of Collection. """ 62 | create_collection(self.session) 63 | 64 | collections = model.Collection.search(self.session, 'EPEL%') 65 | self.assertEqual(len(collections), 0) 66 | 67 | collections = model.Collection.search(self.session, 'f%', 'Active') 68 | self.assertEqual("Collection(u'Fedora', u'17', u'Active', " 69 | "owner:u'toshio')", 70 | collections[0].__repr__()) 71 | 72 | collections = model.Collection.search(self.session, 'f%') 73 | self.assertEqual(2, len(collections)) 74 | 75 | cnt = model.Collection.search(self.session, 'f%', count=True) 76 | self.assertEqual(2, cnt) 77 | 78 | collections = model.Collection.search( 79 | session=self.session, 80 | clt_name='f%', 81 | offset=1) 82 | self.assertEqual(1, len(collections)) 83 | 84 | collections = model.Collection.search( 85 | session=self.session, 86 | clt_name='f%', 87 | limit=1) 88 | self.assertEqual(1, len(collections)) 89 | 90 | def test_to_json(self): 91 | """ Test the to_json function of Collection. """ 92 | create_collection(self.session) 93 | collection = model.Collection.by_name(self.session, 'f18') 94 | collection = collection.to_json() 95 | self.assertEqual( 96 | sorted(collection.keys()), 97 | sorted([ 98 | 'allow_retire', 'branchname', 'date_created', 'date_updated', 99 | 'dist_tag', 'koji_name', 'name', 'status', 'version' ] 100 | ) 101 | ) 102 | 103 | 104 | if __name__ == '__main__': 105 | SUITE = unittest.TestLoader().loadTestsFromTestCase(Collectiontests) 106 | unittest.TextTestRunner(verbosity=2).run(SUITE) 107 | -------------------------------------------------------------------------------- /tests/test_orphan_group.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2015 Red Hat, Inc. 4 | # 5 | # This copyrighted material is made available to anyone wishing to use, 6 | # modify, copy, or redistribute it subject to the terms and conditions 7 | # of the GNU General Public License v.2, or (at your option) any later 8 | # version. This program is distributed in the hope that it will be 9 | # useful, but WITHOUT ANY WARRANTY expressed or implied, including the 10 | # implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR 11 | # PURPOSE. See the GNU General Public License for more details. You 12 | # should have received a copy of the GNU General Public License along 13 | # with this program; if not, write to the Free Software Foundation, 14 | # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 | # 16 | # Any Red Hat trademarks that are incorporated in the source 17 | # code or documentation are not subject to the GNU General Public 18 | # License and may only be used or replicated with the express permission 19 | # of Red Hat, Inc. 20 | # 21 | 22 | ''' 23 | pkgdb tests for orphaning/retiring a package whose PoC is a group. 24 | ''' 25 | 26 | __requires__ = ['SQLAlchemy >= 0.8'] 27 | import pkg_resources 28 | 29 | import unittest 30 | import sys 31 | import os 32 | 33 | from mock import patch 34 | 35 | sys.path.insert(0, os.path.join(os.path.dirname( 36 | os.path.abspath(__file__)), '..')) 37 | 38 | import pkgdb2 39 | import pkgdb2.lib as pkgdblib 40 | import pkgdb2.lib.model as model 41 | from tests import Modeltests, FakeFasUser, FakeFasUserAdmin, \ 42 | create_collection, create_package 43 | 44 | 45 | class PkgdbOrphanGrouptests(Modeltests): 46 | """ pkgdb orphan group tests. """ 47 | 48 | @patch('pkgdb2.lib.utils.set_bugzilla_owner') 49 | def test_orphan_group_package(self, bz_owner): 50 | """ Test the is_pkgdb_admin function of pkgdb2. """ 51 | bz_owner.return_value = None 52 | 53 | create_collection(self.session) 54 | create_package(self.session) 55 | 56 | guake_pkg = model.Package.by_name(self.session, 'rpms', 'guake') 57 | fedocal_pkg = model.Package.by_name(self.session, 'rpms', 'fedocal') 58 | 59 | f18_collec = model.Collection.by_name(self.session, 'f18') 60 | devel_collec = model.Collection.by_name(self.session, 'master') 61 | 62 | # Pkg: guake - Collection: master - Approved 63 | pkgltg = model.PackageListing( 64 | point_of_contact='group::infra-sig', 65 | status='Approved', 66 | package_id=guake_pkg.id, 67 | collection_id=devel_collec.id, 68 | ) 69 | self.session.add(pkgltg) 70 | 71 | # Pkg: guake - Collection: f18 - Approved 72 | pkgltg = model.PackageListing( 73 | point_of_contact='pingou', 74 | status='Approved', 75 | package_id=guake_pkg.id, 76 | collection_id=f18_collec.id, 77 | ) 78 | self.session.add(pkgltg) 79 | 80 | # Pkg: fedocal - Collection: master - Approved 81 | pkgltg = model.PackageListing( 82 | point_of_contact='group::infra-sig', 83 | status='Approved', 84 | package_id=fedocal_pkg.id, 85 | collection_id=devel_collec.id, 86 | ) 87 | self.session.add(pkgltg) 88 | 89 | user = FakeFasUser() 90 | 91 | # Orphan allowed (?) 92 | msg = pkgdblib.update_pkg_status( 93 | self.session, namespace='rpms', pkg_name='fedocal', 94 | pkg_branch='master', status='Orphaned', user=user, poc='orphan') 95 | 96 | self.assertEqual( 97 | msg, 98 | 'user: pingou updated package: fedocal status from: Approved to ' 99 | 'Orphaned on branch: master') 100 | 101 | # Retired blocked 102 | msg = pkgdblib.update_pkg_status( 103 | self.session, namespace='rpms', pkg_name='guake', 104 | pkg_branch='master', status='Retired', user=user, poc='orphan') 105 | 106 | self.assertEqual( 107 | msg, 108 | 'user: pingou updated package: guake status from: Approved to ' 109 | 'Retired on branch: master') 110 | 111 | 112 | if __name__ == '__main__': 113 | SUITE = unittest.TestLoader().loadTestsFromTestCase(PkgdbOrphanGrouptests) 114 | unittest.TextTestRunner(verbosity=2).run(SUITE) 115 | -------------------------------------------------------------------------------- /utility/pkgdb2.cfg.sample: -------------------------------------------------------------------------------- 1 | # Beware that the quotes around the values are mandatory 2 | 3 | ### Secret key for the Flask application 4 | SECRET_KEY='12 | PkgDB stores currently information about {{ collections | length }} 13 | active {{ config['PROJECT_NAME'] }} releases. 14 |
15 | 16 | 17 || {{ config['PROJECT_NAME'] }} branch / release | 20 |Number of packages | 21 |
|---|---|
| {{ collec[0] }} | 25 |{{ collec[1] }} | 26 |
| 43 | #{{ loop.index }} 44 | | 45 |46 | {{ row[0] | avatar(32) | safe }} 47 | 48 | {{ row[0] }} 49 | 50 | | 51 |52 | {{ row[1] }} 53 | | 54 |
| 64 | #{{ loop.index }} 65 | | 66 |67 | {{ row[0] | avatar(32) | safe }} 68 | 69 | {{ row[0] }} 70 | 71 | | 72 |73 | {{ row[1] }} 74 | | 75 |
See the list of orphaned 46 | or retired packages
47 | {% elif origin == 'list_orphaned' %} 48 |See the list of active 49 | or retired packages
50 | {% elif origin == 'list_retired' %} 51 |See the list of active 52 | or orphaned packages
53 | {% endif %} 54 | 55 |{{ packages_count }} packages found
56 | 57 | {% if total_page and total_page > 1 and total_page >= page %} 58 || 61 | {% if page > 1 %} 62 | 68 | < Previous 69 | 70 | {% else %} 71 | < Previous 72 | {% endif %} 73 | | 74 |{{ page }} / {{ total_page }} | 75 |76 | {% if page < total_page %} 77 | 83 | Next > 84 | 85 | {% else %} 86 | Next > 87 | {% endif %} 88 | | 89 |
No packages found in the database.
123 | {% endif %} 124 |
13 |
14 |
27 |
28 |
41 |
42 |
56 |
57 |
70 |
71 |
84 |
85 |
98 |
99 | 102 | The pkgdb2 api has few other endpoints that are used for very specific 103 | tasks such as synchronizing the point of contact and CC list with 104 | bugzilla, or synchronizing the ACLs with the version control system (vcs). 105 | These endpoints, althought listed here, are not quite meant for public 106 | consumption, you may use them, just be cautious. 107 |
108 | 109 || 60 | {% if page > 1%} 61 | {% if select %} 62 | 65 | {% else %} 66 | 69 | {% endif %} 70 | < Previous 71 | 72 | {% else %} 73 | < Previous 74 | {% endif %} 75 | | 76 |{{ page }} / {{ total_page }} | 77 |78 | {% if page < total_page %} 79 | {% if select %} 80 | 82 | {% else %} 83 | 85 | {% endif %} 86 | Next > 87 | 88 | {% else %} 89 | Next > 90 | {% endif %} 91 | | 92 |
| Date | 102 |User | 103 |Package | 104 |Action | 105 |Branch | 106 |Status | 107 |108 | |
|---|---|---|---|---|---|---|
| 120 | {{ action.date_created.strftime('%Y-%m-%d %H:%M:%S') }} 121 | | 122 |123 | 124 | {{ action.user }} 125 | 126 | | 127 |128 | {% if action.package %} 129 | 132 | {{ action.package.name }} 133 | 134 | {% elif action.action == 'request.package' and 135 | action.status == 'Approved' %} 136 | 140 | {{ action.info_data['pkg_name'] }} 141 | 142 | {% else %} 143 | {{ action.info_data['pkg_name'] }} 144 | {% endif %} 145 | | 146 |{{ action.action }} | 147 |{{ action.collection.branchname }} | 148 |149 | {{ action.status }} {%- if action.message %}: 150 | {{ action.message }}{% endif %} 151 | | 152 |153 | {% if not select %} 154 | 155 | Update 156 | 157 | {% else %} 158 | 160 | {% if action.status in ['Pending', 'Awaiting Review'] 161 | and g.fas_user and g.fas_user.username == action.user %} 162 | Update 163 | {% else %} 164 | Details 165 | {% endif %} 166 | 167 | {% endif %} 168 | | 169 |
No actions found
176 | {% endif %} 177 | 178 | {% endblock %} 179 | 180 | {% block jscripts %} 181 | {{ super() }} 182 | 183 | 188 | 189 | 197 | {% endblock %} 198 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | # the i18n builder cannot share the environment and doctrees with the others 15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 16 | 17 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 18 | 19 | help: 20 | @echo "Please use \`make