Skip to content

fix(sync): restore the empty params table for a Build image - #1584

Open
cplieger wants to merge 2 commits into
moghtech:mainfrom
cplieger:fix/deployment-build-id-blanked-breaks-sync
Open

fix(sync): restore the empty params table for a Build image#1584
cplieger wants to merge 2 commits into
moghtech:mainfrom
cplieger:fix/deployment-build-id-blanked-breaks-sync

Conversation

@cplieger

Copy link
Copy Markdown
Contributor

A Deployment with a Build image whose build is unset serializes to TOML that Komodo cannot read back, so every later read of the sync file fails. Same failure class as #1581, reached without any name/id confusion.

The bug

Deployment::edit_config_object renames build_id to build and removes version when it is 0.0.0, which the entity documents as meaning latest. If the build is also unset, no keys remain, skip_empty_object drops the whole params table, and DeploymentImage is adjacently tagged (tag = "type", content = "params"), so this cannot be deserialized:

image.type = "Build"
TOML parse error at line 1, column 1
missing field `params`

Tests in this PR cover all three states: the empty table is dropped and fails to parse, restoring it round trips, and a populated image is unaffected.

Precedent

This file already works around the identical hazard twice, both with comments:

  • Builder::push_additional appends a literal params = {} because "toml_pretty will remove empty map but in this case its needed to deserialize the enums".
  • The Procedure stage serializer passes TOML_PRETTY_OPTIONS.skip_empty_object(false) because "If the execution.params are fully missing, deserialization will fail".

The nested image case was missed. The first commit follows the Builder precedent, one level deeper: image.params = {}.

Two ways to reach it

Build unset. validate_config does not require a non-empty build_id for a Build image, so a Deployment in that state is constructible and its export is already unreadable.

A dangling reference. ReplaceIds blanked build_id when the Build lookup missed, which is the common route into the state above. The lookup misses whenever the reference is dangling, and a dangling reference is the normal outcome here: deleting a resource clears permissions, recently-viewed and alerter targets via delete_from_alerters, but nothing clears a Deployment's build_id. Build::pre_delete is empty and post_delete only drops a build_state_cache entry.

The second commit stops that blanking. It is not the parse fix, and I have kept it separate on purpose: its value is that it no longer overwrites a reference the user committed to a git-tracked file with an empty string, matching the change made for ResourceTarget ids in #1581. It does not make a dangling reference resolve; it makes it legible instead of blank. Drop that commit if you would rather keep blanking.

Deliberately not included

The sibling lookups in ReplaceIds (server_id, swarm_id, linked_repo, builder_id, and the two server_ids vectors) blank the same way. They do not break parsing, because those fields carry #[serde(default)] and an empty string is valid TOML, so I have left them alone rather than send a dozen unrequested edits. They do still erase a committed reference. Happy to follow up if you want them consistent.

Verification

cargo check -p komodo_core clean, cargo fmt --check clean, the three new tests pass. bin/core had no test module before this, so tell me if you would rather these lived elsewhere or not at all.

A Deployment with a Build image whose build is unset serializes to TOML that
cannot be read back, so every later read of the sync file fails and the sync
stops until someone edits the file.

Deployment::edit_config_object renames build_id to 'build' and REMOVES
'version' when it is 0.0.0, which means latest. When the build is also unset
that leaves no keys at all, skip_empty_object drops the whole params table, and
the emitted

  image.type = "Build"

cannot be deserialized, because DeploymentImage is adjacently tagged
(tag = "type", content = "params").

This is the same hazard the Builder impl in this file already works around one
level up, appending 'params = {}' because 'toml_pretty will remove empty map
but in this case its needed to deserialize the enums', and the same one the
Procedure stage serializer avoids with skip_empty_object(false) because 'if the
execution.params are fully missing, deserialization will fail'. The nested
image case was missed.

Tests cover all three states: the empty table is dropped and fails to parse,
restoring it round trips, and a populated image is unaffected.
ReplaceIds rewrites image.build_id to the Build name for the sync TOML and fell
back to an empty string when the lookup missed. That overwrites a reference the
user committed to a git-tracked file with nothing, and it is the most common way
to reach the empty params table the previous commit now guards against.

The lookup misses whenever the reference is dangling, and a dangling reference
is the normal outcome here: deleting a resource clears permissions,
recently-viewed and alerter targets via delete_from_alerters, but nothing clears
a Deployment's build_id. Build::pre_delete is empty and post_delete only drops a
build_state_cache entry.

Preserving the value on a miss keeps the declared reference visible instead of
erasing it, and matches the same change made for ResourceTarget ids in moghtech#1581.
It does not make the reference resolve; a dangling build id stays dangling, and
is now legible rather than silently blank.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant