Skip to content
Snippets Groups Projects
Commit 5cca85c5e7f5 authored by Georges Racinet's avatar Georges Racinet
Browse files

Support multiple storages

This was left aside in the project bootstrap.
We won't actually need multiple storages for a while, hence
the server command still uses a single `repositories-root`.

But we better have the internals support multiple storages right
away: its easier to do right now than to add it afterwards.
parent 4917ed9df786
No related branches found
No related tags found
No related merge requests found
Pipeline #7094 passed with warnings
......@@ -12,5 +12,5 @@
@pytest.fixture(scope='module')
def grpc_server(_grpc_server, grpc_addr, server_repos_root):
repos_root_bytes = str(server_repos_root).encode()
storages = dict(default=str(server_repos_root / 'default').encode())
......@@ -16,3 +16,3 @@
add_CommitServiceServicer_to_server(CommitServicer(repos_root_bytes),
add_CommitServiceServicer_to_server(CommitServicer(storages),
_grpc_server)
......@@ -18,4 +18,4 @@
_grpc_server)
add_RefServiceServicer_to_server(RefServicer(repos_root_bytes),
add_RefServiceServicer_to_server(RefServicer(storages),
_grpc_server)
add_RepositoryServiceServicer_to_server(
......@@ -20,6 +20,6 @@
_grpc_server)
add_RepositoryServiceServicer_to_server(
RepositoryServiceServicer(repos_root_bytes),
RepositoryServiceServicer(storages),
_grpc_server)
_grpc_server.add_insecure_port(grpc_addr)
_grpc_server.start()
......
......@@ -62,7 +62,7 @@
norepo=True
)
def serve(ui, **opts):
"""Start a HGitaly server.
"""Start a HGitaly server with only one storage, named 'default'
By default the root of repositories is read from the
`heptapod.repositories-root` configuration item if present.
......@@ -85,4 +85,6 @@
b"'heptapod.repositories-root'. Please define it or run "
b"the command with the --repositories-root option."
))
storages = dict(default=repos_root)
server = grpc.server(futures.ThreadPoolExecutor(max_workers=1))
......@@ -88,4 +90,4 @@
server = grpc.server(futures.ThreadPoolExecutor(max_workers=1))
add_CommitServiceServicer_to_server(CommitServicer(repos_root), server)
add_RefServiceServicer_to_server(RefServicer(repos_root), server)
add_CommitServiceServicer_to_server(CommitServicer(storages), server)
add_RefServiceServicer_to_server(RefServicer(storages), server)
add_RepositoryServiceServicer_to_server(
......@@ -91,5 +93,5 @@
add_RepositoryServiceServicer_to_server(
RepositoryServiceServicer(repos_root), server)
RepositoryServiceServicer(storages), server)
for url in listen_urls:
try:
......
......@@ -22,6 +22,7 @@
Attributes:
- `repositories_root`: should be given as bytes, since we'll have
- :attr:`storages`: a :class:`dict` mapping storage names to corresponding
root directory absolute paths, which are given as bytes since we'll have
to convert paths to bytes anyway, which is the only promise a filesystem
can make, and what Mercurial expects.
......@@ -26,4 +27,6 @@
to convert paths to bytes anyway, which is the only promise a filesystem
can make, and what Mercurial expects.
- :attr:`ui`: base :class:`mercurial.ui.ui` instance from which repository
uis are derived. In particular, it bears the common configuration.
"""
......@@ -28,7 +31,7 @@
"""
def __init__(self, repositories_root):
self.repos_root = repositories_root
def __init__(self, storages):
self.storages = storages
self.ui = uimod.ui.load()
def load_repo(self, repository: Repository):
......@@ -38,4 +41,10 @@
rpath = repository.relative_path
if rpath.endswith('.git'):
rpath = rpath[:-4] + '.hg'
root_dir = self.storages.get(repository.storage_name)
if root_dir is None:
# TODO produce proper error. Keep uncovered by tests until then
raise KeyError("No storage named %r" % repository.storage_name)
# GitLab filesystem paths are always ASCII
......@@ -41,5 +50,5 @@
# GitLab filesystem paths are always ASCII
repo_path = os.path.join(self.repos_root, rpath.encode('ascii'))
repo_path = os.path.join(root_dir, rpath.encode('ascii'))
logger.info("loading repo at %r", repo_path)
# ensure caller gets private copy of ui
......
......@@ -9,9 +9,9 @@
from ..stub.shared_pb2 import Repository
def make_empty_repo(server_repos_root, relative_path='repo1'):
def make_empty_repo(storages_root, relative_path='repo1', storage='default'):
"""Create an empty repo, ready for most of HGitaly tests.
:relative_path: path to the repo, relative to server_repos_root, and
hence also relative path in the sense of Gitaly protocol.
Can be given as :class:`str` or :class:`pathlib.Path`
......@@ -13,7 +13,10 @@
"""Create an empty repo, ready for most of HGitaly tests.
:relative_path: path to the repo, relative to server_repos_root, and
hence also relative path in the sense of Gitaly protocol.
Can be given as :class:`str` or :class:`pathlib.Path`
:storage: name of the target storage, will have to be created and
registered before hand on the testing grpc server if needed.
return: wrapper, gRPC Repository message
"""
......@@ -18,6 +21,6 @@
return: wrapper, gRPC Repository message
"""
repo_path = server_repos_root / relative_path
repo_path = storages_root / storage / relative_path
wrapper = LocalRepoWrapper.init(repo_path,
config={b'extensions': {b'topic': b''}}
)
......@@ -26,5 +29,6 @@
(repo_path / '.hg' / 'hgrc').write_text(
'\n'.join(('[extensions]', 'topic=')))
grpc_repo = Repository(relative_path=str(relative_path))
grpc_repo = Repository(relative_path=str(relative_path),
storage_name=storage)
return wrapper, grpc_repo
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment