refactor: remove service id altogether
Deploy bin / deploy (push) Successful in 2s
Deploy agebd python package / deploy (push) Successful in 4s

This commit is contained in:
Benjamin Labrecque
2026-07-08 16:47:42 +02:00
parent 3d921e69c1
commit debac0cf5e
34 changed files with 76 additions and 92 deletions
+2 -2
View File
@@ -20,11 +20,11 @@ jobs:
run: |
BRANCH="${{ github.ref_name }}"
SERVICE_NAME="${BRANCH#feature/add-service-}"
echo "new_service_dir_name=$SERVICE_NAME" >> $GITHUB_OUTPUT
echo "service_name_lower=$SERVICE_NAME" >> $GITHUB_OUTPUT
- name: Run New Service Playbook
run: |
ansible-playbook ansible/playbooks/add-new-service.yml \
-i ansible/hosts.yml \
--extra-vars="repo_root=${{ github.workspace }} agebd_env=dev new_service_dir_name=${{ steps.parse_branch.outputs.new_service_dir_name }}" \
--extra-vars="repo_root=${{ github.workspace }} agebd_env=dev service_name_lower=${{ steps.parse_branch.outputs.service_name_lower }}" \
-v
@@ -19,7 +19,7 @@
# env:
# # commit tagged ? yes->prod : no->dev
# AGEBD_ENV: ${{ github.ref_type == 'tag' && 'prod' || 'dev' }}
# SVC_CURRRENT_DIR: /sls/bd/hla/${{ github.ref_type == 'tag' && 'prod' || 'dev' }}/services/000-master/current
# SVC_CURRRENT_DIR: /sls/bd/hla/${{ github.ref_type == 'tag' && 'prod' || 'dev' }}/services/master/current
# steps:
# - name: Checkout repository
@@ -30,7 +30,7 @@
# - name: Copy files and replace {{ agebd_env }} with dev or prod
# run: |
# mkdir -p ${SVC_CURRRENT_DIR}
# cp -r 000-master/* ${SVC_CURRRENT_DIR}
# cp -r master/* ${SVC_CURRRENT_DIR}
# sed -i 's/{{ agebd_env }}/${AGEBD_ENV}/g' ${SVC_CURRRENT_DIR}/systemd/AGEBD-SERVICE-MASTER.service
# - name: Create Python venv
@@ -55,7 +55,7 @@
# CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }})
# set -e
# # 1. Parse changed directory names into space-separated string (e.g. "000-master 001-secondary")
# # 1. Parse changed directory names into space-separated string (e.g. "master secondary")
# CHANGED_SVC=$(echo "$CHANGED_FILES" | awk -F/ '$1=="services" {print $2}' | sort -u | xargs)
# echo "Detected changed services: '$CHANGED_SVC'"
+9 -9
View File
@@ -3,35 +3,35 @@
# - name: Install Master IOC
# vars:
# ioc_service_dir_name: 000-master
# branch_name: "feature/add-service-{{ new_service_dir_name }}"
# ioc_service_name_lower: master
# branch_name: "feature/add-service-{{ service_name_lower }}"
# import_playbook: ../plays/ioc/ioc-install.yml
# - name: Restart Master IOC
# vars:
# ioc_service_dir_name: 000-master
# branch_name: "feature/add-service-{{ new_service_dir_name }}"
# ioc_service_name_lower: master
# branch_name: "feature/add-service-{{ service_name_lower }}"
# import_playbook: ../plays/ioc/ioc-restart.yml
- name: Deploy and Restart Master Service
vars:
ioc_service_dir_name: 000-master
branch_name: "feature/add-service-{{ new_service_dir_name }}"
ioc_service_name_lower: master
branch_name: "feature/add-service-{{ service_name_lower }}"
import_playbook: ../plays/service/service-deploy-and-restart.yml
# TODO: ioc_port
# - name: Install New IOC
# vars:
# branch_name: "feature/add-service-{{ new_service_dir_name }}"
# branch_name: "feature/add-service-{{ service_name_lower }}"
# import_playbook: ../plays/ioc/ioc-install.yml
# TODO: ioc_port
# - name: Start New IOC
# vars:
# branch_name: "feature/add-service-{{ new_service_dir_name }}"
# branch_name: "feature/add-service-{{ service_name_lower }}"
# import_playbook: ../plays/ioc/ioc-start.yml
- name: Deploy and Restart New Service
vars:
branch_name: "feature/add-service-{{ new_service_dir_name }}"
branch_name: "feature/add-service-{{ service_name_lower }}"
import_playbook: ../plays/service/service-deploy-and-restart.yml
@@ -3,7 +3,7 @@
gather_facts: yes
vars:
# Passed from the Gitea workflow, e.g., "000-master 001-secondary"
# Passed from the Gitea workflow, e.g., "master playground"
changed_services_raw: ""
agebd_env: "dev"
@@ -18,4 +18,4 @@
include_tasks: plays/service/service-deploy-and-restart.yml
loop: "{{ changed_services_raw.split() }}"
loop_control:
loop_var: service_dir_name
loop_var: service_name_lower
+12 -13
View File
@@ -15,49 +15,48 @@
version: "{{ branch_name }}"
force: true
- name: Initialize isolated service directory name
- name: Initialize service name
ansible.builtin.set_fact:
# Uses ioc_service_dir_name if defined in vars, otherwise falls back to the CLI extra-vars
service_dir_name: "{{ ioc_service_dir_name | default(new_service_dir_name) }}"
# Uses ioc_service_name_lower if defined in vars, otherwise falls back to the CLI extra-vars
service_name_lower: "{{ ioc_service_name_lower | default(service_name_lower) }}"
- name: "[{{ service_dir_name }}] Establish environment naming conventions"
- name: "[{{ service_name_lower }}] Establish environment naming conventions"
ansible.builtin.set_fact:
# Extract MASTER from 000-master
service_name_upper: "{{ service_dir_name[4:] | upper }}"
service_name_upper: "{{ service_name_lower | upper }}"
# Set suffix to "-DEV" if dev, otherwise empty ""
env_suffix_upper: "{{ '-DEV' if agebd_env == 'dev' else '' }}"
# Set suffix to "-dev" if dev, otherwise empty ""
env_suffix_lower: "{{ '-dev' if agebd_env == 'dev' else '' }}"
- name: "[{{ service_dir_name }}] Define file paths"
- name: "[{{ service_name_lower }}] Define file paths"
ansible.builtin.set_fact:
ioc_base_dir: "{{ workspace_dir }}/services/{{ service_dir_name }}/current/ioc"
ioc_base_dir: "{{ workspace_dir }}/services/{{ 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: "[{{ service_dir_name }}] Rename substitution file for environment"
- name: "[{{ 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: "[{{ service_dir_name }}] Rename parameters file for environment"
- name: "[{{ 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 }} inside the newly renamed subs file
- name: "[{{ service_dir_name }}] Substitute environment tokens inside subs file"
- name: "[{{ service_name_lower }}] Substitute environment tokens inside subs file"
ansible.builtin.replace:
path: "{{ ioc_base_dir }}/{{ target_subs_name }}"
regexp: '\{\{\s*agebd_env\s*\}\}'
replace: "{{ env_suffix_upper }}"
# Replace {{ agebd_env }} and {{ ioc_port }} inside the newly renamed params file
- name: "[{{ service_dir_name }}] Substitute environment token inside params file"
- name: "[{{ service_name_lower }}] Substitute environment token inside params file"
ansible.builtin.replace:
path: "{{ ioc_base_dir }}/{{ target_params_name }}"
regexp: "{{ item.regexp }}"
@@ -66,7 +65,7 @@
- { regexp: '\{\{\s*agebd_env\s*\}\}', replace: "{{ env_suffix_lower }}" }
- { regexp: '\{\{\s*ioc_port\s*\}\}', replace: "{{ ioc_port }}" }
- name: "[{{ service_dir_name }}] Run ioc install"
- name: "[{{ 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 }}"
+8 -9
View File
@@ -15,23 +15,22 @@
version: "{{ branch_name }}"
force: true
- name: Initialize isolated service directory name
- name: Initialize service name
ansible.builtin.set_fact:
# Uses ioc_service_dir_name if defined in vars, otherwise falls back to the CLI extra-vars
service_dir_name: "{{ ioc_service_dir_name | default(new_service_dir_name) }}"
# Uses ioc_service_name_lower if defined in vars, otherwise falls back to the CLI extra-vars
service_name_lower: "{{ ioc_service_name_lower | default(service_name_lower) }}"
- name: "[{{ service_dir_name }}] Establish environment naming conventions"
- name: "[{{ service_name_lower }}] Establish environment naming conventions"
ansible.builtin.set_fact:
# Example: extract MASTER from 000-master
service_name_upper: "{{ service_dir_name[4:] | upper }}"
service_name_upper: "{{ service_name_lower | upper }}"
# Set suffix to "-DEV" if dev, otherwise empty ""
env_suffix_upper: "{{ '-DEV' if agebd_env == 'dev' else '' }}"
- name: "[{{ service_dir_name }}] Define file paths"
- name: "[{{ service_name_lower }}] Define file paths"
ansible.builtin.set_fact:
ioc_base_dir: "{{ workspace_dir }}/services/{{ service_dir_name }}/current/ioc"
ioc_base_dir: "{{ workspace_dir }}/services/{{ service_name_lower }}/current/ioc"
- name: "[{{ service_dir_name }}] Restart IOC"
- name: "[{{ service_name_lower }}] Restart IOC"
ansible.builtin.shell:
cmd: "ioc restart AGEBD-CPCL-{{ service_name_upper }}{{ env_suffix_upper }}"
chdir: "{{ ioc_base_dir }}"
+4 -4
View File
@@ -4,12 +4,12 @@
gather_facts: false
tasks:
- name: Initialize isolated service directory name
- name: Initialize service name
ansible.builtin.set_fact:
# Uses ioc_service_dir_name if defined in vars, otherwise falls back to the CLI extra-vars
service_dir_name: "{{ ioc_service_dir_name | default(new_service_dir_name) }}"
# Uses ioc_service_name_lower if defined in vars, otherwise falls back to the CLI extra-vars
service_name_lower: "{{ ioc_service_name_lower | default(service_name_lower) }}"
- name: "[{{ service_dir_name }}] Start IOC"
- name: "[{{ service_name_lower }}] Start IOC"
ansible.builtin.shell: |
sudo shellbox start {{ ioc_port }}
changed_when: true
@@ -5,40 +5,38 @@
gather_facts: false
tasks:
- name: Initialize isolated service directory name
- name: Initialize service name
ansible.builtin.set_fact:
# Uses ioc_service_dir_name if defined in vars, otherwise falls back to the CLI extra-vars
service_dir_name: "{{ ioc_service_dir_name | default(new_service_dir_name) }}"
# Uses ioc_service_name_lower if defined in vars, otherwise falls back to the CLI extra-vars
service_name_lower: "{{ ioc_service_name_lower | default(service_name_lower) }}"
- name: "[{{ service_dir_name }}] Define service specific paths and names"
- name: "[{{ service_name_lower }}] Define service specific paths and names"
ansible.builtin.set_fact:
# 1. The literal directory name on disk (e.g., "000-master")
svc_current_dir: "/sls/bd/hla/{{ agebd_env }}/services/{{ service_dir_name }}/current"
# 2. Extract logical service name by dropping the first 4 characters and converting to UPPERCASE (e.g., "MASTER")
service_unit_name: "AGEBD-SERVICE-{{ service_dir_name[4:] | upper }}.service"
svc_current_dir: "/sls/bd/hla/{{ agebd_env }}/services/{{ service_name_lower }}/current"
service_unit_name: "AGEBD-SERVICE-{{ service_name_lower | upper }}.service"
- name: "[{{ service_dir_name }}] Ensure target directory structure exists"
- name: "[{{ 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 }}"
- name: "[{{ service_dir_name }}] Sync service deployment files"
- name: "[{{ service_name_lower }}] Sync service deployment files"
ansible.builtin.copy:
src: "{{ playbook_dir }}/../../../services/{{ service_dir_name }}/current/"
src: "{{ playbook_dir }}/../../../services/{{ service_name_lower }}/current/"
dest: "{{ svc_current_dir }}/"
mode: 'preserve'
# ansible.builtin.shell: |
# cp -r "{{ repo_root }}/services/{{ service_dir_name }}/current/" "{{ svc_current_dir }}"
# cp -r "{{ repo_root }}/services/{{ service_name_lower }}/current/" "{{ svc_current_dir }}"
- name: "[{{ service_dir_name }}] Substitute environment variable inline"
- name: "[{{ 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 }}"
- name: "[{{ service_dir_name }}] Restart Systemd Service using Relative Paths"
- name: "[{{ service_name_lower }}] Restart Systemd Service using Relative Paths"
ansible.builtin.shell: |
export XDG_RUNTIME_DIR=/run/user/$(id -u)
+2 -4
View File
@@ -1,15 +1,13 @@
#!/bin/bash
SVC_ID=$1
SVC_NAME=$2
ENV=$3
SVC_NAME=$1
set --
# TODO:
# PSI_FACILITY=SLS
SERVICES_DIR=/sls/bd/hla/${AGEBD_ENV}/services
SVC_NAME_LOWER=${SVC_NAME,,}
SVC_DIR=${SERVICES_DIR}/${SVC_ID}-${SVC_NAME_LOWER}
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
+5 -14
View File
@@ -11,7 +11,7 @@ REPO_ROOT = get_git_root(__file__)
CONFIG_DIR = REPO_ROOT / "config"
SERVICE_REGISTRY_FILENAME = CONFIG_DIR / "services_registry.yml"
MASTER_SERVICE_DIR = REPO_ROOT / "services" / "000-master" / "current"
MASTER_SERVICE_DIR = REPO_ROOT / "services" / "master" / "current"
MASTER_SERVICE_CONFIG_DIR = MASTER_SERVICE_DIR / "app" / "config"
MASTER_HLA_NAMES_FILENAME = MASTER_SERVICE_CONFIG_DIR / "hla_names.yml"
@@ -19,7 +19,6 @@ IOCS_OVERVIEW_FILENAME = REPO_ROOT / "docs" / "ioc" / "ioc_overview.md"
class Service(BaseModel):
id: int
name: str
ioc_port: int
status: ServiceStatus
@@ -34,12 +33,7 @@ class Service(BaseModel):
@property
def dir_name(self):
return f"{self.id_str}-{self.name_lower}"
@property
def id_str(self):
# TODO: max 999 services, enough?
return f"{self.id:03d}"
return f"{self.name_lower}"
def to_dict(self):
return {"name": self.name_lower, "ioc_port": self.ioc_port, "status": str(self.status)}
@@ -58,9 +52,8 @@ class Service(BaseModel):
class ServiceRegistry(BaseModel):
config_path: ClassVar[str] = str(SERVICE_REGISTRY_FILENAME)
next_available_id: int
next_available_ioc_port: int
services: dict[str, dict]
services: list[dict]
@classmethod
def read_from_config(cls) -> "ServiceRegistry":
@@ -71,17 +64,15 @@ class ServiceRegistry(BaseModel):
return registry
def get_services(self) -> list[Service]:
return [Service(id=int(svc_id), **svc_data) for svc_id, svc_data in self.services.items()]
return [Service(**svc_data) for svc_data in self.services]
def add_service(self, name: str) -> Service:
svc = Service(
id=self.next_available_id,
name=name,
ioc_port=self.next_available_ioc_port,
status=ServiceStatus.ACTIVE,
)
self.services.update({svc.id_str: svc.to_dict()})
self.next_available_id += 1
self.services.append(svc.to_dict())
self.next_available_ioc_port += 1
return svc
+3 -4
View File
@@ -23,7 +23,7 @@ REPO_ROOT = get_git_root(__file__)
SERVICE_TEMPLATES_DIR = REPO_ROOT / "templates" / "service"
SERVICE_DEST_DIR = REPO_ROOT / "services"
MASTER_SERVICE_DIR = REPO_ROOT / "services" / "000-master" / "current"
MASTER_SERVICE_DIR = REPO_ROOT / "services" / "master" / "current"
MASTER_IOC_SUBS_FILE = MASTER_SERVICE_DIR / "ioc" / "AGEBD-CPCL-MASTER_main.subs"
# TODO: lots of hardcoded paths. Create config object?
@@ -77,8 +77,8 @@ class ServiceCreator:
service_dir_rel_path=f"services/{service.dir_name}/current",
registry_file_rel_path="config/services_registry.yml",
# TODO: maybe assert/get correct master service dirname from registry
master_hla_names_rel_path="services/000-master/current/app/config/hla_names.yml",
master_ioc_subs_rel_path="services/000-master/current/ioc/AGEBD-CPCL-MASTER_main.subs",
master_hla_names_rel_path="services/master/current/app/config/hla_names.yml",
master_ioc_subs_rel_path="services/master/current/ioc/AGEBD-CPCL-MASTER_main.subs",
iocs_overview_rel_path="docs/ioc/ioc_overview.md",
commit_msg=f"feature: add new service {service.name_lower}",
)
@@ -103,7 +103,6 @@ class ServiceCreator:
src_path=str(SERVICE_TEMPLATES_DIR),
dst_path=str(SERVICE_DEST_DIR),
data={
"service_id": service.id_str,
"service_name_upper": service.name_upper,
"service_name_lower": service.name_lower,
"user": user,
+3 -5
View File
@@ -1,7 +1,5 @@
next_available_id: 1
next_available_ioc_port: 50003
next_available_ioc_port: 50001
services:
"000":
name: master
ioc_port: 50011
- name: master
ioc_port: 50000
status: active
+4 -4
View File
@@ -7,7 +7,7 @@ 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 new_service_dir_name=<service dir name>" \
--extra-vars="repo_root=${{ github.workspace }} agebd_env=dev service_name_lower=<service dir name>" \
-v
```
@@ -15,7 +15,7 @@ ansible-playbook ansible/playbooks/add-new-service.yml \
```
ansible-playbook ansible/plays/ioc/ioc-install.yml \
-i ansible/hosts.yml \
--extra-vars="agebd_env=dev branch_name=feature/add-service-001-playground new_service_dir_name=001-playground ioc_port=50003" \
--extra-vars="agebd_env=dev branch_name=feature/add-service-playground service_name_lower=playground ioc_port=50003" \
-v
```
@@ -24,7 +24,7 @@ TODO: how to get the ioc_port in cicd? Add it to the branch name?
```
ansible-playbook ansible/plays/ioc/ioc-start.yml \
-i ansible/hosts.yml \
--extra-vars="new_service_dir_name=001-playground ioc_port=50003" \
--extra-vars="service_name_lower=playground ioc_port=50003" \
-v
```
@@ -32,6 +32,6 @@ ansible-playbook ansible/plays/ioc/ioc-start.yml \
```
ansible-playbook ansible/plays/ioc/ioc-restart.yml \
-i ansible/hosts.yml \
--extra-vars="agebd_env=dev branch_name=feature/add-service-001-playground new_service_dir_name=001-playground" \
--extra-vars="agebd_env=dev branch_name=feature/add-service-playground service_name_lower=playground" \
-v
```
+5 -3
View File
@@ -1,5 +1,7 @@
# Overview of IOCs for Beam Dynamics
| IOC NAME | Port | Description |
|---|---|---|
| AGEBD-CPCL-MASTER | 50011 | IOC providing PVs for the service master application IOC enabling to monitor the health status of BD High Level Application Services with the alarm handler ALH |
The ports are configured in the [service registry](../../docs/ioc/ioc_overview.md)
| IOC NAME | Description |
|---|---|
| AGEBD-CPCL-MASTER | IOC providing PVs for the service master application IOC enabling to monitor the health status of BD High Level Application Services with the alarm handler ALH |
@@ -4,7 +4,7 @@ After=network.target
[Service]
Environment=AGEBD_ENV={{ agebd_env }}
ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh 000 MASTER
ExecStart=/sls/bd/hla/{{ agebd_env }}/bin/start_service.sh MASTER
Restart=no
[Install]
@@ -4,7 +4,7 @@ After=network.target
[Service]
Environment=AGEBD_ENV={{ '{{ agebd_env }}' }}
ExecStart=/sls/bd/hla/{{'{{ agebd_env }}'}}/bin/start_service.sh {{ service_id }} {{ service_name_upper }}
ExecStart=/sls/bd/hla/{{'{{ agebd_env }}'}}/bin/start_service.sh {{ service_name_upper }}
Restart=no
[Install]