Show More
@@ -0,0 +1,111 b'' | |||
|
1 | # RhodeCode VCSServer provides access to different vcs backends via network. | |
|
2 | # Copyright (C) 2014-2023 RhodeCode GmbH | |
|
3 | # | |
|
4 | # This program is free software; you can redistribute it and/or modify | |
|
5 | # it under the terms of the GNU General Public License as published by | |
|
6 | # the Free Software Foundation; either version 3 of the License, or | |
|
7 | # (at your option) any later version. | |
|
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 General Public License | |
|
15 | # along with this program; if not, write to the Free Software Foundation, | |
|
16 | # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
|
17 | ||
|
18 | import logging | |
|
19 | import redis | |
|
20 | ||
|
21 | from ..lib import rc_cache | |
|
22 | from ..lib.ext_json import json | |
|
23 | ||
|
24 | ||
|
25 | log = logging.getLogger(__name__) | |
|
26 | ||
|
27 | redis_client = None | |
|
28 | ||
|
29 | ||
|
30 | class RedisTxnClient: | |
|
31 | ||
|
32 | def __init__(self, url): | |
|
33 | self.url = url | |
|
34 | self._create_client(url) | |
|
35 | ||
|
36 | def _create_client(self, url): | |
|
37 | connection_pool = redis.ConnectionPool.from_url(url) | |
|
38 | self.writer_client = redis.StrictRedis( | |
|
39 | connection_pool=connection_pool | |
|
40 | ) | |
|
41 | self.reader_client = self.writer_client | |
|
42 | ||
|
43 | def set(self, key, value): | |
|
44 | self.writer_client.set(key, value) | |
|
45 | ||
|
46 | def get(self, key): | |
|
47 | return self.reader_client.get(key) | |
|
48 | ||
|
49 | def delete(self, key): | |
|
50 | self.writer_client.delete(key) | |
|
51 | ||
|
52 | ||
|
53 | def get_redis_client(url=''): | |
|
54 | ||
|
55 | global redis_client | |
|
56 | if redis_client is not None: | |
|
57 | return redis_client | |
|
58 | if not url: | |
|
59 | from vcsserver import CONFIG | |
|
60 | url = CONFIG['vcs.svn.redis_conn'] | |
|
61 | redis_client = RedisTxnClient(url) | |
|
62 | return redis_client | |
|
63 | ||
|
64 | ||
|
65 | def get_txn_id_data_key(repo_path, svn_txn_id): | |
|
66 | log.debug('svn-txn-id: %s, obtaining data path', svn_txn_id) | |
|
67 | repo_key = rc_cache.utils.compute_key_from_params(repo_path) | |
|
68 | final_key = f'{repo_key}.{svn_txn_id}.svn_txn_id' | |
|
69 | log.debug('computed final key: %s', final_key) | |
|
70 | ||
|
71 | return final_key | |
|
72 | ||
|
73 | ||
|
74 | def store_txn_id_data(repo_path, svn_txn_id, data_dict): | |
|
75 | log.debug('svn-txn-id: %s, storing data', svn_txn_id) | |
|
76 | ||
|
77 | if not svn_txn_id: | |
|
78 | log.warning('Cannot store txn_id because it is empty') | |
|
79 | return | |
|
80 | ||
|
81 | redis_conn = get_redis_client() | |
|
82 | ||
|
83 | store_key = get_txn_id_data_key(repo_path, svn_txn_id) | |
|
84 | store_data = json.dumps(data_dict) | |
|
85 | redis_conn.set(store_key, store_data) | |
|
86 | ||
|
87 | ||
|
88 | def get_txn_id_from_store(repo_path, svn_txn_id, rm_on_read=False): | |
|
89 | """ | |
|
90 | Reads txn_id from store and if present returns the data for callback manager | |
|
91 | """ | |
|
92 | log.debug('svn-txn-id: %s, retrieving data', svn_txn_id) | |
|
93 | redis_conn = get_redis_client() | |
|
94 | ||
|
95 | store_key = get_txn_id_data_key(repo_path, svn_txn_id) | |
|
96 | data = {} | |
|
97 | redis_conn.get(store_key) | |
|
98 | raw_data = 'not-set' | |
|
99 | try: | |
|
100 | raw_data = redis_conn.get(store_key) | |
|
101 | if not raw_data: | |
|
102 | raise ValueError(f'Failed to get txn_id metadata, from store: {store_key}') | |
|
103 | data = json.loads(raw_data) | |
|
104 | except Exception: | |
|
105 | log.exception('Failed to get txn_id metadata: %s', raw_data) | |
|
106 | ||
|
107 | if rm_on_read: | |
|
108 | log.debug('Cleaning up txn_id at %s', store_key) | |
|
109 | redis_conn.delete(store_key) | |
|
110 | ||
|
111 | return data |
@@ -66,6 +66,10 b' debugtoolbar.exclude_prefixes =' | |||
|
66 | 66 | ; or /usr/local/bin/rhodecode_bin/vcs_bin |
|
67 | 67 | core.binary_dir = |
|
68 | 68 | |
|
69 | ; Redis connection settings for svn integrations logic | |
|
70 | ; This connection string needs to be the same on ce and vcsserver | |
|
71 | vcs.svn.redis_conn = redis://redis:6379/0 | |
|
72 | ||
|
69 | 73 | ; Custom exception store path, defaults to TMPDIR |
|
70 | 74 | ; This is used to store exception from RhodeCode in shared directory |
|
71 | 75 | #exception_tracker.store_path = |
@@ -46,6 +46,10 b' use = egg:rhodecode-vcsserver' | |||
|
46 | 46 | ; or /usr/local/bin/rhodecode_bin/vcs_bin |
|
47 | 47 | core.binary_dir = |
|
48 | 48 | |
|
49 | ; Redis connection settings for svn integrations logic | |
|
50 | ; This connection string needs to be the same on ce and vcsserver | |
|
51 | vcs.svn.redis_conn = redis://redis:6379/0 | |
|
52 | ||
|
49 | 53 | ; Custom exception store path, defaults to TMPDIR |
|
50 | 54 | ; This is used to store exception from RhodeCode in shared directory |
|
51 | 55 | #exception_tracker.store_path = |
@@ -87,8 +87,16 b' def install_git_hooks(repo_path, bare, e' | |||
|
87 | 87 | |
|
88 | 88 | if _rhodecode_hook or force_create: |
|
89 | 89 | log.debug('writing git %s hook file at %s !', h_type, _hook_file) |
|
90 | env_expand = str([ | |
|
91 | ('RC_INI_FILE', vcsserver.CONFIG['__file__']), | |
|
92 | ('RC_CORE_BINARY_DIR', vcsserver.settings.BINARY_DIR), | |
|
93 | ('RC_GIT_EXECUTABLE', vcsserver.settings.GIT_EXECUTABLE()), | |
|
94 | ('RC_SVN_EXECUTABLE', vcsserver.settings.SVN_EXECUTABLE()), | |
|
95 | ('RC_SVNLOOK_EXECUTABLE', vcsserver.settings.SVNLOOK_EXECUTABLE()), | |
|
96 | ]) | |
|
90 | 97 | try: |
|
91 | 98 | with open(_hook_file, 'wb') as f: |
|
99 | template = template.replace(b'_OS_EXPAND_', safe_bytes(env_expand)) | |
|
92 | 100 | template = template.replace(b'_TMPL_', safe_bytes(vcsserver.get_version())) |
|
93 | 101 | template = template.replace(b'_DATE_', safe_bytes(timestamp)) |
|
94 | 102 | template = template.replace(b'_ENV_', safe_bytes(executable)) |
@@ -141,17 +149,17 b' def install_svn_hooks(repo_path, executa' | |||
|
141 | 149 | log.debug('writing svn %s hook file at %s !', h_type, _hook_file) |
|
142 | 150 | |
|
143 | 151 | env_expand = str([ |
|
152 | ('RC_INI_FILE', vcsserver.CONFIG['__file__']), | |
|
144 | 153 | ('RC_CORE_BINARY_DIR', vcsserver.settings.BINARY_DIR), |
|
145 | 154 | ('RC_GIT_EXECUTABLE', vcsserver.settings.GIT_EXECUTABLE()), |
|
146 | 155 | ('RC_SVN_EXECUTABLE', vcsserver.settings.SVN_EXECUTABLE()), |
|
147 | 156 | ('RC_SVNLOOK_EXECUTABLE', vcsserver.settings.SVNLOOK_EXECUTABLE()), |
|
148 | ||
|
149 | 157 | ]) |
|
150 | 158 | try: |
|
151 | 159 | with open(_hook_file, 'wb') as f: |
|
160 | template = template.replace(b'_OS_EXPAND_', safe_bytes(env_expand)) | |
|
152 | 161 | template = template.replace(b'_TMPL_', safe_bytes(vcsserver.get_version())) |
|
153 | 162 | template = template.replace(b'_DATE_', safe_bytes(timestamp)) |
|
154 | template = template.replace(b'_OS_EXPAND_', safe_bytes(env_expand)) | |
|
155 | 163 | template = template.replace(b'_ENV_', safe_bytes(executable)) |
|
156 | 164 | template = template.replace(b'_PATH_', safe_bytes(path)) |
|
157 | 165 |
@@ -1,4 +1,5 b'' | |||
|
1 | 1 | #!_ENV_ |
|
2 | ||
|
2 | 3 | import os |
|
3 | 4 | import sys |
|
4 | 5 | path_adjust = [_PATH_] |
@@ -6,6 +7,11 b' path_adjust = [_PATH_]' | |||
|
6 | 7 | if path_adjust: |
|
7 | 8 | sys.path = path_adjust |
|
8 | 9 | |
|
10 | # special trick to pass in some information from rc to hooks | |
|
11 | # mod_dav strips ALL env vars and we can't even access things like PATH | |
|
12 | for env_k, env_v in _OS_EXPAND_: | |
|
13 | os.environ[env_k] = env_v | |
|
14 | ||
|
9 | 15 | try: |
|
10 | 16 | from vcsserver import hooks |
|
11 | 17 | except ImportError: |
@@ -30,11 +36,13 b' def main():' | |||
|
30 | 36 | |
|
31 | 37 | repo_path = os.getcwd() |
|
32 | 38 | push_data = sys.stdin.readlines() |
|
33 | os.environ['RC_HOOK_VER'] = RC_HOOK_VER | |
|
39 | ||
|
34 | 40 | # os.environ is modified here by a subprocess call that |
|
35 | 41 | # runs git and later git executes this hook. |
|
36 | 42 | # Environ gets some additional info from rhodecode system |
|
37 | 43 | # like IP or username from basic-auth |
|
44 | ||
|
45 | os.environ['RC_HOOK_VER'] = RC_HOOK_VER | |
|
38 | 46 | try: |
|
39 | 47 | result = hooks.git_post_receive(repo_path, push_data, os.environ) |
|
40 | 48 | sys.exit(result) |
@@ -1,4 +1,5 b'' | |||
|
1 | 1 | #!_ENV_ |
|
2 | ||
|
2 | 3 | import os |
|
3 | 4 | import sys |
|
4 | 5 | path_adjust = [_PATH_] |
@@ -6,6 +7,11 b' path_adjust = [_PATH_]' | |||
|
6 | 7 | if path_adjust: |
|
7 | 8 | sys.path = path_adjust |
|
8 | 9 | |
|
10 | # special trick to pass in some information from rc to hooks | |
|
11 | # mod_dav strips ALL env vars and we can't even access things like PATH | |
|
12 | for env_k, env_v in _OS_EXPAND_: | |
|
13 | os.environ[env_k] = env_v | |
|
14 | ||
|
9 | 15 | try: |
|
10 | 16 | from vcsserver import hooks |
|
11 | 17 | except ImportError: |
@@ -30,11 +36,13 b' def main():' | |||
|
30 | 36 | |
|
31 | 37 | repo_path = os.getcwd() |
|
32 | 38 | push_data = sys.stdin.readlines() |
|
33 | os.environ['RC_HOOK_VER'] = RC_HOOK_VER | |
|
39 | ||
|
34 | 40 | # os.environ is modified here by a subprocess call that |
|
35 | 41 | # runs git and later git executes this hook. |
|
36 | 42 | # Environ gets some additional info from rhodecode system |
|
37 | 43 | # like IP or username from basic-auth |
|
44 | ||
|
45 | os.environ['RC_HOOK_VER'] = RC_HOOK_VER | |
|
38 | 46 | try: |
|
39 | 47 | result = hooks.git_pre_receive(repo_path, push_data, os.environ) |
|
40 | 48 | sys.exit(result) |
@@ -7,6 +7,11 b' path_adjust = [_PATH_]' | |||
|
7 | 7 | if path_adjust: |
|
8 | 8 | sys.path = path_adjust |
|
9 | 9 | |
|
10 | # special trick to pass in some information from rc to hooks | |
|
11 | # mod_dav strips ALL env vars and we can't even access things like PATH | |
|
12 | for env_k, env_v in _OS_EXPAND_: | |
|
13 | os.environ[env_k] = env_v | |
|
14 | ||
|
10 | 15 | try: |
|
11 | 16 | from vcsserver import hooks |
|
12 | 17 | except ImportError: |
@@ -20,11 +25,6 b' except ImportError:' | |||
|
20 | 25 | RC_HOOK_VER = '_TMPL_' |
|
21 | 26 | |
|
22 | 27 | |
|
23 | # special trick to pass in some information from rc to hooks | |
|
24 | # mod_dav strips ALL env vars and we can't even access things like PATH | |
|
25 | for env_k, env_v in _OS_EXPAND_: | |
|
26 | os.environ[env_k] = env_v | |
|
27 | ||
|
28 | 28 | def main(): |
|
29 | 29 | if hooks is None: |
|
30 | 30 | # exit with success if we cannot import vcsserver.hooks !! |
@@ -33,13 +33,13 b' def main():' | |||
|
33 | 33 | |
|
34 | 34 | if os.environ.get('RC_SKIP_HOOKS') or os.environ.get('RC_SKIP_SVN_HOOKS'): |
|
35 | 35 | sys.exit(0) |
|
36 | repo_path = os.getcwd() | |
|
36 | cwd_repo_path = os.getcwd() | |
|
37 | 37 | push_data = sys.argv[1:] |
|
38 | 38 | |
|
39 | 39 | os.environ['RC_HOOK_VER'] = RC_HOOK_VER |
|
40 | 40 | |
|
41 | 41 | try: |
|
42 | result = hooks.svn_post_commit(repo_path, push_data, os.environ) | |
|
42 | result = hooks.svn_post_commit(cwd_repo_path, push_data, os.environ) | |
|
43 | 43 | sys.exit(result) |
|
44 | 44 | except Exception as error: |
|
45 | 45 | # TODO: johbo: Improve handling of this special case |
@@ -7,6 +7,11 b' path_adjust = [_PATH_]' | |||
|
7 | 7 | if path_adjust: |
|
8 | 8 | sys.path = path_adjust |
|
9 | 9 | |
|
10 | # special trick to pass in some information from rc to hooks | |
|
11 | # mod_dav strips ALL env vars and we can't even access things like PATH | |
|
12 | for env_k, env_v in _OS_EXPAND_: | |
|
13 | os.environ[env_k] = env_v | |
|
14 | ||
|
10 | 15 | try: |
|
11 | 16 | from vcsserver import hooks |
|
12 | 17 | except ImportError: |
@@ -20,11 +25,6 b' except ImportError:' | |||
|
20 | 25 | RC_HOOK_VER = '_TMPL_' |
|
21 | 26 | |
|
22 | 27 | |
|
23 | # special trick to pass in some information from rc to hooks | |
|
24 | # mod_dav strips ALL env vars and we can't even access things like PATH | |
|
25 | for env_k, env_v in _OS_EXPAND_: | |
|
26 | os.environ[env_k] = env_v | |
|
27 | ||
|
28 | 28 | def main(): |
|
29 | 29 | if os.environ.get('SSH_READ_ONLY') == '1': |
|
30 | 30 | sys.stderr.write('Only read-only access is allowed') |
@@ -37,13 +37,12 b' def main():' | |||
|
37 | 37 | |
|
38 | 38 | if os.environ.get('RC_SKIP_HOOKS') or os.environ.get('RC_SKIP_SVN_HOOKS'): |
|
39 | 39 | sys.exit(0) |
|
40 | repo_path = os.getcwd() | |
|
40 | cwd_repo_path = os.getcwd() | |
|
41 | 41 | push_data = sys.argv[1:] |
|
42 | 42 | |
|
43 | 43 | os.environ['RC_HOOK_VER'] = RC_HOOK_VER |
|
44 | ||
|
45 | 44 | try: |
|
46 | result = hooks.svn_pre_commit(repo_path, push_data, os.environ) | |
|
45 | result = hooks.svn_pre_commit(cwd_repo_path, push_data, os.environ) | |
|
47 | 46 | sys.exit(result) |
|
48 | 47 | except Exception as error: |
|
49 | 48 | # TODO: johbo: Improve handling of this special case |
@@ -31,9 +31,10 b' from celery import Celery' | |||
|
31 | 31 | import mercurial.scmutil |
|
32 | 32 | import mercurial.node |
|
33 | 33 | |
|
34 | from vcsserver import exceptions, subprocessio, settings | |
|
34 | 35 | from vcsserver.lib.ext_json import json |
|
35 | from vcsserver import exceptions, subprocessio, settings | |
|
36 | 36 | from vcsserver.lib.str_utils import ascii_str, safe_str |
|
37 | from vcsserver.lib.svn_txn_utils import get_txn_id_from_store | |
|
37 | 38 | from vcsserver.remote.git_remote import Repository |
|
38 | 39 | |
|
39 | 40 | celery_app = Celery('__vcsserver__') |
@@ -293,20 +294,28 b' def _get_hg_env(old_rev, new_rev, txnid,' | |||
|
293 | 294 | return [(k, v) for k, v in env.items()] |
|
294 | 295 | |
|
295 | 296 | |
|
297 | def _get_ini_settings(ini_file): | |
|
298 | from vcsserver.http_main import sanitize_settings_and_apply_defaults | |
|
299 | from vcsserver.lib.config_utils import get_app_config_lightweight, configure_and_store_settings | |
|
300 | ||
|
301 | global_config = {'__file__': ini_file} | |
|
302 | ini_settings = get_app_config_lightweight(ini_file) | |
|
303 | sanitize_settings_and_apply_defaults(global_config, ini_settings) | |
|
304 | configure_and_store_settings(global_config, ini_settings) | |
|
305 | ||
|
306 | return ini_settings | |
|
307 | ||
|
308 | ||
|
296 | 309 | def _fix_hooks_executables(ini_path=''): |
|
297 | 310 | """ |
|
298 | 311 | This is a trick to set proper settings.EXECUTABLE paths for certain execution patterns |
|
299 | 312 | especially for subversion where hooks strip entire env, and calling just 'svn' command will most likely fail |
|
300 | 313 | because svn is not on PATH |
|
301 | 314 | """ |
|
302 | from vcsserver.http_main import sanitize_settings_and_apply_defaults | |
|
303 | from vcsserver.lib.config_utils import get_app_config_lightweight | |
|
304 | ||
|
315 | # set defaults, in case we can't read from ini_file | |
|
305 | 316 | core_binary_dir = settings.BINARY_DIR or '/usr/local/bin/rhodecode_bin/vcs_bin' |
|
306 | 317 | if ini_path: |
|
307 | ||
|
308 | ini_settings = get_app_config_lightweight(ini_path) | |
|
309 | ini_settings = sanitize_settings_and_apply_defaults({'__file__': ini_path}, ini_settings) | |
|
318 | ini_settings = _get_ini_settings(ini_path) | |
|
310 | 319 | core_binary_dir = ini_settings['core.binary_dir'] |
|
311 | 320 | |
|
312 | 321 | settings.BINARY_DIR = core_binary_dir |
@@ -570,7 +579,7 b' def git_pre_receive(unused_repo_path, re' | |||
|
570 | 579 | rev_data = _parse_git_ref_lines(revision_lines) |
|
571 | 580 | if 'push' not in extras['hooks']: |
|
572 | 581 | return 0 |
|
573 | _fix_hooks_executables() | |
|
582 | _fix_hooks_executables(env.get('RC_INI_FILE')) | |
|
574 | 583 | |
|
575 | 584 | empty_commit_id = '0' * 40 |
|
576 | 585 | |
@@ -616,7 +625,7 b' def git_post_receive(unused_repo_path, r' | |||
|
616 | 625 | if 'push' not in extras['hooks']: |
|
617 | 626 | return 0 |
|
618 | 627 | |
|
619 | _fix_hooks_executables() | |
|
628 | _fix_hooks_executables(env.get('RC_INI_FILE')) | |
|
620 | 629 | |
|
621 | 630 | rev_data = _parse_git_ref_lines(revision_lines) |
|
622 | 631 | |
@@ -720,37 +729,8 b' def git_post_receive(unused_repo_path, r' | |||
|
720 | 729 | return status_code |
|
721 | 730 | |
|
722 | 731 | |
|
723 |
def |
|
|
724 | _fix_hooks_executables() | |
|
725 | ||
|
726 | extras = {} | |
|
727 | try: | |
|
728 | cmd = [settings.SVNLOOK_EXECUTABLE(), 'pget', | |
|
729 | '-t', txn_id, | |
|
730 | '--revprop', path, 'rc-scm-extras'] | |
|
731 | stdout, stderr = subprocessio.run_command( | |
|
732 | cmd, env=os.environ.copy()) | |
|
733 | extras = json.loads(base64.urlsafe_b64decode(stdout)) | |
|
734 | except Exception: | |
|
735 | log.exception('Failed to extract extras info from txn_id') | |
|
736 | ||
|
737 | return extras | |
|
738 | ||
|
739 | ||
|
740 | def _get_extras_from_commit_id(commit_id, path): | |
|
741 | _fix_hooks_executables() | |
|
742 | ||
|
743 | extras = {} | |
|
744 | try: | |
|
745 | cmd = [settings.SVNLOOK_EXECUTABLE(), 'pget', | |
|
746 | '-r', commit_id, | |
|
747 | '--revprop', path, 'rc-scm-extras'] | |
|
748 | stdout, stderr = subprocessio.run_command( | |
|
749 | cmd, env=os.environ.copy()) | |
|
750 | extras = json.loads(base64.urlsafe_b64decode(stdout)) | |
|
751 | except Exception: | |
|
752 | log.exception('Failed to extract extras info from commit_id') | |
|
753 | ||
|
732 | def get_extras_from_txn_id(repo_path, txn_id): | |
|
733 | extras = get_txn_id_from_store(repo_path, txn_id) | |
|
754 | 734 | return extras |
|
755 | 735 | |
|
756 | 736 | |
@@ -763,13 +743,18 b' def svn_pre_commit(repo_path, commit_dat' | |||
|
763 | 743 | if env.get('RC_SCM_DATA'): |
|
764 | 744 | extras = json.loads(env['RC_SCM_DATA']) |
|
765 | 745 | else: |
|
746 | ini_path = env.get('RC_INI_FILE') | |
|
747 | if ini_path: | |
|
748 | _get_ini_settings(ini_path) | |
|
766 | 749 | # fallback method to read from TXN-ID stored data |
|
767 |
extras = |
|
|
750 | extras = get_extras_from_txn_id(path, txn_id) | |
|
768 | 751 | |
|
769 | 752 | if not extras: |
|
770 | #TODO: temporary fix until svn txn-id changes are merged | |
|
753 | raise ValueError('SVN-PRE-COMMIT: Failed to extract context data in called extras for hook execution') | |
|
754 | ||
|
755 | if extras.get('rc_internal_commit'): | |
|
756 | # special marker for internal commit, we don't call hooks client | |
|
771 | 757 | return 0 |
|
772 | raise ValueError('Failed to extract context data called extras for hook execution') | |
|
773 | 758 | |
|
774 | 759 | extras['hook_type'] = 'pre_commit' |
|
775 | 760 | extras['commit_ids'] = [txn_id] |
@@ -805,13 +790,18 b' def svn_post_commit(repo_path, commit_da' | |||
|
805 | 790 | if env.get('RC_SCM_DATA'): |
|
806 | 791 | extras = json.loads(env['RC_SCM_DATA']) |
|
807 | 792 | else: |
|
793 | ini_path = env.get('RC_INI_FILE') | |
|
794 | if ini_path: | |
|
795 | _get_ini_settings(ini_path) | |
|
808 | 796 | # fallback method to read from TXN-ID stored data |
|
809 |
extras = |
|
|
797 | extras = get_extras_from_txn_id(path, txn_id) | |
|
810 | 798 | |
|
811 | if not extras: | |
|
812 | #TODO: temporary fix until svn txn-id changes are merged | |
|
799 | if not extras and txn_id: | |
|
800 | raise ValueError('SVN-POST-COMMIT: Failed to extract context data in called extras for hook execution') | |
|
801 | ||
|
802 | if extras.get('rc_internal_commit'): | |
|
803 | # special marker for internal commit, we don't call hooks client | |
|
813 | 804 | return 0 |
|
814 | raise ValueError('Failed to extract context data called extras for hook execution') | |
|
815 | 805 | |
|
816 | 806 | extras['hook_type'] = 'post_commit' |
|
817 | 807 | extras['commit_ids'] = [commit_id] |
@@ -37,20 +37,23 b' from pyramid.wsgi import wsgiapp' | |||
|
37 | 37 | from pyramid.response import Response |
|
38 | 38 | |
|
39 | 39 | from vcsserver.base import BytesEnvelope, BinaryEnvelope |
|
40 | from vcsserver.lib.ext_json import json | |
|
40 | ||
|
41 | 41 | from vcsserver.config.settings_maker import SettingsMaker |
|
42 | from vcsserver.lib.str_utils import safe_int | |
|
43 | from vcsserver.lib.statsd_client import StatsdClient | |
|
42 | ||
|
44 | 43 | from vcsserver.tweens.request_wrapper import get_headers_call_context |
|
45 | 44 | |
|
46 | import vcsserver | |
|
47 | from vcsserver import remote_wsgi, scm_app, settings, hgpatches | |
|
45 | from vcsserver import remote_wsgi, scm_app, hgpatches | |
|
46 | from vcsserver.server import VcsServer | |
|
48 | 47 | from vcsserver.git_lfs.app import GIT_LFS_CONTENT_TYPE, GIT_LFS_PROTO_PAT |
|
49 | 48 | from vcsserver.echo_stub import remote_wsgi as remote_wsgi_stub |
|
50 | 49 | from vcsserver.echo_stub.echo_app import EchoApp |
|
51 | 50 | from vcsserver.exceptions import HTTPRepoLocked, HTTPRepoBranchProtected |
|
52 | 51 | from vcsserver.lib.exc_tracking import store_exception, format_exc |
|
53 |
from vcsserver. |
|
|
52 | from vcsserver.lib.str_utils import safe_int | |
|
53 | from vcsserver.lib.statsd_client import StatsdClient | |
|
54 | from vcsserver.lib.ext_json import json | |
|
55 | from vcsserver.lib.config_utils import configure_and_store_settings | |
|
56 | ||
|
54 | 57 | |
|
55 | 58 | strict_vcs = True |
|
56 | 59 | |
@@ -94,8 +97,7 b' log = logging.getLogger(__name__)' | |||
|
94 | 97 | try: |
|
95 | 98 | locale.setlocale(locale.LC_ALL, '') |
|
96 | 99 | except locale.Error as e: |
|
97 | log.error( | |
|
98 | 'LOCALE ERROR: failed to set LC_ALL, fallback to LC_ALL=C, org error: %s', e) | |
|
100 | log.error('LOCALE ERROR: failed to set LC_ALL, fallback to LC_ALL=C, org error: %s', e) | |
|
99 | 101 | os.environ['LC_ALL'] = 'C' |
|
100 | 102 | |
|
101 | 103 | |
@@ -248,25 +250,10 b' class HTTPApplication:' | |||
|
248 | 250 | log.warning("Using EchoApp for VCS operations.") |
|
249 | 251 | self.remote_wsgi = remote_wsgi_stub |
|
250 | 252 | |
|
251 |
|
|
|
253 | configure_and_store_settings(global_config, settings) | |
|
252 | 254 | |
|
253 | 255 | self._configure() |
|
254 | 256 | |
|
255 | def _configure_settings(self, global_config, app_settings): | |
|
256 | """ | |
|
257 | Configure the settings module. | |
|
258 | """ | |
|
259 | settings_merged = global_config.copy() | |
|
260 | settings_merged.update(app_settings) | |
|
261 | ||
|
262 | binary_dir = app_settings['core.binary_dir'] | |
|
263 | ||
|
264 | settings.BINARY_DIR = binary_dir | |
|
265 | ||
|
266 | # Store the settings to make them available to other modules. | |
|
267 | vcsserver.PYRAMID_SETTINGS = settings_merged | |
|
268 | vcsserver.CONFIG = settings_merged | |
|
269 | ||
|
270 | 257 | def _configure(self): |
|
271 | 258 | self.config.add_renderer(name='msgpack', factory=self._msgpack_renderer_factory) |
|
272 | 259 | |
@@ -715,6 +702,8 b' def sanitize_settings_and_apply_defaults' | |||
|
715 | 702 | 'core.binary_dir', '/usr/local/bin/rhodecode_bin/vcs_bin', |
|
716 | 703 | default_when_empty=True, parser='string:noquote') |
|
717 | 704 | |
|
705 | settings_maker.make_setting('vcs.svn.redis_conn', 'redis://redis:6379/0') | |
|
706 | ||
|
718 | 707 | temp_store = tempfile.gettempdir() |
|
719 | 708 | default_cache_dir = os.path.join(temp_store, 'rc_cache') |
|
720 | 709 | # save default, cache dir, and use it for all backends later. |
@@ -16,6 +16,8 b'' | |||
|
16 | 16 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
17 | 17 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
18 | 18 | import os |
|
19 | import vcsserver | |
|
20 | import vcsserver.settings | |
|
19 | 21 | |
|
20 | 22 | |
|
21 | 23 | def get_config(ini_path, **kwargs): |
@@ -38,3 +40,19 b' def get_app_config(ini_path):' | |||
|
38 | 40 | """ |
|
39 | 41 | from paste.deploy.loadwsgi import appconfig |
|
40 | 42 | return appconfig(f'config:{ini_path}', relative_to=os.getcwd()) |
|
43 | ||
|
44 | ||
|
45 | def configure_and_store_settings(global_config, app_settings): | |
|
46 | """ | |
|
47 | Configure the settings module. | |
|
48 | """ | |
|
49 | settings_merged = global_config.copy() | |
|
50 | settings_merged.update(app_settings) | |
|
51 | ||
|
52 | binary_dir = app_settings['core.binary_dir'] | |
|
53 | ||
|
54 | vcsserver.settings.BINARY_DIR = binary_dir | |
|
55 | ||
|
56 | # Store the settings to make them available to other modules. | |
|
57 | vcsserver.PYRAMID_SETTINGS = settings_merged | |
|
58 | vcsserver.CONFIG = settings_merged |
@@ -28,7 +28,6 b' import urllib.parse' | |||
|
28 | 28 | import urllib.error |
|
29 | 29 | import traceback |
|
30 | 30 | |
|
31 | ||
|
32 | 31 | import svn.client # noqa |
|
33 | 32 | import svn.core # noqa |
|
34 | 33 | import svn.delta # noqa |
@@ -47,10 +46,11 b' from vcsserver.base import (' | |||
|
47 | 46 | BinaryEnvelope, |
|
48 | 47 | ) |
|
49 | 48 | from vcsserver.exceptions import NoContentException |
|
49 | from vcsserver.vcs_base import RemoteBase | |
|
50 | 50 | from vcsserver.lib.str_utils import safe_str, safe_bytes |
|
51 | 51 | from vcsserver.lib.type_utils import assert_bytes |
|
52 | from vcsserver.vcs_base import RemoteBase | |
|
53 | 52 | from vcsserver.lib.svnremoterepo import svnremoterepo |
|
53 | from vcsserver.lib.svn_txn_utils import store_txn_id_data | |
|
54 | 54 | |
|
55 | 55 | log = logging.getLogger(__name__) |
|
56 | 56 | |
@@ -503,6 +503,11 b' class SvnRemote(RemoteBase):' | |||
|
503 | 503 | for node in removed: |
|
504 | 504 | TxnNodeProcessor(node, txn_root).remove() |
|
505 | 505 | |
|
506 | svn_txn_id = safe_str(svn.fs.svn_fs_txn_name(txn)) | |
|
507 | full_repo_path = wire['path'] | |
|
508 | txn_id_data = {'svn_txn_id': svn_txn_id, 'rc_internal_commit': True} | |
|
509 | ||
|
510 | store_txn_id_data(full_repo_path, svn_txn_id, txn_id_data) | |
|
506 | 511 | commit_id = svn.repos.fs_commit_txn(repo, txn) |
|
507 | 512 | |
|
508 | 513 | if timestamp: |
General Comments 0
You need to be logged in to leave comments.
Login now