diff --git a/CDB/stations/cs032.json b/CDB/stations/cs032.json index 1191d59c1a9257954293a9857467e5ef87d9b4e9..4e8c3564a536e375cf503148e597d735c36de9a1 100644 --- a/CDB/stations/cs032.json +++ b/CDB/stations/cs032.json @@ -6,10 +6,10 @@ "STAT/StationManager/1": { "properties": { "Station_Name": [ - "CS032" + "CS032" ], "Station_Number": [ - "32" + "32" ] } } @@ -22,7 +22,7 @@ "STAT/Calibration/1": { "properties": { "Station_Name": [ - "CS032" + "CS032" ] } } @@ -86,7 +86,7 @@ "53260", "53261", "53262", - "53263" + "53263" ], "FPGA_beamlet_output_multiple_hdr_eth_destination_mac_RW_default_shorthand": [ "e4:43:4b:3d:86:e2", @@ -104,7 +104,7 @@ "10320", "10321", "10322", - "10323" + "10323" ] } }, @@ -162,7 +162,7 @@ "53260", "53261", "53262", - "53263" + "53263" ], "FPGA_beamlet_output_multiple_hdr_eth_destination_mac_RW_default_shorthand": [ "e4:43:4b:3d:86:e2", @@ -180,7 +180,7 @@ "10320", "10321", "10322", - "10323" + "10323" ] } }, @@ -238,7 +238,7 @@ "53260", "53261", "53262", - "53263" + "53263" ], "FPGA_beamlet_output_multiple_hdr_eth_destination_mac_RW_default_shorthand": [ "e4:43:4b:3d:86:e2", @@ -256,7 +256,7 @@ "10326", "10327", "10328", - "10329" + "10329" ] } } @@ -269,22 +269,22 @@ "STAT/AFL/LBA": { "properties": { "Antenna_Cables": [ - "80m", "80m", "80m", "80m", "80m", "80m", - "80m", "80m", "80m", "115m", "80m", "80m", - "80m", "80m", "80m", "80m", "80m", "80m", - "80m", "115m", "115m", "115m", "115m", "80m", - "80m", "80m", "80m", "80m", "80m", "80m", - "80m", "80m", "80m", "80m", "115m", "115m", - "115m", "80m", "80m", "80m", "80m", "80m", - "80m", "80m", "80m", "80m", "80m", "80m", - "80m", "80m", "80m", "80m", "115m", "115m", - "80m", "80m", "80m", "80m", "50m", "50m", - "50m", "80m", "80m", "80m", "115m", "115m", - "115m", "115m", "115m", "80m", "80m", "50m", - "50m", "50m", "80m", "80m", "80m", "115m", - "115m", "115m", "115m", "115m", "115m", "80m", - "80m", "50m", "50m", "50m", "50m", "80m", - "80m", "115m", "115m", "115m", "115m", "50m" + "80m", "80m", "80m", "80m", "80m", "80m", + "80m", "80m", "80m", "115m", "80m", "80m", + "80m", "80m", "80m", "80m", "80m", "80m", + "80m", "115m", "115m", "115m", "115m", "80m", + "80m", "80m", "80m", "80m", "80m", "80m", + "80m", "80m", "80m", "80m", "115m", "115m", + "115m", "80m", "80m", "80m", "80m", "80m", + "80m", "80m", "80m", "80m", "80m", "80m", + "80m", "80m", "80m", "80m", "115m", "115m", + "80m", "80m", "80m", "80m", "50m", "50m", + "50m", "80m", "80m", "80m", "115m", "115m", + "115m", "115m", "115m", "80m", "80m", "50m", + "50m", "50m", "80m", "80m", "80m", "115m", + "115m", "115m", "115m", "115m", "115m", "80m", + "80m", "50m", "50m", "50m", "50m", "80m", + "80m", "115m", "115m", "115m", "115m", "50m" ], "Antenna_Field_Reference_ITRF": [ "3826891.530", "460387.957", "5064715.320" @@ -430,7 +430,7 @@ "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", - "80.00", "80.00", "80.00", "80.00", "80.00", "80.00" + "80.00", "80.00", "80.00", "80.00", "80.00", "80.00" ], "PQR_to_ETRS_rotation_matrix": [ "-0.1195951054", "-0.7919544517", "0.5987530018", @@ -474,7 +474,7 @@ "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", "80.00", - "80.00", "80.00", "80.00", "80.00", "80.00", "80.00" + "80.00", "80.00", "80.00", "80.00", "80.00", "80.00" ], "PQR_to_ETRS_rotation_matrix": [ "-0.1195951054", "-0.7919544517", "0.5987530018", diff --git a/CDB/stations/rs307.json b/CDB/stations/rs307.json index 5205bb4375de102709f3962f5d164050ceaa4c2f..b838b99058bab69c79118c4adafe87568c5ac330 100644 --- a/CDB/stations/rs307.json +++ b/CDB/stations/rs307.json @@ -6,10 +6,10 @@ "STAT/StationManager/1": { "properties": { "Station_Name": [ - "RS307" + "RS307" ], "Station_Number": [ - "307" + "307" ] } } @@ -22,7 +22,7 @@ "STAT/Calibration/1": { "properties": { "Station_Name": [ - "RS307" + "RS307" ] } } @@ -86,7 +86,7 @@ "53260", "53261", "53262", - "53263" + "53263" ], "FPGA_beamlet_output_multiple_hdr_eth_destination_mac_RW_default_shorthand": [ "f8:f2:1e:42:39:70", @@ -104,7 +104,7 @@ "13070", "13071", "13072", - "13073" + "13073" ] } }, @@ -162,7 +162,7 @@ "53260", "53261", "53262", - "53263" + "53263" ], "FPGA_beamlet_output_multiple_hdr_eth_destination_mac_RW_default_shorthand": [ "f8:f2:1e:42:39:70", @@ -180,7 +180,7 @@ "13070", "13071", "13072", - "13073" + "13073" ] } } @@ -193,22 +193,22 @@ "STAT/AFL/LBA": { "properties": { "Antenna_Cables": [ - "80m", "80m", "80m", "80m", "80m", "80m", - "80m", "80m", "80m", "80m", "80m", "80m", - "80m", "115m", "80m", "80m", "80m", "80m", - "80m", "80m", "80m", "80m", "80m", "80m", - "80m", "115m", "115m", "80m", "80m", "80m", - "80m", "80m", "80m", "80m", "80m", "80m", - "80m", "80m", "80m", "80m", "80m", "115m", - "115m", "115m", "80m", "80m", "115m", "50m", - "80m", "80m", "80m", "80m", "80m", "80m", - "80m", "80m", "115m", "115m", "115m", "115m", - "80m", "80m", "80m", "80m", "50m", "50m", - "50m", "80m", "115m", "115m", "115m", "115m", - "115m", "80m", "80m", "80m", "50m", "50m", - "50m", "50m", "80m", "80m", "115m", "115m", - "115m", "115m", "115m", "115m", "115m", "80m", - "50m", "50m", "50m", "80m", "115m", "115m" + "80m", "80m", "80m", "80m", "80m", "80m", + "80m", "80m", "80m", "80m", "80m", "80m", + "80m", "115m", "80m", "80m", "80m", "80m", + "80m", "80m", "80m", "80m", "80m", "80m", + "80m", "115m", "115m", "80m", "80m", "80m", + "80m", "80m", "80m", "80m", "80m", "80m", + "80m", "80m", "80m", "80m", "80m", "115m", + "115m", "115m", "80m", "80m", "115m", "50m", + "80m", "80m", "80m", "80m", "80m", "80m", + "80m", "80m", "115m", "115m", "115m", "115m", + "80m", "80m", "80m", "80m", "50m", "50m", + "50m", "80m", "115m", "115m", "115m", "115m", + "115m", "80m", "80m", "80m", "50m", "50m", + "50m", "50m", "80m", "80m", "115m", "115m", + "115m", "115m", "115m", "115m", "115m", "80m", + "50m", "50m", "50m", "80m", "115m", "115m" ], "Antenna_Field_Reference_ITRF": [ "3837940.905", "449560.803", "5057381.316" @@ -382,7 +382,7 @@ "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", "10.00", - "10.00", "10.00", "10.00", "10.00", "10.00", "10.00" + "10.00", "10.00", "10.00", "10.00", "10.00", "10.00" ], "PQR_to_ETRS_rotation_matrix": [ "-0.1195951054", "-0.7919544517", "0.5987530018", diff --git a/README.md b/README.md index ef6c5d8f7f9e198b36662e7f8093bd89fe6f36c2..cfe7612ac0653049dcf9cdee9963445183d07c52 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,7 @@ Next change the version in the following places: # Release Notes +* 0.40.2 Add `ds_debug_pycharm` command to debug device servers during integration tests * 0.40.1 Deploy SDPTR for HBA only on RS stations * 0.40.0 Added CS032/RS307, and scripts to generate their CDB file and caltables * 0.39.12 SDPTR v1.4.0 diff --git a/docker/Makefile b/docker/Makefile index 891fcf920fb7e14e207883a7cd4d9e949505b079..b5d6d3c3fe9304c90d0b414e4e7f37681556d7e2 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -1,6 +1,6 @@ TAG ?= latest SHELL = /bin/bash -TANGO_STATION_CONTROL ?= 1 +DEBUG_BUILD ?= 0 LOCAL_DOCKER_REGISTRY ?= $(shell shyaml get-value registry.astron.url < "../infra/env/common.yaml") TANGO_ITANGO_VERSION ?= $(shell shyaml get-value tango.itango.version < "../infra/env/common.yaml") TANGO_DSCONFIG_VERSION ?= $(shell shyaml get-value tango.dsconfig.version < "../infra/env/common.yaml") @@ -19,6 +19,7 @@ context: ## Move and build the necessary files to create minimal docker context fi; \ cp ../tangostationcontrol/dist/*.whl lofar-device-base/tmp/; \ cp ../tangostationcontrol/requirements.txt lofar-device-base/tmp/; \ + cp ../tangostationcontrol/debug-requirements.txt lofar-device-base/tmp/; \ jupyter-lab ec-sim grafana landing-page: docker build -f $@/Dockerfile -t $(LOCAL_DOCKER_REGISTRY)/$@:$(TAG) $@ @@ -31,7 +32,7 @@ dsconfig: docker build --build-arg SOURCE_IMAGE=$(LOCAL_DOCKER_REGISTRY)/tango-dsconfig:$(TANGO_DSCONFIG_VERSION) -f dsconfig/Dockerfile -t $(LOCAL_DOCKER_REGISTRY)/dsconfig:$(TAG) dsconfig lofar-device-base: context - docker build --build-arg TANGO_STATION_CONTROL=$(TANGO_STATION_CONTROL) --build-arg SOURCE_IMAGE=$(LOCAL_DOCKER_REGISTRY)/tango-itango:$(TANGO_ITANGO_VERSION) -f lofar-device-base/Dockerfile -t $(LOCAL_DOCKER_REGISTRY)/lofar-device-base:$(TAG) lofar-device-base + docker build --build-arg DEBUG_BUILD=$(DEBUG_BUILD) --build-arg SOURCE_IMAGE=$(LOCAL_DOCKER_REGISTRY)/tango-itango:$(TANGO_ITANGO_VERSION) -f lofar-device-base/Dockerfile -t $(LOCAL_DOCKER_REGISTRY)/lofar-device-base:$(TAG) lofar-device-base ci-runner: docker build --build-arg SOURCE_IMAGE=$(LOCAL_DOCKER_REGISTRY)/tango-itango:$(TANGO_ITANGO_VERSION) -f ci-runner/Dockerfile -t $(LOCAL_DOCKER_REGISTRY)/ci-build-runner:$(TAG) ci-runner diff --git a/docker/lofar-device-base/Dockerfile b/docker/lofar-device-base/Dockerfile index 858657b182f24c8f8a68b3d6391b61843e5e9e48..925f33cda5a362945df7d6fd7ceb2a508e0257ec 100644 --- a/docker/lofar-device-base/Dockerfile +++ b/docker/lofar-device-base/Dockerfile @@ -1,7 +1,8 @@ ARG SOURCE_IMAGE FROM ${SOURCE_IMAGE} -ARG TANGO_STATION_CONTROL -ENV TANGO_STATION_CONTROL $TANGO_STATION_CONTROL + +ARG DEBUG_BUILD +ENV DEBUG_BUILD=$DEBUG_BUILD RUN --mount=type=cache,target=/var/cache/apt \ sudo apt-get update @@ -59,21 +60,17 @@ RUN mkdir /tmp/python-casacore && \ # Install tangostationcontrol and its dependencies COPY tmp/requirements.txt /tangostationcontrol-requirements.txt +COPY tmp/debug-requirements.txt /tangostationcontrol-debug-requirements.txt -RUN echo "TANGO_STATION_CONTROL: ${TANGO_STATION_CONTROL}" -RUN if [ -z $TANGO_STATION_CONTROL ]; then \ - echo "Installing requirements only"; \ - sudo pip3 install -r /tangostationcontrol-requirements.txt --extra-index-url=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple; \ +RUN echo "DEBUG_BUILD: ${DEBUG_BUILD}" +RUN if [ $DEBUG_BUILD ]; then \ + echo "Installing debug requirements"; \ + sudo pip3 install -r /tangostationcontrol-debug-requirements.txt --extra-index-url=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple; \ fi -# This COPY typically triggers a new build instead of pulling from cache. -# We thus perform it after installing the requirements.txt in case -# $TANGO_STATION_CONTROL is not defined. COPY tmp/*.whl / -RUN if [ $TANGO_STATION_CONTROL ]; then \ - echo "Installing prebuild Station Control wheel"; \ - sudo pip3 install /*.whl --extra-index-url=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple; \ - fi +RUN echo "Installing prebuild Station Control wheel"; \ + sudo pip3 install /*.whl --extra-index-url=https://git.astron.nl/api/v4/projects/395/packages/pypi/simple; # install and use ephimerides and geodetic ("measures") tables for casacore. # we install a _stub_ since the tables need to be deployed explicitly from within the software. diff --git a/infra/README.md b/infra/README.md index 27c8326b7af9ade74a8deadcd4dadda075470fe5..fd18a5e6fca75f7d5e335221f30ed052d89e6e10 100644 --- a/infra/README.md +++ b/infra/README.md @@ -78,16 +78,16 @@ This container can be identified programmatically as follows. Use the additional ``-q`` parameter to obtain just the container ID: ``` -$ docker ps --filter 'name=client.station.nomad.nomad-cluster.jumppad.dev' +$ docker ps --filter 'name=client.station.nomad.nomad-cluster.local.jmpd.in' CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -90f6f253fb58 shipyardrun/nomad:1.6.1 "/usr/bin/supervisor…" 3 minutes ago Up 3 minutes fee02e87.client.station.nomad.nomad-cluster.jumppad.dev +90f6f253fb58 shipyardrun/nomad:1.6.1 "/usr/bin/supervisor…" 3 minutes ago Up 3 minutes 8592d129.client.station.nomad.nomad-cluster.local.jmpd.in $ ``` You can login interactively to this container using ``sh``: ``` -$ CLIENT_CONTAINER_ID=$(docker ps -q --filter 'name=client.station.nomad.nomad-cluster.jumppad.dev') -$ docker exec -it ${CLIENT_CONTAINER_ID} sh +$ CLIENT_CONTAINER_ID=$(docker ps -q --filter 'name=client.station.nomad.nomad-cluster.local.jmpd.in') +$ docker exec -it ${CLIENT_CONTAINER_ID} bash # ``` @@ -120,6 +120,22 @@ logger=settings t=2024-02-13T13:14:47.767713444Z level=info msg="Config loaded f This allows you to use the regular docker commands like ``attach``, ``logs``, and ``restart``. Note that any interactive use requires ``-it`` for in the top lin ``docker exec -it "${CLIENT_CONTAINER_ID}"``. +To debug a device server you could use `/sbin/run_integration_test.sh --interactive` combined with: + +```shell +docker exec -it "${CLIENT_CONTAINER_ID}" docker attach device-xxx-xxx +``` + +Followed by manually starting the integration tests: `tox -e integration`. +If your environment is already setup and you do not which to recreate it you could start the integration test +container manually + +```shell +docker run --rm -e "TANGO_HOST=$TANGO_HOST" -e "DEBUG_HOST=${local_ip}" --network="station" --dns="$DNS" -it + -v "$LOFAR20_DIR":/opt/lofar/tango:rw -w="/opt/lofar/tango/tangostationcontrol" -e "TEST_MODULE=${test_module}" \ + "git.astron.nl:5000/lofar2.0/tango/ci-build-runner:$TAG" tox -e integration +``` + ## Patching a device server live Sometimes it is handy to modify the tangostationcontrol source code for a running device server. To do so: @@ -147,6 +163,20 @@ b75f633c837e shipyardrun/nomad:1.6.1 "/usr/bin/supervisor…" 2 minutes ag $ ``` +## Using jummpad: live changes and adaptations + +When using the `run_integration_test.sh` the entire setup can be performed and left for further adaptation. This +allows, for instance to step-by-step debug device servers during an integration test! + +Steps: +1. Setup the environment: `./sbin/run_integration_test.sh --skip-tests` +2. Identify the test volume: `docker volume ls | grep "test_"`, use this in the run command `export $TEST_VOLUME=xxx` +3. Change the `/infra/dev/` files as required +4. Run `DOCKER_HOST="unix:///var/run/docker.sock" ./.bin/jumppad up --var="host_volume=${TEST_VOLUME}" --var="lofar20_dir=$(pwd)" --var="image_tag=latest" infra/dev/all.hcl` + +Example, one could change the entrypoint in `device-server.nomad` for a specific device such that you can start the +device manually and debug it during a run of integration test. + ## Using nomad: Manage jobs on the client The server allows you to manage the jobs on the client through Nomad. Each *job* consists of one or more *tasks* that are collectively managed. The tasks are (typically) the docker containers. A job is run inside an *allocation*, which represents an execution instance of a job. diff --git a/infra/dev/all.hcl b/infra/dev/all.hcl index e47a4e80205b0c9ba8fee9625121d626a05ab9d6..0d0a81ea678c3fe6a32c7ae40cc84d8cf36fc1d6 100644 --- a/infra/dev/all.hcl +++ b/infra/dev/all.hcl @@ -8,6 +8,10 @@ variable "image_tag" { default = "latest" } +variable "debug_host" { + default = "" +} + module "nomad" { source = "./nomad" variables = { @@ -22,6 +26,7 @@ module "tango" { nomad_cluster = module.nomad.output.nomad_cluster lofar20_dir = variable.lofar20_dir image_tag = variable.image_tag + debug_host = variable.debug_host } } diff --git a/infra/dev/tango.hcl b/infra/dev/tango.hcl index 29bb0afdc5c3b97aee759ac7b301548f8b018879..8c77d9aadac9d9315ae9734263f612a58fa613f3 100644 --- a/infra/dev/tango.hcl +++ b/infra/dev/tango.hcl @@ -8,6 +8,10 @@ variable "image_tag" { default = "latest" } +variable "debug_host" { + default = "" +} + module "nomad" { source = "./nomad" variables = { @@ -22,5 +26,6 @@ module "tango" { nomad_cluster = module.nomad.output.nomad_cluster lofar20_dir = variable.lofar20_dir image_tag = variable.image_tag + debug_host = variable.debug_host } } diff --git a/infra/dev/tango/variables.hcl b/infra/dev/tango/variables.hcl index 311bbc9a2b96cc0ba8587fff8ac4f27bf951cd59..f396640ec739d6cbac1a25e77719fd497d240172 100644 --- a/infra/dev/tango/variables.hcl +++ b/infra/dev/tango/variables.hcl @@ -9,3 +9,7 @@ variable "image_tag" { variable "lofar20_dir" { default = "" } + +variable "debug_host" { + default = "" +} diff --git a/infra/jobs/station/Makefile b/infra/jobs/station/Makefile index 5353d431290ec546aaf342792723d68bbde76f6a..9520f70abe5caacc0caf88a9a6b760669f3d395f 100644 --- a/infra/jobs/station/Makefile +++ b/infra/jobs/station/Makefile @@ -12,4 +12,4 @@ render: $(JOBS) # parse .levant.nomad files into .nomad files for jumppad %.nomad: %.levant.nomad - levant render $(addprefix -var-file=, $(realpath $(ENV))) -var image_tag="$(TAG)" -var station="$(STATION)" -out=$(realpath $(DIR_OUT))/$@ $(realpath $(DIR_SRC))/$< + levant render $(addprefix -var-file=, $(realpath $(ENV))) -var debug_host="$(LOCAL_IP)" -var image_tag="$(TAG)" -var station="$(STATION)" -out=$(realpath $(DIR_OUT))/$@ $(realpath $(DIR_SRC))/$< diff --git a/infra/jobs/station/device-server.levant.nomad b/infra/jobs/station/device-server.levant.nomad index ab9401f4fc1b4b29970b2c786f940c3921829c3d..9959b62eaa1cb189310663e82bde1b919e8d0b7a 100644 --- a/infra/jobs/station/device-server.levant.nomad +++ b/infra/jobs/station/device-server.levant.nomad @@ -116,6 +116,9 @@ job "device-servers" { TANGO_ZMQ_HEARTBEAT_PORT = "4506" MINIO_ROOT_USER = "minioadmin" MINIO_ROOT_PASSWORD = "minioadmin" +[[ if eq $.station "dev" ]] + DEBUG_HOST = "[[ $.debug_host ]]" +[[ end ]] } resources { diff --git a/sbin/run_integration_test.sh b/sbin/run_integration_test.sh index f9a54302de9d348df749584fa56cbe6602f1a3ed..3bdeb962c386d8a8bc182de13dee4ed01d7d3b8c 100755 --- a/sbin/run_integration_test.sh +++ b/sbin/run_integration_test.sh @@ -5,6 +5,8 @@ # export DNS=192.168.76.1 +LOCAL_IP=$(ip route get 195.169.155.206 | head -1 | cut -d' ' -f7) +export LOCAL_IP export do_cleanup=true # Usage function explains how parameters are parsed @@ -213,10 +215,9 @@ function integration_test { if [ -n "${interactive+x}" ]; then echo "Preparing interactive session ..." - local_ip=$(ip route get 195.169.155.206 | head -1 | cut -d' ' -f7) - echo "Using local ip: ${local_ip}" + echo "Using local ip: ${LOCAL_IP}" export docker_args=( - run --rm -e "TANGO_HOST=$TANGO_HOST" -e "DEBUG_HOST=${local_ip}" --network="station" --dns="$DNS" -it + run --rm -e "TANGO_HOST=$TANGO_HOST" -e "DEBUG_HOST=${LOCAL_IP}" --network="station" --dns="$DNS" -it -v "$LOFAR20_DIR":/opt/lofar/tango:rw -w="/opt/lofar/tango/tangostationcontrol" ) @@ -280,10 +281,11 @@ dsconfig_image="git.astron.nl:5000/lofar2.0/tango/dsconfig:$TAG" docker pull -q "$dsconfig_image" || docker pull -q "git.astron.nl:5000/lofar2.0/tango/dsconfig:latest" || true docker image inspect "$dsconfig_image" > /dev/null || docker tag "git.astron.nl:5000/lofar2.0/tango/dsconfig:latest" "$dsconfig_image" -jumppad_options=( +jumppad_options=( # these don't seem to propagate --var="host_volume=$tmp_volume" --var="lofar20_dir=$LOFAR20_DIR" --var="image_tag=$TAG" + --var="debug_host=$LOCAL_IP" ) echo "Start module: $module" diff --git a/tangostationcontrol/VERSION b/tangostationcontrol/VERSION index d0a191543146bd5339b173d32f985fde11ea1f60..385bb682d05148616e149e4ab7c1690228d8ca70 100644 --- a/tangostationcontrol/VERSION +++ b/tangostationcontrol/VERSION @@ -1 +1 @@ -0.40.1 +0.40.2 diff --git a/tangostationcontrol/debug-requirements.txt b/tangostationcontrol/debug-requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..0b000cc9a0495dfc1cd2c9ad535d705e4364ae33 --- /dev/null +++ b/tangostationcontrol/debug-requirements.txt @@ -0,0 +1 @@ +pydevd-pycharm~=241.14494.241 diff --git a/tangostationcontrol/requirements.txt b/tangostationcontrol/requirements.txt index 09f7b1f67a53de09e8282c0d3ac1af7cc9008cf7..7768e755b9f20e2e3b161617a9fccc2813683181 100644 --- a/tangostationcontrol/requirements.txt +++ b/tangostationcontrol/requirements.txt @@ -26,7 +26,6 @@ logfmter # MIT psutil >= 5.4.6 # BSD3 grpcio # Apache 2 grpcio-tools # Apache 2 - parse # MIT mergedeep # MIT getmac # MIT diff --git a/tangostationcontrol/setup.cfg b/tangostationcontrol/setup.cfg index 348438d8e18759ec7152790236452bf82612157e..0401b8bc5dd5afb57f0ac4e5eb171ed5e357a59e 100644 --- a/tangostationcontrol/setup.cfg +++ b/tangostationcontrol/setup.cfg @@ -26,6 +26,9 @@ packages = find: python_requires = >3.10 install_requires = file: requirements.txt +[options.extras_require] +debug = file: debug-requirements.txt + [options.packages.find] where = . diff --git a/tangostationcontrol/tangostationcontrol/configuration/schemas/__init__.py b/tangostationcontrol/tangostationcontrol/configuration/schemas/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py index c878cbc0e9b41a30174df68a76c25c7d4bc4e71e..7704260400a7f4037aa995854a1677144d046aea 100644 --- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py @@ -30,9 +30,10 @@ from tango import ( DevFailed, DevState, ) +from tango._tango import AttrWriteType # PyTango imports -from tango.server import attribute, command, Device, device_property +from tango.server import attribute, command, class_property, Device, device_property # Additional import from tangostationcontrol import __version__ as version @@ -263,10 +264,17 @@ class LOFARDevice(Device): # ----------------- # Device Properties # ----------------- + Power_Children = device_property(dtype="DevVarStringArray", mandatory=False) Control_Children = device_property(dtype="DevVarStringArray", mandatory=False) + Debug = class_property( + dtype=bool, + default_value=True, + doc="The initial debug state when the device is started", + ) + # ---------- # Attributes # ---------- @@ -282,6 +290,19 @@ class LOFARDevice(Device): fget=lambda self: numpy.int64(time.time() - self.device_start_time), ) + @attribute( + access=AttrWriteType.READ_WRITE, + dtype=bool, + doc="Runtime configuration to enable / disable debug functionality", + ) + def Debug_RW(self): + return self._debug + + @Debug_RW.write + def Debug_RW(self, value): + self._debug = value + self._set_log_level(self._debug) + access_count_R = attribute( doc="How often this software device was accessed for commands or attributes", dtype=numpy.int64, @@ -497,6 +518,8 @@ class LOFARDevice(Device): return self.attribute_poller.is_registered(attr_name) def __init__(self, cl, name): + self._debug = False + # a proxy to ourself. can only be constructed in or after init_device # is called, during super().__init__(). self.proxy = None @@ -521,6 +544,9 @@ class LOFARDevice(Device): def _init_device(self): logger.debug("[LOFARDevice] init_device") + self._debug = self.Debug + self._set_log_level(self._debug) + self.properties_changed() self.set_state(DevState.OFF) @@ -535,6 +561,12 @@ class LOFARDevice(Device): self.proxy = create_device_proxy(self.get_name(), self.Device_Proxy_Timeout) + def _set_log_level(self, debug: bool): + if debug: + logger.setLevel(logging.DEBUG) + else: + logger.setLevel(logging.INFO) + @command(dtype_out=str) def get_children(self): return pprint.pformat(self.control.children(-1)) @@ -888,6 +920,23 @@ class LOFARDevice(Device): restart_python() logger.error("Failed to restart Device Server") + @command() + def ds_debug_pycharm(self): + """Activate connection to pycharm debugger""" + import pydevd_pycharm + + if os.environ.get("DEBUG_HOST") and os.environ.get("DEBUG_HOST") != "": + pydevd_pycharm.settrace( + os.environ["DEBUG_HOST"], + port=12345, + stdoutToServer=True, + stderrToServer=True, + ) + else: + raise RuntimeError( + "Failed no ip to connect, need DEBUG_HOST environment variables" + ) + @only_in_states([DevState.OFF]) def _boot(self): # setup connections