fix(tiller): register YAML representer for ImageRef #5
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "arrdem/imageref-yaml-representer"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
ImageRefvalues auto-unwrap fromOpaquePythonObjectat the Starlark→Python boundary, so they reach the rendered manifest tree as raw dataclass instances. Without a custom YAML representer, PyYAML emits them as the!!python/object:tiller.types.ImageReftag shape, which is invalid Kubernetes YAML.This was fine in practice for all existing Tillerfiles because the builder functions (
deployment,statefulset, etc.) convert theirimage=argument viastr(image)before the value enters the manifest. But any user-composed dict — e.g.extra_containers=[{"image": some_ref}]for a sidecar — skips that conversion and reachesyaml.dumpwith the raw ImageRef.Change
Register
_imageref_representeron the dumper to emitstr(imageref)(already correctly defined asrepo:tagorrepo@digest). Users can now pass ImageRef values anywhere in a manifest without needing to stringify manually.Motivation
A downstream flowmetal Tillerfile wanted to add a chaos sidecar to a Deployment via
extra_containers=; it was forced to typechaos_imageas a plainstrinput to avoid the rendering bug, losing the tag/digest semanticsImageRefwould provide.Test plan
Three new tests in
tests/test_render.py:test_imageref_in_image_kwarg— baseline: ImageRef passed todeployment(image=)still renders asrepo:tag.test_imageref_in_extra_container— defect case: ImageRef inside a rawextra_containers=[{...}]dict now renders correctly, and the rendered YAML contains no!!python/objecttag (explicit regression guard).test_imageref_digest— digest form (repo@sha256:...) also works.242 tests pass in the full tiller suite.
ImageRef values auto-unwrap from OpaquePythonObject at the Starlark->Python boundary, so they reach the rendered manifest tree as raw dataclass instances. Without a custom representer PyYAML emits them as the `!!python/object:tiller.types.ImageRef` tag shape, which is invalid Kubernetes YAML. This was fine in practice for all existing Tillerfiles because the builder functions (`deployment`, `statefulset`, etc.) convert their `image=` argument via `str(image)` before the value enters the manifest. But any user-composed dict — e.g. `extra_containers=[{"image": some_ref}]` for a sidecar — skips that conversion and reaches yaml.dump with the raw ImageRef. Register `_imageref_representer` on the dumper to emit `str(imageref)` (which is already correctly defined as `repo:tag` or `repo@digest`). Users can now pass ImageRef values anywhere in a manifest without needing to stringify manually. Prompted by a downstream Tillerfile that wanted to add a chaos sidecar to a Deployment; it was forced to type `chaos_image` as a plain `str` input to avoid the rendering bug, losing the tag/digest semantics ImageRef would provide. Three new tests in tests/test_render.py pin the behavior: - ImageRef passed to `deployment(image=)`. - ImageRef inside a raw `extra_containers=[{...}]` dict. - ImageRef with a digest rather than a tag. The extra_containers test also asserts the rendered YAML contains no `!!python/object` tag — an explicit regression guard on the class of bug.