Conversation
## What I filled the doc-comment gaps across `internal/` flagged in #579, judged against our style standard: every public item carries a doc comment stating its contract (errors, invariants, **units**, side effects), not a restatement of the signature. ## Changes - **Real defect fixed** — `engine/health.rs`: the doc block describing `wait_healthy` was glued above `wait_services_healthy`, so rustdoc rendered the wrong function's docs and `wait_healthy` had none. Moved it to the function it describes. - **libpod wire types** — documented fields with their units/format where it's a correctness hazard: `HealthConfig` timing = nanoseconds, `LinuxMemory` = bytes, `shm_size` = bytes, `stop_timeout` = seconds, throttle rates = bytes/s or iops by field. Verified each unit against how the value is produced/consumed; converted the serde wire-rename rationale comments from `//` to `///`. - **compose types** — every `Service` field (compose key, unit/default, precedence: `scale` vs `deploy.replicas`, top-level `cpus`/`mem` over `deploy.resources`, `restart` vs `deploy.restart_policy`, `pull_policy` values), plus `SecretConfig`/`ConfigConfig`/`ModelConfig`/`ComposeFile` and the `develop` watch types. - **engine / quadlet / crate root** — `build_resource_limits`/`build_ulimits`, `parse_device`, the quadlet `unit`/`render` helpers, and the public module surface in `lib.rs`. - **doc-build hygiene** — fixed stale/broken intra-doc links surfaced by rustdoc (so docs build clean under `-D warnings`) and corrected the `include.rs` module header that omitted `models` from the merged-fields list. ## Scope Documentation only — no behavior change. ## Verification - `cargo fmt --check` — clean - `cargo doc --no-deps --document-private-items` under `RUSTDOCFLAGS=-D warnings` — clean - `cargo check --all-targets` — clean - `cargo test --lib` — 836 passing Closes #579 Signed-off-by: Jaro-c <anacaicedo1224@gmail.com> Co-authored-by: Jaro-c <anacaicedo1224@gmail.com>
## What I reviewed every doc under `docs/` (plus `bench/`/`fuzz/` READMEs) one by one, fixed claims that drifted from the code, and reorganized each by its document type. `README.md` is intentionally untouched (separate pass). ## Accuracy fixes (verified against code) - **`self-update.md`** — failure exit code is **`3`**, not `2` (`internal/update/mod.rs:109`, test asserts `!= 2`). Added the package-manager-managed refusal that happens *before* any download (`mod.rs:79-85`). - **`docker-migration.md`** — added the `network_mode: bridge` divergence (isolated netns under rootless Podman; siblings unreachable; use a shared `networks:` entry) per `compose/diagnostics/ignored_fields.rs`. Corrected `env_file.format` to a **warning** (not an error). Fixed `provider`/`models` wording (modeled-but-not-honored, not "unknown key"). Qualified GPU as NVIDIA-only/host-dependent. Made the ignored-fields list explicitly examples, not exhaustive. - **`commands.md`** — filled missing flags/commands: `up -t/-V/--timestamps`, `down/stop/restart -t`, `start --wait/--wait-timeout`, the `build` flag set, `rm -s`, the whole `exec` option set, `pull --policy/...`, `create` flags, `port --index`, aliases. ## Restructure (no claim changed) - **`commands.md`** — grouped by purpose, one options table per command, exit-status table. - **`docker-migration.md`** — works-out-of-the-box → divergences → accepted-no-effect → not-yet-supported. - **`self-update.md`** — flow ordered to match the code. - **`security-model.md`** — reorganized for an auditor read (trust boundaries → connection → secrets → filesystem → memory safety → supply chain → self-update → reporting). - **`debian-packaging.md`** — noted the `.deb` is built `--no-default-features` (self-update compiled out, hence the `podup update` refusal); native per-arch builds; trimmed an unverifiable aside. `bench/README.md` and `fuzz/README.md` were already accurate and left as is. ## Scope Documentation only — no behavior change. Code fences balanced, every documented command/flag verified to exist in `internal/cli/`, no external badges/hotlinks. Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
## What Remove the "Refresh the Glyndor apt repository" step from `release.yml`. ## Why `Glyndor/apt` no longer listens for a `repository_dispatch` (Glyndor/apt#20) — it rebuilds on its daily schedule and on demand. This step was already a no-op without an `APT_DISPATCH_TOKEN` (a write credential on apt, which was never provisioned), so removing it drops dead code and the need for podup to ever hold any credential on apt. A new podup release is picked up by apt's next daily build. Replaces the now-closed #585. Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
## What The public security docs carried maintainer-only mechanics that don't belong on a public surface: - `docs/self-update.md` — the public-key derivation script (`RELEASE_SIGN_KEY` → python) and the step-by-step two-release key-rotation procedure (slot edits, CI-secret switch). - `docs/debian-packaging.md` — the "Refreshing after a release" runbook (`gh workflow run publish.yml`, the `APT_DISPATCH_TOKEN` setup). Those are operator runbooks, not third-party trust-model content. ## Change I trimmed both docs to keep only what a third party needs to trust and independently verify a release: the two-key trust anchor, fail-closed verification, rotation that never strands installs, and offline/air-gapped verification. The operator procedures move to the private ops context (no information lost). Net: +7 −45. Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
## What `.editorconfig` set indentation only per language, so a file without a matching section (e.g. `.py`) inherited no indent rule at all. ## Change - Moved the tabs-width-4 default onto `[*]` so it applies to every file type. - Dropped the now-redundant per-language `rs`/`sh`/`toml` sections (covered by the default). - Kept spaces only for the YAML/JSON exception the style standard allows. - Markdown keeps its `trim_trailing_whitespace = false` override and inherits the tab default. Net: 12 deletions, no behavioural change beyond filling the gap the standard requires. Closes #583 Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
Adds `max_line_length = 120` to `[*]`, matching the org scaffold (`template-repository`) and `apt`. podup's `.editorconfig` was the only thing the now-closed #584 carried that #588 dropped; this brings it over without #584's Markdown-on-tabs regression. Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
Fixes the empty STATUS column and missing host IP in `podup ps` on Podman 5. ## Problem (#590) Podman 5's libpod list endpoint leaves `Status` empty and reports the machine state in `State`. `podup ps` rendered `Status` directly, so the STATUS column was blank for running containers; the ports column also dropped the host IP (`:8080` instead of `0.0.0.0:8080`). ## Fix - `display_status()` falls back to `State` when `Status` is empty (table + JSON). - `format_ports()` defaults an unset host IP to `0.0.0.0`, matching docker/podman. - Both helpers are pure and unit-tested against the real wire shape (empty `Status` + populated `State`). ## Verified Built and run against real Podman 5.4.2: ``` NAME IMAGE STATUS PORTS v590-web alpine running 0.0.0.0:8080->80/tcp ``` JSON `"Status": "running"`. Was blank + `:8080` before. Closes #590 Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
…ning (#601) ## Problem (#591) `podup stats` always failed on Podman 5: ``` HTTP 404: unable to look up container v591-api,v591-web: no such container ``` libpod's `/containers/stats` wants `containers` **repeated** per container; podup comma-joined them into one value, parsed as a single container name. ## Fix Emit `&containers=a&containers=b` instead of `&containers=a,b`. Updated the unit test that had encoded the comma-joined form (it asserted an input the daemon never accepts — the fixture enshrined the bug). ## Verified Probed the real libpod socket: repeated form returns `Stats`, comma/array forms 404. Built and run against Podman 5.4.2: ``` NAME CPU % MEM USAGE / LIMIT ... v591-api 0.25% 48.0KiB / 60.7GiB v591-web 0.26% 48.0KiB / 60.7GiB ``` Closes #591 Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
) ## Problem (#592) After a runtime `scale`/`up --scale`, by-service commands broke. The running containers are `svc-1..N` but the targeting commands derived names from the compose file's **static** replica count (`replica_names`, which is 1), so they looked for the unsuffixed `project-svc` and 404'd or warned: ``` $ podup scale api=3 && podup restart api HTTP 404: no container with name or ID "sweep-api" found ``` Affected `stop`/`start`/`restart`/`kill`/`pause`/`unpause`/`top`/`stats`/`wait`; `down` emitted a spurious `could not stop project-svc` warning before its label sweep. ## Fix `live_replica_names()` lists the containers Podman actually has for a service (by the `podup.service` label) and falls back to the static names only when none exist yet. The targeting commands route through it; `down` stops the real replicas directly. ## Verified Built and run against real Podman 5.4.2 — `scale api=3` then: ``` restart api -> exit 0 (was 404) top api -> 3 replicas (was warning) stop api -> 3 stopped (was 404) down -> 3 removed, no warning ``` Closes #592 Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
## Problem (#597) `podup completions bash | head` aborted with SIGABRT (exit 134): `clap_complete::generate` panics when its writer errors, and a reader that closes the pipe early makes the stdout write fail. ## Fix Render the completion script into a `Vec` (which never fails to write), then write it to stdout and treat `BrokenPipe` as a clean exit — standard Unix-tool behaviour. ## Verified (Podman not needed) ``` podup completions bash | head -1 -> exit 0 (was 134) podup completions zsh | head -1 -> exit 0 podup completions bash > /dev/null -> exit 0 (output unchanged) ``` Closes #597 Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
## Problem (#594) `podup logs` printed raw output with no service tag — in a multi-service stack you can't tell which service a line came from. `docker compose logs` prefixes each line with the service. ## Fix `LinePrefixer` buffers stream frames (which may split a line) and tags each complete line with `<container> | `, applied on both the concurrent `-f` path and the sequential path, with a tail flush for an unterminated final line. stdout/stderr keep separate buffers. ## Verified Built and run against real Podman 5.4.2 on a two-service stack: ``` v594-alpha | alpha-1 v594-alpha | alpha-2 v594-beta | beta-1 v594-beta | beta-2 ``` Plus unit tests for line tagging, partial-frame buffering and tail flush. Closes #594 --------- Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
## Problem (part of #593) A generated `.container` unit set `ContainerName` to the bare service key (`ContainerName=web`), so the container it creates is named `web` — colliding with any other project's `web` service and diverging from `up`, which names it `project-web`. ## Fix Default `ContainerName` to `{project}-{service}`, matching `up`. An explicit `container_name:` still wins. ## Verified `generate quadlet` on project `sweep`: ``` ContainerName=sweep-web # was: web ``` 74 quadlet tests pass, including a new one for the default. ## Out of scope (left on #593) Prefixing the unit **filenames** (`web.container` → `sweep-web.container`, and the same for `.network`/`.volume`) needs a coordinated rename plus an audit of every cross-unit reference (`After=`/`Requires=`/`Network=`), and Quadlet-resolution verification — its own PR. Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
## Problem (#599) Two CLI output gaps found in the empirical sweep: 1. `podup watch` looked silent — it logs each sync/rebuild/restart at INFO, but the default WARN log floor hid them. 2. `podup top --format json` errored `service '--format' not found` — `top` had no `--format` and its `trailing_var_arg` swallowed the flag as a service name. ## Fix - Initialize tracing with an **INFO** floor for the interactive `watch` command (every other command keeps WARN; `RUST_LOG` always overrides). - Add `--format json` to `top` (like ps/ls/images), emitting `[{Container, Titles, Processes}]`. ## Verified (Podman 5.4.2) ``` # watch (no RUST_LOG) now prints: podup: info: synced …/src/f.txt -> /app # top --format json: [ { "Container": "v599c-web", "Processes": [[ "root", "1", … ]] } ] ``` Table `top` output unchanged. Closes #599 --------- Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
#607) ## Problem (#595) `podup config` printed `field: null` for every unset field plus empty `volumes: {}`/`networks: {}`/… sections — noisy and unlike `docker compose config`. It also didn't validate a missing image/build (`up` does), so `config --quiet` (validate-only) passed an invalid file. ## Fix - Prune null and empty values from the rendered YAML/JSON, bottom-up (a section emptied by its own nulls is dropped too). - Validate every service has an image or build, before the `--quiet`/`--services` short-circuits, matching `up` and `docker compose config`. ## Verified (Podman 5.4.2) ``` # before: ~15 `: null` lines + 5 empty sections # after: name: v595 services: web: image: …/alpine:latest command: [sleep, '600'] networks: [default] $ podup -f no-image.yml config -> error: service 'bad' has no image or build config (exit 1) $ podup -f no-image.yml config --quiet -> same (validate-only now validates) ``` Unit tests for both prune paths. Closes #595 Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
…608) ## Problem (#598) `stop`/`start`/`restart`/`kill`/`pause`/`unpause` handled failure inconsistently: `stop` warned and exited 0 even on a real error (masking it), while the others propagated every error — including the harmless "already in that state" (304) and "no such container" (404). ## Fix A shared `run_lifecycle_op` maps the libpod response consistently: - **304** (already in the desired state) and **404** (no such container) → idempotent no-op, exit 0. - any other failure → real error, propagated (non-zero exit) instead of swallowed. ## Verified (Podman 5.4.2, probed the real status codes) ``` start (already running) -> exit 0 (was 1; 304 is idempotent now) stop (already stopped) -> exit 0 (304) restart / kill / pause -> consistent ``` `stop` no longer swallows a genuine podman error into a warning. (`pause` on an already-paused container still exits non-zero — podman returns 500 "already paused" there, not 304, so podup faithfully surfaces it.) Closes #598 Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
Release 1.4.0 — the empirical-sweep fixes verified against real Podman 5.4.2. Bumps Cargo.toml/Cargo.lock and prepends the debian/changelog entry. Highlights since 1.3.0: - `ps` STATUS/host-IP, `stats` on Podman 5, scale+lifecycle replica resolution, `logs` prefixes (#600/#601/#602/#604) - `completions` broken-pipe, `config` prune+validate, lifecycle exit codes, `top --format json` + `watch` progress (#603/#607/#608/#606) - quadlet `ContainerName=<project>-<service>` (#605) After this lands on develop, I'll open the develop → main release PR (merge commit) and tag v1.4.0. Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
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.
Promote develop to main for the 1.4.0 release.
All commits since 1.3.0 — the empirical-sweep fixes (#600-#608, #605) verified against real Podman 5.4.2, plus the editorconfig/docs chores. Merged as a merge commit per the release flow; tag v1.4.0 follows on main.
The README redesign is intentionally NOT included (it lives on its own branch, unmerged).