# 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`: ```bash 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`: ```bash 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 ``` Each XML element maps to an ibek entity type: ``. --- ## 2. Run xml2yaml ```bash 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 # 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 [](../reference/dlsplc-migration.md) 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.yaml` as compatible with the original XML as possible. - **Schema validation**: open the YAML in VSCode with the Red Hat YAML extension; the `$schema` line at the top will highlight any type mismatches. :::{important} You will need to update the schema when you have made changes — see [](#schema-update). ::: For schema validation to work your `ioc.yaml` should have the following header: ```yaml # 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: ```bash 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-with-devcontainer.md) for the full workflow. In brief: ```bash # 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 ``` (schema-update)= ## 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: ```bash ./update-schema # first time only - after that use ibek to update schema as below ``` In a generic IOC devcontainer: ```bash 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 | |---|---|---| | `devIocStats.devIocStatsHelper` | `devIocStats.iocAdminSoft` | renamed by converter | | `autosave.Autosave` | `autosave.Autosave` | converter adjusts path handling | | `pvlogging.PvLogging` | `pvlogging.PvLogging` | direct mapping | | `asyn.AsynIP` | `asyn.AsynIP` | direct mapping | | `hidenRGA.hidenRGA_qga` | `hidenRGA.hidenRGA_qga` | direct mapping | | `EPICS_BASE.EpicsEnvSet` | `epics.EpicsEnvSet` | 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.