diff --git a/src/wormhole/scripts/runner.py b/src/wormhole/scripts/runner.py index 8cff151..b4fbd3f 100644 --- a/src/wormhole/scripts/runner.py +++ b/src/wormhole/scripts/runner.py @@ -5,22 +5,6 @@ from ..timing import DebugTiming from .cli_args import parser def dispatch(args): - if args.func == "server/start": - from ..servers import cmd_server - return cmd_server.start_server(args) - if args.func == "server/stop": - from ..servers import cmd_server - return cmd_server.stop_server(args) - if args.func == "server/restart": - from ..servers import cmd_server - return cmd_server.restart_server(args) - if args.func == "usage/usage": - from ..servers import cmd_usage - return cmd_usage.show_usage(args) - if args.func == "usage/tail": - from ..servers import cmd_usage - return cmd_usage.tail_usage(args) - if args.func == "send/send": from . import cmd_send return cmd_send.send_twisted_sync(args) diff --git a/src/wormhole_server/__init__.py b/src/wormhole_server/__init__.py index e69de29..0ff5129 100644 --- a/src/wormhole_server/__init__.py +++ b/src/wormhole_server/__init__.py @@ -0,0 +1,2 @@ +from wormhole import __version__ +__version__ # hush pyflakes diff --git a/src/wormhole_server/cli_args.py b/src/wormhole_server/cli_args.py new file mode 100644 index 0000000..f37946a --- /dev/null +++ b/src/wormhole_server/cli_args.py @@ -0,0 +1,64 @@ +import argparse +from textwrap import dedent +from wormhole import __version__ + +parser = argparse.ArgumentParser( + usage="wormhole-server SUBCOMMAND (subcommand-options)", + description=dedent(""" + Create a Magic Wormhole and communicate through it. Wormholes are created + by speaking the same magic CODE in two different places at the same time. + Wormholes are secure against anyone who doesn't use the same code."""), + ) + +parser.add_argument("--version", action="version", + version="magic-wormhole "+ __version__) +s = parser.add_subparsers(title="subcommands", dest="subcommand") + + +# CLI: run-server +sp_start = s.add_parser("start", description="Start a relay server", + usage="wormhole server start [opts] [TWISTD-ARGS..]") +sp_start.add_argument("--rendezvous", default="tcp:3000", metavar="tcp:PORT", + help="endpoint specification for the rendezvous port") +sp_start.add_argument("--transit", default="tcp:3001", metavar="tcp:PORT", + help="endpoint specification for the transit-relay port") +sp_start.add_argument("--advertise-version", metavar="VERSION", + help="version to recommend to clients") +sp_start.add_argument("--blur-usage", default=None, type=int, + metavar="SECONDS", + help="round logged access times to improve privacy") +sp_start.add_argument("-n", "--no-daemon", action="store_true") +#sp_start.add_argument("twistd_args", nargs="*", default=None, +# metavar="[TWISTD-ARGS..]", +# help=dedent("""\ +# Additional arguments to pass to twistd"""), +# ) +sp_start.set_defaults(func="server/start") + +sp_stop = s.add_parser("stop", description="Stop the relay server", + usage="wormhole server stop") +sp_stop.set_defaults(func="server/stop") + +sp_restart = s.add_parser("restart", description="Restart the relay server", + usage="wormhole server restart") +sp_restart.add_argument("--rendezvous", default="tcp:3000", metavar="tcp:PORT", + help="endpoint specification for the rendezvous port") +sp_restart.add_argument("--transit", default="tcp:3001", metavar="tcp:PORT", + help="endpoint specification for the transit-relay port") +sp_restart.add_argument("--advertise-version", metavar="VERSION", + help="version to recommend to clients") +sp_restart.add_argument("--blur-usage", default=None, type=int, + metavar="SECONDS", + help="round logged access times to improve privacy") +sp_restart.add_argument("-n", "--no-daemon", action="store_true") +sp_restart.set_defaults(func="server/restart") + +sp_show_usage = s.add_parser("show-usage", description="Display usage data", + usage="wormhole server show-usage") +sp_show_usage.add_argument("-n", default=100, type=int, + help="show last N entries") +sp_show_usage.set_defaults(func="usage/usage") + +sp_tail_usage = s.add_parser("tail-usage", description="Follow latest usage", + usage="wormhole server tail-usage") +sp_tail_usage.set_defaults(func="usage/tail") diff --git a/src/wormhole_server/cmd_server.py b/src/wormhole_server/cmd_server.py index a42267b..938d451 100644 --- a/src/wormhole_server/cmd_server.py +++ b/src/wormhole_server/cmd_server.py @@ -1,5 +1,7 @@ from __future__ import print_function import os, time +from twisted.python import usage +from twisted.scripts import twistd class MyPlugin: tapname = "xyznode" @@ -13,13 +15,10 @@ class MyPlugin: self.args.advertise_version, "relay.sqlite", self.args.blur_usage) +class MyTwistdConfig(twistd.ServerOptions): + subCommands = [("XYZ", None, usage.Options, "node")] + def start_server(args): - from twisted.python import usage - from twisted.scripts import twistd - - class MyTwistdConfig(twistd.ServerOptions): - subCommands = [("XYZ", None, usage.Options, "node")] - c = MyTwistdConfig() #twistd_args = tuple(args.twistd_args) + ("XYZ",) base_args = [] diff --git a/src/wormhole_server/cmd_usage.py b/src/wormhole_server/cmd_usage.py index 5b983d2..e021206 100644 --- a/src/wormhole_server/cmd_usage.py +++ b/src/wormhole_server/cmd_usage.py @@ -1,8 +1,8 @@ from __future__ import print_function import os, time from collections import defaultdict -from ..database import get_db -from ..errors import UsageError +from .database import get_db +from wormhole.errors import UsageError def abbrev(t): if t is None: diff --git a/src/wormhole_server/database.py b/src/wormhole_server/database.py index d9a52d8..66ed1d0 100644 --- a/src/wormhole_server/database.py +++ b/src/wormhole_server/database.py @@ -6,7 +6,8 @@ class DBError(Exception): pass def get_schema(version): - schema_bytes = resource_string("wormhole", "db-schemas/v%d.sql" % version) + schema_bytes = resource_string("wormhole_server", + "db-schemas/v%d.sql" % version) return schema_bytes.decode("utf-8") def get_db(dbfile, stderr=sys.stderr): diff --git a/src/wormhole_server/runner.py b/src/wormhole_server/runner.py new file mode 100644 index 0000000..58f413a --- /dev/null +++ b/src/wormhole_server/runner.py @@ -0,0 +1,56 @@ +from __future__ import print_function +import os, sys +from .cli_args import parser + +def dispatch(args): + if args.func == "server/start": + from . import cmd_server + return cmd_server.start_server(args) + if args.func == "server/stop": + from . import cmd_server + return cmd_server.stop_server(args) + if args.func == "server/restart": + from . import cmd_server + return cmd_server.restart_server(args) + if args.func == "usage/usage": + from . import cmd_usage + return cmd_usage.show_usage(args) + if args.func == "usage/tail": + from . import cmd_usage + return cmd_usage.tail_usage(args) + + raise ValueError("unknown args.func %s" % args.func) + +def run(args, cwd, stdout, stderr, executable=None): + """This is invoked directly by the 'wormhole-server' entry-point script. + It can also invoked by entry() below.""" + + args = parser.parse_args() + if not getattr(args, "func", None): + # So far this only works on py3. py2 exits with a really terse + # "error: too few arguments" during parse_args(). + parser.print_help() + sys.exit(0) + args.cwd = cwd + args.stdout = stdout + args.stderr = stderr + + try: + rc = dispatch(args) + return rc + except ImportError as e: + print("--- ImportError ---", file=stderr) + print(e, file=stderr) + print("Please run 'python setup.py build'", file=stderr) + raise + return 1 + +def entry(): + """This is used by a setuptools entry_point. When invoked this way, + setuptools has already put the installed package on sys.path .""" + return run(sys.argv[1:], os.getcwd(), sys.stdout, sys.stderr, + executable=sys.argv[0]) + +if __name__ == "__main__": + args = parser.parse_args() + print(args) diff --git a/src/wormhole_server/server.py b/src/wormhole_server/server.py index 1bfee9a..321ee27 100644 --- a/src/wormhole_server/server.py +++ b/src/wormhole_server/server.py @@ -3,9 +3,9 @@ from twisted.python import log from twisted.internet import reactor, endpoints from twisted.application import service from twisted.web import server, static, resource -from ..util.endpoint_service import ServerEndpointService -from .. import __version__ -from ..database import get_db +from .endpoint_service import ServerEndpointService +from wormhole import __version__ +from .database import get_db from .relay_server import Relay from .transit_server import Transit