##// END OF EJS Templates
release: Merge default into stable for release preparation
super-admin -
r4770:a5598123 merge stable
parent child Browse files
Show More
@@ -0,0 +1,58 b''
1 |RCE| 4.27.0 |RNS|
2 ------------------
3
4 Release Date
5 ^^^^^^^^^^^^
6
7 - 2022-09-01
8
9
10 New Features
11 ^^^^^^^^^^^^
12
13
14 - Git: allow overriding default master branch with an env variable.
15 - VCS settings: when setting landing ref from UI switch default GIT branch too.
16 This allows having non-default branches set as default.
17 - Users: enable full edit mode for super admins.
18 Super-Admins now are allowed to edit even LDAP/OAuth user attributes.
19 We'll enable the users to change their names via external auth for rename cases.
20
21
22 General
23 ^^^^^^^
24
25 - Commits/summary: unify fetching remote attribute in summary and commits page to properly and in the same way show the data.
26 - Caches: updated logging and some timings
27 - Caches: allow regional per repo caches, and invalidate caches via a remote call.
28 - Caches: invalidate cache on remote side from repo settings alongside local cache.
29 - Git: allow setting symbolic ref for repos without master branch.
30 - Sys-info: added helpers for faster loading of sys-info data
31 - Debugging: debug = true flag now prints associated exception and logs right into the error page
32
33
34 Security
35 ^^^^^^^^
36
37 - Healthcheck: Added authentication because we expose DB information
38 - Security: fixed self-xss on archive download page.
39
40
41 Performance
42 ^^^^^^^^^^^
43
44
45
46 Fixes
47 ^^^^^
48
49 - Drafts: show TODO drafts properly in edge cases.
50 - Files: fixed unicode problems in specially encoded paths handler.
51 - Caches: fixed issue with exception on handling non-ascii cache keys.
52 - Git: handle archive generation crash case when submodules are present.
53
54
55 Upgrade notes
56 ^^^^^^^^^^^^^
57
58 - Scheduled release 4.27.0.
@@ -1,5 +1,5 b''
1 1 [bumpversion]
2 current_version = 4.26.0
2 current_version = 4.27.0
3 3 message = release: Bump version {current_version} to {new_version}
4 4
5 5 [bumpversion:file:rhodecode/VERSION]
@@ -5,26 +5,20 b' done = false'
5 5 done = true
6 6
7 7 [task:rc_tools_pinned]
8 done = true
9 8
10 9 [task:fixes_on_stable]
11 done = true
12 10
13 11 [task:pip2nix_generated]
14 done = true
15 12
16 13 [task:changelog_updated]
17 done = true
18 14
19 15 [task:generate_api_docs]
20 done = true
21 16
22 17 [task:updated_translation]
23 done = true
24 18
25 19 [release]
26 state = prepared
27 version = 4.26.0
20 state = in_progress
21 version = 4.27.0
28 22
29 23 [task:generate_js_routes]
30 24
@@ -169,4 +169,4 b' Deprecated Support'
169 169 - Internet Explorer 9 support deprecated since version 3.8.0.
170 170
171 171 .. _here: https://rhodecode.com/licenses/
172 .. _Transifex: https://www.transifex.com/projects/p/RhodeCode/
172 .. _Transifex: https://explore.transifex.com/rhodecode/RhodeCode/
@@ -9,6 +9,7 b' Release Notes'
9 9 .. toctree::
10 10 :maxdepth: 1
11 11
12 release-notes-4.27.0.rst
12 13 release-notes-4.26.0.rst
13 14 release-notes-4.25.2.rst
14 15 release-notes-4.25.1.rst
@@ -1,6 +1,6 b''
1 diff -rup rhodecode-tools-1.4.0-orig/setup.py rhodecode-tools-1.4.0/setup.py
2 --- rhodecode-tools-1.4.0/setup-orig.py 2021-03-11 12:34:45.000000000 +0100
3 +++ rhodecode-tools-1.4.0/setup.py 2021-03-11 12:34:56.000000000 +0100
1 diff -rup rhodecode-tools-1.4.1-orig/setup.py rhodecode-tools-1.4.1/setup.py
2 --- rhodecode-tools-1.4.1/setup-orig.py 2021-03-11 12:34:45.000000000 +0100
3 +++ rhodecode-tools-1.4.1/setup.py 2021-03-11 12:34:56.000000000 +0100
4 4 @@ -69,7 +69,7 @@ def _get_requirements(req_filename, excl
5 5
6 6
@@ -1883,7 +1883,7 b' self: super: {'
1883 1883 };
1884 1884 };
1885 1885 "rhodecode-enterprise-ce" = super.buildPythonPackage {
1886 name = "rhodecode-enterprise-ce-4.26.0";
1886 name = "rhodecode-enterprise-ce-4.27.0";
1887 1887 buildInputs = [
1888 1888 self."pytest"
1889 1889 self."py"
@@ -2020,7 +2020,7 b' self: super: {'
2020 2020 };
2021 2021 };
2022 2022 "rhodecode-tools" = super.buildPythonPackage {
2023 name = "rhodecode-tools-1.4.0";
2023 name = "rhodecode-tools-1.4.1";
2024 2024 doCheck = false;
2025 2025 propagatedBuildInputs = [
2026 2026 self."click"
@@ -2037,8 +2037,8 b' self: super: {'
2037 2037 self."elasticsearch1-dsl"
2038 2038 ];
2039 2039 src = fetchurl {
2040 url = "https://code.rhodecode.com/rhodecode-tools-ce/artifacts/download/0-ed54e749-2ef5-4bc7-ae7f-7900e3c2aa15.tar.gz?sha256=76f024bad3a1e55fdb3d64f13f5b77ff21a12fee699918de2110fe21effd5a3a";
2041 sha256 = "0fjszppj3zhh47g1i6b9xqps28gzfxdkzwb47pdmzrd1sfx29w3n";
2040 url = "https://code.rhodecode.com/rhodecode-tools-ce/artifacts/download/0-d9ea7914-e475-44af-a80a-7e32edc17e2f.tar.gz?sha256=6e5aaac455b4a0b2dee013a1241b367e2991e345fda6ed0f4a8c66c941a19184";
2041 sha256 = "6e5aaac455b4a0b2dee013a1241b367e2991e345fda6ed0f4a8c66c941a19184";
2042 2042 };
2043 2043 meta = {
2044 2044 license = [ { fullName = "Apache 2.0 and Proprietary"; } ];
@@ -111,7 +111,7 b' ipdb==0.13.2'
111 111 ipython==5.1.0
112 112
113 113 ## rhodecode-tools, special case, use file://PATH.tar.gz#egg=rhodecode-tools==X.Y.Z, to test local version
114 https://code.rhodecode.com/rhodecode-tools-ce/artifacts/download/0-ed54e749-2ef5-4bc7-ae7f-7900e3c2aa15.tar.gz?sha256=76f024bad3a1e55fdb3d64f13f5b77ff21a12fee699918de2110fe21effd5a3a#egg=rhodecode-tools==1.4.0
114 https://code.rhodecode.com/rhodecode-tools-ce/artifacts/download/0-d9ea7914-e475-44af-a80a-7e32edc17e2f.tar.gz?sha256=6e5aaac455b4a0b2dee013a1241b367e2991e345fda6ed0f4a8c66c941a19184#egg=rhodecode-tools==1.4.1
115 115
116 116
117 117 ## appenlight
@@ -1,1 +1,1 b''
1 4.26.0 No newline at end of file
1 4.27.0 No newline at end of file
@@ -389,6 +389,11 b' class RepoAppView(BaseAppView):'
389 389 return True
390 390 return False
391 391
392 def get_commit_preload_attrs(cls):
393 pre_load = ['author', 'branch', 'date', 'message', 'parents',
394 'obsolete', 'phase', 'hidden']
395 return pre_load
396
392 397
393 398 class PathFilter(object):
394 399
@@ -20,8 +20,7 b''
20 20
21 21 import logging
22 22 import urllib2
23
24
23 import os
25 24
26 25 import rhodecode
27 26 from rhodecode.apps._base import BaseAppView
@@ -40,6 +39,40 b' class AdminSystemInfoSettingsView(BaseAp'
40 39 c = self._get_local_tmpl_context()
41 40 return c
42 41
42 def get_env_data(self):
43 black_list = [
44 'NIX_LDFLAGS',
45 'NIX_CFLAGS_COMPILE',
46 'propagatedBuildInputs',
47 'propagatedNativeBuildInputs',
48 'postInstall',
49 'buildInputs',
50 'buildPhase',
51 'preShellHook',
52 'preShellHook',
53 'preCheck',
54 'preBuild',
55 'postShellHook',
56 'postFixup',
57 'postCheck',
58 'nativeBuildInputs',
59 'installPhase',
60 'installCheckPhase',
61 'checkPhase',
62 'configurePhase',
63 'shellHook'
64 ]
65 secret_list = [
66 'RHODECODE_USER_PASS'
67 ]
68
69 for k, v in sorted(os.environ.items()):
70 if k in black_list:
71 continue
72 if k in secret_list:
73 v = '*****'
74 yield k, v
75
43 76 @LoginRequired()
44 77 @HasPermissionAllDecorator('hg.admin')
45 78 def settings_system_info(self):
@@ -55,6 +88,7 b' class AdminSystemInfoSettingsView(BaseAp'
55 88 snapshot = str2bool(self.request.params.get('snapshot'))
56 89
57 90 c.rhodecode_update_url = UpdateModel().get_update_url()
91 c.env_data = self.get_env_data()
58 92 server_info = system_info.get_system_info(self.request.environ)
59 93
60 94 for key, val in server_info.items():
@@ -311,13 +311,16 b' class UsersView(UserAppView):'
311 311 available_languages=available_languages,
312 312 old_data={'user_id': user_id,
313 313 'email': c.user.email})()
314
315 c.edit_mode = self.request.POST.get('edit') == '1'
314 316 form_result = {}
315 317 old_values = c.user.get_api_data()
316 318 try:
317 319 form_result = _form.to_python(dict(self.request.POST))
318 320 skip_attrs = ['extern_name']
319 321 # TODO: plugin should define if username can be updated
320 if c.extern_type != "rhodecode":
322
323 if c.extern_type != "rhodecode" and not c.edit_mode:
321 324 # forbid updating username for external accounts
322 325 skip_attrs.append('username')
323 326
@@ -485,6 +488,7 b' class UsersView(UserAppView):'
485 488 c.extern_type = c.user.extern_type
486 489 c.extern_name = c.user.extern_name
487 490 c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr)
491 c.edit_mode = self.request.GET.get('edit') == '1'
488 492
489 493 defaults = c.user.get_dict()
490 494 defaults.update({'language': c.user.user_data.get('language')})
@@ -66,18 +66,28 b' class RepoCachesView(RepoAppView):'
66 66 _ = self.request.translate
67 67 c = self.load_default_context()
68 68 c.active = 'caches'
69 invalidated = 0
69 70
70 71 try:
71 72 ScmModel().mark_for_invalidation(self.db_repo_name, delete=True)
72
73 73 Session().commit()
74
75 h.flash(_('Cache invalidation successful'),
76 category='success')
74 invalidated +=1
77 75 except Exception:
78 76 log.exception("Exception during cache invalidation")
79 77 h.flash(_('An error occurred during cache invalidation'),
80 78 category='error')
81 79
80 try:
81 invalidated += 1
82 self.rhodecode_vcs_repo.vcsserver_invalidate_cache(delete=True)
83 except Exception:
84 log.exception("Exception during vcsserver cache invalidation")
85 h.flash(_('An error occurred during vcsserver cache invalidation'),
86 category='error')
87
88 if invalidated:
89 h.flash(_('Cache invalidation successful. Stages {}/2').format(invalidated),
90 category='success')
91
82 92 raise HTTPFound(h.route_path(
83 93 'edit_repo_caches', repo_name=self.db_repo_name)) No newline at end of file
@@ -168,11 +168,6 b' class RepoChangelogView(RepoAppView):'
168 168
169 169 return c
170 170
171 def _get_preload_attrs(self):
172 pre_load = ['author', 'branch', 'date', 'message', 'parents',
173 'obsolete', 'phase', 'hidden']
174 return pre_load
175
176 171 @LoginRequired()
177 172 @HasRepoPermissionAnyDecorator(
178 173 'repository.read', 'repository.write', 'repository.admin')
@@ -200,7 +195,7 b' class RepoChangelogView(RepoAppView):'
200 195 self._check_if_valid_branch(branch_name, self.db_repo_name, f_path)
201 196
202 197 c.changelog_for_path = f_path
203 pre_load = self._get_preload_attrs()
198 pre_load = self.get_commit_preload_attrs()
204 199
205 200 partial_xhr = self.request.environ.get('HTTP_X_PARTIAL_XHR')
206 201
@@ -256,6 +251,8 b' class RepoChangelogView(RepoAppView):'
256 251 raise HTTPFound(
257 252 h.route_path('repo_summary', repo_name=self.db_repo_name))
258 253
254
255
259 256 if partial_xhr or self.request.environ.get('HTTP_X_PJAX'):
260 257 # case when loading dynamic file history in file view
261 258 # loading from ajax, we don't want the first result, it's popped
@@ -304,7 +301,7 b' class RepoChangelogView(RepoAppView):'
304 301 return wrap_for_error(
305 302 safe_str('Branch: {} is not valid'.format(branch_name)))
306 303
307 pre_load = self._get_preload_attrs()
304 pre_load = self.get_commit_preload_attrs()
308 305
309 306 if f_path:
310 307 try:
@@ -381,7 +381,7 b' class RepoFilesView(RepoAppView):'
381 381 try:
382 382 at_path = commit.get_node(at_path).path or default_at_path
383 383 except Exception:
384 return Response(_('No node at path {} for this repository').format(at_path))
384 return Response(_('No node at path {} for this repository').format(h.escape(at_path)))
385 385
386 386 # path sha is part of subdir
387 387 path_sha = ''
@@ -65,7 +65,8 b' class RepoSummaryView(RepoAppView):'
65 65 'repo_summary_commits',
66 66 repo_name=c.rhodecode_db_repo.repo_name, _query=query_params)
67 67
68 pre_load = ['author', 'branch', 'date', 'message']
68 pre_load = self.get_commit_preload_attrs()
69
69 70 try:
70 71 collection = self.rhodecode_vcs_repo.get_commits(
71 72 pre_load=pre_load, translate_tags=False)
@@ -154,6 +154,7 b' def not_found_view(request):'
154 154 def error_handler(exception, request):
155 155 import rhodecode
156 156 from rhodecode.lib import helpers
157 from rhodecode.lib.utils2 import str2bool
157 158
158 159 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
159 160
@@ -205,6 +206,8 b' def error_handler(exception, request):'
205 206
206 207 if c.show_exception_id:
207 208 store_exception(c.exception_id, exc_info)
209 c.exception_debug = str2bool(rhodecode.CONFIG.get('debug'))
210 c.exception_config_ini = rhodecode.CONFIG.get('__file__')
208 211
209 212 response = render_to_response(
210 213 '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
@@ -95,7 +95,7 b' link_config = ['
95 95 {
96 96 "name": "rhodecode_translations",
97 97 "target": "https://rhodecode.com/translate/enterprise",
98 "external_target": "https://www.transifex.com/rhodecode/RhodeCode/",
98 "external_target": "https://explore.transifex.com/rhodecode/RhodeCode/",
99 99 },
100 100
101 101 ]
@@ -4,7 +4,7 b' To create a new language'
4 4
5 5 Translations are available on transifex under::
6 6
7 https://www.transifex.com/projects/p/RhodeCode/
7 https://explore.transifex.com/rhodecode/RhodeCode/
8 8
9 9 Log into transifex and request new language translation.
10 10
@@ -221,7 +221,7 b' class Lock(object):'
221 221 """
222 222 logger = loggers["acquire"]
223 223
224 logger.debug("Getting acquire on %r ...", self._name)
224 logger.debug("Getting blocking: %s acquire on %r ...", blocking, self._name)
225 225
226 226 if self._held:
227 227 owner_id = self.get_owner_id()
@@ -337,11 +337,13 b' def files_breadcrumbs(repo_name, repo_ty'
337 337
338 338
339 339 def files_url_data(request):
340 import urllib
340 341 matchdict = request.matchdict
341 342
342 343 if 'f_path' not in matchdict:
343 344 matchdict['f_path'] = ''
344
345 else:
346 matchdict['f_path'] = urllib.quote(safe_str(matchdict['f_path']))
345 347 if 'commit_id' not in matchdict:
346 348 matchdict['commit_id'] = 'tip'
347 349
@@ -1679,9 +1681,8 b' def process_patterns(text_string, repo_n'
1679 1681 errors = []
1680 1682 new_text = text_string
1681 1683
1682 log.debug('Got %s entries to process', len(active_entries))
1684 log.debug('Got %s pattern entries to process', len(active_entries))
1683 1685 for uid, entry in active_entries.items():
1684 log.debug('found issue tracker entry with uid %s', uid)
1685 1686
1686 1687 if not (entry['pat'] and entry['url']):
1687 1688 log.debug('skipping due to missing data')
@@ -125,20 +125,34 b' class ColorFormatter(ExceptionAwareForma'
125 125
126 126 def _inject_req_id(record):
127 127 from pyramid.threadlocal import get_current_request
128 dummy = '00000000-0000-0000-0000-000000000000'
129 req_id = None
130
128 131 req = get_current_request()
129 dummy = '00000000-0000-0000-0000-000000000000'
130 req_id = 'req_id:%-36s' % (getattr(req, 'req_id', dummy))
132 if req:
133 req_id = getattr(req, 'req_id', None)
134
135 req_id = 'req_id:%-36s' % (req_id or dummy)
131 136 record.req_id = req_id
132 137
133 138
139 def _add_log_to_debug_bucket(formatted_record):
140 from pyramid.threadlocal import get_current_request
141 req = get_current_request()
142 if req:
143 req.req_id_bucket.append(formatted_record)
144
145
134 146 class RequestTrackingFormatter(ExceptionAwareFormatter):
135 147 def format(self, record):
136 148 _inject_req_id(record)
137 149 def_record = logging.Formatter.format(self, record)
150 _add_log_to_debug_bucket(def_record)
138 151 return def_record
139 152
140 153
141 154 class ColorRequestTrackingFormatter(ColorFormatter):
155
142 156 def format(self, record):
143 157 """
144 158 Changes record's levelname to use with COLORS enum
@@ -150,6 +164,7 b' class ColorRequestTrackingFormatter(Colo'
150 164 end = RESET_SEQ
151 165
152 166 colored_record = ''.join([start, def_record, end])
167 _add_log_to_debug_bucket(def_record)
153 168 return colored_record
154 169
155 170
@@ -36,6 +36,7 b' from dogpile.cache.util import memoized_'
36 36 from pyramid.settings import asbool
37 37
38 38 from rhodecode.lib.memory_lru_dict import LRUDict, LRUDictDebug
39 from rhodecode.lib.utils import safe_str
39 40
40 41
41 42 _default_max_size = 1024
@@ -167,7 +168,7 b' class FileNamespaceBackend(PickleSeriali'
167 168 try:
168 169 super(FileNamespaceBackend, self).__init__(arguments)
169 170 except Exception:
170 log.error('Failed to initialize db at: %s', db_file)
171 log.exception('Failed to initialize db at: %s', db_file)
171 172 raise
172 173
173 174 def __repr__(self):
@@ -299,7 +300,7 b' class BaseRedisBackend(redis_backend.Red'
299 300
300 301 def get_mutex(self, key):
301 302 if self.distributed_lock:
302 lock_key = redis_backend.u('_lock_{0}').format(key)
303 lock_key = redis_backend.u('_lock_{0}').format(safe_str(key))
303 304 return get_mutex_lock(self.client, lock_key, self._lock_timeout,
304 305 auto_renewal=self._lock_auto_renewal)
305 306 else:
@@ -24,6 +24,15 b' from pyramid.request import Request as _'
24 24
25 25
26 26 class Request(_Request):
27 _req_id_bucket = list()
28
27 29 @reify
28 30 def req_id(self):
29 31 return str(uuid4())
32
33 @property
34 def req_id_bucket(self):
35 return self._req_id_bucket
36
37 def req_id_records_init(self):
38 self._req_id_bucket = list()
@@ -875,6 +875,9 b' class BaseRepository(object):'
875 875 def get_hooks_info(self):
876 876 return self._remote.get_hooks_info()
877 877
878 def vcsserver_invalidate_cache(self, delete=False):
879 return self._remote.vcsserver_invalidate_cache(delete)
880
878 881
879 882 class BaseCommit(object):
880 883 """
@@ -54,7 +54,7 b' class GitRepository(BaseRepository):'
54 54 """
55 55 Git repository backend.
56 56 """
57 DEFAULT_BRANCH_NAME = 'master'
57 DEFAULT_BRANCH_NAME = os.environ.get('GIT_DEFAULT_BRANCH_NAME') or 'master'
58 58
59 59 contact = BaseRepository.DEFAULT_CONTACT
60 60
@@ -37,6 +37,8 b' import requests'
37 37 from requests.packages.urllib3.util.retry import Retry
38 38
39 39 import rhodecode
40 from rhodecode.lib import rc_cache
41 from rhodecode.lib.rc_cache.utils import compute_key_from_params
40 42 from rhodecode.lib.system_info import get_cert_path
41 43 from rhodecode.lib.vcs import exceptions, CurlSession
42 44
@@ -127,7 +129,6 b' class ServiceConnection(object):'
127 129 def __getattr__(self, name):
128 130 def f(*args, **kwargs):
129 131 return self._call(name, *args, **kwargs)
130
131 132 return f
132 133
133 134 @exceptions.map_vcs_exceptions
@@ -150,6 +151,12 b' class RemoteVCSMaker(object):'
150 151 self._session_factory = session_factory
151 152 self.backend_type = backend_type
152 153
154 @classmethod
155 def init_cache_region(cls, repo_id):
156 cache_namespace_uid = 'cache_repo.{}'.format(repo_id)
157 region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid)
158 return region, cache_namespace_uid
159
153 160 def __call__(self, path, repo_id, config, with_wire=None):
154 161 log.debug('%s RepoMaker call on %s', self.backend_type.upper(), path)
155 162 return RemoteRepo(path, repo_id, config, self, with_wire=with_wire)
@@ -178,6 +185,8 b' class RemoteRepo(object):'
178 185 self.url = remote_maker.url
179 186 self.stream_url = remote_maker.stream_url
180 187 self._session = remote_maker._session_factory()
188 self._cache_region, self._cache_namespace = \
189 remote_maker.init_cache_region(self._repo_id_sanitizer(repo_id))
181 190
182 191 with_wire = with_wire or {}
183 192
@@ -200,6 +209,9 b' class RemoteRepo(object):'
200 209
201 210 self.cert_dir = get_cert_path(rhodecode.CONFIG.get('__file__'))
202 211
212 def _repo_id_sanitizer(self, repo_id):
213 return repo_id.replace('/', '__')
214
203 215 def __getattr__(self, name):
204 216
205 217 if name.startswith('stream:'):
@@ -233,11 +245,34 b' class RemoteRepo(object):'
233 245 url = self.url
234 246
235 247 start = time.time()
248
249 cache_on = False
250 cache_key = ''
251 local_cache_on = rhodecode.CONFIG.get('vcs.methods.cache')
252
253 cache_methods = [
254 'branches', 'tags', 'bookmarks',
255 'is_large_file', 'is_binary', 'fctx_size', 'node_history', 'blob_raw_length',
256 'revision', 'tree_items',
257 'ctx_list',
258 'bulk_request',
259 ]
260
261 if local_cache_on and name in cache_methods:
262 cache_on = True
263 repo_state_uid = self._wire['repo_state_uid']
264 call_args = [a for a in args]
265 cache_key = compute_key_from_params(repo_state_uid, name, *call_args)
266
267 @self._cache_region.conditional_cache_on_arguments(
268 namespace=self._cache_namespace, condition=cache_on and cache_key)
269 def remote_call(_cache_key):
236 270 if self._call_with_logging:
237 log.debug('Calling %s@%s with args:%.10240r. wire_context: %s',
238 url, name, args, context_uid)
271 log.debug('Calling %s@%s with args:%.10240r. wire_context: %s cache_on: %s',
272 url, name, args, context_uid, cache_on)
273 return _remote_call(url, payload, EXCEPTIONS_MAP, self._session)
239 274
240 result = _remote_call(url, payload, EXCEPTIONS_MAP, self._session)
275 result = remote_call(cache_key)
241 276 if self._call_with_logging:
242 277 log.debug('Call %s@%s took: %.4fs. wire_context: %s',
243 278 url, name, time.time()-start, context_uid)
@@ -467,6 +467,9 b' class RepoModel(BaseModel):'
467 467 RepoModel().grant_user_permission(
468 468 repo=cur_repo, user=User.DEFAULT_USER, perm=EMPTY_PERM
469 469 )
470 if kwargs.get('repo_landing_rev'):
471 landing_rev_val = kwargs['repo_landing_rev']
472 RepoModel().set_landing_rev(cur_repo, landing_rev_val)
470 473
471 474 # handle extra fields
472 475 for field in filter(lambda k: k.startswith(RepositoryField.PREFIX), kwargs):
@@ -933,6 +936,13 b' class RepoModel(BaseModel):'
933 936 if field:
934 937 self.sa.delete(field)
935 938
939 def set_landing_rev(self, repo, landing_rev_name):
940 if landing_rev_name.startswith('branch:'):
941 landing_rev_name = landing_rev_name.split('branch:')[-1]
942 scm_instance = repo.scm_instance()
943 if scm_instance:
944 return scm_instance._remote.set_head_ref(landing_rev_name)
945
936 946 def _create_filesystem_repo(self, repo_name, repo_type, repo_group,
937 947 clone_uri=None, repo_store_location=None,
938 948 use_global_config=False, install_hooks=True):
@@ -139,7 +139,7 b' class CloneUriValidator(object):'
139 139 raise colander.Invalid(node, e.message)
140 140 except Exception:
141 141 log.exception('Url validation failed')
142 msg = _(u'invalid clone url for {repo_type} repository').format(
142 msg = _(u'invalid clone url or credentials for {repo_type} repository').format(
143 143 repo_type=self.repo_type)
144 144 raise colander.Invalid(node, msg)
145 145
@@ -624,7 +624,7 b' def ValidCloneUri(localizer):'
624 624
625 625 class _validator(formencode.validators.FancyValidator):
626 626 messages = {
627 'clone_uri': _(u'invalid clone url for %(rtype)s repository'),
627 'clone_uri': _(u'invalid clone url or credentials for %(rtype)s repository'),
628 628 'invalid_clone_uri': _(
629 629 u'Invalid clone url, provide a valid clone '
630 630 u'url starting with one of %(allowed_prefixes)s')
@@ -244,6 +244,7 b' function registerRCRoutes() {'
244 244 pyroutes.register('notifications_show_all', '/_admin/notifications', []);
245 245 pyroutes.register('notifications_update', '/_admin/notifications/%(notification_id)s/update', ['notification_id']);
246 246 pyroutes.register('ops_error_test', '/_admin/ops/error', []);
247 pyroutes.register('ops_healthcheck', '/_admin/ops/status', []);
247 248 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
248 249 pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []);
249 250 pyroutes.register('plugin_admin_chat', '/_admin/plugin_admin_chat/%(action)s', ['action']);
@@ -106,6 +106,14 b' def add_request_user_context(event):'
106 106 request.environ['rc_req_id'] = req_id
107 107
108 108
109 def reset_log_bucket(event):
110 """
111 reset the log bucket on new request
112 """
113 request = event.request
114 request.req_id_records_init()
115
116
109 117 def scan_repositories_if_enabled(event):
110 118 """
111 119 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
@@ -62,6 +62,25 b''
62 62 </div>
63 63 </div>
64 64
65 <div class="panel panel-default">
66 <div class="panel-heading">
67 <h3 class="panel-title">${_('Env Variables')}</h3>
68 </div>
69 <div class="panel-body">
70 <table>
71 <th></th>
72 <th></th>
73 % for env_key, env_val in c.env_data:
74 <tr>
75 <td style="vertical-align: top">${env_key}</td>
76 <td>${env_val}</td>
77 </tr>
78 % endfor
79 </table>
80
81 </div>
82 </div>
83
65 84 <script>
66 85 $('#check_for_update').click(function(e){
67 86 $('#update_notice').show();
@@ -12,7 +12,10 b''
12 12 ${h.secure_form(h.route_path('user_update', user_id=c.user.user_id), class_='form', request=request)}
13 13 <% readonly = None %>
14 14 <% disabled = "" %>
15 %if c.extern_type != 'rhodecode':
15 % if c.edit_mode:
16 ${h.hidden('edit', '1')}
17 % endif
18 %if c.extern_type != 'rhodecode' and not c.edit_mode:
16 19 <% readonly = "readonly" %>
17 20 <% disabled = " disabled" %>
18 21 <div class="alert-warning" style="margin:0px 0px 20px 0px; padding: 10px">
@@ -40,6 +43,12 b''
40 43 </div>
41 44 <div class="input">
42 45 ${h.text('username', class_='%s medium' % disabled, readonly=readonly)}
46 <br/>
47 % if c.extern_type != 'rhodecode' and c.is_super_admin:
48 <p class="help-block">
49 ${_('Super-admin can edit this field by entering ')} <a href="${h.current_route_path(request, edit=1)}">edit mode</a>
50 </p>
51 % endif
43 52 </div>
44 53 </div>
45 54 <div class="field">
@@ -66,7 +66,7 b''
66 66 % endif
67 67 % else:
68 68 ## SKIP TODOs we display them in other area
69 % if comment_obj.is_todo:
69 % if comment_obj.is_todo and not comment_obj.draft:
70 70 <% display = 'none' %>
71 71 % endif
72 72 ## Skip outdated comments
@@ -122,12 +122,21 b''
122 122 'review_status': (comment_obj.review_status or '')
123 123 })
124 124
125 icon = ''
126
125 127 if comment_obj.outdated:
126 icon = 'icon-comment-toggle'
128 icon += ' icon-comment-toggle'
127 129 elif comment_obj.is_inline:
128 icon = 'icon-code'
130 icon += ' icon-code'
129 131 else:
130 icon = 'icon-comment'
132 icon += ' icon-comment'
133
134 if comment_obj.draft:
135 if comment_obj.is_todo:
136 icon = 'icon-flag-filled icon-draft'
137 else:
138 icon = 'icon-comment icon-draft'
139
131 140 %>
132 141
133 142 <i id="commentHovercard${comment_obj.comment_id}"
@@ -237,7 +237,7 b' if (show_disabled) {'
237 237 <time class="timeago" title="<%= created_on %>" datetime="<%= datetime %>"><%= $.timeago(datetime) %></time>
238 238
239 239 <% if (is_todo) { %>
240 <div style="text-align: center; padding-top: 5px">
240 <div style="text-align: left; padding-top: 5px">
241 241 <a class="btn btn-sm" href="#resolveTodo<%- comment_id -%>" onclick="Rhodecode.comments.resolveTodo(this, '<%- comment_id -%>'); return false">
242 242 <strong>Resolve TODO</strong>
243 243 </a>
@@ -84,6 +84,24 b''
84 84
85 85 Super-admins can see details of the above error in the exception tracker found under
86 86 <a href="${h.route_url('admin_settings_exception_tracker')}">admin > settings > exception tracker</a>.
87
88 % if c.exception_debug:
89 <pre>
90 <strong>DEBUG MODE ON FOR EXCEPTION: ${c.exception_id}</strong>
91 <strong>REQUEST_ID: ${getattr(request, 'req_id', None)}</strong>
92 ----------------
93 debug mode is controlled by
94 ${c.exception_config_ini}
95 file settings:
96
97 debug = true
98 ----------------
99
100 % for rec in getattr(request, 'req_id_bucket', []):
101 ${rec}
102 % endfor
103 </pre>
104 % endif
87 105 </p>
88 106 </div>
89 107 % endif
@@ -564,7 +564,6 b''
564 564 <input name="select_all_drafts" type="checkbox" onclick="selectDraftComments(event)">
565 565 </span>
566 566 <span class="sidebar-heading noselect" onclick="refreshDraftComments(); return false">
567 <i class="icon-comment icon-draft"></i>
568 567 ${_('Drafts')}
569 568 </span>
570 569 <span class="block-right action_button last-item" onclick="submitDrafts(event)">${_('Submit')}</span>
@@ -112,6 +112,8 b' def includeme(config):'
112 112 'pyramid.events.NewRequest')
113 113 config.add_subscriber('rhodecode.subscribers.add_localizer',
114 114 'pyramid.events.NewRequest')
115 config.add_subscriber('rhodecode.subscribers.reset_log_bucket',
116 'pyramid.events.NewRequest')
115 117 config.add_subscriber('rhodecode.subscribers.add_request_user_context',
116 118 'pyramid.events.ContextFound')
117 119 config.add_tween('rhodecode.tweens.vcs_detection_tween_factory')
General Comments 0
You need to be logged in to leave comments. Login now