Convert a builder XML IOC instance to ibek YAML#
builder2ibek xml2yaml converts a DLS XMLbuilder IOC definition file (.xml)
into an ibek ioc.yaml that can be consumed by ibek at runtime to generate
st.cmd and database files.
Prerequisites#
In order to test the converted IOC you should be working inside a devcontainer.
There are two options:
builder2ibek devcontainer — the devcontainer shipped with this repository.
It has the full ibek-support and ibek-support-dls submodule trees checked
out, so every supported module’s YAML is available. Run builder2ibek with
uv run:
uv run builder2ibek xml2yaml ...
Generic IOC devcontainer — the devcontainer for a specific Generic IOC
(e.g. ioc-bl11i-rga). Only the ibek support YAML that was built into that
container image is available, so schema validation can only validate
entities that the target IOC already supports. Here builder2ibek is not
installed in the repo but can be run directly with uvx:
uvx builder2ibek xml2yaml ...
In both cases the ibek support YAML for every module referenced in the XML must be present — either in the builder2ibek submodules or in the Generic IOC’s installed support tree.
1. Locate the builder XML#
DLS XMLbuilder IOC definitions are in the builder support module e.g.
/dls_sw/work/R3.14.12.7/support/BL11I-BUILDER/etc/makeIocs/BL11I-CS-IOC-09.xml
Example — BL11I-CS-IOC-09.xml:
<?xml version="1.0" ?>
<components arch="linux-x86_64">
<devIocStats.devIocStatsHelper ioc="BL11I-CS-IOC-09" name="CSIOC2"/>
<autosave.Autosave bl="True" iocName="BL11I-CS-IOC-09"
name="BL11I-CS-IOC-09.AS" path="/dls_sw/i11/epics/autosave" skip_1="True"/>
<pvlogging.PvLogging/>
<asyn.AsynIP name="rgaPort" port="10.111.5.1:5025"/>
<hidenRGA.hidenRGA_qga BUFFER_SIZE="100" P="BL11I-EA-RGA-01"
PORT="rgaPort" Q="" name="ENV.RGA"/>
</components>
Each XML element maps to an ibek entity type: <module.Class attribute="value"/>.
2. Run xml2yaml#
uv run builder2ibek xml2yaml BL11I-CS-IOC-09.xml --yaml bl11i-cs-ioc-09.yaml
For the example above this produces bl11i-cs-ioc-09.yaml:
# yaml-language-server: $schema=/epics/ibek-defs/ioc.schema.json
ioc_name: "{{ _global.get_env('IOC_NAME') }}"
description: auto-generated by https://github.com/epics-containers/builder2ibek
entities:
- type: epics.EpicsEnvSet
name: EPICS_TS_MIN_WEST
value: '0'
- type: epics.EpicsEnvSet
name: STREAM_PROTOCOL_PATH
value: /epics/runtime/protocol/
- type: devIocStats.iocAdminSoft
IOC: '{{ ioc_name | upper }}'
- type: autosave.Autosave
P: 'BL11I-CS-IOC-09:'
debug: false
- type: pvlogging.PvLogging
access_file: /epics/support/pvlogging/src/access.acf
- type: asyn.AsynIP
name: rgaPort
port: 10.111.5.1:5025
- type: hidenRGA.hidenRGA_qga
BUFFER_SIZE: 100
P: BL11I-EA-RGA-01
PORT: rgaPort
Notice that asyn.AsynIP and hidenRGA.hidenRGA_qga remain as separate entities
in the output, reflecting the original XML structure. The ibek entity models
for both must be present in the ibek-support* submodules used by the Generic IOC.
3. Review and adjust#
Note
If your IOC uses the older vacuumValve, interlock, or temperature modules,
xml2yaml will automatically translate many entities to their dlsPLC
equivalents. Some cases (e.g. vacuumValveRead2, pump templates) require
manual fixup. See the dlsPLC migration reference
for the complete mapping table and argument transformation rules.
Auto-conversion is a best-effort translation; review the output for:
Commented-out elements: builder XML comments (
<!-- ... -->) are skipped. If the original had alternative configurations in comments, choose the right one now.Default values: some converters inject sensible defaults (e.g. autosave
debug: false). Verify these are appropriate.Module coverage: if a module has no converter, its entities will just have identical parameters to the XML attributes in the original. For some entities this will be perfectly OK as we try to make the
xxx.ibek.support.yamlas compatible with the original XML as possible.Schema validation: open the YAML in VSCode with the Red Hat YAML extension; the
$schemaline at the top will highlight any type mismatches.
Important
You will need to update the schema when you have made changes — see 6. Updating the schema.
For schema validation to work your ioc.yaml should have the following header:
# yaml-language-server: $schema=/epics/ibek-defs/ioc.schema.json
4. Add to the test suite#
If your IOC is using support modules that are not currently covered in the builder2ibek tests then it could be worth updating the tests as follows.
To prevent regressions, copy the XML into tests/samples/ and regenerate:
cp BL11I-CS-IOC-09.xml tests/samples/
cd tests/samples && ./make_samples.sh
make_samples.sh converts all XML files in the folder and updates the
corresponding .yaml files. Review the diff, then commit both.
5. Verify with db-compare#
Once you have converted an IOC, the definitive verification is to generate the
EPICS database inside the devcontainer and compare it record-by-record against
the original builder _expanded.db. See
Verify a converted IOC using db-compare for the
full workflow. In brief:
# inside the devcontainer
ibek dev instance /workspaces/my-project/iocs/my-ioc
ibek runtime generate2 /epics/ioc/config
uv run builder2ibek db-compare \
/dls_sw/.../MY-IOC_expanded.db \
/epics/runtime/ioc.db
6. Updating the schema#
If you have added new entity models to ibek-support* or changed existing models,
regenerate the global schema that VSCode uses for validation.
In the builder2ibek devcontainer:
./update-schema # first time only - after that use ibek to update schema as below
In a generic IOC devcontainer:
ibek ioc generate-schema > /epics/ibek-defs/ioc.schema.json
Both commands update the ioc instance schema in /epics/ibek-defs/ioc.schema.json#
Relationship between XML elements and ibek entity types#
XML element prefix |
ibek entity type prefix |
notes |
|---|---|---|
|
|
renamed by converter |
|
|
converter adjusts path handling |
|
|
direct mapping |
|
|
direct mapping |
|
|
direct mapping |
|
|
renamed by converter |
The converter modules in src/builder2ibek/converters/ handle the non-trivial
mappings. Each file corresponds to one support module. See src/builder2ibek/converters/
for the full list.