Mercurial: fix ssh-server support for UI objects
- fixed evolve/topic usage - fixed propagation of publishing and extension flags
This commit is contained in:
parent
d621ac19ee
commit
d693a556b4
3 changed files with 65 additions and 46 deletions
|
|
@ -20,12 +20,12 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import logging
|
||||
import tempfile
|
||||
import textwrap
|
||||
|
||||
import collections
|
||||
from .base import VcsServer
|
||||
from rhodecode.model.settings import VcsSettingsModel
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -37,14 +37,15 @@ class MercurialTunnelWrapper(object):
|
|||
self.server = server
|
||||
self.stdin = sys.stdin
|
||||
self.stdout = sys.stdout
|
||||
self.svn_conf_fd, self.svn_conf_path = tempfile.mkstemp()
|
||||
self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp()
|
||||
self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp(prefix='hgrc_rhodecode_')
|
||||
|
||||
def create_hooks_env(self):
|
||||
repo_name = self.server.repo_name
|
||||
hg_flags = self.config_to_hgrc(repo_name)
|
||||
|
||||
content = textwrap.dedent(
|
||||
'''
|
||||
# SSH hooks version=1.0.0
|
||||
# SSH hooks version=2.0.0
|
||||
[hooks]
|
||||
pretxnchangegroup.ssh_auth=python:vcsserver.hooks.pre_push_ssh_auth
|
||||
pretxnchangegroup.ssh=python:vcsserver.hooks.pre_push_ssh
|
||||
|
|
@ -53,46 +54,38 @@ class MercurialTunnelWrapper(object):
|
|||
preoutgoing.ssh=python:vcsserver.hooks.pre_pull_ssh
|
||||
outgoing.ssh=python:vcsserver.hooks.post_pull_ssh
|
||||
|
||||
# Custom Config version=2.0.0
|
||||
{custom}
|
||||
'''
|
||||
)
|
||||
).format(custom='\n'.join(hg_flags))
|
||||
|
||||
root = self.server.get_root_store()
|
||||
hgrc_custom = os.path.join(root, repo_name, '.hg', 'hgrc_rhodecode')
|
||||
hgrc_main = os.path.join(root, repo_name, '.hg', 'hgrc')
|
||||
|
||||
# cleanup custom hgrc file
|
||||
if os.path.isfile(hgrc_custom):
|
||||
with open(hgrc_custom, 'wb') as f:
|
||||
f.write('')
|
||||
log.debug('Cleanup custom hgrc file under %s', hgrc_custom)
|
||||
|
||||
# write temp
|
||||
with os.fdopen(self.hooks_env_fd, 'w') as hooks_env_file:
|
||||
hooks_env_file.write(content)
|
||||
root = self.server.get_root_store()
|
||||
|
||||
hgrc_custom = os.path.join(
|
||||
root, self.server.repo_name, '.hg', 'hgrc_rhodecode')
|
||||
log.debug('Wrote custom hgrc file under %s', hgrc_custom)
|
||||
shutil.move(
|
||||
self.hooks_env_path, hgrc_custom)
|
||||
return self.hooks_env_path
|
||||
|
||||
hgrc_main = os.path.join(
|
||||
root, self.server.repo_name, '.hg', 'hgrc')
|
||||
include_marker = '%include hgrc_rhodecode'
|
||||
def remove_configs(self):
|
||||
os.remove(self.hooks_env_path)
|
||||
|
||||
if not os.path.isfile(hgrc_main):
|
||||
os.mknod(hgrc_main)
|
||||
|
||||
with open(hgrc_main, 'rb') as f:
|
||||
data = f.read()
|
||||
has_marker = include_marker in data
|
||||
|
||||
if not has_marker:
|
||||
log.debug('Adding include marker for hooks')
|
||||
with open(hgrc_main, 'wa') as f:
|
||||
f.write(textwrap.dedent('''
|
||||
# added by RhodeCode
|
||||
{}
|
||||
'''.format(include_marker)))
|
||||
|
||||
def command(self):
|
||||
def command(self, hgrc_path):
|
||||
root = self.server.get_root_store()
|
||||
|
||||
command = (
|
||||
"cd {root}; {hg_path} -R {root}{repo_name} "
|
||||
"cd {root}; HGRCPATH={hgrc} {hg_path} -R {root}{repo_name} "
|
||||
"serve --stdio".format(
|
||||
root=root, hg_path=self.server.hg_path,
|
||||
repo_name=self.server.repo_name))
|
||||
repo_name=self.server.repo_name, hgrc=hgrc_path))
|
||||
log.debug("Final CMD: %s", command)
|
||||
return command
|
||||
|
||||
|
|
@ -102,22 +95,43 @@ class MercurialTunnelWrapper(object):
|
|||
action = '?'
|
||||
# permissions are check via `pre_push_ssh_auth` hook
|
||||
self.server.update_environment(action=action, extras=extras)
|
||||
self.create_hooks_env()
|
||||
return os.system(self.command())
|
||||
custom_hgrc_file = self.create_hooks_env()
|
||||
|
||||
try:
|
||||
return os.system(self.command(custom_hgrc_file))
|
||||
finally:
|
||||
self.remove_configs()
|
||||
|
||||
|
||||
class MercurialServer(VcsServer):
|
||||
backend = 'hg'
|
||||
cli_flags = ['phases', 'largefiles', 'extensions', 'experimental']
|
||||
|
||||
def __init__(self, store, ini_path, repo_name,
|
||||
user, user_permissions, config, env):
|
||||
super(MercurialServer, self).\
|
||||
__init__(user, user_permissions, config, env)
|
||||
def __init__(self, store, ini_path, repo_name, user, user_permissions, config, env):
|
||||
super(MercurialServer, self).__init__(user, user_permissions, config, env)
|
||||
|
||||
self.store = store
|
||||
self.ini_path = ini_path
|
||||
self.repo_name = repo_name
|
||||
self._path = self.hg_path = config.get(
|
||||
'app:main', 'ssh.executable.hg')
|
||||
|
||||
self._path = self.hg_path = config.get('app:main', 'ssh.executable.hg')
|
||||
self.tunnel = MercurialTunnelWrapper(server=self)
|
||||
|
||||
def config_to_hgrc(self, repo_name):
|
||||
ui_sections = collections.defaultdict(list)
|
||||
ui = VcsSettingsModel(repo=repo_name).get_ui_settings(section=None, key=None)
|
||||
|
||||
for entry in ui:
|
||||
if not entry.active:
|
||||
continue
|
||||
sec = entry.section
|
||||
|
||||
if sec in self.cli_flags:
|
||||
ui_sections[sec].append([entry.key, entry.value])
|
||||
|
||||
flags = []
|
||||
for _sec, key_val in ui_sections.items():
|
||||
flags.append(' ')
|
||||
flags.append('[{}]'.format(_sec))
|
||||
for key, val in key_val:
|
||||
flags.append('{}= {}'.format(key, val))
|
||||
return flags
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import os
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
|
|
@ -68,14 +69,16 @@ def hg_server(app):
|
|||
|
||||
class TestMercurialServer(object):
|
||||
|
||||
def test_command(self, hg_server):
|
||||
def test_command(self, hg_server, tmpdir):
|
||||
server = hg_server.create()
|
||||
custom_hgrc = os.path.join(str(tmpdir), 'hgrc')
|
||||
expected_command = (
|
||||
'cd {root}; {hg_path} -R {root}{repo_name} serve --stdio'.format(
|
||||
root=hg_server.root, hg_path=hg_server.hg_path,
|
||||
'cd {root}; HGRCPATH={custom_hgrc} {hg_path} -R {root}{repo_name} serve --stdio'.format(
|
||||
root=hg_server.root, custom_hgrc=custom_hgrc, hg_path=hg_server.hg_path,
|
||||
repo_name=hg_server.repo_name)
|
||||
)
|
||||
assert expected_command == server.tunnel.command()
|
||||
server_command = server.tunnel.command(custom_hgrc)
|
||||
assert expected_command == server_command
|
||||
|
||||
@pytest.mark.parametrize('permissions, action, code', [
|
||||
({}, 'pull', -2),
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@ class VcsSettingsModel(object):
|
|||
('extensions', 'evolve'),
|
||||
('extensions', 'topic'),
|
||||
('experimental', 'evolution'),
|
||||
('experimental', 'evolution.exchange'),
|
||||
)
|
||||
GIT_SETTINGS = (
|
||||
('vcs_git_lfs', 'enabled'),
|
||||
|
|
@ -461,6 +462,7 @@ class VcsSettingsModel(object):
|
|||
('extensions', 'evolve'),
|
||||
('extensions', 'topic'),
|
||||
('experimental', 'evolution'),
|
||||
('experimental', 'evolution.exchange'),
|
||||
)
|
||||
|
||||
GLOBAL_GIT_SETTINGS = (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue