Repository navigation
RTOP-392: deliver conf/<plugin>.* sibling files to the plugin's install dir - #229
Conversation
Plugins such as the Weidmuller VPP need extra files next to their JSON config (e.g. <name>.station.bin). apply_vpp_plugin_conf now copies every regular conf/<name>.* file other than .json and .license into VPP_DATA_DIR, guarded by is_inside_root, so the plugin finds them beside plugin_specific_config_file_path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review — RTOP-392Reviewed against the task's acceptance criteria and the real code paths ( Findings
Minor style point: Checked, no finding
CI and validationGreen here does not mean this change was tested — the |
JulioSergioFS
left a comment
There was a problem hiding this comment.
Requesting changes on finding 1 only: the new spec does not run in CI (tests.yml ignores tests/pytest/plugins and the known-green allowlist does not include it), so AC6 is unproven on the base branch and unguarded from here on. Add test_vpp_sibling_delivery.py and test_vpp_license_delivery.py to the "pytest (plugin suites known green)" step and this is good to go. The rest of the review is nits.
The plugin pytest step now runs test_vpp_license_delivery.py and test_vpp_sibling_delivery.py, with -rs so an importorskip skip shows in the log instead of passing silently. apply_vpp_plugin_conf lists conf/ once instead of once per VPP plugin, and the plugin_specific_config_file_path comment states that ride-along files land in dirname() of that path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for the review — the CI catch in particular was a good one. Addressed in
Not addressed here
|
Problem
The Weidmuller UC20 VPP, and any future VPP that follows the same model,
needs an opaque archive next to its JSON config (for Weidmuller:
conf/<name>.station.bin, which the plugin forwards to/var/run/devices.sockas a
DeployRequest.datapayload for the u-OS systembus service). The editoralready emits that archive in the uploaded zip, but the runtime copies only
conf/<name>.jsonand the.licensesibling (hardcoded carve-out) toVPP_DATA_DIR. The archive is extracted intocore/generated/conf/and leftthere, so
wm_deploy_applycannot find it and the station is never deployed.Issue: RTOP-392
Change
apply_vpp_plugin_conf(webserver/plcapp_management.py) now copies everyregular
conf/<name>.*sibling, other than.json(handled above) and.license(kept on its own path throughderive_license_path), toVPP_DATA_DIR/<name>.<ext>. The containment guard that already protectsdest_config(is_inside_root) applies to every sibling destination.Discovery stays
vpp_plugins.conf-anchored: an orphan sibling with nomatching VPP entry is ignored.
The ABI docstring on
plugin_specific_config_file_pathincore/src/drivers/plugin_types.his updated to document the siblingconvention. The struct layout, field count and offsets are unchanged.
Scope is VPP-only. The built-in plugin path
(
plugin_config_model.update_plugins_from_config_dir) is a separate codepath, skips VPP explicitly, and no built-in plugin ships siblings today, so
it is left untouched.
Verification
Unit tests (new
tests/pytest/plugins/test_vpp_sibling_delivery.py,following the
test_vpp_license_delivery.pypattern):test_station_bin_sibling_lands_in_persistent_dir-- AC1test_station_bin_and_license_coexist-- AC2test_no_sibling_leaves_persistent_dir_at_the_json-- AC3test_orphan_sibling_without_vpp_entry_is_ignored-- AC4test_two_vpp_plugins_each_get_only_their_own_siblingstest_subdirectory_under_conf_is_not_copiedtest_second_upload_updates_sibling_contentpytest tests/pytest/plugins/test_vpp_sibling_delivery.py tests/pytest/plugins/test_vpp_license_delivery.py-> 18 passed. The.licenseregression suite (test_vpp_license_delivery.py) is untouched and keeps passing.Full
pytest tests/pytest(excluding opcua/modbus suites blocked bypre-existing dev-env dep gaps): 241 passed, 3 pre-existing failures in
test_etherdog_manager.pyandtest_ethercat_upload.pyfrom a permissionissue on a generated
c_blocks.h, unrelated to this change.AC5 (ABI docs) satisfied by the
plugin_types.hcomment.Out of scope
conf/<plugin>.station.binas a carve-out inbuild-vpp-plugin-files.ts; kept as-is.openplc-packagesmanifests.com.weidmuller.ucontrol/hal/**).plugin_config_model.update_plugins_from_config_dir(built-in path).conf/<plugin>/directory. Flat siblings only.safe_extractare unchanged.Attack surface
No attack surface touched.
safe_extractand its path-traversal/size/extension guards are unchanged; the generalization operates only on files
already normalized by
safe_extract, and copied siblings are placed ondisk for the plugin to read, never executed. The same
is_inside_root(dest, VPP_DATA_DIR)guard that protectsdest_configcovers every sibling destination.
No requirements document for this task: small change, task description is
the record. The task was re-read against what shipped and brought in line
(the
plugin_config_model.pybullet dropped, built-in path marked out ofscope); ACs stay satisfied by the test file above.
Contributor License Agreement
🤖 Generated with Claude Code