##// END OF EJS Templates
process-managemet: added simple page to monitor worker processes of RhodeCode.
marcink -
r1885:629a1200 default
parent child Browse files
Show More
@@ -0,0 +1,92 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import logging
22
23 import psutil
24 from pyramid.view import view_config
25
26 from rhodecode.apps._base import BaseAppView
27 from rhodecode.apps.admin.navigation import navigation_list
28 from rhodecode.lib import helpers as h
29 from rhodecode.lib.auth import (
30 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
31 from vcsserver.utils import safe_int
32
33 log = logging.getLogger(__name__)
34
35
36 class AdminProcessManagementView(BaseAppView):
37 def load_default_context(self):
38 c = self._get_local_tmpl_context()
39 self._register_global_c(c)
40 return c
41
42 @LoginRequired()
43 @HasPermissionAllDecorator('hg.admin')
44 @view_config(
45 route_name='admin_settings_process_management', request_method='GET',
46 renderer='rhodecode:templates/admin/settings/settings.mako')
47 def process_management(self):
48 _ = self.request.translate
49 c = self.load_default_context()
50
51 c.active = 'process_management'
52 c.navlist = navigation_list(self.request)
53 c.gunicorn_processes = (
54 p for p in psutil.process_iter() if 'gunicorn' in p.name())
55 return self._get_template_context(c)
56
57 @LoginRequired()
58 @HasPermissionAllDecorator('hg.admin')
59 @CSRFRequired()
60 @view_config(
61 route_name='admin_settings_process_management_signal',
62 request_method='POST', renderer='json_ext')
63 def process_management_signal(self):
64 pids = self.request.json.get('pids', [])
65 result = []
66 def on_terminate(proc):
67 msg = "process `PID:{}` terminated with exit code {}".format(
68 proc.pid, proc.returncode)
69 result.append(msg)
70
71 procs = []
72 for pid in pids:
73 pid = safe_int(pid)
74 if pid:
75 try:
76 proc = psutil.Process(pid)
77 except psutil.NoSuchProcess:
78 continue
79
80 children = proc.children(recursive=True)
81 if children:
82 print('Wont kill Master Process')
83 else:
84 procs.append(proc)
85
86 for p in procs:
87 p.terminate()
88 gone, alive = psutil.wait_procs(procs, timeout=10, callback=on_terminate)
89 for p in alive:
90 p.kill()
91
92 return {'result': result}
@@ -0,0 +1,83 b''
1
2 <div id="update_notice" style="display: none; margin: -40px 0px 20px 0px">
3 <div>${_('Checking for updates...')}</div>
4 </div>
5
6
7 <div class="panel panel-default">
8 <div class="panel-heading">
9 <h3 class="panel-title">${_('Gunicorn process management')}</h3>
10
11 </div>
12 <div class="panel-body" id="app">
13 <h3>List of Gunicorn processes on this machine</h3>
14 <table>
15 % for proc in c.gunicorn_processes:
16 <% mem = proc.memory_info()%>
17
18 <tr>
19 <td>
20 <code>
21 ${proc.pid} - ${proc.name()}
22 </code>
23 </td>
24 <td>
25 RSS:${h.format_byte_size_binary(mem.rss)}
26 </td>
27 <td>
28 VMS:${h.format_byte_size_binary(mem.vms)}
29 </td>
30 <td>
31 <% is_master = proc.children(recursive=True) %>
32 % if is_master:
33 MASTER
34 % else:
35 <a href="#restartProcess" onclick="restart(this, ${proc.pid});return false">
36 restart
37 </a>
38 % endif
39 </td>
40 </tr>
41 % endfor
42 </table>
43 </div>
44 </div>
45
46
47 <script>
48
49
50 restart = function(elem, pid) {
51
52 if ($(elem).hasClass('disabled')){
53 return;
54 }
55 $(elem).addClass('disabled');
56 $(elem).html('processing...');
57
58 $.ajax({
59 url: pyroutes.url('admin_settings_process_management_signal'),
60 headers: {
61 "X-CSRF-Token": CSRF_TOKEN,
62 },
63 data: JSON.stringify({'pids': [pid]}),
64 dataType: 'json',
65 type: 'POST',
66 contentType: "application/json; charset=utf-8",
67 success: function (data) {
68 $(elem).html(data.result);
69 $(elem).removeClass('disabled');
70 },
71 failure: function (data) {
72 $(elem).text('FAILED TO LOAD RESULT');
73 $(elem).removeClass('disabled');
74 },
75 error: function (data) {
76 $(elem).text('FAILED TO LOAD RESULT');
77 $(elem).removeClass('disabled');
78 }
79 })
80 }
81
82
83 </script>
@@ -1,142 +1,149 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 from rhodecode.apps.admin.navigation import NavigationRegistry
23 23 from rhodecode.config.routing import ADMIN_PREFIX
24 24 from rhodecode.lib.utils2 import str2bool
25 25
26 26
27 27 def admin_routes(config):
28 28 """
29 29 Admin prefixed routes
30 30 """
31 31
32 32 config.add_route(
33 33 name='admin_audit_logs',
34 34 pattern='/audit_logs')
35 35
36 36 config.add_route(
37 37 name='pull_requests_global_0', # backward compat
38 38 pattern='/pull_requests/{pull_request_id:[0-9]+}')
39 39 config.add_route(
40 40 name='pull_requests_global_1', # backward compat
41 41 pattern='/pull-requests/{pull_request_id:[0-9]+}')
42 42 config.add_route(
43 43 name='pull_requests_global',
44 44 pattern='/pull-request/{pull_request_id:[0-9]+}')
45 45
46 46 config.add_route(
47 47 name='admin_settings_open_source',
48 48 pattern='/settings/open_source')
49 49 config.add_route(
50 50 name='admin_settings_vcs_svn_generate_cfg',
51 51 pattern='/settings/vcs/svn_generate_cfg')
52 52
53 53 config.add_route(
54 54 name='admin_settings_system',
55 55 pattern='/settings/system')
56 56 config.add_route(
57 57 name='admin_settings_system_update',
58 58 pattern='/settings/system/updates')
59 59
60 60 config.add_route(
61 61 name='admin_settings_sessions',
62 62 pattern='/settings/sessions')
63 63 config.add_route(
64 64 name='admin_settings_sessions_cleanup',
65 65 pattern='/settings/sessions/cleanup')
66 66
67 config.add_route(
68 name='admin_settings_process_management',
69 pattern='/settings/process_management')
70 config.add_route(
71 name='admin_settings_process_management_signal',
72 pattern='/settings/process_management/signal')
73
67 74 # global permissions
68 75 config.add_route(
69 76 name='admin_permissions_ips',
70 77 pattern='/permissions/ips')
71 78
72 79 # users admin
73 80 config.add_route(
74 81 name='users',
75 82 pattern='/users')
76 83
77 84 config.add_route(
78 85 name='users_data',
79 86 pattern='/users_data')
80 87
81 88 # user auth tokens
82 89 config.add_route(
83 90 name='edit_user_auth_tokens',
84 91 pattern='/users/{user_id:\d+}/edit/auth_tokens')
85 92 config.add_route(
86 93 name='edit_user_auth_tokens_add',
87 94 pattern='/users/{user_id:\d+}/edit/auth_tokens/new')
88 95 config.add_route(
89 96 name='edit_user_auth_tokens_delete',
90 97 pattern='/users/{user_id:\d+}/edit/auth_tokens/delete')
91 98
92 99 # user emails
93 100 config.add_route(
94 101 name='edit_user_emails',
95 102 pattern='/users/{user_id:\d+}/edit/emails')
96 103 config.add_route(
97 104 name='edit_user_emails_add',
98 105 pattern='/users/{user_id:\d+}/edit/emails/new')
99 106 config.add_route(
100 107 name='edit_user_emails_delete',
101 108 pattern='/users/{user_id:\d+}/edit/emails/delete')
102 109
103 110 # user IPs
104 111 config.add_route(
105 112 name='edit_user_ips',
106 113 pattern='/users/{user_id:\d+}/edit/ips')
107 114 config.add_route(
108 115 name='edit_user_ips_add',
109 116 pattern='/users/{user_id:\d+}/edit/ips/new')
110 117 config.add_route(
111 118 name='edit_user_ips_delete',
112 119 pattern='/users/{user_id:\d+}/edit/ips/delete')
113 120
114 121 # user groups management
115 122 config.add_route(
116 123 name='edit_user_groups_management',
117 124 pattern='/users/{user_id:\d+}/edit/groups_management')
118 125
119 126 config.add_route(
120 127 name='edit_user_groups_management_updates',
121 128 pattern='/users/{user_id:\d+}/edit/edit_user_groups_management/updates')
122 129
123 130 # user audit logs
124 131 config.add_route(
125 132 name='edit_user_audit_logs',
126 133 pattern='/users/{user_id:\d+}/edit/audit')
127 134
128 135
129 136 def includeme(config):
130 137 settings = config.get_settings()
131 138
132 139 # Create admin navigation registry and add it to the pyramid registry.
133 140 labs_active = str2bool(settings.get('labs_settings_active', False))
134 141 navigation_registry = NavigationRegistry(labs_active=labs_active)
135 142 config.registry.registerUtility(navigation_registry)
136 143
137 144 # main admin routes
138 145 config.add_route(name='admin_home', pattern=ADMIN_PREFIX)
139 146 config.include(admin_routes, route_prefix=ADMIN_PREFIX)
140 147
141 148 # Scan module for configuration decorators.
142 149 config.scan()
@@ -1,140 +1,142 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 import logging
23 23 import collections
24 24
25 25 from pylons import url
26 26 from zope.interface import implementer
27 27
28 28 from rhodecode.apps.admin.interfaces import IAdminNavigationRegistry
29 29 from rhodecode.lib.utils import get_registry
30 30 from rhodecode.translation import _
31 31
32 32
33 33 log = logging.getLogger(__name__)
34 34
35 35 NavListEntry = collections.namedtuple('NavListEntry', ['key', 'name', 'url'])
36 36
37 37
38 38 class NavEntry(object):
39 39 """
40 40 Represents an entry in the admin navigation.
41 41
42 42 :param key: Unique identifier used to store reference in an OrderedDict.
43 43 :param name: Display name, usually a translation string.
44 44 :param view_name: Name of the view, used generate the URL.
45 45 :param pyramid: Indicator to use pyramid for URL generation. This should
46 46 be removed as soon as we are fully migrated to pyramid.
47 47 """
48 48
49 49 def __init__(self, key, name, view_name, pyramid=False):
50 50 self.key = key
51 51 self.name = name
52 52 self.view_name = view_name
53 53 self.pyramid = pyramid
54 54
55 55 def generate_url(self, request):
56 56 if self.pyramid:
57 57 if hasattr(request, 'route_path'):
58 58 return request.route_path(self.view_name)
59 59 else:
60 60 # TODO: johbo: Remove this after migrating to pyramid.
61 61 # We need the pyramid request here to generate URLs to pyramid
62 62 # views from within pylons views.
63 63 from pyramid.threadlocal import get_current_request
64 64 pyramid_request = get_current_request()
65 65 return pyramid_request.route_path(self.view_name)
66 66 else:
67 67 return url(self.view_name)
68 68
69 69 def get_localized_name(self, request):
70 70 if hasattr(request, 'translate'):
71 71 return request.translate(self.name)
72 72 else:
73 73 # TODO(marcink): Remove this after migrating to pyramid
74 74 from pyramid.threadlocal import get_current_request
75 75 pyramid_request = get_current_request()
76 76 return pyramid_request.translate(self.name)
77 77
78 78
79 79 @implementer(IAdminNavigationRegistry)
80 80 class NavigationRegistry(object):
81 81
82 82 _base_entries = [
83 83 NavEntry('global', _('Global'), 'admin_settings_global'),
84 84 NavEntry('vcs', _('VCS'), 'admin_settings_vcs'),
85 85 NavEntry('visual', _('Visual'), 'admin_settings_visual'),
86 86 NavEntry('mapping', _('Remap and Rescan'), 'admin_settings_mapping'),
87 87 NavEntry('issuetracker', _('Issue Tracker'),
88 88 'admin_settings_issuetracker'),
89 89 NavEntry('email', _('Email'), 'admin_settings_email'),
90 90 NavEntry('hooks', _('Hooks'), 'admin_settings_hooks'),
91 91 NavEntry('search', _('Full Text Search'), 'admin_settings_search'),
92 92
93 93 NavEntry('integrations', _('Integrations'),
94 94 'global_integrations_home', pyramid=True),
95 95 NavEntry('system', _('System Info'),
96 96 'admin_settings_system', pyramid=True),
97 NavEntry('process_management', _('Processes'),
98 'admin_settings_process_management', pyramid=True),
97 99 NavEntry('sessions', _('User Sessions'),
98 100 'admin_settings_sessions', pyramid=True),
99 101 NavEntry('open_source', _('Open Source Licenses'),
100 102 'admin_settings_open_source', pyramid=True),
101 103
102 104 # TODO: marcink: we disable supervisor now until the supervisor stats
103 105 # page is fixed in the nix configuration
104 106 # NavEntry('supervisor', _('Supervisor'), 'admin_settings_supervisor'),
105 107 ]
106 108
107 109 _labs_entry = NavEntry('labs', _('Labs'), 'admin_settings_labs')
108 110
109 111 def __init__(self, labs_active=False):
110 112 self._registered_entries = collections.OrderedDict([
111 113 (item.key, item) for item in self.__class__._base_entries
112 114 ])
113 115
114 116 if labs_active:
115 117 self.add_entry(self._labs_entry)
116 118
117 119 def add_entry(self, entry):
118 120 self._registered_entries[entry.key] = entry
119 121
120 122 def get_navlist(self, request):
121 123 navlist = [NavListEntry(i.key, i.get_localized_name(request),
122 124 i.generate_url(request))
123 125 for i in self._registered_entries.values()]
124 126 return navlist
125 127
126 128
127 129 def navigation_registry(request):
128 130 """
129 131 Helper that returns the admin navigation registry.
130 132 """
131 133 pyramid_registry = get_registry(request)
132 134 nav_registry = pyramid_registry.queryUtility(IAdminNavigationRegistry)
133 135 return nav_registry
134 136
135 137
136 138 def navigation_list(request):
137 139 """
138 140 Helper that returns the admin navigation as list of NavListEntry objects.
139 141 """
140 142 return navigation_registry(request).get_navlist(request)
@@ -1,154 +1,156 b''
1 1
2 2 /******************************************************************************
3 3 * *
4 4 * DO NOT CHANGE THIS FILE MANUALLY *
5 5 * *
6 6 * *
7 7 * This file is automatically generated when the app starts up with *
8 8 * generate_js_files = true *
9 9 * *
10 10 * To add a route here pass jsroute=True to the route definition in the app *
11 11 * *
12 12 ******************************************************************************/
13 13 function registerRCRoutes() {
14 14 // routes registration
15 15 pyroutes.register('new_repo', '/_admin/create_repository', []);
16 16 pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
17 17 pyroutes.register('edit_user_group_members', '/_admin/user_groups/%(user_group_id)s/edit/members', ['user_group_id']);
18 18 pyroutes.register('gists', '/_admin/gists', []);
19 19 pyroutes.register('new_gist', '/_admin/gists/new', []);
20 20 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
21 21 pyroutes.register('changeset_home', '/%(repo_name)s/changeset/%(revision)s', ['repo_name', 'revision']);
22 22 pyroutes.register('changeset_comment', '/%(repo_name)s/changeset/%(revision)s/comment', ['repo_name', 'revision']);
23 23 pyroutes.register('changeset_comment_preview', '/%(repo_name)s/changeset/comment/preview', ['repo_name']);
24 24 pyroutes.register('changeset_comment_delete', '/%(repo_name)s/changeset/comment/%(comment_id)s/delete', ['repo_name', 'comment_id']);
25 25 pyroutes.register('changeset_info', '/%(repo_name)s/changeset_info/%(revision)s', ['repo_name', 'revision']);
26 26 pyroutes.register('compare_url', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
27 27 pyroutes.register('pullrequest_home', '/%(repo_name)s/pull-request/new', ['repo_name']);
28 28 pyroutes.register('pullrequest', '/%(repo_name)s/pull-request/new', ['repo_name']);
29 29 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
30 30 pyroutes.register('pullrequest_repo_destinations', '/%(repo_name)s/pull-request/repo-destinations', ['repo_name']);
31 31 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
32 32 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
33 33 pyroutes.register('pullrequest_comment', '/%(repo_name)s/pull-request-comment/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
34 34 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request-comment/%(comment_id)s/delete', ['repo_name', 'comment_id']);
35 35 pyroutes.register('changelog_home', '/%(repo_name)s/changelog', ['repo_name']);
36 36 pyroutes.register('changelog_file_home', '/%(repo_name)s/changelog/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
37 37 pyroutes.register('changelog_elements', '/%(repo_name)s/changelog_details', ['repo_name']);
38 38 pyroutes.register('files_home', '/%(repo_name)s/files/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
39 39 pyroutes.register('files_history_home', '/%(repo_name)s/history/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
40 40 pyroutes.register('files_authors_home', '/%(repo_name)s/authors/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
41 41 pyroutes.register('files_annotate_home', '/%(repo_name)s/annotate/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
42 42 pyroutes.register('files_annotate_previous', '/%(repo_name)s/annotate-previous/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
43 43 pyroutes.register('files_archive_home', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
44 44 pyroutes.register('files_nodelist_home', '/%(repo_name)s/nodelist/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
45 45 pyroutes.register('files_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
46 46 pyroutes.register('favicon', '/favicon.ico', []);
47 47 pyroutes.register('robots', '/robots.txt', []);
48 48 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
49 49 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
50 50 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
51 51 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
52 52 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
53 53 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
54 54 pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/settings/integrations', ['repo_group_name']);
55 55 pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
56 56 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/settings/integrations/new', ['repo_group_name']);
57 57 pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
58 58 pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
59 59 pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
60 60 pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
61 61 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
62 62 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
63 63 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
64 64 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
65 65 pyroutes.register('admin_home', '/_admin', []);
66 66 pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []);
67 67 pyroutes.register('pull_requests_global_0', '/_admin/pull_requests/%(pull_request_id)s', ['pull_request_id']);
68 68 pyroutes.register('pull_requests_global_1', '/_admin/pull-requests/%(pull_request_id)s', ['pull_request_id']);
69 69 pyroutes.register('pull_requests_global', '/_admin/pull-request/%(pull_request_id)s', ['pull_request_id']);
70 70 pyroutes.register('admin_settings_open_source', '/_admin/settings/open_source', []);
71 71 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '/_admin/settings/vcs/svn_generate_cfg', []);
72 72 pyroutes.register('admin_settings_system', '/_admin/settings/system', []);
73 73 pyroutes.register('admin_settings_system_update', '/_admin/settings/system/updates', []);
74 74 pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []);
75 75 pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []);
76 pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []);
77 pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
76 78 pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
77 79 pyroutes.register('users', '/_admin/users', []);
78 80 pyroutes.register('users_data', '/_admin/users_data', []);
79 81 pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
80 82 pyroutes.register('edit_user_auth_tokens_add', '/_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
81 83 pyroutes.register('edit_user_auth_tokens_delete', '/_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
82 84 pyroutes.register('edit_user_emails', '/_admin/users/%(user_id)s/edit/emails', ['user_id']);
83 85 pyroutes.register('edit_user_emails_add', '/_admin/users/%(user_id)s/edit/emails/new', ['user_id']);
84 86 pyroutes.register('edit_user_emails_delete', '/_admin/users/%(user_id)s/edit/emails/delete', ['user_id']);
85 87 pyroutes.register('edit_user_ips', '/_admin/users/%(user_id)s/edit/ips', ['user_id']);
86 88 pyroutes.register('edit_user_ips_add', '/_admin/users/%(user_id)s/edit/ips/new', ['user_id']);
87 89 pyroutes.register('edit_user_ips_delete', '/_admin/users/%(user_id)s/edit/ips/delete', ['user_id']);
88 90 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
89 91 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
90 92 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
91 93 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
92 94 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
93 95 pyroutes.register('channelstream_proxy', '/_channelstream', []);
94 96 pyroutes.register('login', '/_admin/login', []);
95 97 pyroutes.register('logout', '/_admin/logout', []);
96 98 pyroutes.register('register', '/_admin/register', []);
97 99 pyroutes.register('reset_password', '/_admin/password_reset', []);
98 100 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
99 101 pyroutes.register('home', '/', []);
100 102 pyroutes.register('user_autocomplete_data', '/_users', []);
101 103 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
102 104 pyroutes.register('repo_list_data', '/_repos', []);
103 105 pyroutes.register('goto_switcher_data', '/_goto_data', []);
104 106 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
105 107 pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
106 108 pyroutes.register('repo_commit', '/%(repo_name)s/changeset/%(commit_id)s', ['repo_name', 'commit_id']);
107 109 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
108 110 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
109 111 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
110 112 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
111 113 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
112 114 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
113 115 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
114 116 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
115 117 pyroutes.register('pullrequest_show_all_data', '/%(repo_name)s/pull-request-data', ['repo_name']);
116 118 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
117 119 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
118 120 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
119 121 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
120 122 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
121 123 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
122 124 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
123 125 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
124 126 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
125 127 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']);
126 128 pyroutes.register('repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
127 129 pyroutes.register('repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
128 130 pyroutes.register('strip', '/%(repo_name)s/settings/strip', ['repo_name']);
129 131 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
130 132 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
131 133 pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
132 134 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
133 135 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
134 136 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
135 137 pyroutes.register('search', '/_admin/search', []);
136 138 pyroutes.register('search_repo', '/%(repo_name)s/search', ['repo_name']);
137 139 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
138 140 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
139 141 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
140 142 pyroutes.register('my_account_password_update', '/_admin/my_account/password', []);
141 143 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
142 144 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
143 145 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
144 146 pyroutes.register('my_account_emails', '/_admin/my_account/emails', []);
145 147 pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []);
146 148 pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []);
147 149 pyroutes.register('my_account_repos', '/_admin/my_account/repos', []);
148 150 pyroutes.register('my_account_watched', '/_admin/my_account/watched', []);
149 151 pyroutes.register('my_account_perms', '/_admin/my_account/perms', []);
150 152 pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
151 153 pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
152 154 pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
153 155 pyroutes.register('apiv2', '/_admin/api', []);
154 156 }
General Comments 0
You need to be logged in to leave comments. Login now