Deploy-time placeholders were spread across four independent
implementations: sed in the Gitea deploy script, ansible.builtin.replace
in two playbooks, a hardcoded suffix in bin/sls_hla_launch_gui.sh, and
another in agebd/pv.py. Each defined its own values, so nothing kept them
in sync and a missed substitution failed silently.
Step 1 -- one source of truth:
* config/environments.yml declares every deploy-time token, its value
per environment, and where tokens are allowed to live. An environment
that is missing a token, or defines an undeclared one, is a load-time
error.
* agebd.subs loads it and renders. Rendering is a strict regex over
declared token names rather than a template engine: the rendered
files are EPICS db/substitution files and Qt XML, and an unknown
token must raise rather than survive into the output.
* scripts/ci/check_subs.py enforces the contract in CI: tokens in a
rendered path are declared, declared tokens only appear where they
are rendered or generated, and no pre-migration delimiters survive.
Step 2 -- separate the two substitution stages by delimiter:
* Creation-time (copier, once per new service) keeps {{ token }}.
Deploy-time (every deploy, per environment) becomes @@token@@.
* This drops the {{ '{{ token }}' }} escaping from templates/, which
existed only because one Jinja pass had to emit syntax for a second.
* Angle brackets were tried first and rejected: << >> is not
well-formed XML, and cli parses qt/*.ui with ElementTree.
* The existing sed and ansible consumers are repointed at the new
delimiters so this stays behaviour-preserving. Routing them through
agebd.subs is step 3.
Also fixes, as a side effect of having one implementation:
* The sed pattern '{{ *agebd_env_suffix_upper* }}' quantified 'r'
rather than the space, so it only matched one exact spacing.
* agebd.subs.read_ioc_port compares service names case-insensitively;
ansible/tasks/utils/get-ioc-port.yml still compares CamelCase
registry names against a lowercase input and never matches.
qt/*.ui is declared as a render path but nothing renders it yet -- the
Qt deploy step is still a plain rsync. Wiring that up is step 4.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
223 lines
5.5 KiB
XML
223 lines
5.5 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<ui version="4.0">
|
|
<class>MainWindow</class>
|
|
<widget class="QMainWindow" name="MainWindow">
|
|
<property name="geometry">
|
|
<rect>
|
|
<x>0</x>
|
|
<y>0</y>
|
|
<width>1200</width>
|
|
<height>1060</height>
|
|
</rect>
|
|
</property>
|
|
<property name="windowTitle">
|
|
<string>MainWindow</string>
|
|
</property>
|
|
<widget class="QWidget" name="centralwidget">
|
|
<widget class="wmSignalPropagator" name="wmsignalpropagator">
|
|
<property name="geometry">
|
|
<rect>
|
|
<x>1290</x>
|
|
<y>170</y>
|
|
<width>70</width>
|
|
<height>20</height>
|
|
</rect>
|
|
</property>
|
|
</widget>
|
|
<widget class="caCalc" name="cacalc_2">
|
|
<property name="geometry">
|
|
<rect>
|
|
<x>1290</x>
|
|
<y>110</y>
|
|
<width>70</width>
|
|
<height>20</height>
|
|
</rect>
|
|
</property>
|
|
<property name="text">
|
|
<string>Reload</string>
|
|
</property>
|
|
<property name="variable">
|
|
<string notr="true">RELOAD</string>
|
|
</property>
|
|
<property name="calc">
|
|
<string notr="true">A</string>
|
|
</property>
|
|
<property name="channel" stdset="0">
|
|
<string notr="true">AGEBD-ALH@@agebd_env_suffix_upper@@:MASTER-GUIRELOAD</string>
|
|
</property>
|
|
<property name="eventSignal">
|
|
<enum>caCalc::TriggerZeroToOne</enum>
|
|
</property>
|
|
</widget>
|
|
<widget class="caMessageButton" name="camessagebutton_7">
|
|
<property name="geometry">
|
|
<rect>
|
|
<x>10</x>
|
|
<y>10</y>
|
|
<width>101</width>
|
|
<height>30</height>
|
|
</rect>
|
|
</property>
|
|
<property name="text">
|
|
<string>Clear Logs</string>
|
|
</property>
|
|
<property name="channel" stdset="0">
|
|
<string notr="true">AGEBD-MASTER@@agebd_env_suffix_upper@@:LOG-CLEAR</string>
|
|
</property>
|
|
<property name="label">
|
|
<string notr="true">Clear Logs</string>
|
|
</property>
|
|
<property name="background">
|
|
<color>
|
|
<red>160</red>
|
|
<green>160</green>
|
|
<blue>160</blue>
|
|
</color>
|
|
</property>
|
|
<property name="releaseMessage">
|
|
<string notr="true"/>
|
|
</property>
|
|
<property name="pressMessage">
|
|
<string notr="true">1</string>
|
|
</property>
|
|
</widget>
|
|
<widget class="caMessageButton" name="camessagebutton_8">
|
|
<property name="geometry">
|
|
<rect>
|
|
<x>840</x>
|
|
<y>10</y>
|
|
<width>351</width>
|
|
<height>30</height>
|
|
</rect>
|
|
</property>
|
|
<property name="text">
|
|
<string>Get Systemd Status for each Service</string>
|
|
</property>
|
|
<property name="channel" stdset="0">
|
|
<string notr="true">AGEBD-MASTER@@agebd_env_suffix_upper@@:GET-SYSTEMD-STATUS</string>
|
|
</property>
|
|
<property name="label">
|
|
<string notr="true">Get Systemd Status for each Service</string>
|
|
</property>
|
|
<property name="background">
|
|
<color>
|
|
<red>160</red>
|
|
<green>160</green>
|
|
<blue>160</blue>
|
|
</color>
|
|
</property>
|
|
<property name="releaseMessage">
|
|
<string notr="true"/>
|
|
</property>
|
|
<property name="pressMessage">
|
|
<string notr="true">1</string>
|
|
</property>
|
|
</widget>
|
|
<widget class="QTextBrowser" name="textBrowser">
|
|
<property name="geometry">
|
|
<rect>
|
|
<x>10</x>
|
|
<y>50</y>
|
|
<width>1180</width>
|
|
<height>1000</height>
|
|
</rect>
|
|
</property>
|
|
<property name="lineWrapMode">
|
|
<enum>QTextEdit::NoWrap</enum>
|
|
</property>
|
|
<property name="textInteractionFlags">
|
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
</property>
|
|
<property name="openLinks">
|
|
<bool>false</bool>
|
|
</property>
|
|
</widget>
|
|
<widget class="caLineEdit" name="calineedit">
|
|
<property name="geometry">
|
|
<rect>
|
|
<x>1310</x>
|
|
<y>210</y>
|
|
<width>31</width>
|
|
<height>5</height>
|
|
</rect>
|
|
</property>
|
|
<property name="maxLength">
|
|
<number>20000</number>
|
|
</property>
|
|
<property name="echoMode">
|
|
<enum>QLineEdit::NoEcho</enum>
|
|
</property>
|
|
<property name="readOnly">
|
|
<bool>true</bool>
|
|
</property>
|
|
<property name="channel" stdset="0">
|
|
<string notr="true">AGEBD-MASTER@@agebd_env_suffix_upper@@:LOG</string>
|
|
</property>
|
|
<property name="limitsMode">
|
|
<enum>caLineEdit::User</enum>
|
|
</property>
|
|
<property name="formatType">
|
|
<enum>caLineEdit::string</enum>
|
|
</property>
|
|
</widget>
|
|
</widget>
|
|
</widget>
|
|
<customwidgets>
|
|
<customwidget>
|
|
<class>caMessageButton</class>
|
|
<extends>QPushButton</extends>
|
|
<header>caMessageButton</header>
|
|
</customwidget>
|
|
<customwidget>
|
|
<class>caLineEdit</class>
|
|
<extends>QLineEdit</extends>
|
|
<header>caLineEdit</header>
|
|
</customwidget>
|
|
<customwidget>
|
|
<class>caCalc</class>
|
|
<extends>QLabel</extends>
|
|
<header>caCalc</header>
|
|
</customwidget>
|
|
<customwidget>
|
|
<class>wmSignalPropagator</class>
|
|
<extends>QLabel</extends>
|
|
<header>wmSignalPropagator</header>
|
|
</customwidget>
|
|
</customwidgets>
|
|
<resources/>
|
|
<connections>
|
|
<connection>
|
|
<sender>cacalc_2</sender>
|
|
<signal>emitSignal(bool)</signal>
|
|
<receiver>wmsignalpropagator</receiver>
|
|
<slot>reloadwindow()</slot>
|
|
<hints>
|
|
<hint type="sourcelabel">
|
|
<x>1290</x>
|
|
<y>110</y>
|
|
</hint>
|
|
<hint type="destinationlabel">
|
|
<x>1290</x>
|
|
<y>172</y>
|
|
</hint>
|
|
</hints>
|
|
</connection>
|
|
<connection>
|
|
<sender>calineedit</sender>
|
|
<signal>textChanged(QString)</signal>
|
|
<receiver>textBrowser</receiver>
|
|
<slot>setHtml(QString)</slot>
|
|
<hints>
|
|
<hint type="sourcelabel">
|
|
<x>1322</x>
|
|
<y>229</y>
|
|
</hint>
|
|
<hint type="destinationlabel">
|
|
<x>1133</x>
|
|
<y>269</y>
|
|
</hint>
|
|
</hints>
|
|
</connection>
|
|
</connections>
|
|
</ui>
|