From 11793e6c443dd9a452fe372e0715a5786c376b5d Mon Sep 17 00:00:00 2001 From: stedif <stefano.difrischia@inaf.it> Date: Mon, 24 Oct 2022 11:59:39 +0200 Subject: [PATCH] L2SS-1030: create skeleton for configuration device --- .gitlab-ci.yml | 26 ++++++--- CDB/LOFAR_ConfigDb.json | 7 +++ docker-compose/device-configuration.yml | 53 +++++++++++++++++++ .../startup/01-devices.py | 3 +- .../startup/01-devices.py | 3 +- .../lofar2-policy.json | 2 + sbin/run_integration_test.sh | 2 +- sbin/tag_and_push_docker_image.sh | 1 + .../docs/source/devices/configuration.rst | 7 +++ tangostationcontrol/docs/source/index.rst | 1 + tangostationcontrol/setup.cfg | 1 + .../tangostationcontrol/devices/README.md | 2 +- .../tangostationcontrol/devices/boot.py | 1 + .../devices/configuration_device.py | 8 +++ .../devices/docker_device.py | 2 + .../devices/test_device_configuration.py | 16 ++++++ 16 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 docker-compose/device-configuration.yml create mode 100644 tangostationcontrol/docs/source/devices/configuration.rst create mode 100644 tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_configuration.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 82cbc3f55..f86c6aae2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -106,26 +106,27 @@ docker_build_image_all: - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh recv-sim latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh sdptr-sim latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh unb2-sim latest + - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-antennafield latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apsct latest - - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-ccd latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apspu latest - - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-tilebeam latest + - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-boot latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-beamlet latest + - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-ccd latest + - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-configuration latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-digitalbeam latest - - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-antennafield latest - - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-boot latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-docker latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-observation latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-observation-control latest - - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-psoc latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-pcon latest + - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-psoc latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-recv latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-sdp latest + - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-temperature-manager latest + - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-tilebeam latest + - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-unb2 latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-bst latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-sst latest - - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-unb2 latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-xst latest - - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-temperature-manager latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh archiver-timescale latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh hdbpp latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh hdbppts-cm latest @@ -310,6 +311,17 @@ docker_build_image_device_ccd: script: # Do not remove 'bash' or statement will be ignored by primitive docker shell - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-ccd $tag +docker_build_image_device_configuration: + extends: .base_docker_images_except + only: + refs: + - merge_requests + changes: + - docker-compose/device-configuration.yml + - docker-compose/lofar-device-base/* + script: +# Do not remove 'bash' or statement will be ignored by primitive docker shell + - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-configuration $tag docker_build_image_device_apspu: extends: .base_docker_images_except only: diff --git a/CDB/LOFAR_ConfigDb.json b/CDB/LOFAR_ConfigDb.json index b2d2f517e..0370c7c90 100644 --- a/CDB/LOFAR_ConfigDb.json +++ b/CDB/LOFAR_ConfigDb.json @@ -17,6 +17,13 @@ } } }, + "Configuration": { + "STAT": { + "Configuration": { + "STAT/Configuration/1": {} + } + } + }, "Observation": { "STAT": { "Observation": { diff --git a/docker-compose/device-configuration.yml b/docker-compose/device-configuration.yml new file mode 100644 index 000000000..3a7f1a624 --- /dev/null +++ b/docker-compose/device-configuration.yml @@ -0,0 +1,53 @@ +# +# Docker compose file that launches an interactive iTango session. +# +# Connect to the interactive session with 'docker attach itango'. +# Disconnect with the Docker deattach sequence: <CTRL>+<P> <CTRL>+<Q> +# +# Defines: +# - itango: iTango interactive session +# +# Requires: +# - lofar-device-base.yml +# +version: '3' + +services: + device-configuration: + image: device-configuration + # build explicitly, as docker-compose does not understand a local image + # being shared among services. + build: + context: . + dockerfile: lofar-device-base/Dockerfile + args: + SOURCE_IMAGE: ${LOCAL_DOCKER_REGISTRY_HOST}/${LOCAL_DOCKER_REGISTRY_USER}/tango-itango:${TANGO_ITANGO_VERSION} + container_name: ${CONTAINER_NAME_PREFIX}device-configuration + logging: + driver: "json-file" + options: + max-size: "100m" + max-file: "10" + networks: + - control + ports: + - "5722:5722" # unique port for this DS + - "5822:5822" # ZeroMQ event port + - "5922:5922" # ZeroMQ heartbeat port + extra_hosts: + - "host.docker.internal:host-gateway" + volumes: + - ..:/opt/lofar/tango:rw + environment: + - TANGO_HOST=${TANGO_HOST} + - TANGO_ZMQ_EVENT_PORT=5822 + - TANGO_ZMQ_HEARTBEAT_PORT=5922 + working_dir: /opt/lofar/tango + entrypoint: + - bin/start-ds.sh + # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA + # can't know about our Docker port forwarding + - l2ss-configuration-device Configuration STAT -v -ORBendPoint giop:tcp:device-configuration:5722 -ORBendPointPublish giop:tcp:${HOSTNAME}:5722 + restart: on-failure + stop_signal: SIGINT # request a graceful shutdown of Tango + stop_grace_period: 2s diff --git a/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py b/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py index 350ecb1e8..4b33c8132 100644 --- a/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py +++ b/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py @@ -16,6 +16,7 @@ digitalbeam = DeviceProxy("STAT/DigitalBeam/1") antennafield = DeviceProxy("STAT/AntennaField/1") docker = DeviceProxy("STAT/Docker/1") temperaturemanager = DeviceProxy("STAT/TemperatureManager/1") +configuration = DeviceProxy("STAT/Configuration/1") # Put them in a list in case one wants to iterate -devices = [apsct, ccd, apspu, recv, sdp, bst, sst, xst, unb2, boot, tilebeam, beamlet, digitalbeam, antennafield, temperaturemanager, docker] +devices = [apsct, ccd, apspu, recv, sdp, bst, sst, xst, unb2, boot, tilebeam, beamlet, digitalbeam, antennafield, temperaturemanager, docker, configuration] diff --git a/docker-compose/jupyterlab/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py b/docker-compose/jupyterlab/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py index 350ecb1e8..4b33c8132 100644 --- a/docker-compose/jupyterlab/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py +++ b/docker-compose/jupyterlab/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py @@ -16,6 +16,7 @@ digitalbeam = DeviceProxy("STAT/DigitalBeam/1") antennafield = DeviceProxy("STAT/AntennaField/1") docker = DeviceProxy("STAT/Docker/1") temperaturemanager = DeviceProxy("STAT/TemperatureManager/1") +configuration = DeviceProxy("STAT/Configuration/1") # Put them in a list in case one wants to iterate -devices = [apsct, ccd, apspu, recv, sdp, bst, sst, xst, unb2, boot, tilebeam, beamlet, digitalbeam, antennafield, temperaturemanager, docker] +devices = [apsct, ccd, apspu, recv, sdp, bst, sst, xst, unb2, boot, tilebeam, beamlet, digitalbeam, antennafield, temperaturemanager, docker, configuration] diff --git a/docker-compose/tango-prometheus-exporter/lofar2-policy.json b/docker-compose/tango-prometheus-exporter/lofar2-policy.json index 606f06499..bfb587489 100644 --- a/docker-compose/tango-prometheus-exporter/lofar2-policy.json +++ b/docker-compose/tango-prometheus-exporter/lofar2-policy.json @@ -17,6 +17,8 @@ }, "stat/ccd/1": { }, + "stat/configuration/1": { + }, "stat/apspu/1": { }, "stat/beamlet/1": { diff --git a/sbin/run_integration_test.sh b/sbin/run_integration_test.sh index 563b2c7fb..ffd18c715 100755 --- a/sbin/run_integration_test.sh +++ b/sbin/run_integration_test.sh @@ -76,7 +76,7 @@ sleep 1 # dsconfig container must be up and running... # shellcheck disable=SC2016 echo '/usr/local/bin/wait-for-it.sh ${TANGO_HOST} --strict --timeout=300 -- true' | make run dsconfig bash - -DEVICES="device-boot device-apsct device-ccd device-apspu device-sdp device-recv device-bst device-sst device-unb2 device-xst device-beamlet device-digitalbeam device-tilebeam device-psoc device-pcon device-antennafield device-temperature-manager device-observation device-observation-control" +DEVICES="device-boot device-apsct device-ccd device-apspu device-sdp device-recv device-bst device-sst device-unb2 device-xst device-beamlet device-digitalbeam device-tilebeam device-psoc device-pcon device-antennafield device-temperature-manager device-observation device-observation-control device-configuration" SIMULATORS="sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim ccd-sim" diff --git a/sbin/tag_and_push_docker_image.sh b/sbin/tag_and_push_docker_image.sh index d3b5ea894..c785e4c8f 100755 --- a/sbin/tag_and_push_docker_image.sh +++ b/sbin/tag_and_push_docker_image.sh @@ -72,6 +72,7 @@ LOCAL_IMAGES=( "device-antennafield device-antennafield y" "device-apsct device-apsct y" "device-apspu device-apspu y" "device-ccd device-ccd y" + "device-configuration device-configuration y" "device-boot device-boot y" "device-docker device-docker y" "device-observation device-observation y" "device-observation-control device-observation-control y" diff --git a/tangostationcontrol/docs/source/devices/configuration.rst b/tangostationcontrol/docs/source/devices/configuration.rst new file mode 100644 index 000000000..65f8c0280 --- /dev/null +++ b/tangostationcontrol/docs/source/devices/configuration.rst @@ -0,0 +1,7 @@ +.. _configuration: + +Configuration +-------------------- + +The ``Configuration == DeviceProxy("STAT/Configuration/1")`` Configuration Device controls the loading, updating, exposing +and dumping of the whole Station Configuration diff --git a/tangostationcontrol/docs/source/index.rst b/tangostationcontrol/docs/source/index.rst index 4c56206df..250804f4e 100644 --- a/tangostationcontrol/docs/source/index.rst +++ b/tangostationcontrol/docs/source/index.rst @@ -30,6 +30,7 @@ Even without having access to any LOFAR2.0 hardware, you can install the full st devices/docker devices/psoc devices/ccd + devices/configuration devices/temperature-manager devices/configure configure_station diff --git a/tangostationcontrol/setup.cfg b/tangostationcontrol/setup.cfg index f42357ef7..36318820c 100644 --- a/tangostationcontrol/setup.cfg +++ b/tangostationcontrol/setup.cfg @@ -56,6 +56,7 @@ console_scripts = l2ss-unb2 = tangostationcontrol.devices.unb2:main l2ss-xst = tangostationcontrol.devices.sdp.xst:main l2ss-temperature-manager = tangostationcontrol.devices.temperature_manager:main + l2ss-configuration-device = tangostationcontrol.devices.configuration_device: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/devices/README.md b/tangostationcontrol/tangostationcontrol/devices/README.md index 64390631b..0a1081baa 100644 --- a/tangostationcontrol/tangostationcontrol/devices/README.md +++ b/tangostationcontrol/tangostationcontrol/devices/README.md @@ -9,7 +9,7 @@ If a new device is added, it will (likely) need to be referenced in several plac - Adjust `CDB/LOFAR_ConfigDb.json` to create the device in the Tango device database, - Adjust `docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py` and `docker-compose/jupyterlab/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py` to make an alias for it available in Jupyter and Jupyter-Lab, - Adjust `tangostationcontrol/tangostationcontrol/devices/boot.py` to add the device to the station initialisation sequence, -- Add to `docker-compose/` to create a YaML file to start the device in a docker container. NOTE: it needs a unique 57xx port assigned (current _unused_ port value: 5722), a unique 58xx port for ZMQ events, and a unique 59xx port for ZMQ heartbeat +- Add to `docker-compose/` to create a YaML file to start the device in a docker container. NOTE: it needs a unique 57xx port assigned (current _unused_ port value: 5723), a unique 58xx port for ZMQ events, and a unique 59xx port for ZMQ heartbeat - Adjust `tangostationcontrol/setup.cfg` to add an entry point for the device in the package installation, - Add to `tangostationcontrol/tangostationcontrol/integration_test/default/devices/` to add an integration test, - Adjust `sbin/run_integration_test.sh` to have the device started when running the integration tests, diff --git a/tangostationcontrol/tangostationcontrol/devices/boot.py b/tangostationcontrol/tangostationcontrol/devices/boot.py index 42ce74d74..e0899c743 100644 --- a/tangostationcontrol/tangostationcontrol/devices/boot.py +++ b/tangostationcontrol/tangostationcontrol/devices/boot.py @@ -251,6 +251,7 @@ class Boot(lofar_device): "STAT/TileBeam/1", # Accesses AntennaField "STAT/DigitalBeam/1", # Accessed SDP and Beamlet "STAT/TemperatureManager/1", + "STAT/Configuration/1", ], ) diff --git a/tangostationcontrol/tangostationcontrol/devices/configuration_device.py b/tangostationcontrol/tangostationcontrol/devices/configuration_device.py index 9394c0705..bc8222cd3 100644 --- a/tangostationcontrol/tangostationcontrol/devices/configuration_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/configuration_device.py @@ -40,6 +40,14 @@ class Configuration(lofar_device): def read_tangodb_properties_RW(self): return self._dump_configdb() + def write_tangodb_properties_RW(self, tangodb_properties): + """ Takes a JSON string which represents the station configuration + and loads the whole configuration from scratch. + + N.B. it does not update, it loads a full new configuration. + """ + self.proxy.tangodb_properties_RW = tangodb_properties + def _dump_configdb(self): """ Returns the TangoDB station configuration as a JSON string """ return 'Configuration' diff --git a/tangostationcontrol/tangostationcontrol/devices/docker_device.py b/tangostationcontrol/tangostationcontrol/devices/docker_device.py index 71e13119d..a746ad1cd 100644 --- a/tangostationcontrol/tangostationcontrol/devices/docker_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/docker_device.py @@ -48,6 +48,8 @@ class Docker(lofar_device): device_boot_R = attribute_wrapper(comms_annotation={"container": "device-boot"}, datatype=bool) device_boot_RW = attribute_wrapper(comms_annotation={"container": "device-boot"}, datatype=bool, access=AttrWriteType.READ_WRITE) device_docker_R = attribute_wrapper(comms_annotation={"container": "device-docker"}, datatype=bool) + device_configuration_R = attribute_wrapper(comms_annotation={"container": "device-configuration"}, datatype=bool) + device_configuration_RW = attribute_wrapper(comms_annotation={"container": "device-configuration"}, datatype=bool, access=AttrWriteType.READ_WRITE) # device_docker_RW is not available, as we cannot start our own container` device_temperature_manager_R = attribute_wrapper(comms_annotation={"container": "device-temperature-manager"}, datatype=bool) device_temperature_manager_RW = attribute_wrapper(comms_annotation={"container": "device-temperature-manager"}, datatype=bool, access=AttrWriteType.READ_WRITE) diff --git a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_configuration.py b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_configuration.py new file mode 100644 index 000000000..4a34cad03 --- /dev/null +++ b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_configuration.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# +# This file is part of the LOFAR 2.0 Station Software +# +# +# +# Distributed under the terms of the APACHE license. +# See LICENSE.txt for more info. + +from .base import AbstractTestBases + + +class TestDeviceConfiguration(AbstractTestBases.TestDeviceBase): + + def setUp(self): + super().setUp("STAT/Configuration/1") -- GitLab