##// END OF EJS Templates
Mercurial: fix ssh-server support for UI objects...
marcink -
r3626:30cddb61 default
parent child Browse files
Show More
@@ -20,12 +20,12 b''
20 20
21 21 import os
22 22 import sys
23 import shutil
24 23 import logging
25 24 import tempfile
26 25 import textwrap
27
26 import collections
28 27 from .base import VcsServer
28 from rhodecode.model.settings import VcsSettingsModel
29 29
30 30 log = logging.getLogger(__name__)
31 31
@@ -37,14 +37,15 b' class MercurialTunnelWrapper(object):'
37 37 self.server = server
38 38 self.stdin = sys.stdin
39 39 self.stdout = sys.stdout
40 self.svn_conf_fd, self.svn_conf_path = tempfile.mkstemp()
41 self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp()
40 self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp(prefix='hgrc_rhodecode_')
42 41
43 42 def create_hooks_env(self):
43 repo_name = self.server.repo_name
44 hg_flags = self.config_to_hgrc(repo_name)
44 45
45 46 content = textwrap.dedent(
46 47 '''
47 # SSH hooks version=1.0.0
48 # SSH hooks version=2.0.0
48 49 [hooks]
49 50 pretxnchangegroup.ssh_auth=python:vcsserver.hooks.pre_push_ssh_auth
50 51 pretxnchangegroup.ssh=python:vcsserver.hooks.pre_push_ssh
@@ -53,46 +54,38 b' class MercurialTunnelWrapper(object):'
53 54 preoutgoing.ssh=python:vcsserver.hooks.pre_pull_ssh
54 55 outgoing.ssh=python:vcsserver.hooks.post_pull_ssh
55 56
57 # Custom Config version=2.0.0
58 {custom}
56 59 '''
57 )
60 ).format(custom='\n'.join(hg_flags))
61
62 root = self.server.get_root_store()
63 hgrc_custom = os.path.join(root, repo_name, '.hg', 'hgrc_rhodecode')
64 hgrc_main = os.path.join(root, repo_name, '.hg', 'hgrc')
58 65
66 # cleanup custom hgrc file
67 if os.path.isfile(hgrc_custom):
68 with open(hgrc_custom, 'wb') as f:
69 f.write('')
70 log.debug('Cleanup custom hgrc file under %s', hgrc_custom)
71
72 # write temp
59 73 with os.fdopen(self.hooks_env_fd, 'w') as hooks_env_file:
60 74 hooks_env_file.write(content)
61 root = self.server.get_root_store()
62 75
63 hgrc_custom = os.path.join(
64 root, self.server.repo_name, '.hg', 'hgrc_rhodecode')
65 log.debug('Wrote custom hgrc file under %s', hgrc_custom)
66 shutil.move(
67 self.hooks_env_path, hgrc_custom)
68
69 hgrc_main = os.path.join(
70 root, self.server.repo_name, '.hg', 'hgrc')
71 include_marker = '%include hgrc_rhodecode'
76 return self.hooks_env_path
72 77
73 if not os.path.isfile(hgrc_main):
74 os.mknod(hgrc_main)
75
76 with open(hgrc_main, 'rb') as f:
77 data = f.read()
78 has_marker = include_marker in data
78 def remove_configs(self):
79 os.remove(self.hooks_env_path)
79 80
80 if not has_marker:
81 log.debug('Adding include marker for hooks')
82 with open(hgrc_main, 'wa') as f:
83 f.write(textwrap.dedent('''
84 # added by RhodeCode
85 {}
86 '''.format(include_marker)))
87
88 def command(self):
81 def command(self, hgrc_path):
89 82 root = self.server.get_root_store()
90 83
91 84 command = (
92 "cd {root}; {hg_path} -R {root}{repo_name} "
85 "cd {root}; HGRCPATH={hgrc} {hg_path} -R {root}{repo_name} "
93 86 "serve --stdio".format(
94 87 root=root, hg_path=self.server.hg_path,
95 repo_name=self.server.repo_name))
88 repo_name=self.server.repo_name, hgrc=hgrc_path))
96 89 log.debug("Final CMD: %s", command)
97 90 return command
98 91
@@ -102,22 +95,43 b' class MercurialTunnelWrapper(object):'
102 95 action = '?'
103 96 # permissions are check via `pre_push_ssh_auth` hook
104 97 self.server.update_environment(action=action, extras=extras)
105 self.create_hooks_env()
106 return os.system(self.command())
98 custom_hgrc_file = self.create_hooks_env()
99
100 try:
101 return os.system(self.command(custom_hgrc_file))
102 finally:
103 self.remove_configs()
107 104
108 105
109 106 class MercurialServer(VcsServer):
110 107 backend = 'hg'
108 cli_flags = ['phases', 'largefiles', 'extensions', 'experimental']
111 109
112 def __init__(self, store, ini_path, repo_name,
113 user, user_permissions, config, env):
114 super(MercurialServer, self).\
115 __init__(user, user_permissions, config, env)
110 def __init__(self, store, ini_path, repo_name, user, user_permissions, config, env):
111 super(MercurialServer, self).__init__(user, user_permissions, config, env)
116 112
117 113 self.store = store
118 114 self.ini_path = ini_path
119 115 self.repo_name = repo_name
120 self._path = self.hg_path = config.get(
121 'app:main', 'ssh.executable.hg')
116 self._path = self.hg_path = config.get('app:main', 'ssh.executable.hg')
117 self.tunnel = MercurialTunnelWrapper(server=self)
118
119 def config_to_hgrc(self, repo_name):
120 ui_sections = collections.defaultdict(list)
121 ui = VcsSettingsModel(repo=repo_name).get_ui_settings(section=None, key=None)
122 122
123 self.tunnel = MercurialTunnelWrapper(server=self)
123 for entry in ui:
124 if not entry.active:
125 continue
126 sec = entry.section
127
128 if sec in self.cli_flags:
129 ui_sections[sec].append([entry.key, entry.value])
130
131 flags = []
132 for _sec, key_val in ui_sections.items():
133 flags.append(' ')
134 flags.append('[{}]'.format(_sec))
135 for key, val in key_val:
136 flags.append('{}= {}'.format(key, val))
137 return flags
@@ -18,6 +18,7 b''
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 import os
21 22 import mock
22 23 import pytest
23 24
@@ -68,14 +69,16 b' def hg_server(app):'
68 69
69 70 class TestMercurialServer(object):
70 71
71 def test_command(self, hg_server):
72 def test_command(self, hg_server, tmpdir):
72 73 server = hg_server.create()
74 custom_hgrc = os.path.join(str(tmpdir), 'hgrc')
73 75 expected_command = (
74 'cd {root}; {hg_path} -R {root}{repo_name} serve --stdio'.format(
75 root=hg_server.root, hg_path=hg_server.hg_path,
76 'cd {root}; HGRCPATH={custom_hgrc} {hg_path} -R {root}{repo_name} serve --stdio'.format(
77 root=hg_server.root, custom_hgrc=custom_hgrc, hg_path=hg_server.hg_path,
76 78 repo_name=hg_server.repo_name)
77 79 )
78 assert expected_command == server.tunnel.command()
80 server_command = server.tunnel.command(custom_hgrc)
81 assert expected_command == server_command
79 82
80 83 @pytest.mark.parametrize('permissions, action, code', [
81 84 ({}, 'pull', -2),
@@ -449,6 +449,7 b' class VcsSettingsModel(object):'
449 449 ('extensions', 'evolve'),
450 450 ('extensions', 'topic'),
451 451 ('experimental', 'evolution'),
452 ('experimental', 'evolution.exchange'),
452 453 )
453 454 GIT_SETTINGS = (
454 455 ('vcs_git_lfs', 'enabled'),
@@ -461,6 +462,7 b' class VcsSettingsModel(object):'
461 462 ('extensions', 'evolve'),
462 463 ('extensions', 'topic'),
463 464 ('experimental', 'evolution'),
465 ('experimental', 'evolution.exchange'),
464 466 )
465 467
466 468 GLOBAL_GIT_SETTINGS = (
General Comments 0
You need to be logged in to leave comments. Login now