Show More
@@ -0,0 +1,76 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2011-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 | from pyramid.httpexceptions import HTTPFound | |
|
24 | from pyramid.view import view_config | |
|
25 | ||
|
26 | from rhodecode.apps._base import RepoAppView | |
|
27 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator | |
|
28 | from rhodecode.lib import helpers as h | |
|
29 | from rhodecode.model.meta import Session | |
|
30 | from rhodecode.model.scm import ScmModel | |
|
31 | ||
|
32 | log = logging.getLogger(__name__) | |
|
33 | ||
|
34 | ||
|
35 | class RepoCachesView(RepoAppView): | |
|
36 | def load_default_context(self): | |
|
37 | c = self._get_local_tmpl_context() | |
|
38 | ||
|
39 | # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead | |
|
40 | c.repo_info = self.db_repo | |
|
41 | ||
|
42 | self._register_global_c(c) | |
|
43 | return c | |
|
44 | ||
|
45 | @LoginRequired() | |
|
46 | @HasRepoPermissionAnyDecorator('repository.admin') | |
|
47 | @view_config( | |
|
48 | route_name='edit_repo_caches', request_method='GET', | |
|
49 | renderer='rhodecode:templates/admin/repos/repo_edit.mako') | |
|
50 | def repo_caches(self): | |
|
51 | c = self.load_default_context() | |
|
52 | c.active = 'caches' | |
|
53 | ||
|
54 | return self._get_template_context(c) | |
|
55 | ||
|
56 | @LoginRequired() | |
|
57 | @HasRepoPermissionAnyDecorator('repository.admin') | |
|
58 | @view_config( | |
|
59 | route_name='edit_repo_caches', request_method='POST') | |
|
60 | def repo_caches_purge(self): | |
|
61 | _ = self.request.translate | |
|
62 | c = self.load_default_context() | |
|
63 | c.active = 'caches' | |
|
64 | ||
|
65 | try: | |
|
66 | ScmModel().mark_for_invalidation(self.db_repo_name, delete=True) | |
|
67 | Session().commit() | |
|
68 | h.flash(_('Cache invalidation successful'), | |
|
69 | category='success') | |
|
70 | except Exception: | |
|
71 | log.exception("Exception during cache invalidation") | |
|
72 | h.flash(_('An error occurred during cache invalidation'), | |
|
73 | category='error') | |
|
74 | ||
|
75 | raise HTTPFound(h.route_path( | |
|
76 | 'edit_repo_caches', repo_name=self.db_repo_name)) No newline at end of file |
@@ -26,6 +26,12 b' def includeme(config):' | |||
|
26 | 26 | name='edit_repo', |
|
27 | 27 | pattern='/{repo_name:.*?[^/]}/settings', repo_route=True) |
|
28 | 28 | |
|
29 | # Caches | |
|
30 | config.add_route( | |
|
31 | name='edit_repo_caches', | |
|
32 | pattern='/{repo_name:.*?[^/]}/settings/caches', repo_route=True) | |
|
33 | ||
|
34 | # Maintenance | |
|
29 | 35 | config.add_route( |
|
30 | 36 | name='repo_maintenance', |
|
31 | 37 | pattern='/{repo_name:.*?[^/]}/maintenance', repo_route=True) |
@@ -38,6 +38,7 b' def route_path(name, params=None, **kwar' | |||
|
38 | 38 | |
|
39 | 39 | base_url = { |
|
40 | 40 | 'edit_repo': '/{repo_name}/settings', |
|
41 | 'edit_repo_caches': '/{repo_name}/settings/caches', | |
|
41 | 42 | }[name].format(**kwargs) |
|
42 | 43 | |
|
43 | 44 | if params: |
@@ -58,6 +59,7 b' def _get_permission_for_user(user, repo)' | |||
|
58 | 59 | class TestAdminRepoSettings(object): |
|
59 | 60 | @pytest.mark.parametrize('urlname', [ |
|
60 | 61 | 'edit_repo', |
|
62 | 'edit_repo_caches' | |
|
61 | 63 | ]) |
|
62 | 64 | def test_show_page(self, urlname, app, backend): |
|
63 | 65 | app.get(route_path(urlname, repo_name=backend.repo_name), status=200) |
@@ -75,7 +77,6 b' class TestAdminRepoSettings(object):' | |||
|
75 | 77 | 'repo_vcs_settings', |
|
76 | 78 | 'edit_repo_fields', |
|
77 | 79 | 'repo_settings_issuetracker', |
|
78 | 'edit_repo_caches', | |
|
79 | 80 | 'edit_repo_remote', |
|
80 | 81 | 'edit_repo_statistics', |
|
81 | 82 | ]) |
@@ -708,15 +708,6 b' def make_map(config):' | |||
|
708 | 708 | conditions={'method': ['PUT'], 'function': check_repo}, |
|
709 | 709 | requirements=URL_NAME_REQUIREMENTS) |
|
710 | 710 | |
|
711 | rmap.connect('edit_repo_caches', '/{repo_name}/settings/caches', | |
|
712 | controller='admin/repos', action='edit_caches_form', | |
|
713 | conditions={'method': ['GET'], 'function': check_repo}, | |
|
714 | requirements=URL_NAME_REQUIREMENTS) | |
|
715 | rmap.connect('edit_repo_caches', '/{repo_name}/settings/caches', | |
|
716 | controller='admin/repos', action='edit_caches', | |
|
717 | conditions={'method': ['PUT'], 'function': check_repo}, | |
|
718 | requirements=URL_NAME_REQUIREMENTS) | |
|
719 | ||
|
720 | 711 | rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote', |
|
721 | 712 | controller='admin/repos', action='edit_remote_form', |
|
722 | 713 | conditions={'method': ['GET'], 'function': check_repo}, |
@@ -541,30 +541,6 b' class ReposController(BaseRepoController' | |||
|
541 | 541 | |
|
542 | 542 | @HasRepoPermissionAllDecorator('repository.admin') |
|
543 | 543 | @auth.CSRFRequired() |
|
544 | def edit_caches(self, repo_name): | |
|
545 | """PUT /{repo_name}/settings/caches: invalidate the repo caches.""" | |
|
546 | try: | |
|
547 | ScmModel().mark_for_invalidation(repo_name, delete=True) | |
|
548 | Session().commit() | |
|
549 | h.flash(_('Cache invalidation successful'), | |
|
550 | category='success') | |
|
551 | except Exception: | |
|
552 | log.exception("Exception during cache invalidation") | |
|
553 | h.flash(_('An error occurred during cache invalidation'), | |
|
554 | category='error') | |
|
555 | ||
|
556 | return redirect(url('edit_repo_caches', repo_name=c.repo_name)) | |
|
557 | ||
|
558 | @HasRepoPermissionAllDecorator('repository.admin') | |
|
559 | def edit_caches_form(self, repo_name): | |
|
560 | """GET /repo_name/settings: Form to edit an existing item""" | |
|
561 | c.repo_info = self._load_repo(repo_name) | |
|
562 | c.active = 'caches' | |
|
563 | ||
|
564 | return render('admin/repos/repo_edit.mako') | |
|
565 | ||
|
566 | @HasRepoPermissionAllDecorator('repository.admin') | |
|
567 | @auth.CSRFRequired() | |
|
568 | 544 | def edit_remote(self, repo_name): |
|
569 | 545 | """PUT /{repo_name}/settings/remote: edit the repo remote.""" |
|
570 | 546 | try: |
@@ -98,6 +98,7 b' function registerRCRoutes() {' | |||
|
98 | 98 | pyroutes.register('repo_list_data', '/_repos', []); |
|
99 | 99 | pyroutes.register('goto_switcher_data', '/_goto_data', []); |
|
100 | 100 | pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']); |
|
101 | pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']); | |
|
101 | 102 | pyroutes.register('repo_maintenance', '/%(repo_name)s/maintenance', ['repo_name']); |
|
102 | 103 | pyroutes.register('repo_maintenance_execute', '/%(repo_name)s/maintenance/execute', ['repo_name']); |
|
103 | 104 | pyroutes.register('strip', '/%(repo_name)s/strip', ['repo_name']); |
@@ -58,7 +58,7 b'' | |||
|
58 | 58 | <a href="${h.url('repo_settings_issuetracker', repo_name=c.repo_name)}">${_('Issue Tracker')}</a> |
|
59 | 59 | </li> |
|
60 | 60 | <li class="${'active' if c.active=='caches' else ''}"> |
|
61 |
<a href="${h. |
|
|
61 | <a href="${h.route_path('edit_repo_caches', repo_name=c.repo_name)}">${_('Caches')}</a> | |
|
62 | 62 | </li> |
|
63 | 63 | %if c.repo_info.repo_type != 'svn': |
|
64 | 64 | <li class="${'active' if c.active=='remote' else ''}"> |
@@ -3,21 +3,25 b'' | |||
|
3 | 3 | <h3 class="panel-title">${_('Invalidate Cache for Repository')}</h3> |
|
4 | 4 | </div> |
|
5 | 5 | <div class="panel-body"> |
|
6 | ${h.secure_form(url('edit_repo_caches', repo_name=c.repo_name), method='put')} | |
|
7 | <div> | |
|
6 | ||
|
7 | <h4>${_('Manually invalidate the repository cache. On the next access a repository cache will be recreated.')}</h4> | |
|
8 | ||
|
9 | <p> | |
|
10 | ${_('Cache purge can be automated by such api call called periodically (in crontab etc)')} | |
|
11 | <br/> | |
|
12 | <code> | |
|
13 | curl ${h.route_url('apiv2')} -X POST -H 'content-type:text/plain' --data-binary '{"id":1, "auth_token":"SECRET", "method":"invalidate_cache", "args":{"repoid":"${c.repo_info.repo_name}"}}' | |
|
14 | </code> | |
|
15 | </p> | |
|
16 | ||
|
17 | ${h.secure_form(h.route_path('edit_repo_caches', repo_name=c.repo_name), method='POST')} | |
|
18 | <div class="form"> | |
|
8 | 19 | <div class="fields"> |
|
9 | <p> | |
|
10 | ${h.submit('reset_cache_%s' % c.repo_info.repo_name,_('Invalidate repository cache'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to invalidate repository cache')+"');")} | |
|
11 | </p> | |
|
12 | <div class="field" > | |
|
13 | <span class="help-block"> | |
|
14 | ${_('Manually invalidate the repository cache. On the next access a repository cache will be recreated.')} | |
|
15 | </span> | |
|
16 | </div> | |
|
17 | ||
|
20 | ${h.submit('reset_cache_%s' % c.repo_info.repo_name,_('Invalidate repository cache'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to invalidate repository cache')+"');")} | |
|
18 | 21 | </div> |
|
19 | 22 | </div> |
|
20 | 23 | ${h.end_form()} |
|
24 | ||
|
21 | 25 | </div> |
|
22 | 26 | </div> |
|
23 | 27 | |
@@ -25,7 +29,7 b'' | |||
|
25 | 29 | <div class="panel panel-default"> |
|
26 | 30 | <div class="panel-heading"> |
|
27 | 31 | <h3 class="panel-title"> |
|
28 | ${(ungettext('List of repository caches (%(count)s entry)', 'List of repository caches (%(count)s entries)' ,len(c.repo_info.cache_keys)) % {'count': len(c.repo_info.cache_keys)})} | |
|
32 | ${(_ungettext('List of repository caches (%(count)s entry)', 'List of repository caches (%(count)s entries)' ,len(c.repo_info.cache_keys)) % {'count': len(c.repo_info.cache_keys)})} | |
|
29 | 33 | </h3> |
|
30 | 34 | </div> |
|
31 | 35 | <div class="panel-body"> |
General Comments 0
You need to be logged in to leave comments.
Login now