propose fix for tonersave queue default

This commit is contained in:
juergen committed 2026-10-20 15:42:46 +02:00
1 parent f556103f3c
commit 0b1276843f
5 files changed
+328

No files matched your search

@@ -0,0 +1,130 @@
# Design
## Context
See proposal.md — Why for the observed split. The pieces that shape the
approach:
- `entrypoint.sh` (`apply_printer_options`, lines ~341–383) validates every
`key=value` against `lpoptions -p <queue> -l` and then calls
`lpadmin -p <queue> -o <opt>`, logging `queue default <opt> applied` on exit
status 0. Exit status is the only signal it has, and `lpadmin` returns 0 even
when the setting does not take effect.
- The queue's settings are persisted in the queue's PPD copy
`/etc/cups/ppd/<queue>.ppd` (`*DefaultTonerSaveMode: True`,
`*DefaultBRColorMode: None`), not as `printers.conf` `Default*` lines; with
this CUPS the settings file alone therefore cannot distinguish "applied" from
"accepted and dropped".
- Confirmed in two containers (manual `lpadmin -o` and the entrypoint's own
startup batch): after `lpadmin -o TonerSaveMode=True` the PPD copy says
`True`, while `lpoptions -p <queue> -l` keeps showing `TonerSaveMode/Toner
Save: *False True`; `BRColorMode` in the same batch is consistent
(PPD copy `None`, `-l` `*None`).
- `TonerSaveMode` is a Boolean PPD option (assets/.../BR4150_2.PPD line 327)
whose `True` branch emits `statusdict/tonersave known{statusdict begin true
tonersave end}if`; the six `APPrinterPreset` entries set
`*TonerSaveMode True|False` for draft/normal/high, which is how the
documented driverless draft behaviour is implemented.
- The rejected observation point: `lpoptions -p <queue>` without `-l` lists
only IPP queue attributes, so it never shows PPD option defaults. The
archived `fix-colour-defaults-and-client-options` verification used
`lpoptions -p <queue> -l` (correct), and the `revert-colour-mode-default`
task 3.2 command was corrected to match during apply.
- The repo has no test suite yet; the job-level check introduced here is a
self-contained script that drives `podman`, a placeholder `PRINTER_IP` and a
minimal hand-written PostScript/PDF sample (no sample fixtures exist in the
repo), so it stays runnable without a printer and without network access to a
real device.
## Goals / Non-Goals
**Goals:**
- Determine whether a job actually receives an applied `TonerSaveMode` queue
default, from the emitted PostScript, not from settings files.
- Turn the runtime-queue-default requirement into one that a job-level test can
falsify, so the same class of "accepted but ineffective" defect cannot pass
again.
- Leave the spec honest: a verified behaviour becomes the scenario; a verified
limitation is recorded instead of an aspiration.
**Non-Goals:**
- Changing `entrypoint.sh` validation/plumbing unless the investigation
identifies a fixable server-side cause.
- Re-testing the colour-saturation limitation (documented by
`revert-colour-mode-default`) or re-opening `BRColorMode` behaviour, which is
verified.
- Adding job-level assertions for every PPD option; the example in the
requirement (`BRColorMode` + `TonerSaveMode`) is the coverage.
## Decisions
**D1 — Observation point for queue defaults: `lpoptions -p <queue> -l`
(asterisks) plus the queue PPD copy; never `lpoptions -p` without `-l`.**
Rationale: `-p` without `-l` shows IPP queue attributes only (see Context) and
produced a false negative during `revert-colour-mode-default`. `-l` reflects the
option the queue would use; the PPD copy shows what was persisted. Both are
still *configuration* views, so they are used only to set up and cross-check a
scenario, never as the acceptance signal.
Alternatives considered: `printers.conf` `Default*` lines (absent with this
CUPS — rejected); the CUPS web admin page (same settings source, needs auth —
rejected); `lpstat -l -p` (no option detail — rejected).
**D2 — Acceptance signal is the emitted PostScript spooled by cupsd.**
Rationale: it is the only artefact that shows what the printer receives, it
covers presets, queue defaults and per-job options in one channel, and the
existing spec already reasons in those terms (`<</UseCIEColor false>>`). The
spool file is the last file in `/var/spool/cups/d<JobId>-*` (its name comes from
the preceding `lpstat -W completed -o` line), and is readable as root inside the
container for a few minutes while the socket connection to the placeholder
`PRINTER_IP` fails.
Alternatives considered: asserting on `lpoptions -l` alone (that is exactly the
blind spot being fixed — rejected as the acceptance signal, kept as setup
cross-check); parsing the *source* `/usr/share/cups/model/BR4150_2.PPD` in the
image (proves packaging, not the job — rejected); a throwaway CUPS-side hook or
debug logging (more moving parts than one file read — rejected).
**D3 — Investigate before specifying the `TonerSaveMode` outcome.**
Rationale: the change must not encode an unverified assumption. Task group 1
runs the probe and records the result (spool PostScript, `-l` state, and — for a
second data point — an explicit per-job `-o BRColorMode=Vivid` in the same job
that must visibly differ from the queue default `None`). If the queue default
does reach the job, the scenario as written stands. If it does not, the
investigation result is added to this design and the scenario is reworded to the
verified behaviour plus an explicit limitation note before the checkboxes for
task group 2/3 are ticked.
Alternatives considered: writing the scenario as aspirational and letting the
test fail until someone fixes it (leaves a red suite and an untrue spec —
rejected); downgrading the scenario up front to "the PPD copy is written"
(keeps the blind spot — rejected).
**D4 — Prefer a PostScript-text assertion over a rendered/printed test.**
Rationale: it is deterministic, needs no printer, and is CI-friendly. A physical
print (toner save visibly lighter) stays a human check and is not part of the
automation.
Alternatives considered: rasterising the output and comparing image statistics
(flaky, tooling-heavy — rejected).
**D5 — `TonerSaveMode` is compared against the vendor `False` default, not the
preset wiring.** Rationale: the requirement asserts the *queue default* path;
whether a client preset overrides it is the separate, already documented
driverless scenario. Both must remain visible in the emitted PostScript, which
the test checks by applying the documented `PRINTER_OPTIONS` example.
## Risks / Trade-offs
- The spool file is lifetime-bounded (retention) and the test container's job
never reaches a printer, so the test must read the file soon after submission
and tolerate `connection refused` state messages; if it races, the preferred
per-job capture is `cupsfilter <sample.pdf>` inside the container with the
same PPD, which produces the same PostScript text without a queue.
- `lpadmin -o` behaviour is option- and CUPS-version-specific; the test must
state the CUPS version it was verified against so a future base-image bump
does not silently reinterpret the assertion.
- If the investigation finds the drop is a CUPS/driverd quirk with no image-side
fix, the change still lands value (honest spec + regression guard) but leaves
`TonerSaveMode` as a documented limitation; that outcome must be reported, not
absorbed.
- Boolean `TonerSaveMode` is the same option the draft presets tune, so a future
preset change can mask a broken queue default; the job-level test deliberately
submits a job *without* `print-quality`/preset attributes to keep the two
paths separate.