Skip to content

release: 5.9.10 - #1909

Merged
Jaro-c merged 5 commits into
mainfrom
develop
Sep 24, 2026
Merged

Jaro-c merged 5 commits into
mainfrom
develop

Conversation

@Jaro-c

@Jaro-c Jaro-c commented Sep 24, 2026

Copy link
Copy Markdown
Member

Release 5.9.10: healthcheck inheritance (#1903), events --since (#1904), logging driver (#1905) and watch reporting (#1906).

…1904)

Refs #1896

Podman reads a relative `--since` as a time before now, so `30m` is
thirty minutes ago and `-30m` is thirty minutes in the future, which
matches nothing. The help of `podup events` showed `-30m` as its
example, and the command then printed nothing and exited 0.

- The help and the flag table in `docs/commands.md` now show `30m` and
say a relative time counts back from now.
- A `--since` whose part after `-` is a Go duration (`-30m`, `-1.5h`,
`-.5h`, `-10ms`) is rejected with an error that shows the positive form.
Plain negative numbers (`-1`, `-1.5`, `-1e3`, Unix timestamps to Podman)
and zero offsets (`-0s`) are passed through unchanged, as before.
- The docs and code comments described a past window as `--since -2h
--until -1h`; that only closed because it was empty. They now say
`--since 2h --until -1h` (`--until` counts the other way), with the run
I measured: `--since 30s --until -1s` on Podman 5.7.0 closes the feed.

Checked against Podman 5.7.0 with a service restarting in a loop:
`--since 30s` gives the same 8 `die` events and 28 lines with v5.9.9 and
this branch; `-30m`, `-.5h` and `-1.5h` now exit 1 with the corrective
message; `-1`, `-0s` and `-1e3` behave as before. A test drives
`stream_events_with_options` against a missing socket to prove the check
runs before any request.

---------

Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
…#1903)

Refs #1893

A `healthcheck:` block without a `test` inherits the image's
HEALTHCHECK, but `build_healthcheck` still filled `interval`, `timeout`
and `retries` with the compose defaults (30s/30s/3), and libpod took
those as explicit values over the image's.

Now the defaults are only applied when the block has a test. Without
one, only the timings the user wrote are sent, and when nothing at all
is set (for example a block with only `x-podman-on-failure`) no
`healthconfig` is sent, so Podman inherits the image probe whole. An
empty exec list (`test: []`) counts as no test, since libpod treats it
the same way. An empty shell string (`test: ""`) is still sent as the
explicit `["CMD-SHELL", ""]` probe it always was.

Checked with Podman 5.7.0, an image with `HEALTHCHECK --interval=2s
--timeout=2s --retries=2`, v5.9.9 against this branch:

| healthcheck | v5.9.9 | this branch |
|---|---|---|
| `{x-podman-on-failure: restart}` | 30s / 30s / 3 | 2s / 2s / 2, action
`restart` kept |
| `{test: [], x-podman-on-failure: restart}` | 30s / 30s / 3 | 2s / 2s /
2 |
| `{interval: 5s}` | 5s / 30s / 3 | 5s / 2s / 2 |
| `{test: ["CMD","true"]}` | 30s / 30s / 3 | same |
| `{test: ""}` | `CMD-SHELL ""`, 30s / 30s / 3 | same |
| `{disable: true}` | `NONE` | same |

Not covered: on Podman 5.4.2 a `healthconfig` without a test replaces
the image healthcheck instead of merging it, so a timing-only override
there still loses the image probe. That was already the case and this
does not change it; the no-override case is fixed there too, because no
`healthconfig` is sent.

Reverting each part turns a unit test red. The Quadlet renderer already
emitted only the user's fields and is untouched.

