Skip to content

Commit

Permalink
Fixes #503 w/ bin refactor for project.scripts support; Removed rpycd…
Browse files Browse the repository at this point in the history
… since external daemon service is better
  • Loading branch information
comrumino committed Aug 4, 2022
1 parent 20dd973 commit 85b84ae
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 249 deletions.
130 changes: 2 additions & 128 deletions bin/rpyc_classic.py
Original file line number Diff line number Diff line change
@@ -1,132 +1,6 @@
#!/usr/bin/env python
"""
classic rpyc server (threaded, forking or std) running a SlaveService
usage:
rpyc_classic.py # default settings
rpyc_classic.py -m forking -p 12345 # custom settings
# ssl-authenticated server (keyfile and certfile are required)
rpyc_classic.py --ssl-keyfile keyfile.pem --ssl-certfile certfile.pem --ssl-cafile cafile.pem
"""
import sys
import os
import rpyc
from plumbum import cli
from rpyc.utils.server import ThreadedServer, ForkingServer, OneShotServer
from rpyc.utils.classic import DEFAULT_SERVER_PORT, DEFAULT_SERVER_SSL_PORT
from rpyc.utils.registry import REGISTRY_PORT
from rpyc.utils.registry import UDPRegistryClient, TCPRegistryClient
from rpyc.utils.authenticators import SSLAuthenticator
from rpyc.lib import setup_logger
from rpyc.core import SlaveService


class ClassicServer(cli.Application):
mode = cli.SwitchAttr(["-m", "--mode"], cli.Set("threaded", "forking", "stdio", "oneshot"),
default="threaded", help="The serving mode (threaded, forking, or 'stdio' for "
"inetd, etc.)")

port = cli.SwitchAttr(["-p", "--port"], cli.Range(0, 65535), default=None,
help="The TCP listener port ("
"default = {DEFAULT_SERVER_PORT!r}, "
"default for SSL = {DEFAULT_SERVER_SSL_PORT!r})",
group="Socket Options")
host = cli.SwitchAttr(["--host"], str, default="", help="The host to bind to. "
"The default is localhost", group="Socket Options")
ipv6 = cli.Flag(["--ipv6"], help="Enable IPv6", group="Socket Options")

logfile = cli.SwitchAttr("--logfile", str, default=None, help="Specify the log file to use; "
"the default is stderr", group="Logging")
quiet = cli.Flag(["-q", "--quiet"], help="Quiet mode (only errors will be logged)",
group="Logging")

ssl_keyfile = cli.SwitchAttr("--ssl-keyfile", cli.ExistingFile,
help="The keyfile to use for SSL. Required for SSL", group="SSL",
requires=["--ssl-certfile"])
ssl_certfile = cli.SwitchAttr("--ssl-certfile", cli.ExistingFile,
help="The certificate file to use for SSL. Required for SSL", group="SSL",
requires=["--ssl-keyfile"])
ssl_cafile = cli.SwitchAttr("--ssl-cafile", cli.ExistingFile,
help="The certificate authority chain file to use for SSL. "
"Optional; enables client-side authentication",
group="SSL", requires=["--ssl-keyfile"])

auto_register = cli.Flag("--register", help="Asks the server to attempt registering with "
"a registry server. By default, the server will not attempt to register",
group="Registry")
registry_type = cli.SwitchAttr("--registry-type", cli.Set("UDP", "TCP"),
default="UDP", help="Specify a UDP or TCP registry", group="Registry")
registry_port = cli.SwitchAttr("--registry-port", cli.Range(0, 65535), default=REGISTRY_PORT,
help="The registry's UDP/TCP port", group="Registry")
registry_host = cli.SwitchAttr("--registry-host", str, default=None,
help="The registry host machine. For UDP, the default is 255.255.255.255; "
"for TCP, a value is required", group="Registry")

def main(self):
if not self.host:
self.host = "::1" if self.ipv6 else "127.0.0.1"

if self.registry_type == "UDP":
if self.registry_host is None:
self.registry_host = "255.255.255.255"
self.registrar = UDPRegistryClient(ip=self.registry_host, port=self.registry_port)
else:
if self.registry_host is None:
raise ValueError("With TCP registry, you must specify --registry-host")
self.registrar = TCPRegistryClient(ip=self.registry_host, port=self.registry_port)

if self.ssl_keyfile:
self.authenticator = SSLAuthenticator(self.ssl_keyfile, self.ssl_certfile,
self.ssl_cafile)
default_port = DEFAULT_SERVER_SSL_PORT
else:
self.authenticator = None
default_port = DEFAULT_SERVER_PORT
if self.port is None:
self.port = default_port

setup_logger(self.quiet, self.logfile)

if self.mode == "threaded":
self._serve_mode(ThreadedServer)
elif self.mode == "forking":
self._serve_mode(ForkingServer)
elif self.mode == "oneshot":
self._serve_oneshot()
elif self.mode == "stdio":
self._serve_stdio()

def _serve_mode(self, factory):
t = factory(SlaveService, hostname=self.host, port=self.port,
reuse_addr=True, ipv6=self.ipv6, authenticator=self.authenticator,
registrar=self.registrar, auto_register=self.auto_register)
t.start()

