From 1ec61f8f7d75626ba0b7964277b53df3e5b3ae2c Mon Sep 17 00:00:00 2001 From: Hannes Feldt <feldt@astron.nl> Date: Tue, 30 Apr 2024 06:38:12 +0000 Subject: [PATCH] L2SS-1710: Central Monitor Lobster Migration --- .editorconfig | 3 + .gitignore | 2 + .gitlab-ci.yml | 1 + README.md | 1 + infra/jobs/station/rpc-server.levant.nomad | 42 ++++++++++++++ tangostationcontrol/VERSION | 2 +- tangostationcontrol/proto/observation.proto | 18 ++++++ tangostationcontrol/requirements.txt | 2 + tangostationcontrol/setup.cfg | 1 + .../tangostationcontrol/rpc/__init__.py | 0 .../rpc/_proto/__init__.py | 0 .../tangostationcontrol/rpc/server.py | 57 +++++++++++++++++++ tangostationcontrol/tox.ini | 4 +- 13 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 infra/jobs/station/rpc-server.levant.nomad create mode 100644 tangostationcontrol/proto/observation.proto create mode 100644 tangostationcontrol/tangostationcontrol/rpc/__init__.py create mode 100644 tangostationcontrol/tangostationcontrol/rpc/_proto/__init__.py create mode 100644 tangostationcontrol/tangostationcontrol/rpc/server.py diff --git a/.editorconfig b/.editorconfig index dba68101b..df0525fcb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -149,3 +149,6 @@ ij_yaml_spaces_within_brackets = true [{*.hcl,*.hcl.tmpl,*.nomad,*.hcl.j2}] indent_size = 2 + +[*.proto] +indent_size = 2 diff --git a/.gitignore b/.gitignore index e653de55b..d6ac0c2e4 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ **/vscode-server.tar **/*.orig **/venv +**/*_pb2.* +**/*_pb2_grpc.* tangostationcontrol/build tangostationcontrol/cover diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 848c5c00b..f293ca1a0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -391,6 +391,7 @@ deploy_nomad: - jupyter - snmp-exporter - landing-page + - rpc-server environment: name: $STATION script: diff --git a/README.md b/README.md index 743942ee2..19f96a99e 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ Next change the version in the following places: # Release Notes +* 0.34.0 Add gRPC based 'external' station control service * 0.33.3 Add support for new PCON devices (ACX) * 0.33.2 Fix for XSTs in Observations: Also write FPGA_xst_nof_crosslets_RW * 0.33.1 SDPFirmware: replace FPGA_ucp monitoring points with new TR_ucp ones diff --git a/infra/jobs/station/rpc-server.levant.nomad b/infra/jobs/station/rpc-server.levant.nomad new file mode 100644 index 000000000..2ff5431b8 --- /dev/null +++ b/infra/jobs/station/rpc-server.levant.nomad @@ -0,0 +1,42 @@ +job "rpc-server" { + datacenters = ["stat"] + type = "service" + reschedule { + unlimited = true + delay = "30s" + delay_function = "constant" + } + group "station-rpc" { + network { + mode = "bridge" + + port "grpc" { + static = "50051" + host_network = "external" + } + } + + service { + name = "rpc" + port = "grpc" + } + + task "l2ss-rpc-server" { + driver = "docker" + + config { + image = "[[ $.registry.astron.url ]]/lofar-device-base:[[ $.image_tag ]]" + entrypoint = [""] + command = "l2ss-rpc-server" + } + env { + TANGO_HOST = "tango.service.consul:10000" + } + + resources { + cpu = 25 + memory = 512 + } + } + } +} diff --git a/tangostationcontrol/VERSION b/tangostationcontrol/VERSION index 90d7d2b46..85e60ed18 100644 --- a/tangostationcontrol/VERSION +++ b/tangostationcontrol/VERSION @@ -1 +1 @@ -0.33.3 +0.34.0 diff --git a/tangostationcontrol/proto/observation.proto b/tangostationcontrol/proto/observation.proto new file mode 100644 index 000000000..3a08fe61c --- /dev/null +++ b/tangostationcontrol/proto/observation.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +service Observation { + rpc StartObservation(StartObservationRequest) returns (ObservationReply){} + rpc StopObservation(StopObservationRequest) returns (ObservationReply) {} +} + +message StartObservationRequest { + string configuration = 1; +} +message StopObservationRequest { + int64 observation_id = 1; +} + +message ObservationReply { + bool success = 1; + string exception = 2; +} diff --git a/tangostationcontrol/requirements.txt b/tangostationcontrol/requirements.txt index d6d27e18c..6b628f3e0 100644 --- a/tangostationcontrol/requirements.txt +++ b/tangostationcontrol/requirements.txt @@ -23,3 +23,5 @@ prometheus-client # Apache 2 dnspython # ISC logfmter # MIT psutil >= 5.4.6 # BSD3 +grpcio # Apache 2 +grpcio-tools # Apache 2 diff --git a/tangostationcontrol/setup.cfg b/tangostationcontrol/setup.cfg index f9594fe96..4779dcb7c 100644 --- a/tangostationcontrol/setup.cfg +++ b/tangostationcontrol/setup.cfg @@ -35,6 +35,7 @@ console_scripts = l2ss-analyse-dsconfig-hierarchies = tangostationcontrol.toolkit.analyse_dsconfig_hierarchies:main l2ss-version = tangostationcontrol:print_version l2ss-health = tangostationcontrol.common.health:main + l2ss-rpc-server = tangostationcontrol.rpc.server:main # The following entry points should eventually be removed / replaced l2ss-hardware-device-template = tangostationcontrol.examples.HW_device_template:main diff --git a/tangostationcontrol/tangostationcontrol/rpc/__init__.py b/tangostationcontrol/tangostationcontrol/rpc/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tangostationcontrol/tangostationcontrol/rpc/_proto/__init__.py b/tangostationcontrol/tangostationcontrol/rpc/_proto/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tangostationcontrol/tangostationcontrol/rpc/server.py b/tangostationcontrol/tangostationcontrol/rpc/server.py new file mode 100644 index 000000000..23a220bbe --- /dev/null +++ b/tangostationcontrol/tangostationcontrol/rpc/server.py @@ -0,0 +1,57 @@ +from concurrent import futures + +import grpc +import logging + +from ._proto import observation_pb2 +from ._proto import observation_pb2_grpc +from tangostationcontrol.common.lofar_logging import configure_logger, exception_to_str +from tangostationcontrol.common.proxy import create_proxy + +logger = logging.getLogger() + +TIMEOUT = 5000 +PORT = 50051 + + +class Observation(observation_pb2_grpc.ObservationServicer): + def StartObservation( + self, request: observation_pb2.StartObservationRequest, context + ): + logger.info("Start observation") + try: + observation_control = create_proxy("STAT/ObservationControl/1", TIMEOUT) + observation_control.add_observation(request.configuration) + return observation_pb2.ObservationReply(success=True) + except Exception as e: + logger.exception(f"Starting observation failed: {exception_to_str(e)}") + return observation_pb2.ObservationReply( + success=False, exception=exception_to_str(e) + ) + + def StopObservation(self, request: observation_pb2.StopObservationRequest, context): + logger.info(f"Stop observation {request.observation_id}") + try: + observation_control = create_proxy("STAT/ObservationControl/1", TIMEOUT) + observation_control.stop_observation_now(request.observation_id) + return observation_pb2.ObservationReply(success=True) + except Exception as e: + logger.exception(f"Stopping observation failed: {exception_to_str(e)}") + return observation_pb2.ObservationReply( + success=False, exception=exception_to_str(e) + ) + + +def main(): + configure_logger() + logger.info(f"Start server on insecure port 0.0.0.0:{PORT}") + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + observation_pb2_grpc.add_ObservationServicer_to_server(Observation(), server) + server.add_insecure_port(f"0.0.0.0:{PORT}") + server.start() + logger.info(f"Server started, listening on port {PORT}") + server.wait_for_termination() + + +if __name__ == "__main__": + main() diff --git a/tangostationcontrol/tox.ini b/tangostationcontrol/tox.ini index 499efc4f5..79aa5947d 100644 --- a/tangostationcontrol/tox.ini +++ b/tangostationcontrol/tox.ini @@ -94,7 +94,9 @@ commands = [testenv:build] usedevelop = False -commands = {envpython} -m build +commands = + {envpython} -m grpc_tools.protoc -Itangostationcontrol/rpc/_proto=proto --python_out=. --pyi_out=. --grpc_python_out=. proto/observation.proto + {envpython} -m build [testenv:docs] envdir = {toxworkdir}/docs -- GitLab