##// END OF EJS Templates
fix(svn-hooks): fixed problem with svn subprocess execution fixes RCCE-62
super-admin -
r1214:77e2f888 default
parent child Browse files
Show More
@@ -15,6 +15,7 b''
15 # along with this program; if not, write to the Free Software Foundation,
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
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18
18 import re
19 import re
19 import os
20 import os
20 import sys
21 import sys
@@ -23,6 +24,7 b' import logging'
23 import pkg_resources
24 import pkg_resources
24
25
25 import vcsserver
26 import vcsserver
27 import vcsserver.settings
26 from vcsserver.str_utils import safe_bytes
28 from vcsserver.str_utils import safe_bytes
27
29
28 log = logging.getLogger(__name__)
30 log = logging.getLogger(__name__)
@@ -138,10 +140,18 b' def install_svn_hooks(repo_path, executa'
138 if _rhodecode_hook or force_create:
140 if _rhodecode_hook or force_create:
139 log.debug('writing svn %s hook file at %s !', h_type, _hook_file)
141 log.debug('writing svn %s hook file at %s !', h_type, _hook_file)
140
142
143 env_expand = str([
144 ('RC_CORE_BINARY_DIR', vcsserver.settings.BINARY_DIR),
145 ('RC_GIT_EXECUTABLE', vcsserver.settings.GIT_EXECUTABLE),
146 ('RC_SVN_EXECUTABLE', vcsserver.settings.SVN_EXECUTABLE),
147 ('RC_SVNLOOK_EXECUTABLE', vcsserver.settings.SVNLOOK_EXECUTABLE),
148
149 ])
141 try:
150 try:
142 with open(_hook_file, 'wb') as f:
151 with open(_hook_file, 'wb') as f:
143 template = template.replace(b'_TMPL_', safe_bytes(vcsserver.get_version()))
152 template = template.replace(b'_TMPL_', safe_bytes(vcsserver.get_version()))
144 template = template.replace(b'_DATE_', safe_bytes(timestamp))
153 template = template.replace(b'_DATE_', safe_bytes(timestamp))
154 template = template.replace(b'_OS_EXPAND_', safe_bytes(env_expand))
145 template = template.replace(b'_ENV_', safe_bytes(executable))
155 template = template.replace(b'_ENV_', safe_bytes(executable))
146 template = template.replace(b'_PATH_', safe_bytes(path))
156 template = template.replace(b'_PATH_', safe_bytes(path))
147
157
@@ -20,6 +20,11 b' except ImportError:'
20 RC_HOOK_VER = '_TMPL_'
20 RC_HOOK_VER = '_TMPL_'
21
21
22
22
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
23 def main():
28 def main():
24 if hooks is None:
29 if hooks is None:
25 # exit with success if we cannot import vcsserver.hooks !!
30 # exit with success if we cannot import vcsserver.hooks !!
@@ -45,6 +50,5 b' def main():'
45 sys.exit(0)
50 sys.exit(0)
46
51
47
52
48
49 if __name__ == '__main__':
53 if __name__ == '__main__':
50 main()
54 main()
@@ -20,6 +20,11 b' except ImportError:'
20 RC_HOOK_VER = '_TMPL_'
20 RC_HOOK_VER = '_TMPL_'
21
21
22
22
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
23 def main():
28 def main():
24 if os.environ.get('SSH_READ_ONLY') == '1':
29 if os.environ.get('SSH_READ_ONLY') == '1':
25 sys.stderr.write('Only read-only access is allowed')
30 sys.stderr.write('Only read-only access is allowed')
@@ -29,6 +34,7 b' def main():'
29 # exit with success if we cannot import vcsserver.hooks !!
34 # exit with success if we cannot import vcsserver.hooks !!
30 # this allows simply push to this repo even without rhodecode
35 # this allows simply push to this repo even without rhodecode
31 sys.exit(0)
36 sys.exit(0)
37
32 if os.environ.get('RC_SKIP_HOOKS') or os.environ.get('RC_SKIP_SVN_HOOKS'):
38 if os.environ.get('RC_SKIP_HOOKS') or os.environ.get('RC_SKIP_SVN_HOOKS'):
33 sys.exit(0)
39 sys.exit(0)
34 repo_path = os.getcwd()
40 repo_path = os.getcwd()
@@ -31,6 +31,7 b' from celery import Celery'
31 import mercurial.scmutil
31 import mercurial.scmutil
32 import mercurial.node
32 import mercurial.node
33
33
34 import vcsserver.settings
34 from vcsserver.lib.rc_json import json
35 from vcsserver.lib.rc_json import json
35 from vcsserver import exceptions, subprocessio, settings
36 from vcsserver import exceptions, subprocessio, settings
36 from vcsserver.str_utils import ascii_str, safe_str
37 from vcsserver.str_utils import ascii_str, safe_str
@@ -153,7 +154,7 b' class SvnMessageWriter(RemoteMessageWrit'
153 self.stderr = stderr or sys.stderr
154 self.stderr = stderr or sys.stderr
154
155
155 def write(self, message):
156 def write(self, message):
156 self.stderr.write(message.encode('utf-8'))
157 self.stderr.write(message)
157
158
158
159
159 def _handle_exception(result):
160 def _handle_exception(result):
@@ -293,6 +294,22 b' def _get_hg_env(old_rev, new_rev, txnid,'
293 return [(k, v) for k, v in env.items()]
294 return [(k, v) for k, v in env.items()]
294
295
295
296
297 def _fix_hooks_executables():
298 """
299 This is a trick to set proper settings.EXECUTABLE paths for certain execution patterns
300 especially for subversion where hooks strip entire env, and calling just 'svn' command will most likely fail
301 because svn is not on PATH
302 """
303 vcsserver.settings.BINARY_DIR = (
304 os.environ.get('RC_BINARY_DIR') or vcsserver.settings.BINARY_DIR)
305 vcsserver.settings.GIT_EXECUTABLE = (
306 os.environ.get('RC_GIT_EXECUTABLE') or vcsserver.settings.GIT_EXECUTABLE)
307 vcsserver.settings.SVN_EXECUTABLE = (
308 os.environ.get('RC_SVN_EXECUTABLE') or vcsserver.settings.SVN_EXECUTABLE)
309 vcsserver.settings.SVNLOOK_EXECUTABLE = (
310 os.environ.get('RC_SVNLOOK_EXECUTABLE') or vcsserver.settings.SVNLOOK_EXECUTABLE)
311
312
296 def repo_size(ui, repo, **kwargs):
313 def repo_size(ui, repo, **kwargs):
297 extras = _extras_from_ui(ui)
314 extras = _extras_from_ui(ui)
298 return _call_hook('repo_size', extras, HgMessageWriter(ui))
315 return _call_hook('repo_size', extras, HgMessageWriter(ui))
@@ -554,7 +571,7 b' def git_pre_receive(unused_repo_path, re'
554 empty_commit_id = '0' * 40
571 empty_commit_id = '0' * 40
555
572
556 detect_force_push = extras.get('detect_force_push')
573 detect_force_push = extras.get('detect_force_push')
557
574 _fix_hooks_executables()
558 for push_ref in rev_data:
575 for push_ref in rev_data:
559 # store our git-env which holds the temp store
576 # store our git-env which holds the temp store
560 push_ref['git_env'] = _get_git_env()
577 push_ref['git_env'] = _get_git_env()
@@ -594,6 +611,7 b' def git_post_receive(unused_repo_path, r'
594 extras = json.loads(env['RC_SCM_DATA'])
611 extras = json.loads(env['RC_SCM_DATA'])
595 if 'push' not in extras['hooks']:
612 if 'push' not in extras['hooks']:
596 return 0
613 return 0
614 _fix_hooks_executables()
597
615
598 rev_data = _parse_git_ref_lines(revision_lines)
616 rev_data = _parse_git_ref_lines(revision_lines)
599
617
@@ -732,6 +750,7 b' def svn_pre_commit(repo_path, commit_dat'
732 branches = []
750 branches = []
733 tags = []
751 tags = []
734
752
753 _fix_hooks_executables()
735 if env.get('RC_SCM_DATA'):
754 if env.get('RC_SCM_DATA'):
736 extras = json.loads(env['RC_SCM_DATA'])
755 extras = json.loads(env['RC_SCM_DATA'])
737 else:
756 else:
@@ -757,6 +776,7 b' def svn_post_commit(repo_path, commit_da'
757 """
776 """
758 commit_data is path, rev, txn_id
777 commit_data is path, rev, txn_id
759 """
778 """
779
760 if len(commit_data) == 3:
780 if len(commit_data) == 3:
761 path, commit_id, txn_id = commit_data
781 path, commit_id, txn_id = commit_data
762 elif len(commit_data) == 2:
782 elif len(commit_data) == 2:
@@ -764,10 +784,13 b' def svn_post_commit(repo_path, commit_da'
764 'Some functionality might be limited')
784 'Some functionality might be limited')
765 path, commit_id = commit_data
785 path, commit_id = commit_data
766 txn_id = None
786 txn_id = None
787 else:
788 return 0
767
789
768 branches = []
790 branches = []
769 tags = []
791 tags = []
770
792
793 _fix_hooks_executables()
771 if env.get('RC_SCM_DATA'):
794 if env.get('RC_SCM_DATA'):
772 extras = json.loads(env['RC_SCM_DATA'])
795 extras = json.loads(env['RC_SCM_DATA'])
773 else:
796 else:
@@ -259,12 +259,14 b' class HTTPApplication:'
259 settings_merged = global_config.copy()
259 settings_merged = global_config.copy()
260 settings_merged.update(app_settings)
260 settings_merged.update(app_settings)
261
261
262 git_path = app_settings.get('git_path', None)
262 binary_dir = app_settings['core.binary_dir']
263 if git_path:
263
264 settings.GIT_EXECUTABLE = git_path
264 settings.BINARY_DIR = binary_dir
265 binary_dir = app_settings.get('core.binary_dir', None)
265
266 if binary_dir:
266 # from core.binary dir we set executable paths
267 settings.BINARY_DIR = binary_dir
267 settings.GIT_EXECUTABLE = os.path.join(binary_dir, settings.GIT_EXECUTABLE)
268 settings.SVN_EXECUTABLE = os.path.join(binary_dir, settings.SVN_EXECUTABLE)
269 settings.SVNLOOK_EXECUTABLE = os.path.join(binary_dir, settings.SVNLOOK_EXECUTABLE)
268
270
269 # Store the settings to make them available to other modules.
271 # Store the settings to make them available to other modules.
270 vcsserver.PYRAMID_SETTINGS = settings_merged
272 vcsserver.PYRAMID_SETTINGS = settings_merged
@@ -714,7 +716,7 b' def sanitize_settings_and_apply_defaults'
714 settings_maker.make_setting('pyramid.default_locale_name', 'en')
716 settings_maker.make_setting('pyramid.default_locale_name', 'en')
715 settings_maker.make_setting('locale', 'en_US.UTF-8')
717 settings_maker.make_setting('locale', 'en_US.UTF-8')
716
718
717 settings_maker.make_setting('core.binary_dir', '')
719 settings_maker.make_setting('core.binary_dir', '/usr/local/bin/rhodecode_bin/vcs_bin')
718
720
719 temp_store = tempfile.gettempdir()
721 temp_store = tempfile.gettempdir()
720 default_cache_dir = os.path.join(temp_store, 'rc_cache')
722 default_cache_dir = os.path.join(temp_store, 'rc_cache')
@@ -552,7 +552,7 b' def run_command(arguments, env=None):'
552 proc = SubprocessIOChunker(cmd, **_opts)
552 proc = SubprocessIOChunker(cmd, **_opts)
553 return b''.join(proc), b''.join(proc.stderr)
553 return b''.join(proc), b''.join(proc.stderr)
554 except OSError as err:
554 except OSError as err:
555 cmd = ' '.join(map(safe_str, cmd)) # human friendly CMD
555 cmd = ' '.join(map(safe_str, cmd)) # human friendly CMD
556 tb_err = ("Couldn't run subprocessio command (%s).\n"
556 tb_err = ("Couldn't run subprocessio command (%s).\n"
557 "Original error was:%s\n" % (cmd, err))
557 "Original error was:%s\n" % (cmd, err))
558 log.exception(tb_err)
558 log.exception(tb_err)
General Comments 0
You need to be logged in to leave comments. Login now