scylladb / python-driver

ScyllaDB Python Driver, originally DataStax Python Driver for Apache Cassandra
https://python-driver.docs.scylladb.com
Apache License 2.0
70 stars 42 forks source link

`WhiteListRoundRobinPolicy` does not support unix domain sockets #280

Closed kbr-scylla closed 8 months ago

kbr-scylla commented 8 months ago

Most prominent example of this is when we try to use cqlsh to connect to Scylla maintenance socket (currently queued on next): https://github.com/scylladb/scylladb/issues/16489

$ cqlsh /tmp/scylla-workdir/cql.m 
Traceback (most recent call last):
  File "/home/kbr/dev/scylla/tools/cqlsh/bin/cqlsh.py", line 2706, in <module>
    main(*read_options(sys.argv[1:], os.environ))
  File "/home/kbr/dev/scylla/tools/cqlsh/bin/cqlsh.py", line 2647, in main
    shell = Shell(hostname,
            ^^^^^^^^^^^^^^^
  File "/home/kbr/dev/scylla/tools/cqlsh/bin/cqlsh.py", line 491, in __init__
    profiles[EXEC_PROFILE_DEFAULT].load_balancing_policy = WhiteListRoundRobinPolicy([self.hostname])
                                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kbr/dev/scylla/pyenv/lib64/python3.11/site-packages/cassandra/policies.py", line 425, in __init__
    self._allowed_hosts_resolved = [endpoint[4][0] for a in self._allowed_hosts
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kbr/dev/scylla/pyenv/lib64/python3.11/site-packages/cassandra/policies.py", line 426, in <listcomp>
    for endpoint in socket.getaddrinfo(a, None, socket.AF_UNSPEC, socket.SOCK_STREAM)]
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/socket.py", line 962, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
socket.gaierror: [Errno -2] Name or service not known

A workaround is possible (using HostFilterPolicy), but since cqlsh uses WhiteListRoundRobinPolicy, we need to fix it.

sylwiaszunejko commented 8 months ago

@kbr-scylla This issue have two parts:

socket = "<node's workdir>/cql.m" cluster = Cluster([UnixSocketEndPoint(socket)],

Driver tries to connect to other nodes in the cluster, so we need to filter them out.

              load_balancing_policy=HostFilterPolicy(RoundRobinPolicy(), lambda h: h.address == socket))

session = cluster.connect()

with `WhiteListRoundRobinPolicy` it should look like that:
```python
from cassandra.cluster import Cluster
from cassandra.connection import UnixSocketEndPoint
from cassandra.policies import HostFilterPolicy, RoundRobinPolicy

socket = "<node's workdir>/cql.m"
cluster = Cluster([UnixSocketEndPoint(socket)],
                  # Driver tries to connect to other nodes in the cluster, so we need to filter them out.
                  load_balancing_policy=WhiteListRoundRobinPolicy([UnixSocketEndPoint(socket)])
session = cluster.connect()

so there is a need to introduce a way to cqlsh to recognize if hostname is a unix domain socket and if it is it should wrap self.hostname (here: https://github.com/scylladb/scylla-cqlsh/blob/426fa0eaa72b7d46115188b1af9cdd983b923241/bin/cqlsh.py#L488,L491) in UnixSocketEndPoint.

sylwiaszunejko commented 8 months ago

@kbr-scylla @avelanarius I addressed second part of this issue in https://github.com/scylladb/scylla-cqlsh/pull/67