##// 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 import os
21 import os
22 import sys
22 import sys
23 import shutil
24 import logging
23 import logging
25 import tempfile
24 import tempfile
26 import textwrap
25 import textwrap
27
26 import collections
28 from .base import VcsServer
27 from .base import VcsServer
28 from rhodecode.model.settings import VcsSettingsModel
29
29
30 log = logging.getLogger(__name__)
30 log = logging.getLogger(__name__)
31
31
@@ -37,14 +37,15 b' class MercurialTunnelWrapper(object):'
37 self.server = server
37 self.server = server
38 self.stdin = sys.stdin
38 self.stdin = sys.stdin
39 self.stdout = sys.stdout
39 self.stdout = sys.stdout
40 self.svn_conf_fd, self.svn_conf_path = tempfile.mkstemp()
40 self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp(prefix='hgrc_rhodecode_')
41 self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp()
42
41
43 def create_hooks_env(self):
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 content = textwrap.dedent(
46 content = textwrap.dedent(
46 '''
47 '''
47 # SSH hooks version=1.0.0
48 # SSH hooks version=2.0.0
48 [hooks]
49 [hooks]
49 pretxnchangegroup.ssh_auth=python:vcsserver.hooks.pre_push_ssh_auth
50 pretxnchangegroup.ssh_auth=python:vcsserver.hooks.pre_push_ssh_auth
50 pretxnchangegroup.ssh=python:vcsserver.hooks.pre_push_ssh
51 pretxnchangegroup.ssh=python:vcsserver.hooks.pre_push_ssh
@@ -53,46 +54,38 b' class MercurialTunnelWrapper(object):'
53 preoutgoing.ssh=python:vcsserver.hooks.pre_pull_ssh
54 preoutgoing.ssh=python:vcsserver.hooks.pre_pull_ssh
54 outgoing.ssh=python:vcsserver.hooks.post_pull_ssh
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 with os.fdopen(self.hooks_env_fd, 'w') as hooks_env_file:
73 with os.fdopen(self.hooks_env_fd, 'w') as hooks_env_file:
60 hooks_env_file.write(content)
74 hooks_env_file.write(content)
61 root = self.server.get_root_store()
62
75
63 hgrc_custom = os.path.join(
76 return self.hooks_env_path
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'
72
77
73 if not os.path.isfile(hgrc_main):
78 def remove_configs(self):
74 os.mknod(hgrc_main)
79 os.remove(self.hooks_env_path)
75
76 with open(hgrc_main, 'rb') as f:
77 data = f.read()
78 has_marker = include_marker in data
79
80
80 if not has_marker:
81 def command(self, hgrc_path):
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):
89 root = self.server.get_root_store()
82 root = self.server.get_root_store()
90
83
91 command = (
84 command = (
92 "cd {root}; {hg_path} -R {root}{repo_name} "
85 "cd {root}; HGRCPATH={hgrc} {hg_path} -R {root}{repo_name} "
93 "serve --stdio".format(
86 "serve --stdio".format(
94 root=root, hg_path=self.server.hg_path,
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 log.debug("Final CMD: %s", command)
89 log.debug("Final CMD: %s", command)
97 return command
90 return command
98
91
@@ -102,22 +95,43 b' class MercurialTunnelWrapper(object):'
102 action = '?'
95 action = '?'
103 # permissions are check via `pre_push_ssh_auth` hook
96 # permissions are check via `pre_push_ssh_auth` hook
104 self.server.update_environment(action=action, extras=extras)
97 self.server.update_environment(action=action, extras=extras)
105 self.create_hooks_env()
98 custom_hgrc_file = self.create_hooks_env()
106 return os.system(self.command())
99
100 try:
101 return os.system(self.command(custom_hgrc_file))
102 finally:
103 self.remove_configs()
107
104
108
105
109 class MercurialServer(VcsServer):
106 class MercurialServer(VcsServer):
110 backend = 'hg'
107 backend = 'hg'
108 cli_flags = ['phases', 'largefiles', 'extensions', 'experimental']
111
109
112 def __init__(self, store, ini_path, repo_name,
110 def __init__(self, store, ini_path, repo_name, user, user_permissions, config, env):
113 user, user_permissions, config, env):
111 super(MercurialServer, self).__init__(user, user_permissions, config, env)
114 super(MercurialServer, self).\
115 __init__(user, user_permissions, config, env)
116
112
117 self.store = store
113 self.store = store
118 self.ini_path = ini_path
114 self.ini_path = ini_path
119 self.repo_name = repo_name
115 self.repo_name = repo_name
120 self._path = self.hg_path = config.get(
116 self._path = self.hg_path = config.get('app:main', 'ssh.executable.hg')
121 '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 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import mock
22 import mock
22 import pytest
23 import pytest
23
24
@@ -68,14 +69,16 b' def hg_server(app):'
68
69
69 class TestMercurialServer(object):
70 class TestMercurialServer(object):
70
71
71 def test_command(self, hg_server):
72 def test_command(self, hg_server, tmpdir):
72 server = hg_server.create()
73 server = hg_server.create()
74 custom_hgrc = os.path.join(str(tmpdir), 'hgrc')
73 expected_command = (
75 expected_command = (
74 'cd {root}; {hg_path} -R {root}{repo_name} serve --stdio'.format(
76 'cd {root}; HGRCPATH={custom_hgrc} {hg_path} -R {root}{repo_name} serve --stdio'.format(
75 root=hg_server.root, hg_path=hg_server.hg_path,
77 root=hg_server.root, custom_hgrc=custom_hgrc, hg_path=hg_server.hg_path,
76 repo_name=hg_server.repo_name)
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 @pytest.mark.parametrize('permissions, action, code', [
83 @pytest.mark.parametrize('permissions, action, code', [
81 ({}, 'pull', -2),
84 ({}, 'pull', -2),
@@ -449,6 +449,7 b' class VcsSettingsModel(object):'
449 ('extensions', 'evolve'),
449 ('extensions', 'evolve'),
450 ('extensions', 'topic'),
450 ('extensions', 'topic'),
451 ('experimental', 'evolution'),
451 ('experimental', 'evolution'),
452 ('experimental', 'evolution.exchange'),
452 )
453 )
453 GIT_SETTINGS = (
454 GIT_SETTINGS = (
454 ('vcs_git_lfs', 'enabled'),
455 ('vcs_git_lfs', 'enabled'),
@@ -461,6 +462,7 b' class VcsSettingsModel(object):'
461 ('extensions', 'evolve'),
462 ('extensions', 'evolve'),
462 ('extensions', 'topic'),
463 ('extensions', 'topic'),
463 ('experimental', 'evolution'),
464 ('experimental', 'evolution'),
465 ('experimental', 'evolution.exchange'),
464 )
466 )
465
467
466 GLOBAL_GIT_SETTINGS = (
468 GLOBAL_GIT_SETTINGS = (
General Comments 0
You need to be logged in to leave comments. Login now