diff --git a/artiq/frontend/artiq_ctlmgr.py b/artiq/frontend/artiq_ctlmgr.py index 9c672d187..f73bbde87 100755 --- a/artiq/frontend/artiq_ctlmgr.py +++ b/artiq/frontend/artiq_ctlmgr.py @@ -15,7 +15,7 @@ from artiq.protocols.pc_rpc import AsyncioClient, Server from artiq.protocols.logging import (LogForwarder, parse_log_message, log_with_name, SourceFilter) -from artiq.tools import TaskObject, Condition, atexit_register_coroutine +from artiq.tools import * logger = logging.getLogger(__name__) @@ -284,12 +284,7 @@ def get_argparser(): parser.add_argument( "--retry-master", default=5.0, type=float, help="retry timer for reconnecting to master") - parser.add_argument( - "--bind", default="::1", - help="hostname or IP address to bind to") - parser.add_argument( - "--bind-port", default=3249, type=int, - help="TCP port to listen to for control (default: %(default)d)") + simple_network_args(parser, [("control", "control", 3249)]) return parser @@ -330,7 +325,8 @@ def main(): rpc_target = CtlMgrRPC() rpc_server = Server({"ctlmgr": rpc_target}, builtin_terminate=True) - loop.run_until_complete(rpc_server.start(args.bind, args.bind_port)) + loop.run_until_complete(rpc_server.start(bind_address_from_args(args), + args.port_control)) atexit_register_coroutine(rpc_server.stop) loop.run_until_complete(rpc_server.wait_terminate()) diff --git a/artiq/frontend/artiq_influxdb.py b/artiq/frontend/artiq_influxdb.py index 5fa189a97..2b5997a91 100755 --- a/artiq/frontend/artiq_influxdb.py +++ b/artiq/frontend/artiq_influxdb.py @@ -45,15 +45,10 @@ def get_argparser(): group.add_argument( "--table", default="lab", help="table name to use") group = parser.add_argument_group("filter") - group.add_argument( - "--bind", default="::1", - help="hostname or IP address to bind to") - group.add_argument( - "--bind-port", default=3248, type=int, - help="TCP port to listen to for control (default: %(default)d)") group.add_argument( "--pattern-file", default="influxdb_patterns.pyon", help="file to save the patterns in (default: %(default)s)") + simple_network_args(parser, [("control", "control", 3248)]) verbosity_args(parser) return parser @@ -248,7 +243,8 @@ def main(): filter = Filter(args.pattern_file) rpc_server = Server({"influxdb_filter": filter}, builtin_terminate=True) - loop.run_until_complete(rpc_server.start(args.bind, args.bind_port)) + loop.run_until_complete(rpc_server.start(bind_address_from_args(args), + args.port_control)) atexit_register_coroutine(rpc_server.stop) reader = MasterReader(args.server_master, args.port_master, diff --git a/artiq/frontend/artiq_master.py b/artiq/frontend/artiq_master.py index da421a4a3..54b4a5670 100755 --- a/artiq/frontend/artiq_master.py +++ b/artiq/frontend/artiq_master.py @@ -5,7 +5,7 @@ import argparse import atexit import os -from artiq.tools import atexit_register_coroutine +from artiq.tools import * from artiq.protocols.pc_rpc import Server as RPCServer from artiq.protocols.sync_struct import Publisher from artiq.protocols.logging import Server as LoggingServer @@ -19,19 +19,11 @@ from artiq.master.experiments import FilesystemBackend, GitBackend, ExperimentDB def get_argparser(): parser = argparse.ArgumentParser(description="ARTIQ master") - group = parser.add_argument_group("network") - group.add_argument( - "--bind", default="::1", - help="hostname or IP address to bind to") - group.add_argument( - "--port-notify", default=3250, type=int, - help="TCP port to listen to for notifications (default: %(default)d)") - group.add_argument( - "--port-control", default=3251, type=int, - help="TCP port to listen to for control (default: %(default)d)") - group.add_argument( - "--port-logging", default=1066, type=int, - help="TCP port to listen to for remote logging (default: %(default)d)") + simple_network_args(parser, [ + ("notify", "notifications", 3250), + ("control", "control", 3251), + ("logging", "remote logging", 1066) + ]) group = parser.add_argument_group("databases") group.add_argument("--device-db", default="device_db.pyon", @@ -93,6 +85,8 @@ def main(): scheduler.start() atexit_register_coroutine(scheduler.stop) + bind = bind_address_from_args(args) + server_control = RPCServer({ "master_device_db": device_db, "master_dataset_db": dataset_db, @@ -100,7 +94,7 @@ def main(): "master_experiment_db": experiment_db }) loop.run_until_complete(server_control.start( - args.bind, args.port_control)) + bind, args.port_control)) atexit_register_coroutine(server_control.stop) server_notify = Publisher({ @@ -111,12 +105,12 @@ def main(): "log": log_buffer.data }) loop.run_until_complete(server_notify.start( - args.bind, args.port_notify)) + bind, args.port_notify)) atexit_register_coroutine(server_notify.stop) server_logging = LoggingServer() loop.run_until_complete(server_logging.start( - args.bind, args.port_logging)) + bind, args.port_logging)) atexit_register_coroutine(server_logging.stop) loop.run_forever() diff --git a/artiq/frontend/lda_controller.py b/artiq/frontend/lda_controller.py index 78b0b28f2..db677bccc 100755 --- a/artiq/frontend/lda_controller.py +++ b/artiq/frontend/lda_controller.py @@ -4,7 +4,7 @@ import argparse from artiq.devices.lda.driver import Lda, Ldasim from artiq.protocols.pc_rpc import simple_server_loop -from artiq.tools import verbosity_args, simple_network_args, init_logger +from artiq.tools import * def get_argparser(): @@ -36,7 +36,7 @@ def main(): lda = Lda(args.device, args.product) try: simple_server_loop({"lda": lda}, - args.bind, args.port) + bind_address_from_args(args), args.port) finally: lda.close() diff --git a/artiq/frontend/novatech409b_controller.py b/artiq/frontend/novatech409b_controller.py index 1f74a8a1e..f654a9849 100755 --- a/artiq/frontend/novatech409b_controller.py +++ b/artiq/frontend/novatech409b_controller.py @@ -8,7 +8,7 @@ import sys from artiq.devices.novatech409b.driver import Novatech409B from artiq.protocols.pc_rpc import simple_server_loop -from artiq.tools import verbosity_args, simple_network_args, init_logger +from artiq.tools import * logger = logging.getLogger(__name__) @@ -40,7 +40,7 @@ def main(): dev = Novatech409B(args.device if not args.simulation else None) try: simple_server_loop( - {"novatech409b": dev}, args.bind, args.port) + {"novatech409b": dev}, bind_address_from_args(args), args.port) finally: dev.close() diff --git a/artiq/frontend/pdq2_controller.py b/artiq/frontend/pdq2_controller.py index c8fdd0684..e8b9a77c1 100755 --- a/artiq/frontend/pdq2_controller.py +++ b/artiq/frontend/pdq2_controller.py @@ -5,7 +5,7 @@ import sys from artiq.devices.pdq2.driver import Pdq2 from artiq.protocols.pc_rpc import simple_server_loop -from artiq.tools import verbosity_args, init_logger, simple_network_args +from artiq.tools import * def get_argparser(): @@ -38,7 +38,7 @@ def main(): port = open(args.dump, "wb") dev = Pdq2(url=args.device, dev=port) try: - simple_server_loop({"pdq2": dev}, args.bind, args.port, + simple_server_loop({"pdq2": dev}, bind_address_from_args(args), args.port, description="device=" + str(args.device)) finally: dev.close() diff --git a/artiq/frontend/pxi6733_controller.py b/artiq/frontend/pxi6733_controller.py index 54dca78b1..b0270f2a6 100755 --- a/artiq/frontend/pxi6733_controller.py +++ b/artiq/frontend/pxi6733_controller.py @@ -6,7 +6,7 @@ import sys from artiq.protocols.pc_rpc import simple_server_loop from artiq.devices.pxi6733.driver import DAQmx, DAQmxSim -from artiq.tools import verbosity_args, init_logger, simple_network_args +from artiq.tools import * def get_argparser(): @@ -40,7 +40,7 @@ def main(): try: simple_server_loop({"pxi6733": daq}, - args.bind, args.port) + bind_address_from_args(args), args.port) finally: daq.close() diff --git a/artiq/frontend/thorlabs_tcube_controller.py b/artiq/frontend/thorlabs_tcube_controller.py index 59abe1ff9..6323e1f76 100755 --- a/artiq/frontend/thorlabs_tcube_controller.py +++ b/artiq/frontend/thorlabs_tcube_controller.py @@ -5,7 +5,7 @@ import sys from artiq.devices.thorlabs_tcube.driver import Tdc, Tpz, TdcSim, TpzSim from artiq.protocols.pc_rpc import simple_server_loop -from artiq.tools import verbosity_args, simple_network_args, init_logger +from artiq.tools import * def get_argparser(): @@ -54,7 +54,8 @@ def main(): sys.exit(1) try: - simple_server_loop({product: dev}, args.bind, args.port) + simple_server_loop({product: dev}, + bind_address_from_args(args), args.port) finally: dev.close() diff --git a/artiq/tools.py b/artiq/tools.py index 445399a1b..d589afadf 100644 --- a/artiq/tools.py +++ b/artiq/tools.py @@ -18,7 +18,8 @@ from artiq.protocols import pyon __all__ = ["artiq_dir", "parse_arguments", "elide", "short_format", "file_import", "get_experiment", "verbosity_args", "simple_network_args", "init_logger", - "atexit_register_coroutine", "exc_to_warning", "asyncio_wait_or_cancel", + "bind_address_from_args", "atexit_register_coroutine", + "exc_to_warning", "asyncio_wait_or_cancel", "TaskObject", "Condition", "get_windows_drives"] @@ -117,17 +118,34 @@ def verbosity_args(parser): def simple_network_args(parser, default_port): - group = parser.add_argument_group("network") - group.add_argument("--bind", default="::1", - help="hostname or IP address to bind to") - group.add_argument("-p", "--port", default=default_port, type=int, - help="TCP port to listen to (default: %(default)d)") - + group = parser.add_argument_group("network server") + group.add_argument( + "--bind", default=[], action="append", + help="add an hostname or IP address to bind to") + group.add_argument( + "--no-localhost-bind", default=False, action="store_true", + help="do not implicitly bind to localhost addresses") + if isinstance(default_port, int): + group.add_argument("-p", "--port", default=default_port, type=int, + help="TCP port to listen to (default: %(default)d)") + else: + for name, purpose, default in default_port: + h = ("TCP port to listen to for {} (default: {})" + .format(purpose, default)) + group.add_argument("--port-" + name, default=default, type=int, + help=h) def init_logger(args): logging.basicConfig(level=logging.WARNING + args.quiet*10 - args.verbose*10) +def bind_address_from_args(args): + if args.no_localhost_bind: + return args.bind + else: + return ["127.0.0.1", "::1"] + args.bind + + def atexit_register_coroutine(coroutine, loop=None): if loop is None: loop = asyncio.get_event_loop()