feat(image): add property support to create/update/show - #8
Merged
Conversation
kallioli
force-pushed
the
feat/image-properties
branch
from
April 27, 2026 10:11
ecfc7d1 to
0eec10c
Compare
The CLI could not set or update custom Glance image properties
(`os_distro`, `os_version`, `hw_qemu_guest_agent`,
`cinder_img_volume_type`, …), which made inter-cloud image migration
lossy: properties present on the source image were silently dropped
on re-upload.
Three commands gain matching surface:
- `orca image create --property KEY=VALUE` (repeatable). Properties
ride on the Glance v2 POST body as top-level keys.
- `orca image update --property KEY=VALUE` and `--remove-property KEY`
(both repeatable), composable into a single atomic JSON-Patch.
Add-vs-replace is decided after fetching the current image so
untouched properties survive. Removes are strict by default and
turn idempotent under `--ignore-missing`.
- `orca image show` now surfaces every custom property Glance returns
plus the integrity fields (`checksum`, `os_hash_algo`,
`os_hash_value`, `direct_url`, `tags`): a `Properties` sub-table
in table format; a top-level `"properties"` aggregate in JSON; and
`KEY VALUE` lines in value format. JSON dual-renders each custom
property at the root *and* under `properties` so existing scripts
doing `jq .os_distro` keep working alongside the new
`jq .properties.os_distro`.
Property keys are validated client-side against Glance's
`^[A-Za-z0-9_:.\-]{1,255}$` schema before any HTTP round-trip — a
malformed key fails fast with a friendly error instead of an opaque
Glance 400. Only the first `=` splits a value, so URL-like values
(`--property url=https://x?a=1&b=2`) survive intact.
Tests cover the round-trip on create, untouched-on-update preservation
(only the changed key appears in the JSON-Patch), strict + idempotent
remove modes, key validation aborting before any HTTP write, value
preservation for `=`-bearing strings, and the three show formats
including the JSON dual-render rétrocompat.
kallioli
force-pushed
the
feat/image-properties
branch
from
April 27, 2026 10:15
0eec10c to
6665791
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
The CLI could not set or update custom Glance image properties
(
os_distro,os_version,hw_qemu_guest_agent,cinder_img_volume_type, …), which made inter-cloud image migrationlossy: properties present on the source image were silently
dropped on re-upload. This PR is the building block needed for a
future
orca image migrate(out of scope here, tracked separately).Changes
orca image create --property KEY=VALUE(repeatable). Propertiesride on the Glance v2 POST body as top-level keys.
orca image update --property KEY=VALUEand--remove-property KEYcompose into a single atomic JSON-Patch document. Add-vs-replace
is decided after fetching the current image so untouched properties
survive. Removes are strict by default and turn idempotent under
--ignore-missing.orca image showsurfaces every custom property Glance returnsplus integrity fields (
checksum,os_hash_algo,os_hash_value,direct_url,tags):Propertiessub-table after the standard fields,sorted by key
"properties"aggregate; each custom keyis also mirrored at the JSON root for backward compatibility
(
jq .os_distrokeeps working alongsidejq .properties.os_distro)KEY VALUElines after the standard fieldsProperty keys are validated client-side against Glance's
^[A-Za-z0-9_:.\-]{1,255}$schema before any HTTP round-trip —malformed keys fail fast with a friendly error instead of an opaque
Glance 400. Only the first
=splits a value, so URL-like values(
--property url=https://x?a=1&b=2) survive intact.Tests
15 new tests under
tests/test_image.pycovering the full lifecycle:--propertyflags=replacefor existing keys,addfor new ones--propertyand--remove-propertyin one patch--ignore-missingpropertieskey (json)KEY VALUElines (value format)pytest -q --cov=orca_cli --cov-fail-under=85: 2338 passed, coverage88.42%. ruff + mypy clean.
Risks
os_distroandos_versionmove from the standardimage showfield set into the Properties section. Table/value users see them
in a different visual section. JSON consumers are unaffected
thanks to the dual-render at the root. Documented in CHANGELOG.
ImageService.update. Service layer untouched.Out of scope (tracked separately)
orca image migrate(cloud-to-cloud copy preservingeverything). This PR is the building block it needs.
image create(no use case yet).