---------

Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
…iver (#1905)

Refs #1895

Two logging problems from the issue, measured on Podman 5.7.0:

- `logging: { options: { max-size: 1m } }` with no `driver` reached
libpod with no driver, so the containers.conf default (journald here)
won and the size did nothing. When a block sets a positive `max-size`
without a driver, podup now uses `k8s-file`, the only driver that
applies the size. A block without a driver and without a positive size
(for example only `tag`, or `max-size: "-1"`) keeps the host's default
driver exactly as before, so journald setups are not moved.
- `max-file` was already dropped (Podman does not implement it), but the
warning said to expect unbounded growth. It now names the service and
says Podman keeps a single file, truncated at `max-size` when one is
set, with no rotated history.

`docs/commands.md` listed `max-file: 5` in the default and suggested
`max-file: "0"` to disable rotation, which Podman ignores. It now shows
the real default (`k8s-file`, 10m), `max-size: "-1"` as the opt-out
(noting that a positive `log_size_max` in containers.conf still
applies), and the driverless rule.

v5.9.9 against this branch, `podman inspect` of `HostConfig.LogConfig`:

| logging | v5.9.9 | this branch |
|---|---|---|
| `{options: {max-size: 1m}}` | journald, 1.049MB | k8s-file, 1.049MB |
| `{options: {tag: myapp}}` | journald, tag myapp | same |
| `{options: {max-size: "-1", tag: myapp}}` | journald, tag myapp | same
|
| `{driver: k8s-file, options: {max-size: 1m, max-file: "3"}}` |
k8s-file, 1.049MB | same, clearer warning |
| no `logging:` | k8s-file, 10.49MB | same |

`generate quadlet` uses the same function, so it gets the same driver
choice; the Quadlet tests pass unchanged.

---------

Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
…ing paths (#1906)

Refs #1897

Parts 1 to 3 of the issue. Part 4 (`ignore` semantics) changes how
existing rules match, so I am leaving it for a separate change.

- **Failed container-side steps were logged as done.** `watch_exec`
never read the exec's exit code, so a `rm -f` that failed with
`Permission denied` still logged `removed ...`, and a failing `exec`
rule was silent. It now reads the exit code the way `exec_hook` does and
returns an error for a non-zero exit; the watch loop logs `watch action
failed` and keeps watching. The best-effort `mkdir -p` still ignores its
result.
- **A missing watch path was reported as synced.** The initial sync ran
before the existence check. A path with no directory entry is now
skipped (the existing `watch path not found` warning still fires); a
dangling symlink still has an entry and is still synced as a link, as
before.
- **Syncs into a read-only root filesystem failed on every edit with no
explanation.** With `read_only: true`, a sync target that no compose
volume or tmpfs covers now gets one warning at startup. It is skipped
when the service uses `volumes_from` (not resolved here), and the
message says an image `VOLUME` at that path would also make it writable,
since podup does not inspect the image.

Checked with Podman 5.7.0, v5.9.9 against this branch: the denied delete
now logs the failure instead of `removed` (the file really is still
there); the missing path no longer logs `initial sync` / `synced`; the
read-only service gets the warning; a normal sync, a permitted delete
and a `sync+exec` rule behave as before; a dangling symlink rule syncs
the link (`readlink` shows its target in the container). An integration
test asserts that a command exiting 3 surfaces `exited with status 3`.

Found while testing, not part of this: `volumes_from` does not order
container start, so a service can be created before the one it takes
volumes from and `up` fails with HTTP 500. I will open a separate issue.

---------

Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
Bumps `Cargo.toml`, `Cargo.lock` and `debian/changelog` to 5.9.10 for
#1903, #1904, #1905 and #1906.

Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
@Jaro-c Jaro-c added prio:P2 Medium priority effort:XS Extra small type:chore Maintenance with no product impact area:release Subsystem: release labels Sep 24, 2026
@Jaro-c
Jaro-c merged commit a84921b into main Sep 24, 2026
81 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:release Subsystem: release effort:XS Extra small prio:P2 Medium priority type:chore Maintenance with no product impact

Development

Successfully merging this pull request may close these issues.

1 participant