Commit a05db040 authored by Kirill Smelkov's avatar Kirill Smelkov

lib/zodb: Teach zstor_2zurl about ZEO, NEO and Demo storages

In 6637d216 (lib/zodb: Add zstor_2zurl - way to convert a ZODB storage
into URL to access it) we added zstor_2zurl function to convert a ZODB
storage client object into an URL to access the storage. At that time
the function knew how to understand FileStorage only. Let's add support
for other storages that WCFS will need to support now.

NEO URI scheme matches the one currently used on ZODB/go side. It
semantically needs nexedi/neoppod!18
to be also applied to NEO/py side, but we do not care for now that that
patch is not merged (yet, or forever) because extracted ZURL is used
only with WCFS which uses NEO/go.

NEO support also depends on custom patch to remember SSL credentials on
NEO Client:

kirr/neo@a2f192cb

Some preliminary history:

kirr/wendelin.core@5cb39463    fixup! X wcfs/zeo started to work locally
kirr/wendelin.core@1cf3b228    X zstor_2zurl += NEO
kirr/wendelin.core@7f8fa32a    X lib/zodb: zstor_2zurl += NEO/SSL support
kirr/wendelin.core@e26524df    X wcfs, lib/zodb: DemoStorage support
parent 622fb217
...@@ -358,8 +358,8 @@ def test_zodb_onresync(): ...@@ -358,8 +358,8 @@ def test_zodb_onresync():
# test that zurl does not change from one open to another storage open. # test that zurl does not change from one open to another storage open.
def test_zurlstable(): def test_zurlstable():
if not isinstance(testdb, testing.TestDB_FileStorage): if not isinstance(testdb, (testing.TestDB_FileStorage, testing.TestDB_ZEO, testing.TestDB_NEO)):
pytest.xfail(reason="zstor_2zurl is TODO for ZEO and NEO") pytest.xfail(reason="zstor_2zurl is TODO for %r" % testdb)
zurl0 = None zurl0 = None
for i in range(10): for i in range(10):
zstor = testdb.getZODBStorage() zstor = testdb.getZODBStorage()
......
# -*- coding: utf-8 -*-
# Wendelin.bigfile | common ZODB-related helpers # Wendelin.bigfile | common ZODB-related helpers
# Copyright (C) 2014-2021 Nexedi SA and Contributors. # Copyright (C) 2014-2021 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com> # Kirill Smelkov <kirr@nexedi.com>
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
import ZODB import ZODB
from ZODB.FileStorage import FileStorage from ZODB.FileStorage import FileStorage
from ZODB.DemoStorage import DemoStorage
from ZODB import DB from ZODB import DB
from ZODB import POSException from ZODB import POSException
from ZODB.utils import p64, u64 from ZODB.utils import p64, u64
...@@ -28,6 +30,7 @@ from persistent import Persistent ...@@ -28,6 +30,7 @@ from persistent import Persistent
import zodbtools.util import zodbtools.util
from weakref import WeakSet from weakref import WeakSet
import gc import gc
from six.moves.urllib import parse as urlparse
import pkg_resources import pkg_resources
...@@ -290,5 +293,66 @@ def zstor_2zurl(zstor): ...@@ -290,5 +293,66 @@ def zstor_2zurl(zstor):
if isinstance(zstor, FileStorage): if isinstance(zstor, FileStorage):
return "file://%s" % (zstor._file_name,) return "file://%s" % (zstor._file_name,)
# TODO ZEO + NEO support if isinstance(zstor, DemoStorage):
# demo:(base_zurl)/(δ_zurl)
return "demo:(%s)/(%s)" % (zstor_2zurl(zstor.base), zstor_2zurl(zstor.changes))
ztype = type(zstor).__module__ + "." + type(zstor).__name__
# ZEO
if ztype == "ZEO.ClientStorage.ClientStorage":
# zeo://(path|host:port)?storage=<storageID>
u = "zeo://"
_addr = zstor._addr
addr = None
# ZEO4/3 for backward compatibility accept either a single "address" or single ("host", port) pair
# https://github.com/zopefoundation/ZEO/blob/4.2.0b1-49-g47d3fbe8/src/ZEO/zrpc/client.py#L179
if zmajor <= 4:
if isinstance(_addr, str):
addr = _addr
elif len(_addr) == 2 and isinstance(_addr[0], str) and isinstance(_addr[1], int):
addr = _addr
if addr is None:
if len(_addr) != 1:
raise NotImplementedError("ZEO client has multiple configured servers: %r" % (addr,))
addr = _addr[0]
# addr is either TCP (host,port) or UNIX path
if isinstance(addr, str):
u += addr
else:
host, port = addr
u += '%s:%d' % (host, port)
storage = zstor._storage
if storage != "1":
u += "?storage=%s" % storage
# TODO ssl
return u
# NEO
if ztype == "neo.client.Storage.Storage":
# neo(s)://[<credentials>@]<master>/<cluster>
app = zstor.app
if not app.ssl:
u = "neo://"
else:
q = urlparse.quote_plus
u = "neos://"
ca, cert, key = app.ssl_credentials # .ssl_credentials depend on kirr's patch
u += "ca=%s;cert=%s;key=%s@" % (q(ca), q(cert), q(key))
masterv = app.nm.getMasterList()
if len(masterv) == 0:
raise RuntimeError("%r has empty master list" % zstor)
if len(masterv) > 1:
raise NotImplementedError("NEO client has multiple configured masters: %r" % (masterv,))
master = masterv[0]
host, port = master.getAddress()
u += "%s:%s" % (host, port)
u += "/%s" % app.name
return u
raise NotImplementedError("don't know how to extract zurl from %r" % zstor) raise NotImplementedError("don't know how to extract zurl from %r" % zstor)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment