Skip to content

Commit 0eec10c

Browse files
committed
feat(image): add property support to create/update/show
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.
1 parent 762117f commit 0eec10c

4 files changed

Lines changed: 535 additions & 20 deletions

File tree

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,27 @@ All notable changes to orca are documented here. The format follows
44
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project
55
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [Unreleased]
8+
9+
### Added
10+
11+
- **Full image-property support across `image create`, `image update` and
12+
`image show`.** Custom Glance properties (`os_distro`, `os_version`,
13+
`hw_qemu_guest_agent`, `cinder_img_volume_type`, …) can now be set on
14+
creation (`--property KEY=VALUE`, repeatable) and edited atomically on
15+
existing images (`--property` and `--remove-property`, `--ignore-missing`
16+
for idempotent removal). Property keys are validated client-side against
17+
Glance's `^[A-Za-z0-9_:.\-]{1,255}$` schema before any HTTP round-trip,
18+
and only the first `=` splits the value so URL-like values survive intact
19+
(`--property url=https://x?a=1&b=2`). `image show` surfaces every custom
20+
key Glance returns plus the integrity fields (`checksum`, `os_hash_algo`,
21+
`os_hash_value`, `direct_url`, `tags`): as a `Properties` sub-table in
22+
table format, under a new top-level `"properties"` aggregate in JSON
23+
(with each custom key **also** mirrored at the JSON root for backward
24+
compatibility — `jq .os_distro` keeps working alongside the new
25+
`jq .properties.os_distro`), and as `KEY VALUE` lines in value format.
26+
This unblocks lossless inter-cloud image migration.
27+
728
## [2.0.1] — 2026-04-22
829

930
### Fixed

docs/commands/image.md

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ orca image cache-queue [OPTIONS]
7171
Create a new image (and optionally upload data).
7272

7373
```bash
74-
orca image create [OPTIONS]
74+
orca image create [OPTIONS] NAME
7575
```
7676

7777
| Option | Description |
@@ -82,8 +82,16 @@ orca image create [OPTIONS]
8282
| `--min-ram INTEGER` | Min RAM (MB). [default: 0] |
8383
| `--visibility [private|shared|community|public]` | |
8484
| `--file PATH` | Upload image data from file immediately. |
85+
| `--property KEY=VALUE` | Custom image property to set on creation (repeatable). Values may contain `=` — only the first `=` splits. Keys must match `^[A-Za-z0-9_:.\-]{1,255}$`. |
8586
| `--help` | Show this message and exit. |
8687

88+
```bash
89+
orca image create ubuntu-24.04 --file ubuntu.qcow2 \
90+
--property os_distro=ubuntu \
91+
--property os_version=24.04 \
92+
--property hw_qemu_guest_agent=yes
93+
```
94+
8795
---
8896

8997
## deactivate
@@ -276,18 +284,33 @@ orca image share-and-accept [OPTIONS]
276284

277285
## show
278286

279-
Show image details.
287+
Show image details, including custom properties and integrity hashes.
280288

281289
```bash
282-
orca image show [OPTIONS]
290+
orca image show [OPTIONS] IMAGE_ID
283291
```
284292

293+
Custom properties (anything outside the Glance v2 standard schema, e.g.
294+
`os_distro`, `os_version`, `hw_qemu_guest_agent`, `cinder_img_volume_type`)
295+
are surfaced separately:
296+
297+
- **table** — rendered as a `Properties` sub-table after the main table,
298+
sorted by key.
299+
- **json** — exposed both at the top level (mirroring the raw Glance
300+
response shape, so existing scripts using `jq .os_distro` keep working)
301+
and under a new top-level `"properties"` aggregate so callers can also
302+
do `orca image show <id> -f json | jq .properties`.
303+
- **value** — printed after the standard fields, one `KEY VALUE` per line.
304+
305+
Integrity fields (`checksum`, `os_hash_algo`, `os_hash_value`, `direct_url`)
306+
and `tags` are always included as standard fields when Glance returns them.
307+
285308
| Option | Description |
286309
|--------|-------------|
287310
| `--noindent` | Disable JSON indentation. |
288311
| `--max-width INTEGER` | Maximum table width (0 = unlimited). |
289312
| `--fit-width` | Fit table to terminal width. |
290-
| `-c, --column TEXT` | Column to include (repeatable). Shows all if |
313+
| `-c, --column TEXT` | Column to include (repeatable). Shows all if omitted. |
291314
| `-f, --format [table|json|value]` | |
292315
| `--help` | Show this message and exit. |
293316

@@ -429,17 +452,32 @@ orca image unused [OPTIONS]
429452
Update image properties (JSON-Patch).
430453

431454
```bash
432-
orca image update [OPTIONS]
455+
orca image update [OPTIONS] IMAGE_ID
433456
```
434457

458+
All flags compose into a single atomic JSON-Patch document.
459+
`--property` emits `add` when the key is absent on the image and `replace` when
460+
it already exists, so untouched properties survive. `--remove-property` is
461+
strict by default (errors if the key is absent) and turns idempotent under
462+
`--ignore-missing`.
463+
435464
| Option | Description |
436465
|--------|-------------|
437466
| `--name TEXT` | New name. |
438467
| `--min-disk INTEGER` | New min disk (GB). |
439468
| `--min-ram INTEGER` | New min RAM (MB). |
440469
| `--visibility [private|shared|community|public]` | |
470+
| `--property KEY=VALUE` | Set or replace a custom image property. Repeatable. |
471+
| `--remove-property KEY` | Remove a custom image property by key. Repeatable. |
472+
| `--ignore-missing` | With `--remove-property`: silently skip keys that are not present on the image. |
441473
| `--help` | Show this message and exit. |
442474

475+
```bash
476+
orca image update <id> --property os_distro=ubuntu --property os_version=24.04
477+
orca image update <id> --remove-property hw_qemu_guest_agent
478+
orca image update <id> --remove-property foo --ignore-missing
479+
```
480+
443481
---
444482

445483
## upload

0 commit comments

Comments
 (0)