From ad2cbbd871554f67184c290a5a23440d9fe7283a Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 20 Aug 2026 09:37:22 +0200 Subject: [PATCH 01/30] refactor: extract base runner class --- packages/agebd/src/agebd/runner.py | 162 +++++++++++++++-------------- 1 file changed, 82 insertions(+), 80 deletions(-) diff --git a/packages/agebd/src/agebd/runner.py b/packages/agebd/src/agebd/runner.py index 6a3544c..5429004 100644 --- a/packages/agebd/src/agebd/runner.py +++ b/packages/agebd/src/agebd/runner.py @@ -9,107 +9,109 @@ from agebd.service.base import BaseService logger = logging.getLogger(__name__) -class CallbackRunner: +class _BaseRunner: + """ + Shared control loop: poll abort/onoff PVs, dispatch to the active or + paused tick, ping the alive watchdog, and stop cleanly on exception. + """ + + def __init__(self, service: BaseService): + self.svc = service + self.pvs = service.pvs + + def start(self): + logger.debug(f"Starting {type(self).__name__} for service: {self.svc.name}") + while not self.pvs.abort.get(): + try: + # if service is not paused + if self.pvs.onoff.get(): + self._tick_active() + # if service is paused + else: + self._tick_paused() + + # inform watchdog of service alive state + self.pvs.alive.put(0) + + except Exception as e: + self.svc.exception = e + self.svc.crashed = True + + break + + self._on_stop() + self.svc.finalize_termination() + + def _tick_active(self): + raise NotImplementedError + + def _tick_paused(self): + raise NotImplementedError + + def _on_stop(self): + pass + + +class CallbackRunner(_BaseRunner): """ Executes service updates asynchronously, triggered by EPICS PV events. """ - def __init__(self, service: BaseService): - self.svc = service - self.pvs = service.pvs - self._callback_active = False + def _tick_active(self): + # add callback for triggering the loop if not active + if not self.svc.CallbackActive: + self.svc.transition_to_running() + self.pvs.CallbackPV.add_callback(callback=self.svc.CallbackFun, index=1) + self.svc.CallbackActive = 1 - def start(self): - logger.debug(f"Starting CallbackRunner for service: {self.svc.name}") - while not self.pvs.abort.get(): - try: - # if service is not paused - if self.pvs.onoff.get(): - # add callback for triggering the loop if not active - if not self._callback_active: - self.svc.transition_to_running() - self.pvs.CallbackPV.add_callback(callback=self.svc.CallbackFun, index=1) - self.svc.CallbackActive = 1 + # run mainloop of service + self.svc.update() - # run mainloop of service - self.svc.update() + # inform watchdog of service run state + self.pvs.running.put(0) - # inform watchdog of service run state - self.pvs.running.put(0) + # wait for callback to fire + poll(evt=1.0e-5, iot=0.1) - # wait for callback to fire - poll(evt=1.0e-5, iot=0.1) + def _tick_paused(self): + # remove callback for triggering the loop + if self.svc.CallbackActive: + self.svc.transition_to_paused() + self.pvs.CallbackPV.remove_callback(index=1) + self.svc.CallbackActive = 0 + self.svc.CallbackFired = 0 - # if service is paused - else: - # remove callback for triggering the loop - if self.svc.CallbackActive: - self.svc.transition_to_paused() - self.pvs.CallbackPV.remove_callback(index=1) - self.svc.CallbackActive = 0 - self.svc.CallbackFired = 0 - - # wait until service is unpaused - sleep(0.1) - - # inform watchdog of service alive state - self.pvs.alive.put(0) - - except Exception as e: - self.svc.exception = e - self.svc.crashed = True - - break + # wait until service is unpaused + sleep(0.1) + def _on_stop(self): # remove callback(s) from event(s) self.pvs.CallbackPV.remove_callback(index=1) - self.svc.finalize_termination() -class PeriodicRunner: +class PeriodicRunner(_BaseRunner): """ Executes service updates at a fixed frequency. """ - def __init__(self, service: BaseService): - self.svc = service - self.pvs = service.pvs + def _tick_active(self): + if not self.svc.status == ServiceStatus.RUNNING: + self.svc.transition_to_running() - def start(self): - logger.debug(f"Starting PeriodicRunner for service: {self.svc.name}") - while not self.pvs.abort.get(): - try: - # if service is not paused - if self.pvs.onoff.get(): - if not self.svc.status == ServiceStatus.RUNNING: - self.svc.transition_to_running() + # run mainloop of service + self.svc.update() - # run mainloop of service - self.svc.update() + # inform watchdog of service run state + self.pvs.running.put(0) - # inform watchdog of service run state - self.pvs.running.put(0) + # wait for timer + sleep(self.svc.sleep_interval) - # wait for timer - sleep(self.svc.sleep_interval) + def _tick_paused(self): + if not self.svc.status == ServiceStatus.PAUSED: + self.svc.transition_to_paused() - # if service is paused - else: - if not self.svc.status == ServiceStatus.PAUSED: - self.svc.transition_to_paused() + self.svc.CallbackFired = 0 - self.svc.CallbackFired = 0 - - # wait until service is unpaused - sleep(0.1) - - # inform watchdog of service alive state - self.pvs.alive.put(0) - - except Exception as e: - self.svc.exception = e - self.svc.crashed = True - - break - - self.svc.finalize_termination() + # wait until service is unpaused + sleep(0.1) From 16eac5cd08576579a4a9898a94219827f033933d Mon Sep 17 00:00:00 2001 From: labrec_b Date: Tue, 25 Aug 2026 14:34:31 +0200 Subject: [PATCH 02/30] Feature/ioc on cicd runner (#71) Run `ioc ...` from cicd runner, remove ansible and cli commands Reviewed-on: https://gitea.psi.ch/sls/hla_framework_bd/pulls/71 --- .gitea/scripts/common.sh | 38 +++++ .gitea/scripts/deploy-and-restart-service.sh | 34 ++-- .gitea/scripts/ioc-for-services.sh | 27 ++++ .gitea/scripts/ioc-install.sh | 37 +++++ .gitea/scripts/ioc-restart.sh | 15 ++ .gitea/scripts/ioc-start.sh | 23 +++ .gitea/workflows/add-new-service.yml | 26 +++- .gitea/workflows/ioc.yml | 56 +++++++ ansible/ansible.cfg | 8 - ansible/collections/requirements.yml | 3 - ansible/inventories/dev/hosts.yml | 19 --- ansible/inventories/prod/hosts.yml | 18 --- ansible/playbooks/add-new-service.yml | 42 ----- .../deploy-and-restart-modified-services.yml | 24 --- ansible/playbooks/ioc-install.yml | 11 -- ansible/playbooks/ioc-restart.yml | 11 -- ansible/playbooks/ioc-start.yml | 14 -- ansible/tasks/ioc/ioc-install.yml | 63 -------- ansible/tasks/ioc/ioc-restart.yml | 20 --- ansible/tasks/ioc/ioc-start.yml | 17 -- .../service/service-deploy-and-restart.yml | 53 ------- ansible/tasks/utils/clone-repo.yml | 8 - ansible/tasks/utils/get-ioc-port.yml | 18 --- ansible/tasks/utils/init-service-name.yml | 5 - cli/pyproject.toml | 2 - cli/src/core/ansible.py | 40 ----- cli/src/core/enums.py | 8 - cli/src/ioc.py | 112 ------------- cli/src/main.py | 2 - cli/uv.lock | 147 ------------------ docs/developer/ansible.md | 36 ----- docs/developer/cicd_runner.md | 31 +++- docs/developer/ioc/ioc.md | 21 ++- 33 files changed, 283 insertions(+), 706 deletions(-) create mode 100644 .gitea/scripts/common.sh create mode 100755 .gitea/scripts/ioc-for-services.sh create mode 100755 .gitea/scripts/ioc-install.sh create mode 100755 .gitea/scripts/ioc-restart.sh create mode 100755 .gitea/scripts/ioc-start.sh create mode 100644 .gitea/workflows/ioc.yml delete mode 100644 ansible/ansible.cfg delete mode 100644 ansible/collections/requirements.yml delete mode 100644 ansible/inventories/dev/hosts.yml delete mode 100644 ansible/inventories/prod/hosts.yml delete mode 100644 ansible/playbooks/add-new-service.yml delete mode 100644 ansible/playbooks/deploy-and-restart-modified-services.yml delete mode 100644 ansible/playbooks/ioc-install.yml delete mode 100644 ansible/playbooks/ioc-restart.yml delete mode 100644 ansible/playbooks/ioc-start.yml delete mode 100644 ansible/tasks/ioc/ioc-install.yml delete mode 100644 ansible/tasks/ioc/ioc-restart.yml delete mode 100644 ansible/tasks/ioc/ioc-start.yml delete mode 100644 ansible/tasks/service/service-deploy-and-restart.yml delete mode 100644 ansible/tasks/utils/clone-repo.yml delete mode 100644 ansible/tasks/utils/get-ioc-port.yml delete mode 100644 ansible/tasks/utils/init-service-name.yml delete mode 100644 cli/src/core/ansible.py delete mode 100644 cli/src/ioc.py delete mode 100644 docs/developer/ansible.md diff --git a/.gitea/scripts/common.sh b/.gitea/scripts/common.sh new file mode 100644 index 0000000..d681b86 --- /dev/null +++ b/.gitea/scripts/common.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Shared helpers for the scripts run by the gitea runner. +# Source it as: source "$(dirname "$0")/common.sh" + +# Overridable so the scripts can be exercised outside of the runner +HLA_ROOT=${HLA_ROOT:-/sls/bd/hla} + +# Sets the naming and path variables used by the deploy and ioc scripts. +# Usage: init_service_env +init_service_env() { + local SERVICE_NAME=$1 + AGEBD_ENV=$2 + + if [ -z "${SERVICE_NAME}" ] || [ -z "${AGEBD_ENV}" ]; then + echo "Usage: $0 " >&2 + exit 1 + fi + + if [ "${AGEBD_ENV}" = "dev" ]; then + AGEBD_ENV_SUFFIX_UPPER="-DEV" + AGEBD_ENV_SUFFIX_LOWER="-dev" + elif [ "${AGEBD_ENV}" = "prod" ]; then + AGEBD_ENV_SUFFIX_UPPER="" + AGEBD_ENV_SUFFIX_LOWER="" + else + echo "Unknown environment '${AGEBD_ENV}', expected 'dev' or 'prod'" >&2 + exit 1 + fi + + SERVICE_NAME_LOWER=$(echo "${SERVICE_NAME}" | tr '[:upper:]' '[:lower:]') + SERVICE_NAME_UPPER=$(echo "${SERVICE_NAME}" | tr '[:lower:]' '[:upper:]') + + SERVICE_DIR=${HLA_ROOT}/${AGEBD_ENV}/services/${SERVICE_NAME_LOWER}/current + IOC_DIR=${SERVICE_DIR}/ioc + IOC_NAME=AGEBD-CPCL-${SERVICE_NAME_UPPER}${AGEBD_ENV_SUFFIX_UPPER} + # Host running shellbox, i.e. the host the ioc itself runs on + IOC_HOST=sls-vserv-bd-01${AGEBD_ENV_SUFFIX_LOWER} +} diff --git a/.gitea/scripts/deploy-and-restart-service.sh b/.gitea/scripts/deploy-and-restart-service.sh index 142b509..cd6ff81 100755 --- a/.gitea/scripts/deploy-and-restart-service.sh +++ b/.gitea/scripts/deploy-and-restart-service.sh @@ -1,28 +1,19 @@ #!/bin/bash +# Deploys a service to /sls/bd/hla and (re)starts its systemd unit. +# +# Usage: ./.gitea/scripts/deploy-and-restart-service.sh -SERVICE_NAME=$1 -AGEBD_ENV=$2 +source "$(dirname "$0")/common.sh" +init_service_env "${1:-}" "${2:-}" echo "==========================================" -echo "Deploying service: $SERVICE_NAME (${AGEBD_ENV})" +echo "Deploying service: $SERVICE_NAME_LOWER (${AGEBD_ENV})" echo "==========================================" -SERVICE_NAME_LOWER=$(echo "$SERVICE_NAME" | tr '[:upper:]' '[:lower:]') -SERVICE_NAME_UPPER=$(echo "$SERVICE_NAME" | tr '[:lower:]' '[:upper:]') -SERVICE_DIR=/sls/bd/hla/${AGEBD_ENV}/services/${SERVICE_NAME_LOWER}/current SYSTEMD_UNIT_NAME=AGEBD-SERVICE-${SERVICE_NAME_UPPER}.service SYSTEMD_UNIT_FILE_PATH=${SERVICE_DIR}/systemd/${SYSTEMD_UNIT_NAME} -IOC_DIR=${SERVICE_DIR}/ioc IOC_PORT=$(uv run --directory scripts ci/get_ioc_port.py ${SERVICE_NAME_LOWER}) -if [ "${AGEBD_ENV}" = "dev" ]; then - AGEBD_ENV_SUFFIX_UPPER="-DEV" - AGEBD_ENV_SUFFIX_LOWER="-dev" -else - AGEBD_ENV_SUFFIX_UPPER="" - AGEBD_ENV_SUFFIX_LOWER="" -fi - # TODO: see https://gitea.psi.ch/sls/hla_framework_bd/issues/50 # rm -rf "${SERVICE_DIR}" # mkdir -p ${SERVICE_DIR} @@ -43,6 +34,19 @@ sed -i "s/{{ *agebd_env_suffix_upper* }}/${AGEBD_ENV_SUFFIX_UPPER}/g" "${IOC_DIR sed -i "s/{{ *agebd_env_suffix_lower* }}/${AGEBD_ENV_SUFFIX_LOWER}/g" "${IOC_DIR}/"* sed -i "s/{{ *ioc_port* }}/${IOC_PORT}/g" "${IOC_DIR}/"* +### RENAMING +### The ioc files carry the environment suffix in their name, e.g. in dev +### AGEBD-CPCL-NTURNS_main.subs -> AGEBD-CPCL-NTURNS-DEV_main.subs +### (rsync --delete restores the original names on every deploy, so this runs every time) +if [ -n "${AGEBD_ENV_SUFFIX_UPPER}" ]; then + for FILE_SUFFIX in "_main.subs" "_parameters.yaml"; do + ORIG_FILE=${IOC_DIR}/AGEBD-CPCL-${SERVICE_NAME_UPPER}${FILE_SUFFIX} + if [ -f "${ORIG_FILE}" ]; then + mv "${ORIG_FILE}" "${IOC_DIR}/AGEBD-CPCL-${SERVICE_NAME_UPPER}${AGEBD_ENV_SUFFIX_UPPER}${FILE_SUFFIX}" + fi + done +fi + ### SYSTEMD if [ -f "${SYSTEMD_UNIT_FILE_PATH}" ]; then sed -i "s/{{ *agebd_env* }}/${AGEBD_ENV}/g" "${SYSTEMD_UNIT_FILE_PATH}" diff --git a/.gitea/scripts/ioc-for-services.sh b/.gitea/scripts/ioc-for-services.sh new file mode 100755 index 0000000..c6f651b --- /dev/null +++ b/.gitea/scripts/ioc-for-services.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# Runs an ioc action for a single service or for all services. +# +# Usage: ./.gitea/scripts/ioc-for-services.sh +set -euo pipefail + +IOC_ACTION=${1:-} +SERVICE=${2:-} +AGEBD_ENV=${3:-} + +SCRIPT_DIR=$(dirname "$0") +IOC_SCRIPT=${SCRIPT_DIR}/ioc-${IOC_ACTION}.sh + +if [ ! -f "${IOC_SCRIPT}" ]; then + echo "Unknown ioc action '${IOC_ACTION}', expected 'install', 'start' or 'restart'" >&2 + exit 1 +fi + +if [ "${SERVICE}" = "all" ]; then + SERVICES=$(ls -d services/*/ | xargs -n1 basename) +else + SERVICES=${SERVICE} +fi + +for SERVICE_NAME in ${SERVICES}; do + "${IOC_SCRIPT}" "${SERVICE_NAME}" "${AGEBD_ENV}" +done diff --git a/.gitea/scripts/ioc-install.sh b/.gitea/scripts/ioc-install.sh new file mode 100755 index 0000000..01a68d8 --- /dev/null +++ b/.gitea/scripts/ioc-install.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# Installs the ioc of a service from its deployed ioc dir on /sls. +# Requires the service to have been deployed first (deploy-and-restart-service.sh), +# which is what puts the substituted and environment-renamed ioc files in place. +# +# Usage: ./.gitea/scripts/ioc-install.sh +set -euo pipefail + +source "$(dirname "$0")/common.sh" +init_service_env "${1:-}" "${2:-}" + +echo "==========================================" +echo "Installing ioc: ${IOC_NAME} (${AGEBD_ENV})" +echo "==========================================" + +if [ ! -d "${IOC_DIR}" ]; then + echo "Ioc dir '${IOC_DIR}' not found, deploy the service first" >&2 + exit 1 +fi + +STDERR_FILE=$(mktemp) +trap 'rm -f "${STDERR_FILE}"' EXIT + +set +e +(cd "${IOC_DIR}" && ioc install -V --facility sls --ioc "${IOC_NAME}" --clean) 2>"${STDERR_FILE}" +INSTALL_RC=$? +set -e + +cat "${STDERR_FILE}" >&2 + +# 'ioc install ...' returns exit code 0 even on failure, so its stderr is +# inspected for error keywords to force a pipeline failure. +# Note: -a because some responses of the 'ioc ...' cli are non-utf8. +if [ ${INSTALL_RC} -ne 0 ] || grep -qa -e "\[error\]" -e "Unable to write" "${STDERR_FILE}"; then + echo "Failed to install ioc ${IOC_NAME}" >&2 + exit 1 +fi diff --git a/.gitea/scripts/ioc-restart.sh b/.gitea/scripts/ioc-restart.sh new file mode 100755 index 0000000..f573356 --- /dev/null +++ b/.gitea/scripts/ioc-restart.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# Restarts the ioc of a service. +# +# Usage: ./.gitea/scripts/ioc-restart.sh +set -euo pipefail + +source "$(dirname "$0")/common.sh" +init_service_env "${1:-}" "${2:-}" + +echo "==========================================" +echo "Restarting ioc: ${IOC_NAME} (${AGEBD_ENV})" +echo "==========================================" + +cd "${IOC_DIR}" +ioc restart "${IOC_NAME}" diff --git a/.gitea/scripts/ioc-start.sh b/.gitea/scripts/ioc-start.sh new file mode 100755 index 0000000..8b187cf --- /dev/null +++ b/.gitea/scripts/ioc-start.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Starts the ioc of a service through shellbox on the ioc host. +# Needed once after the initial install of a new ioc. +# +# Usage: ./.gitea/scripts/ioc-start.sh +set -euo pipefail + +source "$(dirname "$0")/common.sh" +init_service_env "${1:-}" "${2:-}" + +IOC_PORT=$(uv run --directory scripts ci/get_ioc_port.py "${SERVICE_NAME_LOWER}") + +echo "==========================================" +echo "Starting ioc: ${IOC_NAME} on ${IOC_HOST}:${IOC_PORT}" +echo "==========================================" + +ssh -o BatchMode=yes "${IOC_HOST}" bash -s <> $GITHUB_OUTPUT - # - name: Install Master IOC - - # - name: Restart Master IOC - + # The ioc steps read the deployed ioc files on /sls, so the service + # has to be deployed before its ioc is installed. - name: Deploy and Restart Master Service run: | ./.gitea/scripts/deploy-and-restart-service.sh "master" "dev" - # - name: Install New IOC + - name: Install Master IOC + run: | + ./.gitea/scripts/ioc-install.sh "master" "dev" - # - name: Start New IOC + - name: Restart Master IOC + run: | + ./.gitea/scripts/ioc-restart.sh "master" "dev" - name: Deploy and Restart New Service run: | SERVICE_NAME=${{ steps.parse_branch.outputs.service_name_lower }} ./.gitea/scripts/deploy-and-restart-service.sh "${SERVICE_NAME}" "dev" + + - name: Install New IOC + run: | + SERVICE_NAME=${{ steps.parse_branch.outputs.service_name_lower }} + ./.gitea/scripts/ioc-install.sh "${SERVICE_NAME}" "dev" + + - name: Start New IOC + run: | + SERVICE_NAME=${{ steps.parse_branch.outputs.service_name_lower }} + ./.gitea/scripts/ioc-start.sh "${SERVICE_NAME}" "dev" diff --git a/.gitea/workflows/ioc.yml b/.gitea/workflows/ioc.yml new file mode 100644 index 0000000..d6abf3f --- /dev/null +++ b/.gitea/workflows/ioc.yml @@ -0,0 +1,56 @@ +name: Ioc + +# Manually install / start / restart iocs. +# The ioc files are read from the deployed dir on /sls, +# so the service has to be deployed (see the 'Deploy' workflow) beforehand. +on: + workflow_dispatch: + inputs: + action: + description: 'What to do with the ioc(s)' + type: choice + required: true + default: 'install' + options: + - install + - restart + - start + service: + description: "Service name in lower case, or 'all' for every service" + type: string + required: true + agebd_env: + description: 'Environment' + type: choice + required: true + default: 'dev' + options: + - dev + - prod + +env: + UV_CACHE_DIR: /var/cache/uv + UV_LINK_MODE: hardlink + +jobs: + ioc-dev: + if: ${{ inputs.agebd_env == 'dev' }} + runs-on: hla-dev + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Run ioc ${{ inputs.action }} + run: | + ./.gitea/scripts/ioc-for-services.sh "${{ inputs.action }}" "${{ inputs.service }}" "dev" + + ioc-prod: + if: ${{ inputs.agebd_env == 'prod' }} + runs-on: hla-prod + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Run ioc ${{ inputs.action }} + run: | + ./.gitea/scripts/ioc-for-services.sh "${{ inputs.action }}" "${{ inputs.service }}" "prod" diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg deleted file mode 100644 index 758081a..0000000 --- a/ansible/ansible.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[defaults] -remote_tmp = /tmp/ansible-$USER - -# some responses of 'ioc ...' cli are non-utf8 -module_strict_utf8_response = False - -# ./ refers to dir in which this file is located -collections_path = ./installed-collections diff --git a/ansible/collections/requirements.yml b/ansible/collections/requirements.yml deleted file mode 100644 index 6b3fb4c..0000000 --- a/ansible/collections/requirements.yml +++ /dev/null @@ -1,3 +0,0 @@ -collections: - - name: ansible.posix - version: 1.6.0 \ No newline at end of file diff --git a/ansible/inventories/dev/hosts.yml b/ansible/inventories/dev/hosts.yml deleted file mode 100644 index 3ac0e24..0000000 --- a/ansible/inventories/dev/hosts.yml +++ /dev/null @@ -1,19 +0,0 @@ -all: - vars: - agebd_env: "dev" - env_suffix_upper: "-DEV" - env_suffix_lower: "-dev" - - children: - lc: - hosts: - sls-lc: - ansible_remote_tmp: /tmp/.ansible_${ansible_user}_tmp - vserv: - hosts: - sls-vserv-bd-01-dev: - ansible_ssh_pipelining: true - ansible_ssh_common_args: '-o ForwardAgent=yes' - vserv-hla: - hosts: - sls-vserv-bd-hla01-dev: diff --git a/ansible/inventories/prod/hosts.yml b/ansible/inventories/prod/hosts.yml deleted file mode 100644 index 20ea709..0000000 --- a/ansible/inventories/prod/hosts.yml +++ /dev/null @@ -1,18 +0,0 @@ -all: - vars: - agebd_env: "prod" - env_suffix_upper: "" - env_suffix_lower: "" - - children: - lc: - hosts: - sls-lca: - ansible_remote_tmp: /tmp/.ansible_${ansible_user}_tmp - vserv: - hosts: - sls-vserv-bd-01: - ansible_ssh_pipelining: true - vserv-hla: - hosts: - sls-vserv-bd-hla01: diff --git a/ansible/playbooks/add-new-service.yml b/ansible/playbooks/add-new-service.yml deleted file mode 100644 index a2bfbd0..0000000 --- a/ansible/playbooks/add-new-service.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -- name: Add a new service - hosts: vserv-hla - connection: local - gather_facts: true # Gather once here, available to all included tasks! - - vars: - repo_root: "{{ playbook_dir }}/../.." - - tasks: - # - name: Install Master IOC - # vars: - # preferred_service_name_lower: master - # branch_name: "feature/add-service-{{ service_name_lower }}" - # import_tasks: ../tasks/ioc/ioc-install.yml - - # - name: Restart Master IOC - # vars: - # preferred_service_name_lower: master - # branch_name: "feature/add-service-{{ service_name_lower }}" - # import_tasks: ../tasks/ioc/ioc-restart.yml - - - name: Deploy and Restart Master Service - vars: - preferred_service_name_lower: master - branch_name: "feature/add-service-{{ service_name_lower }}" - import_tasks: ../tasks/service/service-deploy-and-restart.yml - - # - name: Install New IOC - # vars: - # branch_name: "feature/add-service-{{ service_name_lower }}" - # import_tasks: ../tasks/ioc/ioc-install.yml - - # - name: Start New IOC - # vars: - # branch_name: "feature/add-service-{{ service_name_lower }}" - # import_tasks: ../tasks/ioc/ioc-start.yml - - - name: Deploy and Restart New Service - vars: - branch_name: "feature/add-service-{{ service_name_lower }}" - import_tasks: ../tasks/service/service-deploy-and-restart.yml diff --git a/ansible/playbooks/deploy-and-restart-modified-services.yml b/ansible/playbooks/deploy-and-restart-modified-services.yml deleted file mode 100644 index cb47314..0000000 --- a/ansible/playbooks/deploy-and-restart-modified-services.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: Deploy and Restart Modified Services - hosts: vserv-hla - connection: local - - vars: - # Passed from the Gitea workflow, e.g., "master playground" - changed_services_raw: "" - agebd_env: "dev" - repo_root: "{{ playbook_dir }}/../.." - - tasks: - # Fail early if no services were modified - - name: Check if there are services to deploy - ansible.builtin.meta: end_play - when: changed_services_raw | trim == "" - - # Main Loop: loop through the list of modified service names - - name: Deploy and Restart Modified Services - include_tasks: ../tasks/service/service-deploy-and-restart.yml - loop: "{{ changed_services_raw.split() }}" - loop_control: - loop_var: service_name_lower - extended: yes diff --git a/ansible/playbooks/ioc-install.yml b/ansible/playbooks/ioc-install.yml deleted file mode 100644 index f337812..0000000 --- a/ansible/playbooks/ioc-install.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Install an IOC - hosts: lc - gather_facts: false - - vars: - workspace_dir: "/tmp/hla_framework_bd" - - tasks: - - name: Run ioc install tasks - ansible.builtin.import_tasks: ../tasks/ioc/ioc-install.yml diff --git a/ansible/playbooks/ioc-restart.yml b/ansible/playbooks/ioc-restart.yml deleted file mode 100644 index a36728e..0000000 --- a/ansible/playbooks/ioc-restart.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Restart an IOC - hosts: lc - gather_facts: false - - vars: - workspace_dir: "/tmp/hla_framework_bd" - - tasks: - - name: Run ioc restart tasks - ansible.builtin.include_tasks: ../tasks/ioc/ioc-restart.yml diff --git a/ansible/playbooks/ioc-start.yml b/ansible/playbooks/ioc-start.yml deleted file mode 100644 index 02a6386..0000000 --- a/ansible/playbooks/ioc-start.yml +++ /dev/null @@ -1,14 +0,0 @@ -# TODO: ansible seems to be very slow on this machine -# each step takes quite a while (e.g. cloning repo, which -# is significantly faster on other machines). ---- -- name: Start an IOC - hosts: vserv - gather_facts: false - - vars: - workspace_dir: "/tmp/hla_framework_bd" - - tasks: - - name: Run ioc start tasks - ansible.builtin.import_tasks: ../tasks/ioc/ioc-start.yml diff --git a/ansible/tasks/ioc/ioc-install.yml b/ansible/tasks/ioc/ioc-install.yml deleted file mode 100644 index 225c2c7..0000000 --- a/ansible/tasks/ioc/ioc-install.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- -- name: Init service name - ansible.builtin.import_tasks: ../utils/init-service-name.yml - -- name: Clone repo - ansible.builtin.import_tasks: ../utils/clone-repo.yml - -- name: Get and set ioc_port - ansible.builtin.import_tasks: ../utils/get-ioc-port.yml - -- name: "[{{ target_service_name_lower }}] Establish environment naming conventions" - ansible.builtin.set_fact: - service_name_upper: "{{ target_service_name_lower | upper }}" - -- name: "[{{ target_service_name_lower }}] Define file paths" - ansible.builtin.set_fact: - ioc_base_dir: "{{ workspace_dir }}/services/{{ target_service_name_lower }}/current/ioc" - orig_subs_name: "AGEBD-CPCL-{{ service_name_upper }}_main.subs" - target_subs_name: "AGEBD-CPCL-{{ service_name_upper }}{{ env_suffix_upper }}_main.subs" - orig_params_name: "AGEBD-CPCL-{{ service_name_upper }}_parameters.yaml" - target_params_name: "AGEBD-CPCL-{{ service_name_upper }}{{ env_suffix_upper }}_parameters.yaml" - -# Rename the subs file if we are in DEV -- name: "[{{ target_service_name_lower }}] Rename substitution file for environment" - ansible.builtin.command: - cmd: "mv {{ ioc_base_dir }}/{{ orig_subs_name }} {{ ioc_base_dir }}/{{ target_subs_name }}" - removes: "{{ ioc_base_dir }}/{{ orig_subs_name }}" # Only runs if the original file exists - -# Rename the paramters file if we are in DEV -- name: "[{{ target_service_name_lower }}] Rename parameters file for environment" - ansible.builtin.command: - cmd: "mv {{ ioc_base_dir }}/{{ orig_params_name }} {{ ioc_base_dir }}/{{ target_params_name }}" - removes: "{{ ioc_base_dir }}/{{ orig_params_name }}" # Only runs if the original file exists - -# Replace {{ agebd_env_suffix_upper }} inside the newly renamed subs file -- name: "[{{ target_service_name_lower }}] Substitute environment tokens inside subs file" - ansible.builtin.replace: - path: "{{ ioc_base_dir }}/{{ target_subs_name }}" - regexp: '\{\{\s*agebd_env_suffix_upper\s*\}\}' - replace: "{{ env_suffix_upper }}" - -# Replace {{ agebd_env_suffix_lower }} and {{ ioc_port }} inside the newly renamed params file -- name: "[{{ target_service_name_lower }}] Substitute environment token inside params file" - ansible.builtin.replace: - path: "{{ ioc_base_dir }}/{{ target_params_name }}" - regexp: "{{ item.regexp }}" - replace: "{{ item.replace | string }}" - with_items: - - { regexp: '\{\{\s*agebd_env_suffix_lower\s*\}\}', replace: "{{ env_suffix_lower }}" } - - { regexp: '\{\{\s*ioc_port\s*\}\}', replace: "{{ ioc_port }}" } - -- name: "[{{ target_service_name_lower }}] Run ioc install" - ansible.builtin.shell: - cmd: "ioc install -V --facility sls --ioc AGEBD-CPCL-{{ service_name_upper }}{{ env_suffix_upper }} --clean" - chdir: "{{ ioc_base_dir }}" - changed_when: true - register: ioc_install_result - # Force a pipeline failure if the command output contains error keywords - # (ioc install ... returns exit code 0 even on failure...) - failed_when: > - ioc_install_result.rc != 0 or - "[error]" in ioc_install_result.stderr or - "Unable to write" in ioc_install_result.stderr diff --git a/ansible/tasks/ioc/ioc-restart.yml b/ansible/tasks/ioc/ioc-restart.yml deleted file mode 100644 index ad637ac..0000000 --- a/ansible/tasks/ioc/ioc-restart.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: Init service name - ansible.builtin.import_tasks: ../utils/init-service-name.yml - -- name: Clone repo - ansible.builtin.import_tasks: ../utils/clone-repo.yml - -- name: "[{{ target_service_name_lower }}] Establish environment naming conventions" - ansible.builtin.set_fact: - service_name_upper: "{{ target_service_name_lower | upper }}" - -- name: "[{{ target_service_name_lower }}] Define file paths" - ansible.builtin.set_fact: - ioc_base_dir: "{{ workspace_dir }}/services/{{ target_service_name_lower }}/current/ioc" - -- name: "[{{ target_service_name_lower }}] Restart IOC" - ansible.builtin.shell: - cmd: "ioc restart AGEBD-CPCL-{{ service_name_upper }}{{ env_suffix_upper }}" - chdir: "{{ ioc_base_dir }}" - changed_when: true diff --git a/ansible/tasks/ioc/ioc-start.yml b/ansible/tasks/ioc/ioc-start.yml deleted file mode 100644 index 28d3e64..0000000 --- a/ansible/tasks/ioc/ioc-start.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: Init service name - ansible.builtin.import_tasks: ../utils/init-service-name.yml - -- name: Clone repo - ansible.builtin.import_tasks: ../utils/clone-repo.yml - -- name: Get and set ioc_port - ansible.builtin.import_tasks: ../utils/get-ioc-port.yml - -- name: "[{{ ioc_port }}] Start IOC" - ansible.builtin.shell: | - sudo shellbox status - sudo shellbox reload - sudo shellbox status - sudo shellbox start {{ ioc_port }} - changed_when: true diff --git a/ansible/tasks/service/service-deploy-and-restart.yml b/ansible/tasks/service/service-deploy-and-restart.yml deleted file mode 100644 index 0d38c27..0000000 --- a/ansible/tasks/service/service-deploy-and-restart.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- -- name: Initialize service name - ansible.builtin.set_fact: - # Uses preferred_service_name_lower if defined in vars, otherwise falls back to the CLI extra-vars - target_service_name_lower: "{{ preferred_service_name_lower | default(service_name_lower) }}" - -- name: "[{{ target_service_name_lower }}] Define service specific paths and names" - ansible.builtin.set_fact: - svc_current_dir: "/sls/bd/hla/{{ agebd_env }}/services/{{ target_service_name_lower }}/current" - service_unit_name: "AGEBD-SERVICE-{{ target_service_name_lower | upper }}.service" - -- name: "[{{ target_service_name_lower }}] Ensure target directory structure exists" - ansible.builtin.file: - path: "{{ svc_current_dir }}" - state: directory - # ansible.builtin.shell: | - # mkdir -p "{{ svc_current_dir }}" - -# TODO: make sure this is what we want (essentially wipes existing dest dir). Does it remove .venv? -- name: "[{{ target_service_name_lower }}] Sync service deployment files" - ansible.posix.synchronize: - src: "{{ repo_root }}/services/{{ target_service_name_lower }}/current/" - dest: "{{ svc_current_dir }}/" - delete: yes # This removes stale files on the target that no longer exist locally - recursive: yes - -- name: "[{{ target_service_name_lower }}] Substitute environment variable inline" - ansible.builtin.replace: - path: "{{ svc_current_dir }}/systemd/{{ service_unit_name }}" - regexp: '\{\{\s*agebd_env\s*\}\}' - replace: "{{ agebd_env }}" - - # systemctl --user link --force "./{{ service_unit_name }}" -- name: "[{{ target_service_name_lower }}] Symlink systemd unit file (Absolute Path)" - ansible.builtin.file: - src: "{{ svc_current_dir }}/systemd/{{ service_unit_name }}" - dest: "~/.config/systemd/user/{{ service_unit_name }}" - state: link - force: yes # This overwrites the broken/existing symlink cleanly without error - - # export XDG_RUNTIME_DIR=/run/user/$(id -u) - # systemctl --user daemon-reload - # systemctl --user enable "{{ service_unit_name }}" - # systemctl --user restart "{{ service_unit_name }}" -- name: "[{{ target_service_name_lower }}] Enable and Restart Systemd Service" - ansible.builtin.systemd_service: - name: "{{ service_unit_name }}" - scope: user - daemon_reload: yes - enabled: yes - state: restarted - environment: - XDG_RUNTIME_DIR: "/run/user/{{ ansible_user_uid }}" diff --git a/ansible/tasks/utils/clone-repo.yml b/ansible/tasks/utils/clone-repo.yml deleted file mode 100644 index 3c782bb..0000000 --- a/ansible/tasks/utils/clone-repo.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -- name: Clone this repository - ansible.builtin.git: - repo: "git@gitea.psi.ch:sls/hla_framework_bd.git" - dest: "{{ workspace_dir }}" - accept_hostkey: true - version: "{{ branch_name }}" - force: true diff --git a/ansible/tasks/utils/get-ioc-port.yml b/ansible/tasks/utils/get-ioc-port.yml deleted file mode 100644 index 2f18c69..0000000 --- a/ansible/tasks/utils/get-ioc-port.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -- name: Read the service registry file - ansible.builtin.slurp: - src: "{{ workspace_dir }}/config/services_registry.yml" - register: remote_registry_file - -- name: Parse the service registry YAML content into a fact - ansible.builtin.set_fact: - services_registry: "{{ remote_registry_file.content | b64decode | from_yaml }}" - -- name: Extract the port from the services registry and save it as a persistent fact - ansible.builtin.set_fact: - ioc_port: "{{ services_registry.services | selectattr('name', 'equalto', target_service_name_lower) | map(attribute='ioc_port') | first | default(none) }}" - -- name: Fail if the service or port wasn't found in the registry - ansible.builtin.fail: - msg: "Service '{{ target_service_name_lower }}' not found in services registry or port not set" - when: ioc_port | trim == "" or ioc_port is none diff --git a/ansible/tasks/utils/init-service-name.yml b/ansible/tasks/utils/init-service-name.yml deleted file mode 100644 index 46ad173..0000000 --- a/ansible/tasks/utils/init-service-name.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: Initialize service name - ansible.builtin.set_fact: - # Uses preferred_service_name_lower if defined in vars, otherwise falls back to the CLI extra-vars - target_service_name_lower: "{{ preferred_service_name_lower | default(service_name_lower) }}" diff --git a/cli/pyproject.toml b/cli/pyproject.toml index 0fa047f..e7728cf 100644 --- a/cli/pyproject.toml +++ b/cli/pyproject.toml @@ -9,8 +9,6 @@ authors = [ dependencies = [ "agebd", - "ansible>=8.7.0", - "ansible-runner>=2.4.3", "copier>=9.10.3", "pydantic>=2.13.4", "pydantic-settings>=2.14.2", diff --git a/cli/src/core/ansible.py b/cli/src/core/ansible.py deleted file mode 100644 index 445dca5..0000000 --- a/cli/src/core/ansible.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import sys - -import ansible_runner -import typer - -from agebd.utils import get_git_root -from core.enums import IOC_ENV - -ioc = typer.Typer(no_args_is_help=True) - -REPO_ROOT = get_git_root(__file__) - - -def run_playbook(playbook: str, env: IOC_ENV, vars: list[str]): - env_str = str(env) - if env_str not in ["dev", "prod"]: - raise ValueError("env must be 'dev' or 'prod'") - - current_env = os.environ.copy() - current_env["ANSIBLE_CONFIG"] = f"{REPO_ROOT}/ansible/ansible.cfg" - - extra_vars = [f"--extra-vars={var}" for var in vars] - out, err, rc = ansible_runner.run_command( - executable_cmd=f"ansible-playbook", - cmdline_args=[ - playbook, - "-i", - f"{REPO_ROOT}/ansible/inventories/{env_str}/hosts.yml", - *extra_vars, - "-v", - ], - envvars=current_env, - input_fd=sys.stdin, - output_fd=sys.stdout, - error_fd=sys.stderr, - ) - print("rc: {}".format(rc)) - print("out: {}".format(out)) - print("err: {}".format(err)) diff --git a/cli/src/core/enums.py b/cli/src/core/enums.py index fc6dae1..2379c23 100644 --- a/cli/src/core/enums.py +++ b/cli/src/core/enums.py @@ -6,14 +6,6 @@ class ServiceStatus(str, Enum): DISABLED = "disabled" -class IOC_ENV(str, Enum): - PROD = "prod" - DEV = "dev" - - def __str__(self) -> str: - return self.value - - class GuiOption(str, Enum): NEW = "new" EXISTING = "existing" diff --git a/cli/src/ioc.py b/cli/src/ioc.py deleted file mode 100644 index d0cd20c..0000000 --- a/cli/src/ioc.py +++ /dev/null @@ -1,112 +0,0 @@ -import typer - -from agebd.utils import get_git_root -from config.paths import Paths -from core.ansible import run_playbook -from core.enums import IOC_ENV -from models import ServiceRegistry - -ioc = typer.Typer(no_args_is_help=True) - -REPO_ROOT = get_git_root(__file__) - -ANSIBLE_PLAYBOOKS_DIR = REPO_ROOT / "ansible" / "playbooks" -IOC_PLAYBOOK_INSTALL = ANSIBLE_PLAYBOOKS_DIR / "ioc-install.yml" -IOC_PLAYBOOK_RESTART = ANSIBLE_PLAYBOOKS_DIR / "ioc-restart.yml" -IOC_PLAYBOOK_START = ANSIBLE_PLAYBOOKS_DIR / "ioc-start.yml" - -SERVICE_NAME_HELP = "Service name in lower case" - - -def _resolve_branch_name(branch_name: str | None, service_name_lower: str) -> str: - return branch_name or f"feature/add-service-{service_name_lower}" - - -def _get_registry_services(): - paths = Paths() - registry = ServiceRegistry.read_from_file(paths.service_registry_file) - return registry.get_services() - - -@ioc.command(no_args_is_help=True) -def install( - env: IOC_ENV = typer.Option(..., "--env"), - service_name_lower: str = typer.Option(..., "--service-name", "-s", help=SERVICE_NAME_HELP), - branch_name: str | None = typer.Option( - None, "--branch-name", "-b", help="Default is 'feature/add-service-{service-name}'" - ), -): - branch_name = _resolve_branch_name(branch_name, service_name_lower) - run_playbook( - playbook=str(IOC_PLAYBOOK_INSTALL), - env=env, - vars=[f"branch_name={branch_name}", f"service_name_lower={service_name_lower}"], - ) - - -@ioc.command(no_args_is_help=True) -def install_all( - env: IOC_ENV = typer.Option(..., "--env"), -): - for service in _get_registry_services(): - run_playbook( - playbook=str(IOC_PLAYBOOK_INSTALL), - env=env, - vars=["branch_name=main", f"service_name_lower={service.name_lower}"], - ) - - -@ioc.command(no_args_is_help=True) -def start( - env: IOC_ENV = typer.Option(..., "--env"), - service_name_lower: str = typer.Option(..., "--service-name", "-s", help=SERVICE_NAME_HELP), - branch_name: str | None = typer.Option( - None, "--branch-name", "-b", help="Default is 'feature/add-service-{service-name}'" - ), -): - branch_name = _resolve_branch_name(branch_name, service_name_lower) - run_playbook( - playbook=str(IOC_PLAYBOOK_START), - env=env, - vars=[f"service_name_lower={service_name_lower}", f"branch_name={branch_name}"], - ) - - -@ioc.command() -def start_all( - env: IOC_ENV = typer.Option(..., "--env"), -): - for service in _get_registry_services(): - run_playbook( - playbook=str(IOC_PLAYBOOK_START), - env=env, - vars=[f"service_name_lower={service.name_lower}"], - ) - - -@ioc.command(no_args_is_help=True) -def restart( - env: IOC_ENV = typer.Option(..., "--env"), - service_name_lower: str = typer.Option(..., "--service-name", "-s", help=SERVICE_NAME_HELP), - branch_name: str | None = typer.Option( - None, "--branch-name", "-b", help="Default is 'feature/add-service-{service-name}'" - ), -): - branch_name = _resolve_branch_name(branch_name, service_name_lower) - run_playbook( - playbook=str(IOC_PLAYBOOK_RESTART), - env=env, - vars=[f"branch_name={branch_name}", f"service_name_lower={service_name_lower}"], - ) - - -@ioc.command(no_args_is_help=True) -def restart_all( - env: IOC_ENV = typer.Option(..., "--env"), -): - for service in _get_registry_services(): - run_playbook( - playbook=str(IOC_PLAYBOOK_RESTART), - env=env, - vars=["branch_name=main", f"service_name_lower={service.name_lower}"], - ) diff --git a/cli/src/main.py b/cli/src/main.py index a23e705..7a5c16e 100644 --- a/cli/src/main.py +++ b/cli/src/main.py @@ -2,7 +2,6 @@ import logging import typer -import ioc import service logger = logging.getLogger(__name__) @@ -10,7 +9,6 @@ logger = logging.getLogger(__name__) cli = typer.Typer(no_args_is_help=True, add_completion=False) cli.add_typer(service.service, name="service") -cli.add_typer(ioc.ioc, name="ioc") if __name__ == "__main__": diff --git a/cli/uv.lock b/cli/uv.lock index d56b4cc..568ebd0 100644 --- a/cli/uv.lock +++ b/cli/uv.lock @@ -37,8 +37,6 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "agebd" }, - { name = "ansible" }, - { name = "ansible-runner" }, { name = "copier" }, { name = "pydantic" }, { name = "pydantic-settings" }, @@ -60,8 +58,6 @@ dev = [ [package.metadata] requires-dist = [ { name = "agebd", editable = "../packages/agebd" }, - { name = "ansible", specifier = ">=8.7.0" }, - { name = "ansible-runner", specifier = ">=2.4.3" }, { name = "copier", specifier = ">=9.10.3" }, { name = "pydantic", specifier = ">=2.13.4" }, { name = "pydantic-settings", specifier = ">=2.14.2" }, @@ -98,49 +94,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] -[[package]] -name = "ansible" -version = "10.7.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ansible-core" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d4/64/29fdff6fe7682342adb54802c1cd90b2272d382e1743089af88f90a1d986/ansible-10.7.0.tar.gz", hash = "sha256:59d29e3de1080e740dfa974517d455217601b16d16880314d9be26145c68dc22", size = 41256974, upload-time = "2024-12-03T18:04:25.794Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/95/cb8944902a2cdd94b1e19ff73695548679a388b9c473dc63c8dc64ffea3a/ansible-10.7.0-py3-none-any.whl", hash = "sha256:0089f08e047ceb70edd011be009f5c6273add613fbe491e9697c0556c989d8ea", size = 51576038, upload-time = "2024-12-03T18:04:20.065Z" }, -] - -[[package]] -name = "ansible-core" -version = "2.17.14" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cryptography" }, - { name = "jinja2" }, - { name = "packaging" }, - { name = "pyyaml" }, - { name = "resolvelib" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ff/80/2925a0564f6f99a8002c3be3885b83c3a1dc5f57ebf00163f528889865f5/ansible_core-2.17.14.tar.gz", hash = "sha256:7c17fee39f8c29d70e3282a7e9c10bd70d5cd4fd13ddffc5dcaa52adbd142ff8", size = 3119687, upload-time = "2025-09-08T18:28:03.158Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/86/29/d694562f1a875b50aa74f691521fe493704f79cf1938cd58f28f7e2327d2/ansible_core-2.17.14-py3-none-any.whl", hash = "sha256:34a49582a57c2f2af17ede2cefd3b3602a2d55d22089f3928570d52030cafa35", size = 2189656, upload-time = "2025-09-08T18:28:00.375Z" }, -] - -[[package]] -name = "ansible-runner" -version = "2.4.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "packaging" }, - { name = "pexpect" }, - { name = "python-daemon" }, - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/68/4f/62222b42b52cc771db51ccc77ffac19cc5f0196ff61de7c93585845a819b/ansible_runner-2.4.3.tar.gz", hash = "sha256:5f3025529bb968fdc3b627457dd8d418dbf9d53bc73735d50e69c28544d53031", size = 154148, upload-time = "2026-03-16T18:42:14.861Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/89/fa7f81db6134caa455c9351373ee934b5fdeed212eb939d6c42d80d683d7/ansible_runner-2.4.3-py3-none-any.whl", hash = "sha256:cdac6daa151a50084ffda710e769db23fa975fc0507796191d7708831b286e37", size = 80257, upload-time = "2026-03-16T18:42:13.72Z" }, -] - [[package]] name = "asttokens" version = "3.0.2" @@ -150,29 +103,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/2b/04b8a15f3a1c77bc79ddf5c73875327f34b4fa75982df2b76e45e402d364/asttokens-3.0.2-py3-none-any.whl", hash = "sha256:9da13157f5b28becde0bd374fc677dcd3c290614264eff096f167c469cd9f933", size = 28702, upload-time = "2026-07-12T03:31:47.542Z" }, ] -[[package]] -name = "cffi" -version = "2.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pycparser", marker = "implementation_name != 'PyPy'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/57/5f/ff100cae70ebe9d8df1c01a00e510e45d9adb5c1fdda84791b199141de97/cffi-2.1.0.tar.gz", hash = "sha256:efc1cdd798b1aaf39b4610bba7aad28c9bea9b910f25c784ccf9ec1fa719d1f9", size = 531036, upload-time = "2026-07-06T21:34:30.382Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/e9/6d7724983b3d5a0908dbf74f64038ade77c18646ff6636ec7894fd392ce1/cffi-2.1.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:b65f590ef2a44640f9a05dbb548a429b4ade77913ce683ac8b1480777658a6c0", size = 183837, upload-time = "2026-07-06T21:32:09.655Z" }, - { url = "https://files.pythonhosted.org/packages/69/aa/24580a278de21fd7322635556334d9b535f1cbc00b0a3919447cdf464c65/cffi-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164bff1657b2a74f0b6d54e11c9b375bc97b931f2ca9c43fcf875838da1570dd", size = 184226, upload-time = "2026-07-06T21:32:11.196Z" }, - { url = "https://files.pythonhosted.org/packages/88/a9/02cae418ec4beb282ace11958d9d4737793439d561fadc7e6d56f2e2b354/cffi-2.1.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:c941bb58d5a6e1c3892d86e42927ed6c180302f07e6d395d08c416e594b98b46", size = 211107, upload-time = "2026-07-06T21:32:12.328Z" }, - { url = "https://files.pythonhosted.org/packages/3b/30/c806937ed5e4c2c7ac30d9d6b76b5dc57ff8b75d83800d9bb11a8253cf2a/cffi-2.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a016194dbe13d14ee9556e734b772d8d67b947092b268d757fd4290e3ba2dfc2", size = 218733, upload-time = "2026-07-06T21:32:13.67Z" }, - { url = "https://files.pythonhosted.org/packages/f9/cf/398272b8bbfd58aa314fda5a7f1cdbb26d1d78ae324a11211521315dd1f0/cffi-2.1.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:03e9810d18c646077e501f661b682fbf5dee4676048527ca3cffe66faa9960dd", size = 205543, upload-time = "2026-07-06T21:32:15.148Z" }, - { url = "https://files.pythonhosted.org/packages/45/ca/f91641185cdd90c36d317a9dc7f85e88ef8682d8b300977baff5e23c35d8/cffi-2.1.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:19c54ac121cad98450b4896fa9a43ee0180d57bc4bc911a33db6cab1efab6cd3", size = 205460, upload-time = "2026-07-06T21:32:16.479Z" }, - { url = "https://files.pythonhosted.org/packages/38/66/04781a77b411f0bb5b234d62c1814754ab75ebe455ccff1b08e8d7aae98f/cffi-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d433a51f1870e43a13b6732f92aaf540ff77c2015097c78556f75a2d6c030e0", size = 218760, upload-time = "2026-07-06T21:32:17.98Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9a/bb1d5ed9c3fcae158e9f6391bf309c95d98c2ac37ed56573228471d0af5e/cffi-2.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3d7f118b5adbfdfead90c25822690b02bc8074fba949bb7858bec4ebd55adb43", size = 221230, upload-time = "2026-07-06T21:32:19.407Z" }, - { url = "https://files.pythonhosted.org/packages/41/aa/3c1409cdd26094efacd1c36c66e0a6eb9d4296e4fd4f9901b8b2042f4323/cffi-2.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c5f5df567f6eb216de69be06ce55c8b714090fae02b18a3b40da8163b8c5fa9c", size = 213524, upload-time = "2026-07-06T21:32:20.828Z" }, - { url = "https://files.pythonhosted.org/packages/fa/75/74dfb7c3fc6ebbd408038476bd4c1d7e925c62614e7b9c534ecc34218288/cffi-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:11b3fb55f4f8ad92274ed26705f65d8f91457de71f5380061eb6d125a768fecd", size = 220341, upload-time = "2026-07-06T21:32:21.9Z" }, - { url = "https://files.pythonhosted.org/packages/70/b6/9003c33a3e7d2c1306f5962e646457dcfe5a8cd8fce6bbe02d7af25db783/cffi-2.1.0-cp310-cp310-win32.whl", hash = "sha256:9d72af0cf10a76a600a9690078fe31c63b9588c8e86bf9fd353f713c84b5db0f", size = 174578, upload-time = "2026-07-06T21:32:23.073Z" }, - { url = "https://files.pythonhosted.org/packages/8a/26/710688310447531c7a22f857c7f79d9855ec18b03e04494ced723fb37e2f/cffi-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb62edb5bb52cca65fab91a63afa7561607120d26090a7e8fda6fb9f064726da", size = 185071, upload-time = "2026-07-06T21:32:24.671Z" }, -] - [[package]] name = "colorama" version = "0.4.6" @@ -207,44 +137,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/22/2c/68dec88ee26f96af2d4d8ee9d8567313a0826f4fd6bc5ae4527be670d354/copier-9.17.0-py3-none-any.whl", hash = "sha256:fe4e7b59faf4c0e1386eccbb79c6797e6df33ca20d5de49a8372571d8669f2ad", size = 65954, upload-time = "2026-07-13T14:33:03.301Z" }, ] -[[package]] -name = "cryptography" -version = "49.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1f/99/d1c90d6041656cc6ee229dc99cd67fd0cd5aec3c5f7d72fffc27cc750054/cryptography-49.0.0.tar.gz", hash = "sha256:f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493", size = 854345, upload-time = "2026-06-12T20:02:30.512Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/22/adf66990e63584a68dfb50c24f48a125c07b1699899381c8151e63ed458c/cryptography-49.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:966fe0e9c67490071f14c0d2b1cb2dfb3023c5ce39457343931415f08382f2db", size = 4032100, upload-time = "2026-06-12T20:02:32.143Z" }, - { url = "https://files.pythonhosted.org/packages/09/41/3797cfaf69cae04a13ee78ebd83f0678d9c02b4779d21ce24445326f1a69/cryptography-49.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36d1709f992593689b45bda411498d62c6e365f2ca00b84657d4dadd24de16db", size = 4692978, upload-time = "2026-06-12T20:01:21.305Z" }, - { url = "https://files.pythonhosted.org/packages/e6/8b/43011f7ebe515a8aa20d61f290a326cd890c2e738e16e59eaff8d9c3a412/cryptography-49.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e959b578856a3924bc0cbb710fc12c387b9412a951389f3ca61704a9e25f325", size = 4716422, upload-time = "2026-06-12T20:01:48.566Z" }, - { url = "https://files.pythonhosted.org/packages/4a/91/01ce7303a4579e6d3a6abef01bd322848e9ea7a219adcabc5048b9033571/cryptography-49.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:53ecee2e23f7169b6117e99fc8a944e5e50f79e69758a83b52a00cb98ab2b2d2", size = 4700503, upload-time = "2026-06-12T20:02:47.091Z" }, - { url = "https://files.pythonhosted.org/packages/62/99/a2c95cf8293f07491e9e27c20cc4dcd18176d944e674679adeb1d0173fd6/cryptography-49.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:2eda353d8a27bcbcaa4cbed18994a74ab4d19a2ca897db188ea269ab9b71419b", size = 5309779, upload-time = "2026-06-12T20:02:08.987Z" }, - { url = "https://files.pythonhosted.org/packages/20/2c/0622f20ff02b2ef32558733443805dc82fd4c275be01b2d19d14676f3a1b/cryptography-49.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2afe9051da7ae7bd5905da5a949280c7d2bb75682e188f650a9d0f2756b834c6", size = 4749683, upload-time = "2026-06-12T20:02:03.335Z" }, - { url = "https://files.pythonhosted.org/packages/a3/5b/c5246635d5fd3b64e0d45ae10e99fd32fe9676a79915ccfe5a61ba9af1a5/cryptography-49.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:0b82e28ee398a386f0807bba7884d30f25218855690f45115831bcce5d90822c", size = 4337874, upload-time = "2026-06-12T20:02:54.323Z" }, - { url = "https://files.pythonhosted.org/packages/6d/88/05563c7fe2e914e87d1a536d06fe83e66b4e1d95cb593e05aea375531da8/cryptography-49.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ccac2bfebc306b862133e3bb71f3f6ee8bb525240089b2d952e4144b3a6d5da7", size = 4700283, upload-time = "2026-06-12T20:01:34.822Z" }, - { url = "https://files.pythonhosted.org/packages/c4/b6/d7696e4e890d6ae1469935164c9e5215c557671cb78d6e3f458ccceaa632/cryptography-49.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:d0527ce944105f257f605a827d6ebead966c752038b6e8656abb9c5edee6fc68", size = 5265844, upload-time = "2026-06-12T20:01:24.09Z" }, - { url = "https://files.pythonhosted.org/packages/a9/3c/f3ad17eecc1a57b0ba236dc01f90e783c51f4a2f35f64777cc4f47a184b2/cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:cbc77da8c523d5abd028635ba850a6966fcee2c82e2bf65a41d1d8afe0f98be9", size = 4749290, upload-time = "2026-06-12T20:01:30.848Z" }, - { url = "https://files.pythonhosted.org/packages/4f/01/339573cf1023163a400b0b5d16f6d507de413b9f60be6fd1b77feeaf6737/cryptography-49.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b87e65d263b3e5d3bb92a57e2a6638e2f31110fa7aa890c7b2dbba42248d0a3f", size = 4834612, upload-time = "2026-06-12T20:01:29.246Z" }, - { url = "https://files.pythonhosted.org/packages/71/fd/577302e213a1be9468f92d1afef66fcf1ef83d516819d9992ca547f592bd/cryptography-49.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:66ec79c3904820572d7e987abdf304281f141d37ad9a489b8e97066e7b9b6459", size = 4980804, upload-time = "2026-06-12T20:01:42.853Z" }, - { url = "https://files.pythonhosted.org/packages/1f/09/f42b1d190c5ba75f72062a387f8030d1d75f6ab035788f1d9c4b01de6525/cryptography-49.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:e5dfc1e64de5677cec922ffa8da89c546d0415bf6efdf081842e5d44c84e1f0e", size = 3810026, upload-time = "2026-06-12T20:02:39.262Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/5bb823f5bedcf80718cea7fbc95ec5515cca3769633c4b01a32be7f30e7c/cryptography-49.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ec5e529fb80935c94fe7b729f9972b50e351a0e6b50aa294fd5cabb109fcc29a", size = 4025947, upload-time = "2026-06-12T20:01:25.745Z" }, - { url = "https://files.pythonhosted.org/packages/3d/df/40577043ca124e17012f408ddddaeb213b856336ac82ddb3bc915f39e29f/cryptography-49.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f78ff2c9ed8dc2d036b0f4d640e22522213d047c1b14e61205a7e55c80a494d4", size = 4692429, upload-time = "2026-06-12T20:01:53.628Z" }, - { url = "https://files.pythonhosted.org/packages/2c/99/2d13299eb3dd27b02dcfaafcc91d6b5cb3329f7cbd6d8f51921acd566c1a/cryptography-49.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:35b151772baff2c74cba7fa290ceaff4c3b11c0c881eb93eb5dbc05a7cfbba18", size = 4700968, upload-time = "2026-06-12T20:02:45.383Z" }, - { url = "https://files.pythonhosted.org/packages/a5/4d/9c0cd02f95e2602dd5e563da149ee0830abef3537be8b34dc56281ebe27a/cryptography-49.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0f21641cf4b30fca7aee061ced0ec7ad7b073518088b7c9969a297c0ae796c69", size = 4697758, upload-time = "2026-06-12T20:01:41.13Z" }, - { url = "https://files.pythonhosted.org/packages/24/01/186c825898477d77e2324d5360fefe622ff1d8d1963ec0554e2cada8ec77/cryptography-49.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9e82dcc8e56052715fb18b2429e3bca4823b1629136a2084fc45a9a5cecb9b64", size = 5298863, upload-time = "2026-06-12T20:02:24.579Z" }, - { url = "https://files.pythonhosted.org/packages/b8/7b/62cbbab75d0659865bf0273790031544a0b16c8072d258f9428dcd8190dc/cryptography-49.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6f2debedf9ca60cf1d5bd466475638af5130f89965605cd818484d19987d3a21", size = 4735983, upload-time = "2026-06-12T20:01:50.14Z" }, - { url = "https://files.pythonhosted.org/packages/6c/72/3e798c064bc39e471008075d0f9bc9daf77a80879c092e4a8e170c585ed4/cryptography-49.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:8c25ceb16df5b9435f3f6a9829204985b0e0cbee3b48aacd432c7d2c850b44d9", size = 4334173, upload-time = "2026-06-12T20:01:44.743Z" }, - { url = "https://files.pythonhosted.org/packages/f0/ee/6fca21d1ac73e06f8bef71940abfd4d2f6472b4bca284d770f32bd4086f6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:28d8b15e6275f12c8a207dc309dfa957903c927d08d0cc937ee3f63f200693cc", size = 4697298, upload-time = "2026-06-12T20:02:20.918Z" }, - { url = "https://files.pythonhosted.org/packages/67/d0/a5fcd3515f0bae49a7b6d0413cc1bdccdcc1fc0047037a0d480642cdc5d6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6fc361c34fb6aac015ce19435876635e5c6d21db31998b0920f675f131e043b8", size = 5254338, upload-time = "2026-06-12T20:02:22.737Z" }, - { url = "https://files.pythonhosted.org/packages/a0/84/84fe36f19caf857d61cb7fc9c63035a47ffabd84ea12d1d393148efa3615/cryptography-49.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2400ef9c9e2299a25614eb1dea3db54a69b1349efd043bfac9c67630d136df36", size = 4735650, upload-time = "2026-06-12T20:02:41.389Z" }, - { url = "https://files.pythonhosted.org/packages/6c/a0/db537264e234f7273a73ec020873d6d6b39dfd8a53db78b550ca8320440e/cryptography-49.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:67e1d20ad9ef3a563c59ef22e7a8a0b8210bd26604369ea4a30a7c66aefe504e", size = 4834820, upload-time = "2026-06-12T20:01:51.847Z" }, - { url = "https://files.pythonhosted.org/packages/93/77/8df9eb486495979bccecd1062e2eaf435250e84437040295b57d09048b0b/cryptography-49.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:42b0684e0e40cf26122427802486f6d93aea593612603a94fbf260c7eb1e9c1b", size = 4967968, upload-time = "2026-06-12T20:02:12.524Z" }, - { url = "https://files.pythonhosted.org/packages/c2/e6/f60198ea8d9dfa15fff9ed4ca02ce362f6eadd9ba757dcc50634c4257b63/cryptography-49.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:026ac7423e6fa66872d3bf889be5974507da3944f866f704fa200eadacd00001", size = 3785547, upload-time = "2026-06-12T20:02:26.847Z" }, -] - [[package]] name = "decorator" version = "5.3.1" @@ -406,15 +298,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl", hash = "sha256:e1082f5564917649c76fed239117820610516ec10f87735d0338688800a55b34", size = 18975, upload-time = "2022-06-30T14:08:49.571Z" }, ] -[[package]] -name = "lockfile" -version = "0.12.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/17/47/72cb04a58a35ec495f96984dddb48232b551aafb95bde614605b754fe6f7/lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799", size = 20874, upload-time = "2015-11-25T18:29:58.279Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/22/9460e311f340cb62d26a38c419b1381b8593b0bb6b5d1f056938b086d362/lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa", size = 13564, upload-time = "2015-11-25T18:29:51.462Z" }, -] - [[package]] name = "markdown-it-py" version = "4.2.0" @@ -597,15 +480,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, ] -[[package]] -name = "pycparser" -version = "3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, -] - [[package]] name = "pydantic" version = "2.13.4" @@ -748,18 +622,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5a/cc/06253936f4a7fa2e0f48dfe6d851d9c56df896a9ab09ac019d70b760619c/pytest_mock-3.15.1-py3-none-any.whl", hash = "sha256:0a25e2eb88fe5168d535041d09a4529a188176ae608a6d249ee65abc0949630d", size = 10095, upload-time = "2025-09-16T16:37:25.734Z" }, ] -[[package]] -name = "python-daemon" -version = "3.1.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "lockfile" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3d/37/4f10e37bdabc058a32989da2daf29e57dc59dbc5395497f3d36d5f5e2694/python_daemon-3.1.2.tar.gz", hash = "sha256:f7b04335adc473de877f5117e26d5f1142f4c9f7cd765408f0877757be5afbf4", size = 71576, upload-time = "2024-12-03T08:41:07.843Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/45/3c/b88167e2d6785c0e781ee5d498b07472aeb9b6765da3b19e7cc9e0813841/python_daemon-3.1.2-py3-none-any.whl", hash = "sha256:b906833cef63502994ad48e2eab213259ed9bb18d54fa8774dcba2ff7864cec6", size = 30872, upload-time = "2024-12-03T08:41:03.322Z" }, -] - [[package]] name = "python-dotenv" version = "1.2.2" @@ -798,15 +660,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl", hash = "sha256:a51af13f345f1cdea62347589fbb6df3b290306ab8930713bfae4d475a7d4a59", size = 36753, upload-time = "2025-08-28T19:00:19.56Z" }, ] -[[package]] -name = "resolvelib" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ce/10/f699366ce577423cbc3df3280063099054c23df70856465080798c6ebad6/resolvelib-1.0.1.tar.gz", hash = "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309", size = 21065, upload-time = "2023-03-09T05:10:38.292Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/fc/e9ccf0521607bcd244aa0b3fbd574f71b65e9ce6a112c83af988bbbe2e23/resolvelib-1.0.1-py2.py3-none-any.whl", hash = "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf", size = 17194, upload-time = "2023-03-09T05:10:36.214Z" }, -] - [[package]] name = "rich" version = "15.0.0" diff --git a/docs/developer/ansible.md b/docs/developer/ansible.md deleted file mode 100644 index 28d55c1..0000000 --- a/docs/developer/ansible.md +++ /dev/null @@ -1,36 +0,0 @@ -# Ansible - -## Running a playbook manually - -Set vars on command line: - -``` -ansible-playbook ansible/playbooks/add-new-service.yml \ - -i ansible/hosts.yml \ - --extra-vars="repo_root=${{ github.workspace }} agebd_env=dev service_name_lower=" \ - -v -``` - -### Install an IOC -``` -ansible-playbook ansible/playbooks/ioc-install.yml \ - -i ansible/hosts.yml \ - --extra-vars="agebd_env=dev branch_name=feature/add-service-playground service_name_lower=playground ioc_port=50003" \ - -v -``` - -### Start an IOC -``` -ansible-playbook ansible/playbooks/ioc-start.yml \ - -i ansible/hosts.yml \ - --extra-vars="service_name_lower=playground ioc_port=50003" \ - -v -``` - -### Restart an IOC -``` -ansible-playbook ansible/playbooks/ioc-restart.yml \ - -i ansible/hosts.yml \ - --extra-vars="agebd_env=dev branch_name=feature/add-service-playground service_name_lower=playground" \ - -v -``` diff --git a/docs/developer/cicd_runner.md b/docs/developer/cicd_runner.md index 1efa972..06b0d9b 100644 --- a/docs/developer/cicd_runner.md +++ b/docs/developer/cicd_runner.md @@ -3,9 +3,11 @@ ## Hosts - `sls-vserv-bd-01(-dev)` - - Runs shellbox commands (and `ioc install ...`?) + - Runs the shellbox commands, which the runner triggers over `ssh` + (see `.gitea/scripts/ioc-start.sh`) - `sls-vserv-bd-hla01(-dev)` - - Runs everything else + - Runs the runner itself, and therefore everything else: the deployments + to `/sls/bd/hla//` and the `ioc ...` commands ## Setup @@ -182,3 +184,28 @@ The gitea actions run as user `svcusr-sls2hla` ### #TODO: this is a temporary workaround I created an ssh key on `sls-vserv-bd-hla01-dev` (where the runner runs), and added the public key to my gitea profile ssh keys. That way the `svcusr` can clone the repos I can clone. + + +## Setup `sls-vserv-bd-01-dev` + +On `sls-vserv-bd-hla01-dev` + +``` +sudo su - svcusr-sls2hla +cat ~/.ssh/id_ed25519.pub +``` + +If it does not exist yet: +``` +sudo su - svcusr-sls2hla +ssh-keygen -t ed25519 -N "" -C "svcusr-sls2hla@sls-vserv-bd-hla01-dev" -f ~/.ssh/id_ed25519 +cat ~/.ssh/id_ed25519.pub +``` + +``` +ssh sls-vserv-bd-01-dev # lands as your own user +sudo install -d -m 700 -o svcusr-sls2hla -g unx-nogroup /home/svcusr-sls2hla /home/svcusr-sls2hla/.ssh +echo '' | sudo tee /home/svcusr-sls2hla/.ssh/authorized_keys +sudo chown svcusr-sls2hla:unx-nogroup /home/svcusr-sls2hla/.ssh/authorized_keys +sudo chmod 600 /home/svcusr-sls2hla/.ssh/authorized_keys +``` diff --git a/docs/developer/ioc/ioc.md b/docs/developer/ioc/ioc.md index 96b1d08..c4eef02 100644 --- a/docs/developer/ioc/ioc.md +++ b/docs/developer/ioc/ioc.md @@ -1,6 +1,8 @@ # IOC -The following instructions explain the basics of starting and managing IOCs on the IOC host. +The following instructions explain the basics of starting and managing IOCs on the IOC host. +They describe the manual steps. In practice the CI/CD runner does this for you, see +[Automation](#automation) below. - TODO: some iocs not associated to a service, where to put? - TODO: need to dev/prod template them too @@ -92,3 +94,20 @@ sudo shellbox start 50045 # start ioc sudo shellbox log 50045 -f # log file (tail) exit # exit ssh ``` + + +## Automation + +Installing, starting and restarting IOCs is done by the gitea runner, not by hand: + +- `.gitea/scripts/ioc-install.sh ` +- `.gitea/scripts/ioc-start.sh ` (shellbox, over `ssh`) +- `.gitea/scripts/ioc-restart.sh ` + +The scripts operate on the deployed IOC files in +`/sls/bd/hla//services//current/ioc`, so a service has to be deployed +before its IOC can be installed. + +They run automatically when a new service is added (`.gitea/workflows/add-new-service.yml`), +and can be triggered manually for any service (or `all` services) through the `Ioc` workflow +(`.gitea/workflows/ioc.yml`) in the gitea Actions tab. From e6e1d32e5a7764d264f0160d95fce2a2362229d3 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Tue, 25 Aug 2026 14:41:07 +0200 Subject: [PATCH 03/30] docs: ioc commands manual workflows --- docs/developer/ioc/ioc.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/developer/ioc/ioc.md b/docs/developer/ioc/ioc.md index c4eef02..2bcea75 100644 --- a/docs/developer/ioc/ioc.md +++ b/docs/developer/ioc/ioc.md @@ -110,4 +110,8 @@ before its IOC can be installed. They run automatically when a new service is added (`.gitea/workflows/add-new-service.yml`), and can be triggered manually for any service (or `all` services) through the `Ioc` workflow -(`.gitea/workflows/ioc.yml`) in the gitea Actions tab. +(`.gitea/workflows/ioc.yml`) in the gitea Actions tab: + +``` +Actions tab > Ioc (row on left side) > Run Workflow +``` From e326ef3b3fd713453360268d4945ab5b1ae305a9 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Tue, 25 Aug 2026 15:33:04 +0200 Subject: [PATCH 04/30] docs: ioc user --- docs/developer/ioc/ioc.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/developer/ioc/ioc.md b/docs/developer/ioc/ioc.md index 2bcea75..724997c 100644 --- a/docs/developer/ioc/ioc.md +++ b/docs/developer/ioc/ioc.md @@ -108,10 +108,13 @@ The scripts operate on the deployed IOC files in `/sls/bd/hla//services//current/ioc`, so a service has to be deployed before its IOC can be installed. -They run automatically when a new service is added (`.gitea/workflows/add-new-service.yml`), -and can be triggered manually for any service (or `all` services) through the `Ioc` workflow +They run automatically when a new service is added (`.gitea/workflows/add-new-service.yml`). + +## Manual CICD Workflow trigger + +IOC commands can be triggered manually for any service (or `all` services) through the `Ioc` workflow (`.gitea/workflows/ioc.yml`) in the gitea Actions tab: ``` -Actions tab > Ioc (row on left side) > Run Workflow +Gitea Repo > Actions tab > Ioc (row on left side) > Run Workflow ``` From 0e6dfe5e97910c1193941e6a622c3c68083590bc Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Wed, 26 Aug 2026 10:50:29 +0200 Subject: [PATCH 05/30] test: cicd --- bin/start_service.sh | 2 +- packages/agebd/src/agebd/service/pvs.py | 2 +- services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py | 2 +- .../injectionguard/current/app/src/agebd_injectionguard/main.py | 2 +- services/master/current/app/src/agebd_master/main.py | 2 +- services/plots/current/app/src/agebd_plots/main.py | 2 +- .../postmortemlog/current/app/src/agebd_postmortemlog/main.py | 2 +- services/scrubbing/current/app/src/agebd_scrubbing/main.py | 2 +- services/shifttool/current/app/src/agebd_shifttool/main.py | 2 +- services/taubpm/current/app/src/agebd_taubpm/main.py | 2 +- services/taupct/current/app/src/agebd_taupct/main.py | 2 +- services/timing/current/app/src/agebd_timing/main.py | 2 +- services/topuptool/current/app/src/agebd_topuptool/main.py | 2 +- services/tune/current/app/src/agebd_tune/main.py | 2 +- services/tunebump/current/app/src/agebd_tunebump/main.py | 2 +- services/tunefbx/current/app/src/agebd_tunefbx/main.py | 2 +- services/tunefby/current/app/src/agebd_tunefby/main.py | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/bin/start_service.sh b/bin/start_service.sh index 40dfde6..b839287 100755 --- a/bin/start_service.sh +++ b/bin/start_service.sh @@ -43,4 +43,4 @@ source ${APP_DIR}/.venv/bin/activate # TODO: use `exec python3 ...` here? python -u -B -m agebd_${SVC_NAME_LOWER_UNDERSCORES}.main -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 diff --git a/packages/agebd/src/agebd/service/pvs.py b/packages/agebd/src/agebd/service/pvs.py index 41687c0..41e3c33 100644 --- a/packages/agebd/src/agebd/service/pvs.py +++ b/packages/agebd/src/agebd/service/pvs.py @@ -1,6 +1,6 @@ from agebd.pv import PVLink -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 class BasePVs: diff --git a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py index aaeec5f..f431e39 100644 --- a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py +++ b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_dbpm3curr import PVs, Service from agebd_dbpm3curr.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/injectionguard/current/app/src/agebd_injectionguard/main.py b/services/injectionguard/current/app/src/agebd_injectionguard/main.py index 6d5ea4b..74b9989 100644 --- a/services/injectionguard/current/app/src/agebd_injectionguard/main.py +++ b/services/injectionguard/current/app/src/agebd_injectionguard/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_injectionguard import PVs, Service from agebd_injectionguard.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/master/current/app/src/agebd_master/main.py b/services/master/current/app/src/agebd_master/main.py index a3da2f5..9c4fe1b 100644 --- a/services/master/current/app/src/agebd_master/main.py +++ b/services/master/current/app/src/agebd_master/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_master import PVs, Service from agebd_master.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/plots/current/app/src/agebd_plots/main.py b/services/plots/current/app/src/agebd_plots/main.py index 4817e6d..af3ad0c 100644 --- a/services/plots/current/app/src/agebd_plots/main.py +++ b/services/plots/current/app/src/agebd_plots/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_plots import PVs, Service from agebd_plots.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py index 9f1f67d..fedddd7 100644 --- a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py +++ b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_postmortemlog import PVs, Service from agebd_postmortemlog.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/main.py b/services/scrubbing/current/app/src/agebd_scrubbing/main.py index d8b627b..87ebd05 100644 --- a/services/scrubbing/current/app/src/agebd_scrubbing/main.py +++ b/services/scrubbing/current/app/src/agebd_scrubbing/main.py @@ -6,7 +6,7 @@ from agebd_scrubbing import PVs, Service from agebd_scrubbing.runner import Runner from agebd_scrubbing.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/shifttool/current/app/src/agebd_shifttool/main.py b/services/shifttool/current/app/src/agebd_shifttool/main.py index cab7b15..6fda854 100644 --- a/services/shifttool/current/app/src/agebd_shifttool/main.py +++ b/services/shifttool/current/app/src/agebd_shifttool/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_shifttool import PVs, Service from agebd_shifttool.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/taubpm/current/app/src/agebd_taubpm/main.py b/services/taubpm/current/app/src/agebd_taubpm/main.py index 403a49f..7778449 100644 --- a/services/taubpm/current/app/src/agebd_taubpm/main.py +++ b/services/taubpm/current/app/src/agebd_taubpm/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taubpm import PVs, Service from agebd_taubpm.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/taupct/current/app/src/agebd_taupct/main.py b/services/taupct/current/app/src/agebd_taupct/main.py index 57aa867..80574cc 100644 --- a/services/taupct/current/app/src/agebd_taupct/main.py +++ b/services/taupct/current/app/src/agebd_taupct/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taupct import PVs, Service from agebd_taupct.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/timing/current/app/src/agebd_timing/main.py b/services/timing/current/app/src/agebd_timing/main.py index df4c2be..8415f0b 100644 --- a/services/timing/current/app/src/agebd_timing/main.py +++ b/services/timing/current/app/src/agebd_timing/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_timing import PVs, Service from agebd_timing.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/topuptool/current/app/src/agebd_topuptool/main.py b/services/topuptool/current/app/src/agebd_topuptool/main.py index a2b43c8..175bbcf 100644 --- a/services/topuptool/current/app/src/agebd_topuptool/main.py +++ b/services/topuptool/current/app/src/agebd_topuptool/main.py @@ -6,7 +6,7 @@ from agebd_topuptool import PVs, Service from agebd_topuptool.runner import Runner from agebd_topuptool.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/tune/current/app/src/agebd_tune/main.py b/services/tune/current/app/src/agebd_tune/main.py index eadd7ef..831e6b4 100644 --- a/services/tune/current/app/src/agebd_tune/main.py +++ b/services/tune/current/app/src/agebd_tune/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tune import PVs, Service from agebd_tune.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/tunebump/current/app/src/agebd_tunebump/main.py b/services/tunebump/current/app/src/agebd_tunebump/main.py index a39d6a6..309020b 100644 --- a/services/tunebump/current/app/src/agebd_tunebump/main.py +++ b/services/tunebump/current/app/src/agebd_tunebump/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunebump import PVs, Service from agebd_tunebump.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/tunefbx/current/app/src/agebd_tunefbx/main.py b/services/tunefbx/current/app/src/agebd_tunefbx/main.py index 132cd1c..eff1b04 100644 --- a/services/tunefbx/current/app/src/agebd_tunefbx/main.py +++ b/services/tunefbx/current/app/src/agebd_tunefbx/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunefbx import PVs, Service from agebd_tunefbx.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( diff --git a/services/tunefby/current/app/src/agebd_tunefby/main.py b/services/tunefby/current/app/src/agebd_tunefby/main.py index d00fa2f..07f2fd4 100644 --- a/services/tunefby/current/app/src/agebd_tunefby/main.py +++ b/services/tunefby/current/app/src/agebd_tunefby/main.py @@ -7,7 +7,7 @@ from agebd_tunefby import PVs, Service from agebd_tunefby.service import SERVICE_NAME -# TODO: remove: cicd test 54 +# TODO: remove: cicd test 55 def main( log_level: LogLevel = typer.Option( From 1289fa05a1b3b78717e4a1142d22bad9ee123a79 Mon Sep 17 00:00:00 2001 From: labrec_b Date: Wed, 26 Aug 2026 11:00:41 +0200 Subject: [PATCH 06/30] chore: substitute env vars in qt/ files during deploy time (#72) substitute env vars in qt/ files during deploy time Reviewed-on: https://gitea.psi.ch/sls/hla_framework_bd/pulls/72 --- .gitea/scripts/common.sh | 28 ++++++++++++++++++---------- .gitea/workflows/deploy.yml | 6 ++++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/.gitea/scripts/common.sh b/.gitea/scripts/common.sh index d681b86..387a396 100644 --- a/.gitea/scripts/common.sh +++ b/.gitea/scripts/common.sh @@ -5,6 +5,23 @@ # Overridable so the scripts can be exercised outside of the runner HLA_ROOT=${HLA_ROOT:-/sls/bd/hla} +# Sets AGEBD_ENV_SUFFIX_UPPER/LOWER for the given environment. +# Usage: set_env_suffix +set_env_suffix() { + local ENV=$1 + + if [ "${ENV}" = "dev" ]; then + AGEBD_ENV_SUFFIX_UPPER="-DEV" + AGEBD_ENV_SUFFIX_LOWER="-dev" + elif [ "${ENV}" = "prod" ]; then + AGEBD_ENV_SUFFIX_UPPER="" + AGEBD_ENV_SUFFIX_LOWER="" + else + echo "Unknown environment '${ENV}', expected 'dev' or 'prod'" >&2 + exit 1 + fi +} + # Sets the naming and path variables used by the deploy and ioc scripts. # Usage: init_service_env init_service_env() { @@ -16,16 +33,7 @@ init_service_env() { exit 1 fi - if [ "${AGEBD_ENV}" = "dev" ]; then - AGEBD_ENV_SUFFIX_UPPER="-DEV" - AGEBD_ENV_SUFFIX_LOWER="-dev" - elif [ "${AGEBD_ENV}" = "prod" ]; then - AGEBD_ENV_SUFFIX_UPPER="" - AGEBD_ENV_SUFFIX_LOWER="" - else - echo "Unknown environment '${AGEBD_ENV}', expected 'dev' or 'prod'" >&2 - exit 1 - fi + set_env_suffix "${AGEBD_ENV}" SERVICE_NAME_LOWER=$(echo "${SERVICE_NAME}" | tr '[:upper:]' '[:lower:]') SERVICE_NAME_UPPER=$(echo "${SERVICE_NAME}" | tr '[:lower:]' '[:upper:]') diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index ef7e9ff..b97a9b4 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -116,6 +116,12 @@ jobs: --exclude='.pytest_cache/' \ ./qt/* "${DEST_DIR}/" + ### SUBSTITUTIONS + source "${{ github.workspace }}/.gitea/scripts/common.sh" + set_env_suffix "${AGEBD_ENV}" + sed -i "s/{{ *agebd_env_suffix_upper* }}/${AGEBD_ENV_SUFFIX_UPPER}/g" "${DEST_DIR}/"* + sed -i "s/{{ *agebd_env_suffix_lower* }}/${AGEBD_ENV_SUFFIX_LOWER}/g" "${DEST_DIR}/"* + # ----------------------------------------------------------------- # Services Detection, Testing, and Deployment # ----------------------------------------------------------------- From 0020d2d1ed08560ca1791eed35b2cda10a63d36c Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Wed, 26 Aug 2026 11:01:24 +0200 Subject: [PATCH 07/30] test: cicd --- bin/start_service.sh | 2 +- packages/agebd/src/agebd/service/pvs.py | 2 +- services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py | 2 +- .../injectionguard/current/app/src/agebd_injectionguard/main.py | 2 +- services/master/current/app/src/agebd_master/main.py | 2 +- services/plots/current/app/src/agebd_plots/main.py | 2 +- .../postmortemlog/current/app/src/agebd_postmortemlog/main.py | 2 +- services/scrubbing/current/app/src/agebd_scrubbing/main.py | 2 +- services/shifttool/current/app/src/agebd_shifttool/main.py | 2 +- services/taubpm/current/app/src/agebd_taubpm/main.py | 2 +- services/taupct/current/app/src/agebd_taupct/main.py | 2 +- services/timing/current/app/src/agebd_timing/main.py | 2 +- services/topuptool/current/app/src/agebd_topuptool/main.py | 2 +- services/tune/current/app/src/agebd_tune/main.py | 2 +- services/tunebump/current/app/src/agebd_tunebump/main.py | 2 +- services/tunefbx/current/app/src/agebd_tunefbx/main.py | 2 +- services/tunefby/current/app/src/agebd_tunefby/main.py | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/bin/start_service.sh b/bin/start_service.sh index b839287..b2bdf28 100755 --- a/bin/start_service.sh +++ b/bin/start_service.sh @@ -43,4 +43,4 @@ source ${APP_DIR}/.venv/bin/activate # TODO: use `exec python3 ...` here? python -u -B -m agebd_${SVC_NAME_LOWER_UNDERSCORES}.main -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 diff --git a/packages/agebd/src/agebd/service/pvs.py b/packages/agebd/src/agebd/service/pvs.py index 41e3c33..268594a 100644 --- a/packages/agebd/src/agebd/service/pvs.py +++ b/packages/agebd/src/agebd/service/pvs.py @@ -1,6 +1,6 @@ from agebd.pv import PVLink -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 class BasePVs: diff --git a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py index f431e39..1dae714 100644 --- a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py +++ b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_dbpm3curr import PVs, Service from agebd_dbpm3curr.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/injectionguard/current/app/src/agebd_injectionguard/main.py b/services/injectionguard/current/app/src/agebd_injectionguard/main.py index 74b9989..542f1e1 100644 --- a/services/injectionguard/current/app/src/agebd_injectionguard/main.py +++ b/services/injectionguard/current/app/src/agebd_injectionguard/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_injectionguard import PVs, Service from agebd_injectionguard.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/master/current/app/src/agebd_master/main.py b/services/master/current/app/src/agebd_master/main.py index 9c4fe1b..5e262a2 100644 --- a/services/master/current/app/src/agebd_master/main.py +++ b/services/master/current/app/src/agebd_master/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_master import PVs, Service from agebd_master.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/plots/current/app/src/agebd_plots/main.py b/services/plots/current/app/src/agebd_plots/main.py index af3ad0c..458f3b0 100644 --- a/services/plots/current/app/src/agebd_plots/main.py +++ b/services/plots/current/app/src/agebd_plots/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_plots import PVs, Service from agebd_plots.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py index fedddd7..14c14a6 100644 --- a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py +++ b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_postmortemlog import PVs, Service from agebd_postmortemlog.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/main.py b/services/scrubbing/current/app/src/agebd_scrubbing/main.py index 87ebd05..d1c1956 100644 --- a/services/scrubbing/current/app/src/agebd_scrubbing/main.py +++ b/services/scrubbing/current/app/src/agebd_scrubbing/main.py @@ -6,7 +6,7 @@ from agebd_scrubbing import PVs, Service from agebd_scrubbing.runner import Runner from agebd_scrubbing.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/shifttool/current/app/src/agebd_shifttool/main.py b/services/shifttool/current/app/src/agebd_shifttool/main.py index 6fda854..0987be2 100644 --- a/services/shifttool/current/app/src/agebd_shifttool/main.py +++ b/services/shifttool/current/app/src/agebd_shifttool/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_shifttool import PVs, Service from agebd_shifttool.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/taubpm/current/app/src/agebd_taubpm/main.py b/services/taubpm/current/app/src/agebd_taubpm/main.py index 7778449..8159884 100644 --- a/services/taubpm/current/app/src/agebd_taubpm/main.py +++ b/services/taubpm/current/app/src/agebd_taubpm/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taubpm import PVs, Service from agebd_taubpm.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/taupct/current/app/src/agebd_taupct/main.py b/services/taupct/current/app/src/agebd_taupct/main.py index 80574cc..ad70977 100644 --- a/services/taupct/current/app/src/agebd_taupct/main.py +++ b/services/taupct/current/app/src/agebd_taupct/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taupct import PVs, Service from agebd_taupct.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/timing/current/app/src/agebd_timing/main.py b/services/timing/current/app/src/agebd_timing/main.py index 8415f0b..d0b2648 100644 --- a/services/timing/current/app/src/agebd_timing/main.py +++ b/services/timing/current/app/src/agebd_timing/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_timing import PVs, Service from agebd_timing.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/topuptool/current/app/src/agebd_topuptool/main.py b/services/topuptool/current/app/src/agebd_topuptool/main.py index 175bbcf..8b465bf 100644 --- a/services/topuptool/current/app/src/agebd_topuptool/main.py +++ b/services/topuptool/current/app/src/agebd_topuptool/main.py @@ -6,7 +6,7 @@ from agebd_topuptool import PVs, Service from agebd_topuptool.runner import Runner from agebd_topuptool.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/tune/current/app/src/agebd_tune/main.py b/services/tune/current/app/src/agebd_tune/main.py index 831e6b4..613791d 100644 --- a/services/tune/current/app/src/agebd_tune/main.py +++ b/services/tune/current/app/src/agebd_tune/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tune import PVs, Service from agebd_tune.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/tunebump/current/app/src/agebd_tunebump/main.py b/services/tunebump/current/app/src/agebd_tunebump/main.py index 309020b..a4f6f38 100644 --- a/services/tunebump/current/app/src/agebd_tunebump/main.py +++ b/services/tunebump/current/app/src/agebd_tunebump/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunebump import PVs, Service from agebd_tunebump.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/tunefbx/current/app/src/agebd_tunefbx/main.py b/services/tunefbx/current/app/src/agebd_tunefbx/main.py index eff1b04..794667a 100644 --- a/services/tunefbx/current/app/src/agebd_tunefbx/main.py +++ b/services/tunefbx/current/app/src/agebd_tunefbx/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunefbx import PVs, Service from agebd_tunefbx.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( diff --git a/services/tunefby/current/app/src/agebd_tunefby/main.py b/services/tunefby/current/app/src/agebd_tunefby/main.py index 07f2fd4..747f04c 100644 --- a/services/tunefby/current/app/src/agebd_tunefby/main.py +++ b/services/tunefby/current/app/src/agebd_tunefby/main.py @@ -7,7 +7,7 @@ from agebd_tunefby import PVs, Service from agebd_tunefby.service import SERVICE_NAME -# TODO: remove: cicd test 55 +# TODO: remove: cicd test 56 def main( log_level: LogLevel = typer.Option( From f302f973bc6afd69cfdb7ea6918342d63670b77a Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Wed, 26 Aug 2026 11:09:04 +0200 Subject: [PATCH 08/30] test: cicd --- bin/start_service.sh | 2 +- .../qt/A_BD_TestService99-X00.ui | 1 + packages/agebd/src/agebd/service/pvs.py | 2 +- qt/A_BD_DBPM3Curr.ui | 1 + qt/A_BD_FeedBackOverview.ui | 1 + qt/A_BD_FeedBackOverview_inc.ui | 1 + qt/A_BD_InjectionGuard.ui | 1 + qt/A_BD_InjectionGuard_inc.ui | 1 + qt/A_BD_Master.ui | 1 + qt/A_BD_NTurns.ui | 1 + qt/A_BD_OrbitBump.ui | 1 + qt/A_BD_OrbitBump_Expert.ui | 1 + qt/A_BD_OrbitBump_ExpertBackUp.ui | 1 + qt/A_BD_OrbitBump_Expert_all.ui | 1 + qt/A_BD_OrbitBump_Expert_inc.ui | 1 + qt/A_BD_OrbitBump_Operator.ui | 1 + qt/A_BD_OrbitBump_Operator_inc.ui | 1 + qt/A_BD_PostMortemLog.ui | 1 + qt/A_BD_Scrubbing.ui | 774 +----------------- qt/A_BD_ServiceManager_inc.ui | 1 + qt/A_BD_TauBPM.ui | 1 + qt/A_BD_TauPCT.ui | 1 + qt/A_BD_Timing.ui | 1 + qt/A_BD_TopUpTool.ui | 1 + qt/A_BD_Tune.ui | 1 + qt/A_BD_TuneBump.ui | 1 + .../current/app/src/agebd_dbpm3curr/main.py | 2 +- .../app/src/agebd_injectionguard/main.py | 2 +- .../current/app/src/agebd_master/main.py | 2 +- .../plots/current/app/src/agebd_plots/main.py | 2 +- .../app/src/agebd_postmortemlog/main.py | 2 +- .../current/app/src/agebd_scrubbing/main.py | 2 +- .../current/app/src/agebd_shifttool/main.py | 2 +- .../current/app/src/agebd_taubpm/main.py | 2 +- .../current/app/src/agebd_taupct/main.py | 2 +- .../current/app/src/agebd_timing/main.py | 2 +- .../current/app/src/agebd_topuptool/main.py | 2 +- .../tune/current/app/src/agebd_tune/main.py | 2 +- .../current/app/src/agebd_tunebump/main.py | 2 +- .../current/app/src/agebd_tunefbx/main.py | 2 +- .../current/app/src/agebd_tunefby/main.py | 2 +- templates/qt/A_BD_{{ui_filename}}.ui.jinja | 1 + 42 files changed, 42 insertions(+), 790 deletions(-) diff --git a/bin/start_service.sh b/bin/start_service.sh index b2bdf28..49d915e 100755 --- a/bin/start_service.sh +++ b/bin/start_service.sh @@ -43,4 +43,4 @@ source ${APP_DIR}/.venv/bin/activate # TODO: use `exec python3 ...` here? python -u -B -m agebd_${SVC_NAME_LOWER_UNDERSCORES}.main -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 diff --git a/cli/tests/fixtures/expected_output/qt/A_BD_TestService99-X00.ui b/cli/tests/fixtures/expected_output/qt/A_BD_TestService99-X00.ui index 3e964b9..c9fddf7 100644 --- a/cli/tests/fixtures/expected_output/qt/A_BD_TestService99-X00.ui +++ b/cli/tests/fixtures/expected_output/qt/A_BD_TestService99-X00.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/packages/agebd/src/agebd/service/pvs.py b/packages/agebd/src/agebd/service/pvs.py index 268594a..319b594 100644 --- a/packages/agebd/src/agebd/service/pvs.py +++ b/packages/agebd/src/agebd/service/pvs.py @@ -1,6 +1,6 @@ from agebd.pv import PVLink -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 class BasePVs: diff --git a/qt/A_BD_DBPM3Curr.ui b/qt/A_BD_DBPM3Curr.ui index 288be53..3e9c88d 100644 --- a/qt/A_BD_DBPM3Curr.ui +++ b/qt/A_BD_DBPM3Curr.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_FeedBackOverview.ui b/qt/A_BD_FeedBackOverview.ui index afac466..cd90ba0 100644 --- a/qt/A_BD_FeedBackOverview.ui +++ b/qt/A_BD_FeedBackOverview.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_FeedBackOverview_inc.ui b/qt/A_BD_FeedBackOverview_inc.ui index 953c2f6..be82de8 100644 --- a/qt/A_BD_FeedBackOverview_inc.ui +++ b/qt/A_BD_FeedBackOverview_inc.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_InjectionGuard.ui b/qt/A_BD_InjectionGuard.ui index 4393d06..1cf5b81 100644 --- a/qt/A_BD_InjectionGuard.ui +++ b/qt/A_BD_InjectionGuard.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_InjectionGuard_inc.ui b/qt/A_BD_InjectionGuard_inc.ui index 12b4b31..69343aa 100644 --- a/qt/A_BD_InjectionGuard_inc.ui +++ b/qt/A_BD_InjectionGuard_inc.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_Master.ui b/qt/A_BD_Master.ui index 96b5a3c..de50885 100644 --- a/qt/A_BD_Master.ui +++ b/qt/A_BD_Master.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_NTurns.ui b/qt/A_BD_NTurns.ui index 0921764..14188a6 100644 --- a/qt/A_BD_NTurns.ui +++ b/qt/A_BD_NTurns.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_OrbitBump.ui b/qt/A_BD_OrbitBump.ui index 64c3c4e..0370d55 100644 --- a/qt/A_BD_OrbitBump.ui +++ b/qt/A_BD_OrbitBump.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_OrbitBump_Expert.ui b/qt/A_BD_OrbitBump_Expert.ui index 328eafb..6f652b8 100644 --- a/qt/A_BD_OrbitBump_Expert.ui +++ b/qt/A_BD_OrbitBump_Expert.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_OrbitBump_ExpertBackUp.ui b/qt/A_BD_OrbitBump_ExpertBackUp.ui index 18fac9c..01600ea 100644 --- a/qt/A_BD_OrbitBump_ExpertBackUp.ui +++ b/qt/A_BD_OrbitBump_ExpertBackUp.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_OrbitBump_Expert_all.ui b/qt/A_BD_OrbitBump_Expert_all.ui index b5f2dd1..8fbfd9a 100644 --- a/qt/A_BD_OrbitBump_Expert_all.ui +++ b/qt/A_BD_OrbitBump_Expert_all.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_OrbitBump_Expert_inc.ui b/qt/A_BD_OrbitBump_Expert_inc.ui index 1d0a058..fa6c550 100644 --- a/qt/A_BD_OrbitBump_Expert_inc.ui +++ b/qt/A_BD_OrbitBump_Expert_inc.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_OrbitBump_Operator.ui b/qt/A_BD_OrbitBump_Operator.ui index 0a66761..1d7f6c4 100644 --- a/qt/A_BD_OrbitBump_Operator.ui +++ b/qt/A_BD_OrbitBump_Operator.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_OrbitBump_Operator_inc.ui b/qt/A_BD_OrbitBump_Operator_inc.ui index 3d59a56..40952db 100644 --- a/qt/A_BD_OrbitBump_Operator_inc.ui +++ b/qt/A_BD_OrbitBump_Operator_inc.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_PostMortemLog.ui b/qt/A_BD_PostMortemLog.ui index bf7f8f7..2715a40 100644 --- a/qt/A_BD_PostMortemLog.ui +++ b/qt/A_BD_PostMortemLog.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_Scrubbing.ui b/qt/A_BD_Scrubbing.ui index 0c96232..3f66f82 100644 --- a/qt/A_BD_Scrubbing.ui +++ b/qt/A_BD_Scrubbing.ui @@ -1,3 +1,4 @@ + MainWindow @@ -4551,776 +4552,3 @@ AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:CONTROL-VACUUM-DYN-FRAC 35 - - - 16 - 75 - true - - - - AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:CONTROL-SCRUB - - - - - - 10 - 20 - 191 - 40 - - - - - 20 - 75 - true - - - - Scrubbing - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - ESimpleLabel::None - - - - - - 0 - 95 - 360 - 85 - - - - - 85 - 170 - 0 - - - - caFrame::Calc - - - A>3 - - - AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:CONTROL-SCRUB - - - - - 230 - 45 - 100 - 35 - - - - - Monospace - 13 - PreferDefault - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - ARSGE-CECL-MBFB:MBFB-T-Y-DDS-FRQ - - - - 160 - 160 - 164 - - - - caLineEdit::Default - - - caLineEdit::User - - - caLineEdit::None - - - true - - - - - - 65 - 45 - 100 - 35 - - - - 3 - - - 0 - - - AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:MBFBY-GAIN-SP.VAL - - - caSpinbox::User - - - true - - - caSpinbox::User - - - 100.000000000000000 - - - 0.000000000000000 - - - - - - 230 - 5 - 100 - 35 - - - - - Monospace - 13 - PreferDefault - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - ARSGE-CECL-MBFB:MBFB-T-X-DDS-FRQ - - - - 160 - 160 - 164 - - - - caLineEdit::Default - - - caLineEdit::User - - - caLineEdit::None - - - true - - - - - - 10 - 45 - 45 - 35 - - - - - 8 - 75 - true - - - - MBFBy - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 65 - 5 - 100 - 35 - - - - 3 - - - 0 - - - AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:MBFBX-GAIN-SP.VAL - - - caSpinbox::User - - - true - - - caSpinbox::User - - - 100.000000000000000 - - - 0.000000000000000 - - - - - - 10 - 5 - 45 - 35 - - - - - 8 - 75 - true - - - - MBFBx - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 175 - 45 - 45 - 35 - - - - - Monospace - 13 - PreferDefault - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - ARSGE-CECL-MBFB:MBFB-T-Y-DDS-GAIN - - - - 160 - 160 - 164 - - - - caLineEdit::Default - - - caLineEdit::User - - - caLineEdit::None - - - false - - - - - - 175 - 5 - 45 - 35 - - - - - Monospace - 13 - PreferDefault - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - ARSGE-CECL-MBFB:MBFB-T-X-DDS-GAIN - - - - 160 - 160 - 164 - - - - caLineEdit::Default - - - caLineEdit::User - - - caLineEdit::None - - - false - - - - - - 335 - 5 - 17 - 17 - - - - true - - - false - - - 15 - - - 15 - - - -ARSGE-MBFBT-AMP-03:SET-ON-OFF - - - - 0 - 255 - 0 - - - - - - - 335 - 23 - 17 - 17 - - - - true - - - false - - - 15 - - - 15 - - - -ARSGE-MBFBT-AMP-04:SET-ON-OFF - - - - 0 - 255 - 0 - - - - - - - 335 - 45 - 17 - 17 - - - - true - - - false - - - 15 - - - 15 - - - ARSGE-MBFBT-AMP-01:SET-ON-OFF - - - - 0 - 255 - 0 - - - - - - - 335 - 63 - 17 - 17 - - - - true - - - false - - - 15 - - - 15 - - - -ARSGE-MBFBT-AMP-02:SET-ON-OFF - - - - 0 - 255 - 0 - - - - - - - - 0 - 95 - 360 - 85 - - - - - 85 - 170 - 0 - - - - caFrame::Calc - - - A<4 & A>0 - - - AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:CONTROL-SCRUB - - - - - 70 - 45 - 150 - 35 - - - - 4 - - - 2 - - - ARS01-MKIK-0320:I-SET - - - caSpinbox::User - - - true - - - caSpinbox::User - - - 100.000000000000000 - - - 0.000000000000000 - - - - - - 10 - 45 - 50 - 35 - - - - - 10 - 75 - true - - - - PINGy - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 70 - 5 - 150 - 35 - - - - 4 - - - 2 - - - ARS01-MKIK-0290:I-SET - - - caSpinbox::User - - - true - - - caSpinbox::User - - - 100.000000000000000 - - - 0.000000000000000 - - - - - - 10 - 5 - 50 - 35 - - - - - 10 - 75 - true - - - - PINGx - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 230 - 5 - 35 - 35 - - - - - 35 - 35 - - - - ARS01-MKIK-0290:CTRL-ON-OFF - - - - - - 230 - 45 - 35 - 35 - - - - - 35 - 35 - - - - ARS01-MKIK-0320:CTRL-ON-OFF - - - - - - - - - caMenu - QComboBox -
caMenu
-
- - caChoice - QWidget -
caChoice
-
- - caTextEntry - caLineEdit -
caTextEntry
-
- - caMessageButton - QPushButton -
caMessageButton
-
- - caToggleButton - QCheckBox -
caToggleButton
-
- - caSpinbox - QFrame -
caSpinbox
-
- - caFrame - QFrame -
caFrame
- 1 -
- - caLabel - QLabel -
caLabel
-
- - caGraphics - QWidget -
caGraphics
-
- - caLed - QWidget -
caLed
-
- - caLineEdit - QLineEdit -
caLineEdit
-
- - caCartesianPlot - QwtPlot -
caCartesianPlot
-
- - caStripPlot - QwtPlot -
caStripPlot
- 1 -
- - caCalc - QLabel -
caCalc
-
- - wmSignalPropagator - QLabel -
wmSignalPropagator
-
- - QwtPlot - QFrame -
qwt_plot.h
-
-
- - - - cacalc_2 - emitSignal(bool) - wmsignalpropagator - reloadwindow() - - - 2020 - 374 - - - 2022 - 545 - - - - -
diff --git a/qt/A_BD_ServiceManager_inc.ui b/qt/A_BD_ServiceManager_inc.ui index 4f030fb..839f39d 100644 --- a/qt/A_BD_ServiceManager_inc.ui +++ b/qt/A_BD_ServiceManager_inc.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_TauBPM.ui b/qt/A_BD_TauBPM.ui index 9460e95..1d9f7e1 100644 --- a/qt/A_BD_TauBPM.ui +++ b/qt/A_BD_TauBPM.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_TauPCT.ui b/qt/A_BD_TauPCT.ui index 31c3115..c1ab872 100644 --- a/qt/A_BD_TauPCT.ui +++ b/qt/A_BD_TauPCT.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_Timing.ui b/qt/A_BD_Timing.ui index 3b78166..13dece5 100644 --- a/qt/A_BD_Timing.ui +++ b/qt/A_BD_Timing.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_TopUpTool.ui b/qt/A_BD_TopUpTool.ui index cb126f5..6e52e5d 100644 --- a/qt/A_BD_TopUpTool.ui +++ b/qt/A_BD_TopUpTool.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_Tune.ui b/qt/A_BD_Tune.ui index d6b6403..eb124cc 100644 --- a/qt/A_BD_Tune.ui +++ b/qt/A_BD_Tune.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/qt/A_BD_TuneBump.ui b/qt/A_BD_TuneBump.ui index 55eff01..6f80b81 100644 --- a/qt/A_BD_TuneBump.ui +++ b/qt/A_BD_TuneBump.ui @@ -1,3 +1,4 @@ + MainWindow diff --git a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py index 1dae714..64cbe76 100644 --- a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py +++ b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_dbpm3curr import PVs, Service from agebd_dbpm3curr.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/injectionguard/current/app/src/agebd_injectionguard/main.py b/services/injectionguard/current/app/src/agebd_injectionguard/main.py index 542f1e1..9f6d5c5 100644 --- a/services/injectionguard/current/app/src/agebd_injectionguard/main.py +++ b/services/injectionguard/current/app/src/agebd_injectionguard/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_injectionguard import PVs, Service from agebd_injectionguard.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/master/current/app/src/agebd_master/main.py b/services/master/current/app/src/agebd_master/main.py index 5e262a2..75ef091 100644 --- a/services/master/current/app/src/agebd_master/main.py +++ b/services/master/current/app/src/agebd_master/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_master import PVs, Service from agebd_master.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/plots/current/app/src/agebd_plots/main.py b/services/plots/current/app/src/agebd_plots/main.py index 458f3b0..d0fd47d 100644 --- a/services/plots/current/app/src/agebd_plots/main.py +++ b/services/plots/current/app/src/agebd_plots/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_plots import PVs, Service from agebd_plots.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py index 14c14a6..d924566 100644 --- a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py +++ b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_postmortemlog import PVs, Service from agebd_postmortemlog.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/main.py b/services/scrubbing/current/app/src/agebd_scrubbing/main.py index d1c1956..6226f63 100644 --- a/services/scrubbing/current/app/src/agebd_scrubbing/main.py +++ b/services/scrubbing/current/app/src/agebd_scrubbing/main.py @@ -6,7 +6,7 @@ from agebd_scrubbing import PVs, Service from agebd_scrubbing.runner import Runner from agebd_scrubbing.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/shifttool/current/app/src/agebd_shifttool/main.py b/services/shifttool/current/app/src/agebd_shifttool/main.py index 0987be2..23e54d4 100644 --- a/services/shifttool/current/app/src/agebd_shifttool/main.py +++ b/services/shifttool/current/app/src/agebd_shifttool/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_shifttool import PVs, Service from agebd_shifttool.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/taubpm/current/app/src/agebd_taubpm/main.py b/services/taubpm/current/app/src/agebd_taubpm/main.py index 8159884..a22845f 100644 --- a/services/taubpm/current/app/src/agebd_taubpm/main.py +++ b/services/taubpm/current/app/src/agebd_taubpm/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taubpm import PVs, Service from agebd_taubpm.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/taupct/current/app/src/agebd_taupct/main.py b/services/taupct/current/app/src/agebd_taupct/main.py index ad70977..9984c3d 100644 --- a/services/taupct/current/app/src/agebd_taupct/main.py +++ b/services/taupct/current/app/src/agebd_taupct/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taupct import PVs, Service from agebd_taupct.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/timing/current/app/src/agebd_timing/main.py b/services/timing/current/app/src/agebd_timing/main.py index d0b2648..a4c0937 100644 --- a/services/timing/current/app/src/agebd_timing/main.py +++ b/services/timing/current/app/src/agebd_timing/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_timing import PVs, Service from agebd_timing.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/topuptool/current/app/src/agebd_topuptool/main.py b/services/topuptool/current/app/src/agebd_topuptool/main.py index 8b465bf..ba12f29 100644 --- a/services/topuptool/current/app/src/agebd_topuptool/main.py +++ b/services/topuptool/current/app/src/agebd_topuptool/main.py @@ -6,7 +6,7 @@ from agebd_topuptool import PVs, Service from agebd_topuptool.runner import Runner from agebd_topuptool.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/tune/current/app/src/agebd_tune/main.py b/services/tune/current/app/src/agebd_tune/main.py index 613791d..ece0a01 100644 --- a/services/tune/current/app/src/agebd_tune/main.py +++ b/services/tune/current/app/src/agebd_tune/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tune import PVs, Service from agebd_tune.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/tunebump/current/app/src/agebd_tunebump/main.py b/services/tunebump/current/app/src/agebd_tunebump/main.py index a4f6f38..de620d3 100644 --- a/services/tunebump/current/app/src/agebd_tunebump/main.py +++ b/services/tunebump/current/app/src/agebd_tunebump/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunebump import PVs, Service from agebd_tunebump.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/tunefbx/current/app/src/agebd_tunefbx/main.py b/services/tunefbx/current/app/src/agebd_tunefbx/main.py index 794667a..ffeabbc 100644 --- a/services/tunefbx/current/app/src/agebd_tunefbx/main.py +++ b/services/tunefbx/current/app/src/agebd_tunefbx/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunefbx import PVs, Service from agebd_tunefbx.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( diff --git a/services/tunefby/current/app/src/agebd_tunefby/main.py b/services/tunefby/current/app/src/agebd_tunefby/main.py index 747f04c..ca7aa74 100644 --- a/services/tunefby/current/app/src/agebd_tunefby/main.py +++ b/services/tunefby/current/app/src/agebd_tunefby/main.py @@ -7,7 +7,7 @@ from agebd_tunefby import PVs, Service from agebd_tunefby.service import SERVICE_NAME -# TODO: remove: cicd test 56 +# TODO: remove: cicd test 57 def main( log_level: LogLevel = typer.Option( diff --git a/templates/qt/A_BD_{{ui_filename}}.ui.jinja b/templates/qt/A_BD_{{ui_filename}}.ui.jinja index 307ae6d..0663bd4 100644 --- a/templates/qt/A_BD_{{ui_filename}}.ui.jinja +++ b/templates/qt/A_BD_{{ui_filename}}.ui.jinja @@ -1,3 +1,4 @@ + MainWindow From bebc53d7049414236e313495b96ff36fec92987b Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Wed, 26 Aug 2026 11:16:47 +0200 Subject: [PATCH 09/30] fix: move qt/ cicd test comments --- qt/A_BD_DBPM3Curr.ui | 2 +- qt/A_BD_FeedBackOverview.ui | 2 +- qt/A_BD_FeedBackOverview_inc.ui | 2 +- qt/A_BD_InjectionGuard.ui | 2 +- qt/A_BD_InjectionGuard_inc.ui | 2 +- qt/A_BD_Master.ui | 2 +- qt/A_BD_NTurns.ui | 2 +- qt/A_BD_OrbitBump.ui | 2 +- qt/A_BD_OrbitBump_Expert.ui | 2 +- qt/A_BD_OrbitBump_ExpertBackUp.ui | 2 +- qt/A_BD_OrbitBump_Expert_all.ui | 2 +- qt/A_BD_OrbitBump_Expert_inc.ui | 2 +- qt/A_BD_OrbitBump_Operator.ui | 2 +- qt/A_BD_OrbitBump_Operator_inc.ui | 2 +- qt/A_BD_PostMortemLog.ui | 2 +- qt/A_BD_Scrubbing.ui | 775 +++++++++++++++++++++++++++++- qt/A_BD_ServiceManager_inc.ui | 2 +- qt/A_BD_TauBPM.ui | 2 +- qt/A_BD_TauPCT.ui | 2 +- qt/A_BD_Timing.ui | 2 +- qt/A_BD_TopUpTool.ui | 2 +- qt/A_BD_Tune.ui | 2 +- qt/A_BD_TuneBump.ui | 2 +- 23 files changed, 796 insertions(+), 23 deletions(-) diff --git a/qt/A_BD_DBPM3Curr.ui b/qt/A_BD_DBPM3Curr.ui index 3e9c88d..350323b 100644 --- a/qt/A_BD_DBPM3Curr.ui +++ b/qt/A_BD_DBPM3Curr.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_FeedBackOverview.ui b/qt/A_BD_FeedBackOverview.ui index cd90ba0..be6df57 100644 --- a/qt/A_BD_FeedBackOverview.ui +++ b/qt/A_BD_FeedBackOverview.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_FeedBackOverview_inc.ui b/qt/A_BD_FeedBackOverview_inc.ui index be82de8..c2e527c 100644 --- a/qt/A_BD_FeedBackOverview_inc.ui +++ b/qt/A_BD_FeedBackOverview_inc.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_InjectionGuard.ui b/qt/A_BD_InjectionGuard.ui index 1cf5b81..b037d9f 100644 --- a/qt/A_BD_InjectionGuard.ui +++ b/qt/A_BD_InjectionGuard.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_InjectionGuard_inc.ui b/qt/A_BD_InjectionGuard_inc.ui index 69343aa..3a42b4d 100644 --- a/qt/A_BD_InjectionGuard_inc.ui +++ b/qt/A_BD_InjectionGuard_inc.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_Master.ui b/qt/A_BD_Master.ui index de50885..2e3ed38 100644 --- a/qt/A_BD_Master.ui +++ b/qt/A_BD_Master.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_NTurns.ui b/qt/A_BD_NTurns.ui index 14188a6..39e9cf3 100644 --- a/qt/A_BD_NTurns.ui +++ b/qt/A_BD_NTurns.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_OrbitBump.ui b/qt/A_BD_OrbitBump.ui index 0370d55..d248f98 100644 --- a/qt/A_BD_OrbitBump.ui +++ b/qt/A_BD_OrbitBump.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_OrbitBump_Expert.ui b/qt/A_BD_OrbitBump_Expert.ui index 6f652b8..9155f42 100644 --- a/qt/A_BD_OrbitBump_Expert.ui +++ b/qt/A_BD_OrbitBump_Expert.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_OrbitBump_ExpertBackUp.ui b/qt/A_BD_OrbitBump_ExpertBackUp.ui index 01600ea..272110f 100644 --- a/qt/A_BD_OrbitBump_ExpertBackUp.ui +++ b/qt/A_BD_OrbitBump_ExpertBackUp.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_OrbitBump_Expert_all.ui b/qt/A_BD_OrbitBump_Expert_all.ui index 8fbfd9a..05a106f 100644 --- a/qt/A_BD_OrbitBump_Expert_all.ui +++ b/qt/A_BD_OrbitBump_Expert_all.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_OrbitBump_Expert_inc.ui b/qt/A_BD_OrbitBump_Expert_inc.ui index fa6c550..77781a2 100644 --- a/qt/A_BD_OrbitBump_Expert_inc.ui +++ b/qt/A_BD_OrbitBump_Expert_inc.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_OrbitBump_Operator.ui b/qt/A_BD_OrbitBump_Operator.ui index 1d7f6c4..44e9ac5 100644 --- a/qt/A_BD_OrbitBump_Operator.ui +++ b/qt/A_BD_OrbitBump_Operator.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_OrbitBump_Operator_inc.ui b/qt/A_BD_OrbitBump_Operator_inc.ui index 40952db..51fdace 100644 --- a/qt/A_BD_OrbitBump_Operator_inc.ui +++ b/qt/A_BD_OrbitBump_Operator_inc.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_PostMortemLog.ui b/qt/A_BD_PostMortemLog.ui index 2715a40..ef605fb 100644 --- a/qt/A_BD_PostMortemLog.ui +++ b/qt/A_BD_PostMortemLog.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_Scrubbing.ui b/qt/A_BD_Scrubbing.ui index 3f66f82..fa49779 100644 --- a/qt/A_BD_Scrubbing.ui +++ b/qt/A_BD_Scrubbing.ui @@ -1,5 +1,5 @@ - + MainWindow @@ -4552,3 +4552,776 @@ AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:CONTROL-VACUUM-DYN-FRAC 35 + + + 16 + 75 + true + + + + AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:CONTROL-SCRUB + + + + + + 10 + 20 + 191 + 40 + + + + + 20 + 75 + true + + + + Scrubbing + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + ESimpleLabel::None + + + + + + 0 + 95 + 360 + 85 + + + + + 85 + 170 + 0 + + + + caFrame::Calc + + + A>3 + + + AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:CONTROL-SCRUB + + + + + 230 + 45 + 100 + 35 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + ARSGE-CECL-MBFB:MBFB-T-Y-DDS-FRQ + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + true + + + + + + 65 + 45 + 100 + 35 + + + + 3 + + + 0 + + + AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:MBFBY-GAIN-SP.VAL + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 100.000000000000000 + + + 0.000000000000000 + + + + + + 230 + 5 + 100 + 35 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + ARSGE-CECL-MBFB:MBFB-T-X-DDS-FRQ + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + true + + + + + + 10 + 45 + 45 + 35 + + + + + 8 + 75 + true + + + + MBFBy + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 65 + 5 + 100 + 35 + + + + 3 + + + 0 + + + AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:MBFBX-GAIN-SP.VAL + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 100.000000000000000 + + + 0.000000000000000 + + + + + + 10 + 5 + 45 + 35 + + + + + 8 + 75 + true + + + + MBFBx + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 175 + 45 + 45 + 35 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + ARSGE-CECL-MBFB:MBFB-T-Y-DDS-GAIN + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + false + + + + + + 175 + 5 + 45 + 35 + + + + + Monospace + 13 + PreferDefault + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + ARSGE-CECL-MBFB:MBFB-T-X-DDS-GAIN + + + + 160 + 160 + 164 + + + + caLineEdit::Default + + + caLineEdit::User + + + caLineEdit::None + + + false + + + + + + 335 + 5 + 17 + 17 + + + + true + + + false + + + 15 + + + 15 + + + +ARSGE-MBFBT-AMP-03:SET-ON-OFF + + + + 0 + 255 + 0 + + + + + + + 335 + 23 + 17 + 17 + + + + true + + + false + + + 15 + + + 15 + + + +ARSGE-MBFBT-AMP-04:SET-ON-OFF + + + + 0 + 255 + 0 + + + + + + + 335 + 45 + 17 + 17 + + + + true + + + false + + + 15 + + + 15 + + + ARSGE-MBFBT-AMP-01:SET-ON-OFF + + + + 0 + 255 + 0 + + + + + + + 335 + 63 + 17 + 17 + + + + true + + + false + + + 15 + + + 15 + + + +ARSGE-MBFBT-AMP-02:SET-ON-OFF + + + + 0 + 255 + 0 + + + + + + + + 0 + 95 + 360 + 85 + + + + + 85 + 170 + 0 + + + + caFrame::Calc + + + A<4 & A>0 + + + AGEBD-SCRUBBING{{ agebd_env_suffix_upper }}:CONTROL-SCRUB + + + + + 70 + 45 + 150 + 35 + + + + 4 + + + 2 + + + ARS01-MKIK-0320:I-SET + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 100.000000000000000 + + + 0.000000000000000 + + + + + + 10 + 45 + 50 + 35 + + + + + 10 + 75 + true + + + + PINGy + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 70 + 5 + 150 + 35 + + + + 4 + + + 2 + + + ARS01-MKIK-0290:I-SET + + + caSpinbox::User + + + true + + + caSpinbox::User + + + 100.000000000000000 + + + 0.000000000000000 + + + + + + 10 + 5 + 50 + 35 + + + + + 10 + 75 + true + + + + PINGx + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 230 + 5 + 35 + 35 + + + + + 35 + 35 + + + + ARS01-MKIK-0290:CTRL-ON-OFF + + + + + + 230 + 45 + 35 + 35 + + + + + 35 + 35 + + + + ARS01-MKIK-0320:CTRL-ON-OFF + + + + + + + + + caMenu + QComboBox +
caMenu
+
+ + caChoice + QWidget +
caChoice
+
+ + caTextEntry + caLineEdit +
caTextEntry
+
+ + caMessageButton + QPushButton +
caMessageButton
+
+ + caToggleButton + QCheckBox +
caToggleButton
+
+ + caSpinbox + QFrame +
caSpinbox
+
+ + caFrame + QFrame +
caFrame
+ 1 +
+ + caLabel + QLabel +
caLabel
+
+ + caGraphics + QWidget +
caGraphics
+
+ + caLed + QWidget +
caLed
+
+ + caLineEdit + QLineEdit +
caLineEdit
+
+ + caCartesianPlot + QwtPlot +
caCartesianPlot
+
+ + caStripPlot + QwtPlot +
caStripPlot
+ 1 +
+ + caCalc + QLabel +
caCalc
+
+ + wmSignalPropagator + QLabel +
wmSignalPropagator
+
+ + QwtPlot + QFrame +
qwt_plot.h
+
+
+ + + + cacalc_2 + emitSignal(bool) + wmsignalpropagator + reloadwindow() + + + 2020 + 374 + + + 2022 + 545 + + + + +
diff --git a/qt/A_BD_ServiceManager_inc.ui b/qt/A_BD_ServiceManager_inc.ui index 839f39d..8108fa9 100644 --- a/qt/A_BD_ServiceManager_inc.ui +++ b/qt/A_BD_ServiceManager_inc.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_TauBPM.ui b/qt/A_BD_TauBPM.ui index 1d9f7e1..66455d0 100644 --- a/qt/A_BD_TauBPM.ui +++ b/qt/A_BD_TauBPM.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_TauPCT.ui b/qt/A_BD_TauPCT.ui index c1ab872..702529c 100644 --- a/qt/A_BD_TauPCT.ui +++ b/qt/A_BD_TauPCT.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_Timing.ui b/qt/A_BD_Timing.ui index 13dece5..6ba15a4 100644 --- a/qt/A_BD_Timing.ui +++ b/qt/A_BD_Timing.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_TopUpTool.ui b/qt/A_BD_TopUpTool.ui index 6e52e5d..2ed18e6 100644 --- a/qt/A_BD_TopUpTool.ui +++ b/qt/A_BD_TopUpTool.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_Tune.ui b/qt/A_BD_Tune.ui index eb124cc..8690699 100644 --- a/qt/A_BD_Tune.ui +++ b/qt/A_BD_Tune.ui @@ -1,5 +1,5 @@ - + MainWindow diff --git a/qt/A_BD_TuneBump.ui b/qt/A_BD_TuneBump.ui index 6f80b81..bf4250b 100644 --- a/qt/A_BD_TuneBump.ui +++ b/qt/A_BD_TuneBump.ui @@ -1,5 +1,5 @@ - + MainWindow From c688b48c13da1e9af4d546b422c0897f8de9b6e9 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Wed, 26 Aug 2026 11:21:58 +0200 Subject: [PATCH 10/30] fix: ui launch script -- no macro needed --- bin/sls_hla_launch_gui.sh | 5 +---- docs/user/gui.md | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/bin/sls_hla_launch_gui.sh b/bin/sls_hla_launch_gui.sh index 88de269..dbcc663 100755 --- a/bin/sls_hla_launch_gui.sh +++ b/bin/sls_hla_launch_gui.sh @@ -5,11 +5,8 @@ AGEBD_ENV=$2 # 'dev' for dev environment, any other string launches prod. REMAINING_ARGS=( "${@:3}" ) if [ "$AGEBD_ENV" = "dev" ]; then - AGEBD_ENV_SUFFIX="-DEV" EPICS_CA_ADDR_LIST="$EPICS_CA_ADDR_LIST 129.129.146.255" -else - AGEBD_ENV_SUFFIX="" fi export EPICS_CA_ADDR_LIST -caqtdm -macro "AGEBD_ENV_SUFFIX=${AGEBD_ENV_SUFFIX}" "${REMAINING_ARGS[@]}" "${UI_FILENAME}" +caqtdm "${REMAINING_ARGS[@]}" "${UI_FILENAME}" diff --git a/docs/user/gui.md b/docs/user/gui.md index beb14b6..4f3b281 100644 --- a/docs/user/gui.md +++ b/docs/user/gui.md @@ -16,8 +16,8 @@ In `dev`: ./bin/sls_hla_launch_gui.sh qt/A_BD_InjectionGuard.ui dev ``` -If you need to pass another macro variable in `dev`, you will need to set `AGEBD_ENV_SUFFIX` explicitely: +Any extra arguments are passed straight through to `caqtdm`, e.g. to set a macro: ``` -./bin/sls_hla_launch_gui.sh qt/A_BD_Tune.ui dev -macro "AGEBD_ENV_SUFFIX=-DEV, OTHER_ENV_VAR=HEYHEY" +./bin/sls_hla_launch_gui.sh qt/A_BD_Tune.ui dev -macro "OTHER_ENV_VAR=HEYHEY" ``` From d5379d762eb79fdf1a3cc7914abd7830f2cf6d23 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Wed, 26 Aug 2026 14:16:52 +0200 Subject: [PATCH 11/30] fix: pvlink reconnect gracefully --- packages/agebd/src/agebd/pv.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/agebd/src/agebd/pv.py b/packages/agebd/src/agebd/pv.py index d537018..46f3523 100644 --- a/packages/agebd/src/agebd/pv.py +++ b/packages/agebd/src/agebd/pv.py @@ -60,7 +60,10 @@ class PVLink: sleep(5) - self.link.reconnect() + try: + self.link.reconnect() + except Exception: + print("{:} reconnect attempt raised an error, retrying ...".format(self.pvname)) sleep(1) From 8d1bdcbd4dfe3e3dc28904a0f930d30775efbad6 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Wed, 26 Aug 2026 14:33:33 +0200 Subject: [PATCH 12/30] fix: qt/ui servicemanager dev ssh restart systemd service --- qt/A_BD_ServiceManager.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/A_BD_ServiceManager.ui b/qt/A_BD_ServiceManager.ui index 850dca3..792b30a 100644 --- a/qt/A_BD_ServiceManager.ui +++ b/qt/A_BD_ServiceManager.ui @@ -986,7 +986,7 @@ caLabel[statusTip="Operation"]{ false - ssh svcusr-sls2hla@sls-vserv-bd-hla01 systemctl --user restart AGEBD-SERVICE-MASTER.service + ssh svcusr-sls2hla@sls-vserv-bd-hla01{{ agebd_env_suffix_lower }} systemctl --user restart AGEBD-SERVICE-MASTER.service @@ -1015,7 +1015,7 @@ caLabel[statusTip="Operation"]{ false - terminator -e "ssh svcusr-sls2hla@sls-vserv-bd-hla01" + terminator -e "ssh svcusr-sls2hla@sls-vserv-bd-hla01{{ agebd_env_suffix_lower }}" From af54a24e10dda56860e7fb46f77c643b808ec00d Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Wed, 26 Aug 2026 15:36:12 +0200 Subject: [PATCH 13/30] chore: use exec in bash startup script --- bin/start_service.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/start_service.sh b/bin/start_service.sh index 49d915e..79ef03f 100755 --- a/bin/start_service.sh +++ b/bin/start_service.sh @@ -40,7 +40,6 @@ uv sync --frozen --project ${APP_DIR} # activate .venv, this works in conjunction with the conda environment source ${APP_DIR}/.venv/bin/activate -# TODO: use `exec python3 ...` here? -python -u -B -m agebd_${SVC_NAME_LOWER_UNDERSCORES}.main +exec python -u -B -m agebd_${SVC_NAME_LOWER_UNDERSCORES}.main # TODO: remove: cicd test 57 From ee57cf146c2927ce57c45058ee44f9de0b60226c Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Wed, 26 Aug 2026 16:06:19 +0200 Subject: [PATCH 14/30] docs: update epics docs --- docs/developer/python/epics.md | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/developer/python/epics.md b/docs/developer/python/epics.md index 624581e..56889a8 100644 --- a/docs/developer/python/epics.md +++ b/docs/developer/python/epics.md @@ -62,9 +62,34 @@ Type "help", "copyright", "credits" or "license" for more information. ## Systemd Services -When ssh-ing into a machine, `/etc/profile.d/*` automatically gets sourced. +When ssh-ing into a machine, `/etc/profile.d/*` automatically gets sourced. And thus we have: + +``` +[sls-vserv-bd-hla01-dev ~]$ env | grep EPICS +EPICS_CA_ADDR_LIST=sls-cagw.psi.ch:5062 +``` When running a `systemd` service, this does not happen. +Note -- it seems that the following does not work as expected: +``` That's why we need to source `/etc/profile.d/cas_12_epics.sh` in our startup script -to make sure that `EPICS` is configured properly. +to make sure that `EPICS` is configured properly. +``` +After sourcing the script, we still have: `EPICS_CA_ADDR_LIST=` (i.e. the script does not set `EPICS_CA_ADDR_LIST=sls-cagw.psi.ch:5062`) in `systemd` service. + +Whereas in the shell `unset EPICS_CA_ADDR_LIST` and then `. /etc/profile/cas_12_epics.sh` properly sets `EPICS_CA_ADDR_LIST=sls-cagw.psi.ch:5062`. + +Check which env variables a `systemd` service is running with: + +``` +[sls-vserv-bd-hla01-dev ~]$ systemctl --user restart AGEBD-SERVICE-SCRUBBING.service && sleep 1 && PID=$(systemctl --user show -p MainPID --value AGEBD-SERVICE-SCRUBBING.service) +[sls-vserv-bd-hla01-dev ~]$ tr '\0' '\n' < /proc/$PID/environ | grep EPICS +EPICS_CAS_IGNORE_ADDR_LIST= +EPICS_CA_ADDR_LIST= 129.129.146.255 +EPICS_HOST_ARCH=linux-x86_64 +EPICS_BASE_HOST_BIN=/opt/gfa/python-3.10/20220602/epics/bin/linux-x86_64 +PYEPICS_LIBCA=/opt/gfa/python-3.10/20220602/epics/lib/linux-x86_64/libca.so +EPICS_BASE_VERSION=7.0.5.0 +EPICS_BASE=/opt/gfa/python-3.10/20220602/epics +``` From 124a8f4cfac25510758440d3922b21636eecbdea Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 11:07:36 +0200 Subject: [PATCH 15/30] fix: startup script / epics --- bin/start_service.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bin/start_service.sh b/bin/start_service.sh index 79ef03f..a2d2f85 100755 --- a/bin/start_service.sh +++ b/bin/start_service.sh @@ -3,9 +3,6 @@ SVC_NAME=$1 set -- -# TODO: remove? -# PSI_FACILITY=SLS - SERVICES_DIR=/sls/bd/hla/${AGEBD_ENV}/services SVC_NAME_LOWER=${SVC_NAME,,} SVC_NAME_LOWER_UNDERSCORES="${SVC_NAME_LOWER//-/_}" @@ -14,6 +11,12 @@ SVC_DIR=${SERVICES_DIR}/${SVC_NAME_LOWER} # gfa_12_epics.sh died on the 16.04.2026 due to required AFS write access #. /etc/profile.d/gfa_12_epics.sh #. /sls/bd/exchange/BeamData/user/felix/workarounds/epicsRHEL8.rc # temporary fix + +# cas_12_epics.sh can only fall back to the CA gateway when its broadcast-address +# auto-detection fails (e.g. non-accelerator-network hosts) if PSI_GFA_FACILITY is +# set; systemd --user units don't inherit it from an interactive login shell so we need +# to set PSI_GFA_FACILITY=SLS explicitely. +export PSI_GFA_FACILITY=SLS . /etc/profile.d/cas_12_epics.sh if [ "${AGEBD_ENV}" = "dev" ]; then From 246e6b5eb4e28c41527f02b13d76437a8644d82d Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 11:17:18 +0200 Subject: [PATCH 16/30] fix: PV add init default value and timestamp --- packages/agebd/src/agebd/pv.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/agebd/src/agebd/pv.py b/packages/agebd/src/agebd/pv.py index 46f3523..126b5fe 100644 --- a/packages/agebd/src/agebd/pv.py +++ b/packages/agebd/src/agebd/pv.py @@ -12,6 +12,9 @@ class PVLink: def __init__(self, pvname, **kwargs): self.link = self.connect(pvname, **kwargs) + self.value = np.nan + self.timestamp = time() + # sleep(0.1) # print(self.pvname, self.link.connected) From 3162a6b296d39dfb5ff47a3df0302136b8ac6bf3 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 11:22:02 +0200 Subject: [PATCH 17/30] debug: add better logging in startup script --- bin/start_service.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/start_service.sh b/bin/start_service.sh index a2d2f85..1ba4791 100755 --- a/bin/start_service.sh +++ b/bin/start_service.sh @@ -22,6 +22,8 @@ export PSI_GFA_FACILITY=SLS if [ "${AGEBD_ENV}" = "dev" ]; then export EPICS_CA_ADDR_LIST="$EPICS_CA_ADDR_LIST 129.129.146.255" fi +echo "EPICS_CA_ADDR_LIST:" +echo "$EPICS_CA_ADDR_LIST" # activate conda environment . /opt/gfa/python-3.10/latest/bin/activate From 2ca65e339f2b6664b053d41950657c5d88149ac2 Mon Sep 17 00:00:00 2001 From: labrec_b Date: Thu, 27 Aug 2026 11:47:39 +0200 Subject: [PATCH 18/30] Add deployed version for services (#62) Add deployed version for services --------- Co-authored-by: Benjamin Labrecque Reviewed-on: https://gitea.psi.ch/sls/hla_framework_bd/pulls/62 --- ...d-restart-service.sh => deploy-service.sh} | 20 ++++++++++++++----- .gitea/workflows/add-new-service.yml | 4 ++-- .gitea/workflows/deploy.yml | 2 +- packages/agebd/src/agebd/service/pvs.py | 1 - services/master/current/ioc/MASTER.template | 7 ++++++- 5 files changed, 24 insertions(+), 10 deletions(-) rename .gitea/scripts/{deploy-and-restart-service.sh => deploy-service.sh} (77%) diff --git a/.gitea/scripts/deploy-and-restart-service.sh b/.gitea/scripts/deploy-service.sh similarity index 77% rename from .gitea/scripts/deploy-and-restart-service.sh rename to .gitea/scripts/deploy-service.sh index cd6ff81..6c5c22e 100755 --- a/.gitea/scripts/deploy-and-restart-service.sh +++ b/.gitea/scripts/deploy-service.sh @@ -1,10 +1,13 @@ #!/bin/bash # Deploys a service to /sls/bd/hla and (re)starts its systemd unit. # -# Usage: ./.gitea/scripts/deploy-and-restart-service.sh +# Usage: ./.gitea/scripts/deploy-service.sh [restart] source "$(dirname "$0")/common.sh" init_service_env "${1:-}" "${2:-}" +DO_RESTART_SERVICE=$3 + +NOW=$(date +%Y-%m-%dT%H:%M:%S%Z) echo "==========================================" echo "Deploying service: $SERVICE_NAME_LOWER (${AGEBD_ENV})" @@ -56,7 +59,14 @@ fi mkdir -p ${HOME}/.config/systemd/user ln -sf "${SYSTEMD_UNIT_FILE_PATH}" "${HOME}/.config/systemd/user/${SYSTEMD_UNIT_NAME}" -export XDG_RUNTIME_DIR="/run/user/$(id -u)" -systemctl --user daemon-reload -systemctl --user enable "${SYSTEMD_UNIT_NAME}" -systemctl --user restart "${SYSTEMD_UNIT_NAME}" +VERSION_DEPLOYED_PV="AGEBD-ALH${AGEBD_ENV_SUFFIX_UPPER}:${SERVICE_NAME_UPPER}-VERSION-DEPLOYED" +echo "Putting ${NOW} in ${VERSION_DEPLOYED_PV}" +caput "${VERSION_DEPLOYED_PV}" "${NOW}" + +if [ "$DO_RESTART_SERVICE" ]; then + echo "Enabling and restarting systemd service ${SYSTEMD_UNIT_NAME}" + export XDG_RUNTIME_DIR="/run/user/$(id -u)" + systemctl --user daemon-reload + systemctl --user enable "${SYSTEMD_UNIT_NAME}" + systemctl --user restart "${SYSTEMD_UNIT_NAME}" +fi diff --git a/.gitea/workflows/add-new-service.yml b/.gitea/workflows/add-new-service.yml index eca9e2b..0dc15a4 100644 --- a/.gitea/workflows/add-new-service.yml +++ b/.gitea/workflows/add-new-service.yml @@ -35,7 +35,7 @@ jobs: # has to be deployed before its ioc is installed. - name: Deploy and Restart Master Service run: | - ./.gitea/scripts/deploy-and-restart-service.sh "master" "dev" + ./.gitea/scripts/deploy-service.sh "master" "dev" true - name: Install Master IOC run: | @@ -48,7 +48,7 @@ jobs: - name: Deploy and Restart New Service run: | SERVICE_NAME=${{ steps.parse_branch.outputs.service_name_lower }} - ./.gitea/scripts/deploy-and-restart-service.sh "${SERVICE_NAME}" "dev" + ./.gitea/scripts/deploy-service.sh "${SERVICE_NAME}" "dev" true - name: Install New IOC run: | diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index b97a9b4..e665244 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -175,5 +175,5 @@ jobs: CHANGED_SERVICES=$(git diff --name-only "$BEFORE" "${{ github.sha }}" | awk -F/ '$1=="services" && $2!="" {print $2}' | sort -u) for SERVICE in $CHANGED_SERVICES; do - ./.gitea/scripts/deploy-and-restart-service.sh "${SERVICE}" "${AGEBD_ENV}" + ./.gitea/scripts/deploy-service.sh "${SERVICE}" "${AGEBD_ENV}" false done diff --git a/packages/agebd/src/agebd/service/pvs.py b/packages/agebd/src/agebd/service/pvs.py index 319b594..c462da1 100644 --- a/packages/agebd/src/agebd/service/pvs.py +++ b/packages/agebd/src/agebd/service/pvs.py @@ -16,4 +16,3 @@ class BasePVs: self.abort = pv_factory(f'AGEBD-MASTER:{svc}-ABORT.VAL') self.abortreq = pv_factory(f'AGEBD-MASTER:{svc}-ABORT-REQ.VAL') # fmt: on - diff --git a/services/master/current/ioc/MASTER.template b/services/master/current/ioc/MASTER.template index 2254af9..f8c1814 100644 --- a/services/master/current/ioc/MASTER.template +++ b/services/master/current/ioc/MASTER.template @@ -175,6 +175,11 @@ record(stringout, "AGEBD-ALH$(SUFFIX):$(SERVICE)-VERSION"){ field(ASG, "PROTECTED") } +record(stringout, "AGEBD-ALH$(SUFFIX):$(SERVICE)-VERSION-DEPLOYED"){ + field(DESC, "$(SERVICE) version that is deployed but not necessarily yet running") + field(ASG, "PROTECTED") +} + record(bo, "AGEBD-ALH$(SUFFIX):$(SERVICE)-ONOFF") { field(DESC, "pause/start service") field(ASG, "PROTECTED") @@ -202,4 +207,4 @@ record (bo, "AGEBD-ALH$(SUFFIX):$(SERVICE)-GUIRELOAD"){ field(ZNAM, "idle") field(ONAM, "reload") field(HIGH, "0.5") -} \ No newline at end of file +} From 320b974bf3f65a8a3ae464494094954a16cc6212 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 11:56:05 +0200 Subject: [PATCH 19/30] test: cicd --- packages/agebd/src/agebd/service/pvs.py | 2 +- services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py | 2 +- .../injectionguard/current/app/src/agebd_injectionguard/main.py | 2 +- services/master/current/app/src/agebd_master/main.py | 2 +- services/nturns/current/app/src/agebd_nturns/main.py | 2 ++ services/plots/current/app/src/agebd_plots/main.py | 2 +- .../postmortemlog/current/app/src/agebd_postmortemlog/main.py | 2 +- services/scrubbing/current/app/src/agebd_scrubbing/main.py | 2 +- services/shifttool/current/app/src/agebd_shifttool/main.py | 2 +- services/taubpm/current/app/src/agebd_taubpm/main.py | 2 +- services/taupct/current/app/src/agebd_taupct/main.py | 2 +- services/timing/current/app/src/agebd_timing/main.py | 2 +- services/topuptool/current/app/src/agebd_topuptool/main.py | 2 +- services/tune/current/app/src/agebd_tune/main.py | 2 +- services/tunebump/current/app/src/agebd_tunebump/main.py | 2 +- services/tunefbx/current/app/src/agebd_tunefbx/main.py | 2 +- services/tunefby/current/app/src/agebd_tunefby/main.py | 2 +- 17 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/agebd/src/agebd/service/pvs.py b/packages/agebd/src/agebd/service/pvs.py index c462da1..ab0f853 100644 --- a/packages/agebd/src/agebd/service/pvs.py +++ b/packages/agebd/src/agebd/service/pvs.py @@ -1,6 +1,6 @@ from agebd.pv import PVLink -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 class BasePVs: diff --git a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py index 64cbe76..d0b3a25 100644 --- a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py +++ b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_dbpm3curr import PVs, Service from agebd_dbpm3curr.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/injectionguard/current/app/src/agebd_injectionguard/main.py b/services/injectionguard/current/app/src/agebd_injectionguard/main.py index 9f6d5c5..ae2d086 100644 --- a/services/injectionguard/current/app/src/agebd_injectionguard/main.py +++ b/services/injectionguard/current/app/src/agebd_injectionguard/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_injectionguard import PVs, Service from agebd_injectionguard.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/master/current/app/src/agebd_master/main.py b/services/master/current/app/src/agebd_master/main.py index 75ef091..9673f29 100644 --- a/services/master/current/app/src/agebd_master/main.py +++ b/services/master/current/app/src/agebd_master/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_master import PVs, Service from agebd_master.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/nturns/current/app/src/agebd_nturns/main.py b/services/nturns/current/app/src/agebd_nturns/main.py index 78ad797..24f794a 100644 --- a/services/nturns/current/app/src/agebd_nturns/main.py +++ b/services/nturns/current/app/src/agebd_nturns/main.py @@ -6,6 +6,8 @@ from agebd.utils import init_logging from agebd_nturns import PVs, Service from agebd_nturns.service import SERVICE_NAME +# TODO: remove: cicd test 58 + def main( log_level: LogLevel = typer.Option( diff --git a/services/plots/current/app/src/agebd_plots/main.py b/services/plots/current/app/src/agebd_plots/main.py index d0fd47d..8ee0c0a 100644 --- a/services/plots/current/app/src/agebd_plots/main.py +++ b/services/plots/current/app/src/agebd_plots/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_plots import PVs, Service from agebd_plots.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py index d924566..8df5f5c 100644 --- a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py +++ b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_postmortemlog import PVs, Service from agebd_postmortemlog.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/main.py b/services/scrubbing/current/app/src/agebd_scrubbing/main.py index 6226f63..15c7c90 100644 --- a/services/scrubbing/current/app/src/agebd_scrubbing/main.py +++ b/services/scrubbing/current/app/src/agebd_scrubbing/main.py @@ -6,7 +6,7 @@ from agebd_scrubbing import PVs, Service from agebd_scrubbing.runner import Runner from agebd_scrubbing.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/shifttool/current/app/src/agebd_shifttool/main.py b/services/shifttool/current/app/src/agebd_shifttool/main.py index 23e54d4..598076d 100644 --- a/services/shifttool/current/app/src/agebd_shifttool/main.py +++ b/services/shifttool/current/app/src/agebd_shifttool/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_shifttool import PVs, Service from agebd_shifttool.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/taubpm/current/app/src/agebd_taubpm/main.py b/services/taubpm/current/app/src/agebd_taubpm/main.py index a22845f..c32e175 100644 --- a/services/taubpm/current/app/src/agebd_taubpm/main.py +++ b/services/taubpm/current/app/src/agebd_taubpm/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taubpm import PVs, Service from agebd_taubpm.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/taupct/current/app/src/agebd_taupct/main.py b/services/taupct/current/app/src/agebd_taupct/main.py index 9984c3d..c5b2f3c 100644 --- a/services/taupct/current/app/src/agebd_taupct/main.py +++ b/services/taupct/current/app/src/agebd_taupct/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taupct import PVs, Service from agebd_taupct.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/timing/current/app/src/agebd_timing/main.py b/services/timing/current/app/src/agebd_timing/main.py index a4c0937..5754f86 100644 --- a/services/timing/current/app/src/agebd_timing/main.py +++ b/services/timing/current/app/src/agebd_timing/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_timing import PVs, Service from agebd_timing.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/topuptool/current/app/src/agebd_topuptool/main.py b/services/topuptool/current/app/src/agebd_topuptool/main.py index ba12f29..d14ded7 100644 --- a/services/topuptool/current/app/src/agebd_topuptool/main.py +++ b/services/topuptool/current/app/src/agebd_topuptool/main.py @@ -6,7 +6,7 @@ from agebd_topuptool import PVs, Service from agebd_topuptool.runner import Runner from agebd_topuptool.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/tune/current/app/src/agebd_tune/main.py b/services/tune/current/app/src/agebd_tune/main.py index ece0a01..b13875a 100644 --- a/services/tune/current/app/src/agebd_tune/main.py +++ b/services/tune/current/app/src/agebd_tune/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tune import PVs, Service from agebd_tune.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/tunebump/current/app/src/agebd_tunebump/main.py b/services/tunebump/current/app/src/agebd_tunebump/main.py index de620d3..350a5b8 100644 --- a/services/tunebump/current/app/src/agebd_tunebump/main.py +++ b/services/tunebump/current/app/src/agebd_tunebump/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunebump import PVs, Service from agebd_tunebump.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/tunefbx/current/app/src/agebd_tunefbx/main.py b/services/tunefbx/current/app/src/agebd_tunefbx/main.py index ffeabbc..5691791 100644 --- a/services/tunefbx/current/app/src/agebd_tunefbx/main.py +++ b/services/tunefbx/current/app/src/agebd_tunefbx/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunefbx import PVs, Service from agebd_tunefbx.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( diff --git a/services/tunefby/current/app/src/agebd_tunefby/main.py b/services/tunefby/current/app/src/agebd_tunefby/main.py index ca7aa74..97a7239 100644 --- a/services/tunefby/current/app/src/agebd_tunefby/main.py +++ b/services/tunefby/current/app/src/agebd_tunefby/main.py @@ -7,7 +7,7 @@ from agebd_tunefby import PVs, Service from agebd_tunefby.service import SERVICE_NAME -# TODO: remove: cicd test 57 +# TODO: remove: cicd test 58 def main( log_level: LogLevel = typer.Option( From 3b92c472d7515b02e84b8569ad91ce01b9bec4aa Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 12:08:34 +0200 Subject: [PATCH 20/30] feat: service workflow deploy dispatch --- .gitea/scripts/deploy-for-services.sh | 20 ++++++++++++++++++++ .gitea/workflows/service.yml | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100755 .gitea/scripts/deploy-for-services.sh create mode 100644 .gitea/workflows/service.yml diff --git a/.gitea/scripts/deploy-for-services.sh b/.gitea/scripts/deploy-for-services.sh new file mode 100755 index 0000000..20415c8 --- /dev/null +++ b/.gitea/scripts/deploy-for-services.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Deploys and restarts a single service or all services. +# +# Usage: ./.gitea/scripts/deploy-for-services.sh +set -euo pipefail + +SERVICE=${1:-} +AGEBD_ENV=${2:-} + +SCRIPT_DIR=$(dirname "$0") + +if [ "${SERVICE}" = "all" ]; then + SERVICES=$(ls -d services/*/ | xargs -n1 basename) +else + SERVICES=${SERVICE} +fi + +for SERVICE_NAME in ${SERVICES}; do + "${SCRIPT_DIR}/deploy-service.sh" "${SERVICE_NAME}" "${AGEBD_ENV}" true +done diff --git a/.gitea/workflows/service.yml b/.gitea/workflows/service.yml new file mode 100644 index 0000000..a51cc1c --- /dev/null +++ b/.gitea/workflows/service.yml @@ -0,0 +1,27 @@ +name: Service + +# Manually re-deploy (and restart) individual services, or all of them, in dev. +# There is deliberately no prod option here - prod deploys go through the +# normal push-to-main flow (see the 'Deploy' workflow), which requires review. +on: + workflow_dispatch: + inputs: + service: + description: "Service name in lower case, or 'all' for every service" + type: string + required: true + +env: + UV_CACHE_DIR: /var/cache/uv + UV_LINK_MODE: hardlink + +jobs: + deploy-dev: + runs-on: hla-dev + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Deploy and restart ${{ inputs.service }} + run: | + ./.gitea/scripts/deploy-for-services.sh "${{ inputs.service }}" "dev" From 828cd268ace85c484e4fdfb0597cf82c0137bfc9 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 12:20:13 +0200 Subject: [PATCH 21/30] fix: add Params to services registry --- config/services_registry.yml | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/config/services_registry.yml b/config/services_registry.yml index 0c6af5a..ca01934 100644 --- a/config/services_registry.yml +++ b/config/services_registry.yml @@ -1,4 +1,4 @@ -next_available_ioc_port: 50029 +next_available_ioc_port: 50030 services: - name: Master ioc_port: 50000 @@ -54,36 +54,39 @@ services: - name: TuneFBy ioc_port: 50017 status: active -- name: OpticsFF-X02S +- name: Params ioc_port: 50018 status: inactive -- name: OpticsFF-X03M +- name: OpticsFF-X02S ioc_port: 50019 status: inactive -- name: OpticsFF-X04S +- name: OpticsFF-X03M ioc_port: 50020 status: inactive -- name: OpticsFF-X05L +- name: OpticsFF-X04S ioc_port: 50021 status: inactive -- name: OpticsFF-X06S +- name: OpticsFF-X05L ioc_port: 50022 status: inactive -- name: OpticsFF-X07M +- name: OpticsFF-X06S ioc_port: 50023 status: inactive -- name: OpticsFF-X08S +- name: OpticsFF-X07M ioc_port: 50024 status: inactive -- name: OpticsFF-X09L +- name: OpticsFF-X08S ioc_port: 50025 status: inactive -- name: OpticsFF-X10S +- name: OpticsFF-X09L ioc_port: 50026 status: inactive -- name: OpticsFF-X11M +- name: OpticsFF-X10S ioc_port: 50027 status: inactive -- name: OpticsFF-X12S +- name: OpticsFF-X11M ioc_port: 50028 status: inactive +- name: OpticsFF-X12S + ioc_port: 50029 + status: inactive From 5409590d2114469699c938c1c49be1329bcdc6b1 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 12:23:01 +0200 Subject: [PATCH 22/30] fix: startup script for new services --- .gitea/scripts/deploy-service.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/scripts/deploy-service.sh b/.gitea/scripts/deploy-service.sh index 6c5c22e..b741fa9 100755 --- a/.gitea/scripts/deploy-service.sh +++ b/.gitea/scripts/deploy-service.sh @@ -19,9 +19,10 @@ IOC_PORT=$(uv run --directory scripts ci/get_ioc_port.py ${SERVICE_NAME_LOWER}) # TODO: see https://gitea.psi.ch/sls/hla_framework_bd/issues/50 # rm -rf "${SERVICE_DIR}" -# mkdir -p ${SERVICE_DIR} # cp -r ./services/${SERVICE_NAME_LOWER}/current/* ${SERVICE_DIR}/ +mkdir -p "${SERVICE_DIR}" + rsync -avz --delete \ --exclude='.nfs*' \ --exclude='.git/' \ From cae8d5767a9781601daeed1f885388c4174df04d Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 12:35:09 +0200 Subject: [PATCH 23/30] fix: only execute systemd stuff on deployment for relevant services --- .gitea/scripts/deploy-service.sh | 33 +++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/.gitea/scripts/deploy-service.sh b/.gitea/scripts/deploy-service.sh index b741fa9..500b1d6 100755 --- a/.gitea/scripts/deploy-service.sh +++ b/.gitea/scripts/deploy-service.sh @@ -51,23 +51,26 @@ if [ -n "${AGEBD_ENV_SUFFIX_UPPER}" ]; then done fi -### SYSTEMD -if [ -f "${SYSTEMD_UNIT_FILE_PATH}" ]; then - sed -i "s/{{ *agebd_env* }}/${AGEBD_ENV}/g" "${SYSTEMD_UNIT_FILE_PATH}" -fi - - -mkdir -p ${HOME}/.config/systemd/user -ln -sf "${SYSTEMD_UNIT_FILE_PATH}" "${HOME}/.config/systemd/user/${SYSTEMD_UNIT_NAME}" - VERSION_DEPLOYED_PV="AGEBD-ALH${AGEBD_ENV_SUFFIX_UPPER}:${SERVICE_NAME_UPPER}-VERSION-DEPLOYED" echo "Putting ${NOW} in ${VERSION_DEPLOYED_PV}" caput "${VERSION_DEPLOYED_PV}" "${NOW}" -if [ "$DO_RESTART_SERVICE" ]; then - echo "Enabling and restarting systemd service ${SYSTEMD_UNIT_NAME}" - export XDG_RUNTIME_DIR="/run/user/$(id -u)" - systemctl --user daemon-reload - systemctl --user enable "${SYSTEMD_UNIT_NAME}" - systemctl --user restart "${SYSTEMD_UNIT_NAME}" +### SYSTEMD +# Not every service has a systemd unit (e.g. IOC-only services like params) - +# skip enabling/restarting entirely when there's nothing to enable/restart. +if [ -f "${SYSTEMD_UNIT_FILE_PATH}" ]; then + sed -i "s/{{ *agebd_env* }}/${AGEBD_ENV}/g" "${SYSTEMD_UNIT_FILE_PATH}" + + mkdir -p ${HOME}/.config/systemd/user + ln -sf "${SYSTEMD_UNIT_FILE_PATH}" "${HOME}/.config/systemd/user/${SYSTEMD_UNIT_NAME}" + + if [ "$DO_RESTART_SERVICE" ]; then + echo "Enabling and restarting systemd service ${SYSTEMD_UNIT_NAME}" + export XDG_RUNTIME_DIR="/run/user/$(id -u)" + systemctl --user daemon-reload + systemctl --user enable "${SYSTEMD_UNIT_NAME}" + systemctl --user restart "${SYSTEMD_UNIT_NAME}" + fi +else + echo "No systemd unit for ${SERVICE_NAME_LOWER}, skipping enable/restart" fi From e956ecc5546c41e81c4fb1cd004a2aec3549327d Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 14:01:50 +0200 Subject: [PATCH 24/30] feat: configure epics env in deployments --- .gitea/scripts/common.sh | 20 ++++++++++++++++++++ .gitea/scripts/deploy-service.sh | 1 + 2 files changed, 21 insertions(+) diff --git a/.gitea/scripts/common.sh b/.gitea/scripts/common.sh index 387a396..aba3c89 100644 --- a/.gitea/scripts/common.sh +++ b/.gitea/scripts/common.sh @@ -44,3 +44,23 @@ init_service_env() { # Host running shellbox, i.e. the host the ioc itself runs on IOC_HOST=sls-vserv-bd-01${AGEBD_ENV_SUFFIX_LOWER} } + +# Sets up EPICS_CA_ADDR_LIST so caget/caput/etc. can actually reach IOCs from +# this non-interactive shell (the gitea runner, like a systemd --user unit, +# doesn't inherit an interactive login shell's environment). +# +# cas_12_epics.sh can only fall back to the CA gateway when its broadcast-address +# auto-detection fails (e.g. non-accelerator-network hosts) if PSI_GFA_FACILITY is +# set, so we need to set that explicitly. +# +# Usage: setup_epics_env +setup_epics_env() { + local ENV=$1 + + export PSI_GFA_FACILITY=SLS + . /etc/profile.d/cas_12_epics.sh + + if [ "${ENV}" = "dev" ]; then + export EPICS_CA_ADDR_LIST="$EPICS_CA_ADDR_LIST 129.129.146.255" + fi +} diff --git a/.gitea/scripts/deploy-service.sh b/.gitea/scripts/deploy-service.sh index 500b1d6..7775eeb 100755 --- a/.gitea/scripts/deploy-service.sh +++ b/.gitea/scripts/deploy-service.sh @@ -5,6 +5,7 @@ source "$(dirname "$0")/common.sh" init_service_env "${1:-}" "${2:-}" +setup_epics_env "${AGEBD_ENV}" DO_RESTART_SERVICE=$3 NOW=$(date +%Y-%m-%dT%H:%M:%S%Z) From dd97eec4610f9300ce14ac243af5f3ac01994463 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 14:04:33 +0200 Subject: [PATCH 25/30] feat: configure epics env in deployments --- .gitea/scripts/deploy-service.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/scripts/deploy-service.sh b/.gitea/scripts/deploy-service.sh index 7775eeb..6c4aaf4 100755 --- a/.gitea/scripts/deploy-service.sh +++ b/.gitea/scripts/deploy-service.sh @@ -6,6 +6,8 @@ source "$(dirname "$0")/common.sh" init_service_env "${1:-}" "${2:-}" setup_epics_env "${AGEBD_ENV}" +echo "EPICS_CA_ADDR_LIST: ${EPICS_CA_ADDR_LIST}" +echo "hostname: $(hostname)" DO_RESTART_SERVICE=$3 NOW=$(date +%Y-%m-%dT%H:%M:%S%Z) From da97eb51f39bfe7915e0af294ac367c8f88e8b17 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 14:47:29 +0200 Subject: [PATCH 26/30] fix: shorter master ioc description for deployed version record --- services/master/current/ioc/MASTER.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/master/current/ioc/MASTER.template b/services/master/current/ioc/MASTER.template index f8c1814..e335cf0 100644 --- a/services/master/current/ioc/MASTER.template +++ b/services/master/current/ioc/MASTER.template @@ -176,7 +176,7 @@ record(stringout, "AGEBD-ALH$(SUFFIX):$(SERVICE)-VERSION"){ } record(stringout, "AGEBD-ALH$(SUFFIX):$(SERVICE)-VERSION-DEPLOYED"){ - field(DESC, "$(SERVICE) version that is deployed but not necessarily yet running") + field(DESC, "$(SERVICE) deployed version") field(ASG, "PROTECTED") } From b1a3fe15e761e72028b0ce80f1f743e00f72d223 Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 14:54:03 +0200 Subject: [PATCH 27/30] test: epics cicd --- .gitea/scripts/deploy-service.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitea/scripts/deploy-service.sh b/.gitea/scripts/deploy-service.sh index 6c4aaf4..500b1d6 100755 --- a/.gitea/scripts/deploy-service.sh +++ b/.gitea/scripts/deploy-service.sh @@ -5,9 +5,6 @@ source "$(dirname "$0")/common.sh" init_service_env "${1:-}" "${2:-}" -setup_epics_env "${AGEBD_ENV}" -echo "EPICS_CA_ADDR_LIST: ${EPICS_CA_ADDR_LIST}" -echo "hostname: $(hostname)" DO_RESTART_SERVICE=$3 NOW=$(date +%Y-%m-%dT%H:%M:%S%Z) From 5ee669057d32e081bc9e79fd01f8c2411828c1ff Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Thu, 27 Aug 2026 14:55:36 +0200 Subject: [PATCH 28/30] fix: remove unnecessary code --- .gitea/scripts/common.sh | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/.gitea/scripts/common.sh b/.gitea/scripts/common.sh index aba3c89..387a396 100644 --- a/.gitea/scripts/common.sh +++ b/.gitea/scripts/common.sh @@ -44,23 +44,3 @@ init_service_env() { # Host running shellbox, i.e. the host the ioc itself runs on IOC_HOST=sls-vserv-bd-01${AGEBD_ENV_SUFFIX_LOWER} } - -# Sets up EPICS_CA_ADDR_LIST so caget/caput/etc. can actually reach IOCs from -# this non-interactive shell (the gitea runner, like a systemd --user unit, -# doesn't inherit an interactive login shell's environment). -# -# cas_12_epics.sh can only fall back to the CA gateway when its broadcast-address -# auto-detection fails (e.g. non-accelerator-network hosts) if PSI_GFA_FACILITY is -# set, so we need to set that explicitly. -# -# Usage: setup_epics_env -setup_epics_env() { - local ENV=$1 - - export PSI_GFA_FACILITY=SLS - . /etc/profile.d/cas_12_epics.sh - - if [ "${ENV}" = "dev" ]; then - export EPICS_CA_ADDR_LIST="$EPICS_CA_ADDR_LIST 129.129.146.255" - fi -} From 7c1745325ebf4ff3281e8dabe0ba96990d3184a8 Mon Sep 17 00:00:00 2001 From: labrec_b Date: Thu, 27 Aug 2026 15:32:59 +0200 Subject: [PATCH 29/30] docs: fix and expand user docs (#74) Update user docs Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01A9GjKvXCmfgJpKzbQdZ7UA Co-authored-by: Benjamin Labrecque Reviewed-on: https://gitea.psi.ch/sls/hla_framework_bd/pulls/74 --- docs/user/add-new-service.md | 36 ++++++++++++++++++++++++++++------ docs/user/gui.md | 7 +++++++ docs/user/ioc/iocs_overview.md | 33 +++++++++++++++++++------------ 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/docs/user/add-new-service.md b/docs/user/add-new-service.md index 4836810..6a4056f 100644 --- a/docs/user/add-new-service.md +++ b/docs/user/add-new-service.md @@ -23,6 +23,24 @@ agebd --help agebd service add --help ``` +**This command has side effects you should know about before running it.** It requires a +clean working tree, then it: + +1. Assigns the service the next free IOC port and registers it in + [`config/services_registry.yml`](../../config/services_registry.yml). +2. Adds the service to `AGEBD-CPCL-MASTER`'s IOC pattern file, so it gets the standard + ALH lifecycle PVs (`AGEBD-ALH$(SUFFIX):$(SERVICE)-*`) and appears in the `ServiceManager` + GUI screen. +3. Appends a row to [`iocs_overview.md`](ioc/iocs_overview.md). +4. Creates a new branch **`feature/add-service-`**, scaffolds the new service's files + from the templates, and **pushes the branch automatically** — you don't run `git push` + yourself. + +Pushing that branch triggers the `Add new service` Gitea Actions workflow +(`.gitea/workflows/add-new-service.yml`), which deploys `master`, installs/restarts its IOC, +deploys your new service, and installs/starts its own IOC — all in `dev`. Check the Actions +tab for that run to confirm it succeeded before doing anything else with the new service. + ## Environments The services are deployed to 2 environments: @@ -42,17 +60,23 @@ We distinguish between #### PVs - Service Specific -You create them, see (# TODO: docs...) +These are defined as EPICS records in your service's own `services//current/ioc/*.template` +file, instantiated by `services//current/ioc/AGEBD-CPCL-_main.subs`. -`prod` and `dev` PVs automatically get created. +`prod` and `dev` PVs automatically get created: at deploy time, `{{ agebd_env_suffix_upper }}`/ +`{{ agebd_env_suffix_lower }}` placeholders in those files are substituted with `-DEV`/`-dev` +in `dev`, or left empty in `prod` (see `.gitea/scripts/deploy-service.sh`). -In your code, you only use the `prod` name of a PV. The framework will automatically use the -`dev` name/PV when a service runs in the `dev` environment. +In your code, you only use the `prod` name of a PV, e.g. `PV("AGEBD-MYSERVICE:MYPVNAME")`. +The `PVLink`/`DevPVLink` framework (`packages/agebd/src/agebd/pv.py`) automatically appends +`-DEV` when the service runs in `dev` — but **only** for PVs belonging to your own service, +plus `AGEBD-ALH`/`AGEBD-MASTER`. See "External" below for PVs owned by another service. #### PVs - External -The framework will use the same PV in `prod` and `dev`, i.e. there is no `dev` PV. -However, in `dev` you can only read from the PV, whereas in `prod` you can also write to it. +PVs owned by another service (including another AGEBD service, e.g. `AGEBD-PARAMS:...` used +from a different service) or by real accelerator hardware (e.g. `ARS01-MOCT-...`) are used +verbatim — no `-DEV` suffix is ever added, even in `dev`. #### PVs - Examples diff --git a/docs/user/gui.md b/docs/user/gui.md index 4f3b281..b05ed00 100644 --- a/docs/user/gui.md +++ b/docs/user/gui.md @@ -21,3 +21,10 @@ Any extra arguments are passed straight through to `caqtdm`, e.g. to set a macro ``` ./bin/sls_hla_launch_gui.sh qt/A_BD_Tune.ui dev -macro "OTHER_ENV_VAR=HEYHEY" ``` + +**Note:** launching straight from a git checkout, as above, uses the raw `.ui` files as +committed - including the literal `{{ agebd_env_suffix_upper }}`/`{{ agebd_env_suffix_lower }}` +placeholders in their PV names. Those only get substituted with `-DEV`/`-dev` (or emptied out, +in `prod`) at deploy time, by `.gitea/workflows/deploy.yml`'s `"Qt - deploy"` step, on the +*deployed* copy at `/sls/bd/hla//qt/`. If widgets show up blank or unresponsive, check +whether you're accidentally pointing at the raw checkout instead of the deployed `.ui` file. diff --git a/docs/user/ioc/iocs_overview.md b/docs/user/ioc/iocs_overview.md index 32e7aa5..c0e567c 100644 --- a/docs/user/ioc/iocs_overview.md +++ b/docs/user/ioc/iocs_overview.md @@ -4,8 +4,7 @@ The ports are configured in the [service registry](../../../config/services_regi | IOC NAME | Description | |---|---| -| AGEBD-CPCL-MASTER | IOC providing PVs for the service master application and IOC enabling to monitor the health status of BD High Level Application Services with the alarm handler ALH | -| AGEBD-CPCL-ALH | IOC enabling to monitor the health status of BD High Level Application Services with the alarm handler ALH | +| AGEBD-CPCL-MASTER | IOC providing PVs for the service master application, and monitoring the health status of BD High Level Application Services via the alarm handler ALH. ALH is not a separate IOC - its `AGEBD-ALH$(SUFFIX):$(SERVICE)-*` PVs are defined directly in `MASTER.template`, one row per registered service. | | AGEBD-CPCL-TUNE | IOC providing PVs for the tune measurement | | AGEBD-CPCL-SCRUBBING | IOC providing PVs for the vacuum scrubbing service | | AGEBD-CPCL-NTURNS | IOC providing PVs for the DBPM3 stage0 and stage1 nr. of turns calculation service | @@ -15,15 +14,23 @@ The ports are configured in the [service registry](../../../config/services_regi | AGEBD-CPCL-TUNEBUMP | IOC providing PVs for the tune bump service application | | AGEBD-CPCL-PLOTS | IOC providing Buffers of PVs for plots | | AGEBD-CPCL-ORBITBUMP | IOC providing PVs for orbit bumps for the beamlines | -| AGEBD-CPCL-TAUBPM | IOC providing PVs for the lifetime measurement | +| AGEBD-CPCL-TAUBPM | IOC providing PVs for the lifetime measurement (BPM based) | +| AGEBD-CPCL-TAUPCT | IOC providing PVs for PCT based lifetime measurement | | AGEBD-CPCL-TOPUPTOOL | IOC providing PVs for the top up tool | -| AGEBD-CPCL-TUNEFBX | IOC providing PVs for the top up tool | - -# TODO: -| IOC NAME | Description | -|---|---| -| AGEBD-CPCL-PARAMS | IOC providing PVs for machine parameters | -| AGEBD-CPCL-PARAMS | IOC providing PVs for PCT base lifetime measurement | -| AGEBD-CPCL-SHIFTTOOL | | -| AGEBD-CPCL-DBPM3CURR | | -| AGEBD-CPCL-DBPM3 | IOC providing PVs for the DBPM3 stage2 average current calculation service | +| AGEBD-CPCL-TUNEFBX | IOC providing PVs for the horizontal tune feedback | +| AGEBD-CPCL-TUNEFBY | IOC providing PVs for the vertical tune feedback | +| AGEBD-CPCL-PARAMS | IOC providing PVs for machine parameters (e.g. injection state, lifetime, current limit) | +| AGEBD-CPCL-DBPM3CURR | IOC providing PVs for the DBPM3 stage2 average current calculation service | +| AGEBD-CPCL-SHIFTTOOL | IOC providing PVs for the shift log / handover tool | +| AGEBD-CPCL-BEAMTRANSFERCHECKS | IOC providing PVs for beam transfer checks | +| AGEBD-CPCL-OPTICSFF-X02S | IOC providing PVs for optics feed-forward on the I-TOMCAT beamline | +| AGEBD-CPCL-OPTICSFF-X03M | IOC providing PVs for optics feed-forward on the ADRESS beamline | +| AGEBD-CPCL-OPTICSFF-X04S | IOC providing PVs for optics feed-forward on the ADDAMS beamline | +| AGEBD-CPCL-OPTICSFF-X05L | IOC providing PVs for optics feed-forward on the QUEST beamline | +| AGEBD-CPCL-OPTICSFF-X06S | IOC providing PVs for optics feed-forward on the PXI beamline | +| AGEBD-CPCL-OPTICSFF-X07M | IOC providing PVs for optics feed-forward on the PHOENIX/XTREME beamline | +| AGEBD-CPCL-OPTICSFF-X08S | IOC providing PVs for optics feed-forward on the MicroXAS beamline | +| AGEBD-CPCL-OPTICSFF-X09L | IOC providing PVs for optics feed-forward on the OPERA beamline | +| AGEBD-CPCL-OPTICSFF-X10S | IOC providing PVs for optics feed-forward on the PXII beamline | +| AGEBD-CPCL-OPTICSFF-X11M | IOC providing PVs for optics feed-forward on the SIM beamline | +| AGEBD-CPCL-OPTICSFF-X12S | IOC providing PVs for optics feed-forward on the cSAXS beamline | From 132f924e6b871735c4b640a4d0673ce072500d6a Mon Sep 17 00:00:00 2001 From: labrec_b Date: Thu, 27 Aug 2026 15:47:42 +0200 Subject: [PATCH 30/30] Docs/user docs improvements (#75) Update user docs, better links Co-authored-by: Benjamin Labrecque Reviewed-on: https://gitea.psi.ch/sls/hla_framework_bd/pulls/75 --- docs/user/add-new-service.md | 2 +- docs/user/gui.md | 14 +++++++------- docs/user/ioc/iocs_overview.md | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/user/add-new-service.md b/docs/user/add-new-service.md index 6a4056f..1c901bd 100644 --- a/docs/user/add-new-service.md +++ b/docs/user/add-new-service.md @@ -27,7 +27,7 @@ agebd service add --help clean working tree, then it: 1. Assigns the service the next free IOC port and registers it in - [`config/services_registry.yml`](../../config/services_registry.yml). + [`config/services_registry.yml`](https://gitea.psi.ch/sls/hla_framework_bd/src/branch/main/config/services_registry.yml). 2. Adds the service to `AGEBD-CPCL-MASTER`'s IOC pattern file, so it gets the standard ALH lifecycle PVs (`AGEBD-ALH$(SUFFIX):$(SERVICE)-*`) and appears in the `ServiceManager` GUI screen. diff --git a/docs/user/gui.md b/docs/user/gui.md index b05ed00..908a51d 100644 --- a/docs/user/gui.md +++ b/docs/user/gui.md @@ -2,24 +2,24 @@ ## Launch -``` -cd -``` - In `prod`: +`ssh sls-vserv-bd-hla01` ``` -./bin/sls_hla_launch_gui.sh qt/A_BD_InjectionGuard.ui +cd /sls/bd/hla/prod/qt +../bin/sls_hla_launch_gui.sh A_BD_ServiceManager.ui ``` In `dev`: +`ssh sls-vserv-bd-hla01-dev` ``` -./bin/sls_hla_launch_gui.sh qt/A_BD_InjectionGuard.ui dev +cd /sls/bd/hla/dev/qt +../bin/sls_hla_launch_gui.sh A_BD_ServiceManager.ui "dev" ``` Any extra arguments are passed straight through to `caqtdm`, e.g. to set a macro: ``` -./bin/sls_hla_launch_gui.sh qt/A_BD_Tune.ui dev -macro "OTHER_ENV_VAR=HEYHEY" +../bin/sls_hla_launch_gui.sh A_BD_ServiceManager.ui "dev" -macro "OTHER_ENV_VAR=HEYHEY" ``` **Note:** launching straight from a git checkout, as above, uses the raw `.ui` files as diff --git a/docs/user/ioc/iocs_overview.md b/docs/user/ioc/iocs_overview.md index c0e567c..f51a793 100644 --- a/docs/user/ioc/iocs_overview.md +++ b/docs/user/ioc/iocs_overview.md @@ -1,6 +1,6 @@ # Overview of IOCs for Beam Dynamics -The ports are configured in the [service registry](../../../config/services_registry.yml) +The ports are configured in the [service registry](https://gitea.psi.ch/sls/hla_framework_bd/src/branch/main/config/services_registry.yml) | IOC NAME | Description | |---|---|