diff --git a/CDB/LOFAR_ConfigDb.json b/CDB/LOFAR_ConfigDb.json index 197686104afa47aeb018b0c5caade4d286a4fe9b..020fd7ebc73f0579b85d8a091849ff2fdddf6145 100644 --- a/CDB/LOFAR_ConfigDb.json +++ b/CDB/LOFAR_ConfigDb.json @@ -1,5 +1,12 @@ { "servers": { + "docker_device": { + "LTS": { + "Docker": { + "LTS/Docker/1": {} + } + } + }, "Femto": { "CS999": { "Femto": { diff --git a/devices/devices/docker.py b/devices/devices/docker.py deleted file mode 100644 index f4ed88eb07312ef43954382473da1f9298cd3651..0000000000000000000000000000000000000000 --- a/devices/devices/docker.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of the Docker project -# -# -# -# Distributed under the terms of the APACHE license. -# See LICENSE.txt for more info. - -""" Docker Device Server for LOFAR2.0 - -""" - -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -sys.path.append(parentdir) - -# PyTango imports -from tango import DebugIt -from tango.server import run, command -from tango.server import device_property, attribute -from tango import AttrWriteType -# Additional import - -from device_decorators import * - -from clients.docker_client import DockerClient -from clients.attribute_wrapper import attribute_wrapper -from common.lofar_logging import device_logging_to_python, log_exceptions -from common.lofar_git import get_version - -__all__ = ["Docker", "main"] - -@device_logging_to_python() -class Docker(hardware_device): - """ - - **Properties:** - - - Device Property - OPC_Server_Name - - Type:'DevString' - OPC_Server_Port - - Type:'DevULong' - OPC_Time_Out - - Type:'DevDouble' - """ - - # ----------------- - # Device Properties - # ----------------- - - Docker_Base_URL = device_property( - dtype='DevString', - mandatory=False, - default_value="unix:///var/run/docker.sock" - ) - - # ---------- - # Attributes - # ---------- - version_R = attribute(dtype=str, access=AttrWriteType.READ, fget=lambda self: get_version()) - archiver_maria_db_R = attribute_wrapper(comms_annotation=["archiver-maria-db"], datatype=numpy.bool_) - archiver_maria_db_RW = attribute_wrapper(comms_annotation=["archiver-maria-db"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - databaseds_R = attribute_wrapper(comms_annotation=["databaseds"], datatype=numpy.bool_) - databaseds_RW = attribute_wrapper(comms_annotation=["databaseds"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - device_pcc_R = attribute_wrapper(comms_annotation=["device_pcc"], datatype=numpy.bool_) - device_pcc_RW = attribute_wrapper(comms_annotation=["device_pcc"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - device_sdp_R = attribute_wrapper(comms_annotation=["device_sdp"], datatype=numpy.bool_) - device_sdp_RW = attribute_wrapper(comms_annotation=["device_sdp"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - device_sst_R = attribute_wrapper(comms_annotation=["device_sst"], datatype=numpy.bool_) - device_sst_RW = attribute_wrapper(comms_annotation=["device_sst"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - device_xst_R = attribute_wrapper(comms_annotation=["device_xst"], datatype=numpy.bool_) - device_xst_RW = attribute_wrapper(comms_annotation=["device_xst"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - device_unb2_R = attribute_wrapper(comms_annotation=["device_unb2"], datatype=numpy.bool_) - device_unb2_RW = attribute_wrapper(comms_annotation=["device_unb2"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - docker_R = attribute_wrapper(comms_annotation=["docker"], datatype=numpy.bool_) - # docker_RW is not available, as we cannot start our own container` - dsconfig_R = attribute_wrapper(comms_annotation=["dsconfig"], datatype=numpy.bool_) - dsconfig_RW = attribute_wrapper(comms_annotation=["dsconfig"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - elk_R = attribute_wrapper(comms_annotation=["elk"], datatype=numpy.bool_) - elk_RW = attribute_wrapper(comms_annotation=["elk"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - grafana_R = attribute_wrapper(comms_annotation=["grafana"], datatype=numpy.bool_) - grafana_RW = attribute_wrapper(comms_annotation=["grafana"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - hdbpp_cm_R = attribute_wrapper(comms_annotation=["hdbpp-cm"], datatype=numpy.bool_) - hdbpp_cm_RW = attribute_wrapper(comms_annotation=["hdbpp-cm"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - hdbpp_es_R = attribute_wrapper(comms_annotation=["hdbpp-es"], datatype=numpy.bool_) - hdbpp_es_RW = attribute_wrapper(comms_annotation=["hdbpp-es"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - itango_R = attribute_wrapper(comms_annotation=["itango"], datatype=numpy.bool_) - itango_RW = attribute_wrapper(comms_annotation=["itango"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - jupyter_R = attribute_wrapper(comms_annotation=["jupyter"], datatype=numpy.bool_) - jupyter_RW = attribute_wrapper(comms_annotation=["jupyter"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - prometheus_R = attribute_wrapper(comms_annotation=["prometheus"], datatype=numpy.bool_) - prometheus_RW = attribute_wrapper(comms_annotation=["prometheus"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - tangodb_R = attribute_wrapper(comms_annotation=["tangodb"], datatype=numpy.bool_) - # tangodb_RW is not available, as we cannot start tango from this device if it is down - tango_prometheus_exporter_R = attribute_wrapper(comms_annotation=["tango-prometheus-exporter"], datatype=numpy.bool_) - tango_prometheus_exporter_RW = attribute_wrapper(comms_annotation=["tango-prometheus-exporter"], datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) - - @log_exceptions() - def delete_device(self): - """Hook to delete resources allocated in init_device. - - This method allows for any memory or other resources allocated in the - init_device method to be released. This method is called by the device - destructor and by the device Init command (a Tango built-in). - """ - self.debug_stream("Shutting down...") - - self.Off() - self.debug_stream("Shut down. Good bye.") - - # -------- - # overloaded functions - # -------- - @log_exceptions() - def configure_for_off(self): - """ user code here. is called when the state is set to OFF """ - # Stop keep-alive - try: - self.opcua_connection.stop() - except Exception as e: - self.warn_stream("Exception while stopping OPC ua connection in configure_for_off function: {}. Exception ignored".format(e)) - - @log_exceptions() - def configure_for_initialise(self): - """ user code here. is called when the state is set to INIT """ - - # set up the Docker client - self.docker_client = DockerClient(self.Docker_Base_URL, self.Fault, self) - - # map an access helper class - for i in self.attr_list(): - try: - i.set_comm_client(self.docker_client) - except Exception as e: - # use the pass function instead of setting read/write fails - i.set_pass_func() - self.warn_stream("error while setting the attribute {} read/write function. {}".format(i, e)) - - self.docker_client.start() - - # -------- - # Commands - # -------- - - -# ---------- -# Run server -# ---------- -def main(args=None, **kwargs): - """Main function of the Docker module.""" - - from common.lofar_logging import configure_logger - configure_logger() - - return run((Docker,), args=args, **kwargs) - - -if __name__ == '__main__': - main() diff --git a/devices/devices/docker_device.py b/devices/devices/docker_device.py new file mode 100644 index 0000000000000000000000000000000000000000..1ecab47936ff3c6913043fea3c3fbd77cd0f1361 --- /dev/null +++ b/devices/devices/docker_device.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- +# +# This file is part of the Docker project +# +# +# +# Distributed under the terms of the APACHE license. +# See LICENSE.txt for more info. + +""" Docker Device Server for LOFAR2.0 + +""" + +# TODO(Corne): Remove sys.path.append hack once packaging is in place! +import os, sys +currentdir = os.path.dirname(os.path.realpath(__file__)) +parentdir = os.path.dirname(currentdir) +sys.path.append(parentdir) + +# PyTango imports +from tango import DebugIt +from tango.server import run, command +from tango.server import device_property, attribute +from tango import AttrWriteType +import numpy +# Additional import + +from device_decorators import * + +from clients.docker_client import DockerClient +from clients.attribute_wrapper import attribute_wrapper +from devices.hardware_device import hardware_device +from common.lofar_logging import device_logging_to_python, log_exceptions +from common.lofar_git import get_version + +__all__ = ["Docker", "main"] + +@device_logging_to_python() +class Docker(hardware_device): + """ + + **Properties:** + + - Device Property + OPC_Server_Name + - Type:'DevString' + OPC_Server_Port + - Type:'DevULong' + OPC_Time_Out + - Type:'DevDouble' + """ + + # ----------------- + # Device Properties + # ----------------- + + Docker_Base_URL = device_property( + dtype='DevString', + mandatory=False, + default_value="unix:///var/run/docker.sock" + ) + + # ---------- + # Attributes + # ---------- + version_R = attribute(dtype=str, access=AttrWriteType.READ, fget=lambda self: get_version()) + archiver_maria_db_R = attribute_wrapper(comms_annotation={"container": "archiver-maria-db"}, datatype=numpy.bool_) + archiver_maria_db_RW = attribute_wrapper(comms_annotation={"container": "archiver-maria-db"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + databaseds_R = attribute_wrapper(comms_annotation={"container": "databaseds"}, datatype=numpy.bool_) + databaseds_RW = attribute_wrapper(comms_annotation={"container": "databaseds"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + device_pcc_R = attribute_wrapper(comms_annotation={"container": "device-pcc"}, datatype=numpy.bool_) + device_pcc_RW = attribute_wrapper(comms_annotation={"container": "device-pcc"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + device_sdp_R = attribute_wrapper(comms_annotation={"container": "device-sdp"}, datatype=numpy.bool_) + device_sdp_RW = attribute_wrapper(comms_annotation={"container": "device-sdp"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + device_sst_R = attribute_wrapper(comms_annotation={"container": "device-sst"}, datatype=numpy.bool_) + device_sst_RW = attribute_wrapper(comms_annotation={"container": "device-sst"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + device_xst_R = attribute_wrapper(comms_annotation={"container": "device-xst"}, datatype=numpy.bool_) + device_xst_RW = attribute_wrapper(comms_annotation={"container": "device-xst"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + device_unb2_R = attribute_wrapper(comms_annotation={"container": "device-unb2"}, datatype=numpy.bool_) + device_unb2_RW = attribute_wrapper(comms_annotation={"container": "device-unb2"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + device_docker_R = attribute_wrapper(comms_annotation={"container": "device-docker"}, datatype=numpy.bool_) + # device_docker_RW is not available, as we cannot start our own container` + dsconfig_R = attribute_wrapper(comms_annotation={"container": "dsconfig"}, datatype=numpy.bool_) + dsconfig_RW = attribute_wrapper(comms_annotation={"container": "dsconfig"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + elk_R = attribute_wrapper(comms_annotation={"container": "elk"}, datatype=numpy.bool_) + elk_RW = attribute_wrapper(comms_annotation={"container": "elk"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + grafana_R = attribute_wrapper(comms_annotation={"container": "grafana"}, datatype=numpy.bool_) + grafana_RW = attribute_wrapper(comms_annotation={"container": "grafana"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + hdbpp_cm_R = attribute_wrapper(comms_annotation={"container": "hdbpp-cm"}, datatype=numpy.bool_) + hdbpp_cm_RW = attribute_wrapper(comms_annotation={"container": "hdbpp-cm"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + hdbpp_es_R = attribute_wrapper(comms_annotation={"container": "hdbpp-es"}, datatype=numpy.bool_) + hdbpp_es_RW = attribute_wrapper(comms_annotation={"container": "hdbpp-es"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + itango_R = attribute_wrapper(comms_annotation={"container": "itango"}, datatype=numpy.bool_) + itango_RW = attribute_wrapper(comms_annotation={"container": "itango"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + jupyter_R = attribute_wrapper(comms_annotation={"container": "jupyter"}, datatype=numpy.bool_) + jupyter_RW = attribute_wrapper(comms_annotation={"container": "jupyter"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + prometheus_R = attribute_wrapper(comms_annotation={"container": "prometheus"}, datatype=numpy.bool_) + prometheus_RW = attribute_wrapper(comms_annotation={"container": "prometheus"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + tangodb_R = attribute_wrapper(comms_annotation={"container": "tangodb"}, datatype=numpy.bool_) + # tangodb_RW is not available, as we cannot start tango from this device if it is down + tango_prometheus_exporter_R = attribute_wrapper(comms_annotation={"container": "tango-prometheus-exporter"}, datatype=numpy.bool_) + tango_prometheus_exporter_RW = attribute_wrapper(comms_annotation={"container": "tango-prometheus-exporter"}, datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) + + @log_exceptions() + def delete_device(self): + """Hook to delete resources allocated in init_device. + + This method allows for any memory or other resources allocated in the + init_device method to be released. This method is called by the device + destructor and by the device Init command (a Tango built-in). + """ + self.debug_stream("Shutting down...") + + self.Off() + self.debug_stream("Shut down. Good bye.") + + # -------- + # overloaded functions + # -------- + @log_exceptions() + def configure_for_off(self): + """ user code here. is called when the state is set to OFF """ + # Stop keep-alive + try: + self.opcua_connection.stop() + except Exception as e: + self.warn_stream("Exception while stopping OPC ua connection in configure_for_off function: {}. Exception ignored".format(e)) + + @log_exceptions() + def configure_for_initialise(self): + """ user code here. is called when the state is set to INIT """ + + # set up the Docker client + self.docker_client = DockerClient(self.Docker_Base_URL, self.Fault, self) + + # map an access helper class + for i in self.attr_list(): + try: + i.set_comm_client(self.docker_client) + except Exception as e: + # use the pass function instead of setting read/write fails + i.set_pass_func() + self.warn_stream("error while setting the attribute {} read/write function. {}".format(i, e)) + + self.docker_client.start() + + # -------- + # Commands + # -------- + + +# ---------- +# Run server +# ---------- +def main(args=None, **kwargs): + """Main function of the Docker module.""" + + from common.lofar_logging import configure_logger + configure_logger() + + return run((Docker,), args=args, **kwargs) + + +if __name__ == '__main__': + main() diff --git a/docker-compose/device-docker.yml b/docker-compose/device-docker.yml index 78f43f18e0ce554891b50542c66f12adfe44a77e..82b62bee7f898b36cc1bf4b208a0b18cc09bdaba 100644 --- a/docker-compose/device-docker.yml +++ b/docker-compose/device-docker.yml @@ -30,6 +30,7 @@ services: - ${TANGO_LOFAR_CONTAINER_MOUNT} - /var/run/docker.sock:/var/run/docker.sock:rw privileged: true + user: ${UID}:${UID} environment: - TANGO_HOST=${TANGO_HOST} entrypoint: @@ -40,5 +41,5 @@ services: - -- # 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 - - python3 -u ${TANGO_LOFAR_CONTAINER_DIR}/devices/devices/docker.py LTS -v -ORBendPoint giop:tcp:0:5705 -ORBendPointPublish giop:tcp:${HOSTNAME}:5705 + - python3 -u ${TANGO_LOFAR_CONTAINER_DIR}/devices/devices/docker_device.py LTS -v -ORBendPoint giop:tcp:0:5705 -ORBendPointPublish giop:tcp:${HOSTNAME}:5705 restart: on-failure