diff --git a/src/wormhole/scripts/runner.py b/src/wormhole/scripts/runner.py index d38cb22..1a70a9e 100644 --- a/src/wormhole/scripts/runner.py +++ b/src/wormhole/scripts/runner.py @@ -3,6 +3,7 @@ from textwrap import dedent from .. import public_relay from .. import __version__ from . import cmd_send_text, cmd_receive_text, cmd_send_file, cmd_receive_file +from ..servers import cmd_server parser = argparse.ArgumentParser( usage="wormhole SUBCOMMAND (subcommand-options)", @@ -26,11 +27,39 @@ subparsers = parser.add_subparsers(title="subcommands", dest="subcommand") +# CLI: run-server +s = subparsers.add_parser("server", description="Start/stop a relay server") +sp = s.add_subparsers(title="subcommands", dest="subcommand") +sp_start = sp.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("twistd_args", nargs="*", default=None, +# metavar="[TWISTD-ARGS..]", +# help=dedent("""\ +# Additional arguments to pass to twistd"""), +# ) +sp_start.set_defaults(func=cmd_server.start_server) +sp_stop = sp.add_parser("stop", description="Stop the relay server", + usage="wormhole server stop") +sp_stop.set_defaults(func=cmd_server.stop_server) +sp_restart = sp.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.set_defaults(func=cmd_server.restart_server) + +# CLI: send-text p = subparsers.add_parser("send-text", description="Send a text mesasge", usage="wormhole send-text TEXT") p.add_argument("text", metavar="TEXT", help="the message to send (a string)") p.set_defaults(func=cmd_send_text.send_text) +# CLI: receive-text p = subparsers.add_parser("receive-text", description="Receive a text message", usage="wormhole receive-text [CODE]") p.add_argument("code", nargs="?", default=None, metavar="[CODE]", @@ -40,11 +69,13 @@ p.add_argument("code", nargs="?", default=None, metavar="[CODE]", ) p.set_defaults(func=cmd_receive_text.receive_text) +# CLI: send-file p = subparsers.add_parser("send-file", description="Send a file", usage="wormhole send-file FILENAME") p.add_argument("filename", metavar="FILENAME", help="The file to be sent") p.set_defaults(func=cmd_send_file.send_file) +# CLI: receive-file p = subparsers.add_parser("receive-file", description="Receive a file", usage="wormhole receive-file [-o FILENAME] [CODE]") p.add_argument("-o", "--output-file", default=None, metavar="FILENAME", @@ -66,6 +97,7 @@ p.add_argument("code", nargs="?", default=None, metavar="[CODE]", p.set_defaults(func=cmd_receive_file.receive_file) + def run(args, stdout, stderr, executable=None): """This is invoked directly by the 'wormhole' entry-point script. It can also invoked by entry() below.""" diff --git a/src/wormhole/servers/__init__.py b/src/wormhole/servers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/wormhole/servers/cmd_server.py b/src/wormhole/servers/cmd_server.py new file mode 100644 index 0000000..ab21adf --- /dev/null +++ b/src/wormhole/servers/cmd_server.py @@ -0,0 +1,59 @@ +from __future__ import print_function +import os, time + +class MyPlugin: + tapname = "xyznode" + def __init__(self, args): + self.args = args + def makeService(self, so): + # delay this import as late as possible, to allow twistd's code to + # accept --reactor= selection + from .relay import RelayServer + return RelayServer(self.args.rendezvous, self.args.transit) + +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",) + twistd_args = ("XYZ",) # TODO: allow user to add twistd-specific args + c.parseOptions(twistd_args) + c.loadedPlugins = {"XYZ": MyPlugin(args)} + + print("starting wormhole relay server") + # this forks and never comes back. The parent calls os._exit(0) + twistd.runApp(c) + +def kill_server(): + try: + f = open("twistd.pid", "r") + except EnvironmentError: + print("Unable to find twistd.pid . Is this really a server directory?") + return 1 + pid = int(f.read().strip()) + f.close() + os.kill(pid, 15) + print("server process %d sent SIGTERM" % pid) + return 0 + +def stop_server(args): + return kill_server() + +def restart_server(args): + kill_server() + time.sleep(0.1) + timeout = 0 + while os.path.exists("twistd.pid") and timeout < 10: + if timeout == 0: + print(" waiting for shutdown..") + timeout += 1 + time.sleep(1) + if os.path.exists("twistd.pid"): + print("error: unable to shut down old server") + return 1 + print(" old server shut down") + start_server(args)