def _serve_oneshot(self):
t = OneShotServer(SlaveService, hostname=self.host, port=self.port,
reuse_addr=True, ipv6=self.ipv6, authenticator=self.authenticator,
registrar=self.registrar, auto_register=self.auto_register)
t._listen()
sys.stdout.write("rpyc-oneshot\n")
sys.stdout.write(f"{t.host}\t{t.port}\n")
sys.stdout.flush()
t.start()

def _serve_stdio(self):
origstdin = sys.stdin
origstdout = sys.stdout
sys.stdin = open(os.devnull, "r")
sys.stdout = open(os.devnull, "w")
sys.stderr = open(os.devnull, "w")
conn = rpyc.classic.connect_pipes(origstdin, origstdout)
try:
try:
conn.serve_all()
except KeyboardInterrupt:
print("User interrupt!")
finally:
conn.close()
from rpyc.cli.rpyc_classic import *


if __name__ == "__main__":
ClassicServer.run()
main()
43 changes: 2 additions & 41 deletions bin/rpyc_registry.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,45 +1,6 @@
#!/usr/bin/env python
"""
The registry server listens to broadcasts on UDP port 18812, answering to
discovery queries by clients and registering keepalives from all running
servers. In order for clients to use discovery, a registry service must
be running somewhere on their local network.
"""
from plumbum import cli
from rpyc.utils.registry import REGISTRY_PORT, DEFAULT_PRUNING_TIMEOUT
from rpyc.utils.registry import UDPRegistryServer, TCPRegistryServer
from rpyc.lib import setup_logger


class RegistryServer(cli.Application):
mode = cli.SwitchAttr(["-m", "--mode"], cli.Set("UDP", "TCP"), default="UDP",
help="Serving mode")

ipv6 = cli.Flag(["-6", "--ipv6"], help="use ipv6 instead of ipv4")

port = cli.SwitchAttr(["-p", "--port"], cli.Range(0, 65535), default=REGISTRY_PORT,
help="The UDP/TCP listener port")

logfile = cli.SwitchAttr(["--logfile"], str, default=None,
help="The log file to use; the default is stderr")

quiet = cli.SwitchAttr(["-q", "--quiet"], help="Quiet mode (only errors are logged)")

pruning_timeout = cli.SwitchAttr(["-t", "--timeout"], int,
default=DEFAULT_PRUNING_TIMEOUT, help="Set a custom pruning timeout (in seconds)")

allow_listing = cli.SwitchAttr(["-l", "--listing"], bool, default=False, help="Enable/disable listing on registry")

def main(self):
if self.mode.upper() == "UDP":
server = UDPRegistryServer(host='::' if self.ipv6 else '0.0.0.0', port=self.port,
pruning_timeout=self.pruning_timeout, allow_listing=self.allow_listing)
elif self.mode.upper() == "TCP":
server = TCPRegistryServer(port=self.port, pruning_timeout=self.pruning_timeout,
allow_listing=self.allow_listing)
setup_logger(self.quiet, self.logfile)
server.start()
from rpyc.cli.rpyc_registry import *


if __name__ == "__main__":
RegistryServer.run()
main()
74 changes: 0 additions & 74 deletions bin/rpycd.py

This file was deleted.

2 changes: 1 addition & 1 deletion docs/docs/rpyc-release-process.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A walkthrough of doing a RPyC Release.
1. Ensure a clean and current build environment (i.e., ``git pull; git status``)
2. Describe commit history within ``CHANGELOG.rst`` (see `Generate Entry`_)
3. Update ``release_date`` in ``rpyc/version.py`` and bump version (`Semantic Versioning`_ and `Versioning using Hatch`_)
4. Verify changes and run ``git add .``, ``git push``, and ``export ver=$(python -c 'import rpyc; print(rpyc.__version__)')``.
4. Verify changes and run ``export ver=$(python -c 'import rpyc; print(rpyc.__version__)')``, ``git add .``, and ``git push``.
5. Create an Annotated tag: ``git tag -a ${ver} -m "Updated CHANGELOG.rst and version for release ${ver}"``
6. Publish release tag: ``git push origin ${ver}``
7. Install hatch: ``pyenv exec pip install hatch``
Expand Down
13 changes: 8 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,16 @@ dynamic = [
Homepage = "https://rpyc.readthedocs.org"
Source = "https://github.com/tomerfiliba-org/rpyc"

[project.scripts]
rpyc_classic = "rpyc.cli.rpyc_classic:main"
rpyc_registry = "rpyc.cli.rpyc_registry:main"

[tool.hatch.version]
path = "rpyc/version.py"

[tool.hatch.build.targets.sdist]
only-include = [
"/rpyc",
"/bin",
]
only-include = ["rpyc"]


[tool.hatch.build.targets.wheel]
packages = ["rpyc"]
only-include = ["rpyc"]
1 change: 1 addition & 0 deletions rpyc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@

from rpyc.lib import setup_logger, spawn
from rpyc.utils.server import OneShotServer, ThreadedServer, ThreadPoolServer, ForkingServer
from rpyc import cli

__author__ = "Tomer Filiba (tomerfiliba@gmail.com)"

Expand Down
1 change: 1 addition & 0 deletions rpyc/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from rpyc.cli import rpyc_classic, rpyc_registry

0 comments on commit 85b84ae

Please sign in to comment.