From 75b68fe43897a65619a8e83bf013cfcdacbed37a Mon Sep 17 00:00:00 2001 From: Juergen Holly Date: Tue, 20 Oct 2026 07:29:44 +0200 Subject: [PATCH] add fix color proposal --- .../changes/fix-airprint-discovery/tasks.md | 6 +- .../.openspec.yaml | 2 + .../design.md | 159 ++++++++++++++++++ .../proposal.md | 92 ++++++++++ .../specs/printserver/cups/spec.md | 72 ++++++++ .../tasks.md | 78 +++++++++ .../fix-ipps-certificate-lookup/tasks.md | 2 +- 7 files changed, 407 insertions(+), 4 deletions(-) create mode 100644 openspec/changes/fix-colour-defaults-and-client-options/.openspec.yaml create mode 100644 openspec/changes/fix-colour-defaults-and-client-options/design.md create mode 100644 openspec/changes/fix-colour-defaults-and-client-options/proposal.md create mode 100644 openspec/changes/fix-colour-defaults-and-client-options/specs/printserver/cups/spec.md create mode 100644 openspec/changes/fix-colour-defaults-and-client-options/tasks.md diff --git a/openspec/changes/fix-airprint-discovery/tasks.md b/openspec/changes/fix-airprint-discovery/tasks.md index 25c04c4..597f3ab 100644 --- a/openspec/changes/fix-airprint-discovery/tasks.md +++ b/openspec/changes/fix-airprint-discovery/tasks.md @@ -4,12 +4,12 @@ - [x] 1.1 Add `BrowseDNSSDSubTypes _print,_universal` to `cupsd.conf` with the reason (macOS treats a printer carrying `_cups` as shared and then withholds its AirPrint driver), and verify the directive name, its default and the way it forms the registered sub-type list against the CUPS 2.4 sources (`scheduler/conf.c`, `scheduler/dirsvc.c`) - [x] 1.2 Correct the README "macOS adds the printer as a Generic PostScript printer" section so it names the sub-type cause first, keeps the certificate as the second cause, and shows commands that actually report the advertisement; verify the documented `avahi-browse` commands are valid invocations of the installed Avahi client -- [ ] 1.3 Rebuild and redeploy the image on the podman host, then verify the advertisement: `podman exec systemd-print-server avahi-browse -rt _ipp._tcp,_universal` lists the queue and `avahi-browse -rt _ipp._tcp,_cups` does not list it (other CUPS servers on the network may appear there) -- [ ] 1.4 Verify nothing else regressed: `ipptool -tv ipp://podp.local:631/printers/` and the `ipps://` variant report ipp status 0, and `lpinfo -v` on a CUPS client still resolves the queue to a `dnssd://…/cups?uuid=…` URI +- [x] 1.3 Rebuild and redeploy the image on the podman host, then verify the advertisement: `podman exec systemd-print-server avahi-browse -rt _ipp._tcp,_universal` lists the queue and `avahi-browse -rt _ipp._tcp,_cups` does not list it (other CUPS servers on the network may appear there) +- [x] 1.4 Verify nothing else regressed: `ipptool -tv ipp://podp.local:631/printers/` and the `ipps://` variant report ipp status 0, and `lpinfo -v` on a CUPS client still resolves the queue to a `dnssd://…/cups?uuid=…` URI ## 2. Confirm macOS offers the driverless driver -- [ ] 2.1 On the Mac, remove the queue and add it again; verify the *Use:* popup offers **AirPrint Printer**, `/etc/cups/ppd/.ppd` contains `*APAirPrint: True` and `lpoptions -p -l` lists the duplex, colour and tray-2 options that the generic PPD hid +- [x] 2.1 On the Mac, remove the queue and add it again; verify the *Use:* popup offers **AirPrint Printer**, `/etc/cups/ppd/.ppd` contains `*APAirPrint: True` and `lpoptions -p -l` lists the duplex, colour and tray-2 options that the generic PPD hid ## Workflow follow-up diff --git a/openspec/changes/fix-colour-defaults-and-client-options/.openspec.yaml b/openspec/changes/fix-colour-defaults-and-client-options/.openspec.yaml new file mode 100644 index 0000000..9076a66 --- /dev/null +++ b/openspec/changes/fix-colour-defaults-and-client-options/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-10-20 diff --git a/openspec/changes/fix-colour-defaults-and-client-options/design.md b/openspec/changes/fix-colour-defaults-and-client-options/design.md new file mode 100644 index 0000000..77791e7 --- /dev/null +++ b/openspec/changes/fix-colour-defaults-and-client-options/design.md @@ -0,0 +1,159 @@ +# Design + +## Context + +Motivation und Messergebnisse stehen in `proposal.md`; hier nur die +technischen Randbedingungen, die den Ansatz bestimmen: + +- **Jobkette** für einen AirPrint-Job: macOS/iOS → IPP (PDF) → `pdftopdf` → + `pdftops` → `pstops` (PPD-Optionen, JCL/PJL) → `socket://9100:9100` → + Drucker. +- **`pdftops` (cups-filters 1.28)** läuft mit Default-Renderer + `CUPS_PDFTOPS_RENDERER` = `hybrid`; `hybrid` wechselt für + **Brother** ausdrücklich auf **Poppler**, um Bugs im PS-Interpreter des + Druckers zu umgehen (`filter/pdftops.c`, „Switching to Poppler's pdftops + instead of Ghostscript for Brother …"). Poppler kann keine Graustufen + erzeugen – es wird nur `WARNING: Grayscale/monochrome could be printed as + color with Poppler` geloggt. Deshalb ist ein serverseitiger + Grauzwang über `pdftops-renderer=gs` zwar technisch möglich, aber + ausgeschlossen (siehe Decisions). +- **CUPS-Optionsspalte**: `cupsMarkOptions()` (`cups/ppd-mark.c`) bildet + `print-color-mode` und `print-quality` ausschließlich über + *Presets* ab, die `_ppdCacheCreateWithPPD()` (`cups/ppd-cache.c`) aus + `APPrinterPreset`-Attributen der PPD – oder als Fallback aus einem + bekannten Grau-Optionsschlüssel (`ColorModel=Gray`, `BRMonoColor=Mono`, + `HPColorMode=grayscale`, …) – aufbaut. Die BR-Script3-PPD enthält + keines davon (Brother nutzt `BRPrintQuality=Black`), daher wird + `print-color-mode=monochrome` heute stillschweigend verworfen. + PPD-spezifische Optionen wie `BRColorMode`/`BRMediaType`/`TonerSaveMode` + sind darüber hinaus keine IPP-Attribute und erscheinen im + driverless AirPrint-Dialog grundsätzlich nicht. +- Die Queue wird bei jedem Containerstart neu erzeugt (kein Persistenz-Volume + vorausgesetzt), Queue-Defaults müssen deshalb bei jedem Start erneut + gesetzt werden – so wie bereits `printer-is-shared` und `-D`. + +## Goals / Non-Goals + +**Goals:** + +- Gesättigte Farbausgabe als Zustand (Default `BRColorMode=None`). +- S/W und Qualitätsstufe von macOS/iOS wirken geräteitig, ohne von der + PDF-Renderer-Wahl abzuhängen. +- PPD-Optionen, die der Dialog nicht zeigen kann, dauerhaft über die + Umgebung konfigurierierbar machen (`PRINTER_OPTIONS`). +- Nichts am Containerfile, an Discovery/Zertifikat oder am Windows-Weg ändern. + +**Non-Goals:** + +- Brother-spezifische Optionen (Vivid, Medientyp, Toner Save) im + AirPrint-Dialog sichtbar machen – mangels IPP-Äquivalent nicht darstellbar; + stattdessen serverseitige Defaults + Doku. +- Serverseitige Graustufen-Konvertierung (Poppler-Pfad) oder Wechsel des + Renderers. +- Änderung an der Drucker- oder Panel-Konfiguration selbst. + +## Decisions + +**1. Abbildung über `APPrinterPreset` in der PPD (statt `ColorModel`-Option, +Renderer-Wechsel oder entrypoint-Logik).** + +Sechs Presets – Kombination aus `com.apple.print.preset.output-mode` +(`color`/`monochrome`) und `com.apple.print.preset.quality` +(`low`/`normal`/`high`) – deren PPD-Optionen CUPS bei passendem +Job-Attribut automatisch mitmarkiert: + +| Preset (mode/quality) | PPD-Optionen | +| --- | --- | +| color / low | `TonerSaveMode=True` | +| color / normal | `TonerSaveMode=False` | +| color / high | `CAPT=SuperFine TonerSaveMode=False` | +| monochrome / low | `BRPrintQuality=Black TonerSaveMode=True` | +| monochrome / normal | `BRPrintQuality=Black TonerSaveMode=False` | +| monochrome / high | `BRPrintQuality=Black CAPT=SuperFine TonerSaveMode=False` | + +*Alternativen verworfen:* (a) `ColorModel`-Option mit Choice `Gray` anlegen – +löst zwar ebenfalls das Mono-Preset, verändert aber zusätzlich die +Werbung/Defaults von `print-color-mode` und die `cupsColorSpace`-Semantik in +`pstops`/Raster-Pfaden; (b) `pdftops-renderer=gs` als Queue-Default – +bringt den Grauzwang zurück, riskiert aber genau die PS-Interpreter-Bugs, +wegen derer `hybrid` bei Brother Poppler wählt; (c) Grauzwang im +`entrypoint` per `lpadmin -o` – unmöglich, da die Konvertierung im Filter +passiert und Poppler sie nicht kann. + +CUPS vergibt Preset-Optionen nur, wenn der Client den Namen nicht selbst +geschickt hat – clientseitige Auswahl gewinnt also weiterhin +(`ppd-mark.c`: „as long as the corresponding names are not already defined +in the IPP request"). + +**2. PPD direkt im Repository ändern (nicht zur Build-Zeit patchen).** + +Die Asset-Datei `assets/Brother HL-4150CDN/ppd/BR4150_2.PPD` wird bereits +gecommitted und vom Containerfile unverändert nach `/usr/share/cups/model` +kopiert. Die Änderungen (`*DefaultBRColorMode: None`, Presets, ggf. neue +Choice) werden als PPD-konforme Einträge mit `%`-Kommentar ergänzt, die +Herkunft des Files bleibt dokumentiert. *Alternative verworfen:* +`sed`-Patch im Containerfile – zweite Quellwahrheit, schwerer zu reviewen, +und `COPY` + `RUN`-Logik müsste ohnehin getestet werden. + +**3. Farbmodus-Default in der PPD statt als Entry-Point-Sonderfall.** + +`*DefaultBRColorMode: None` wirkt für jede aus dieser PPD erzeugte Queue, +auch für manuell angelegte, ohne dass `entrypoint.sh` etwas davon wissen +muss. `PRINTER_OPTIONS` bleibt damit generisch (Default leer) und dient nur +der Konfiguration, nicht dem Fix. + +**4. `PRINTER_OPTIONS`-Parsing und Anwendung.** + +Leerzeichengetrennte `key=value`-Tokens (Brother-Choice-Werte enthalten +keine Leerzeichen; getrennt wird auch an Zeilenumbrüchen). Jedes Token wird +einzeln als `lpadmin -o` gesetzt, direkt an der Stelle, an der heute +`printer-is-shared`, `-D` und `-d` gesetzt werden, und **bei jedem Start** – +damit gilt es auch für eine persistente Queue. Fehler pro Token abfangen +(`|| log warning`), da `set -eu` sonst den Start abbricht; unbekannte Namen +werden verworfen, ohne die übrigen zu blockieren. + +**5. Neue `BRColorMode`-Choice `VividNoCIE` nur unter Vorbehalt.** + +`<>` – Kombi, die es bisher nicht gibt +(`None` lässt `/BRColorMode` unangetastet, `Vivid` erzwingt CIE). Wird als +Testdruck gegen `None` verglichen; nur übernommen, wenn der Ausdruck +deutlich besser ist. Spezifikation hängt nicht davon ab (Default bleibt +`None`, Überschreibung ist ohnehin möglich). + +## Risks / Trade-offs + +- [PPD weicht dauerhaft vom Brother-Original ab] → Änderungen mit + `%`-Kommentar markieren, der README-Abschnitt „Änderungen an der PPD" + nennt Grund und Stelle; Upstream-Vergleich bleibt durch die + unveränderte Herkunft im Header möglich. +- [`print-quality=draft` druckt sichtbar weniger Toner („blass")] → + bewusst die Semantik des Reglers; dokumentiert, per Job und über + `PRINTER_OPTIONS` überschreibbar. +- [Mono wird jetzt geräteitig gerendert (`/BRProcessColor 1`), nicht mehr + gar nicht] → Grau-Wiedergabe des Druckers ist die einzige realistische + Route mit Poppler-Renderer; Akzeptanztest im Tasks. +- [`PRINTER_OPTIONS` wird bei falscher Schreibweise ignoriert] → Warning im + Log, `lpoptions -p -l` als Referenz in der Doku genannt. +- [Persistentes Volume: Defaults könnten aus altem Stand zurückkommen] → + Neu-Setzen bei jedem Start überschreibt sie deterministisch. +- [MacOS-Caches bei Drucker-Änderungen] → keine Client-Änderung nötig; + Server-Attribute bleiben gleich, nur Job-Verarbeitung ändert sich. + +## Migration Plan + +1. Image neu bauen (`podman build`), Container neu starten (Queue wird + ohnehin neu erzeugt bzw. Defaults überschrieben). +2. Akzeptanztest: S/W-Druck aus dem macOS-Dialog, Farbdruck-Vergleich mit + und ohne `PRINTER_OPTIONS`. +3. Rollback: Image auf den vorherigen Commit bauen; Einträge in der PPD + sind mit demselben Revert rückgängig zu machen, `PRINTER_OPTIONS` bei + Bedarf leer lassen. + +## Open Questions + +- Ob `VividNoCIE` mehr Sättigung liefert als `None` – wird im Tasks-Test + entschieden; ändert weder Spec (Default bleibt `None`) noch Aufbau. +- Ob macOS/iOS den Qualitätsregler als `print-quality` sendet – falls nicht, + bleiben die `print-quality`-Presets inert, `print-color-mode`-Presets + wirken unabhängig davon (Server-seitig per `lp -o print-quality=…` + testbar). diff --git a/openspec/changes/fix-colour-defaults-and-client-options/proposal.md b/openspec/changes/fix-colour-defaults-and-client-options/proposal.md new file mode 100644 index 0000000..4f795ec --- /dev/null +++ b/openspec/changes/fix-colour-defaults-and-client-options/proposal.md @@ -0,0 +1,92 @@ +# Proposal + +## Why + +Drucken funktioniert von macOS und iOS, aber die Ausgabe ist blass, und +driverless AirPrint-Clients erreichen nur IPP-Standardoptionen – Farbmodus +(Vivid), Medientyp und Toner Save sind reine PPD-Optionen und weder im +Druckdialog wählbar noch dauerhaft konfigurierbar. Zusätzlich wirkt die +im Dialog wählbare Option *Schwarz/Weiß* nicht: Der `pdftops`-Filter läuft +bei Debian für Brother-Drucker mit dem Poppler-Renderer, der keine +Graustufen erzeugen kann – der Job wird farbig gedruckt. + +Messbare Befunde der Testreihe (ein und dieselbe farbige PDF, gleiche +Drucker-Queue): + +- Nur `BRColorMode=None` liefert gesättigte Farben → die Vorgabe + `Normal` setzt `<>`, die CIE-Umrechnung im Drucker-RIP + wäscht die Farben aus. `Vivid` (setzt ebenfalls `UseCIEColor true`) und + `BRPrintQuality=Color` (`BRColorAdapt`) sowie `TonerSaveMode=False` + waren ohne sichtbaren Effekt. +- `print-color-mode=monochrome` gedruckt farbig → Ursache ist der + Poppler-Renderer von `pdftops` (siehe `WARNING: Grayscale/monochrome + could be printed as color with Poppler`). +- Der macOS-Druck ist identisch zu `lp`-Drücken → der Client (ColorSync) + ist nicht beteiligt. + +## What Changes + +- **Queue-Vorgabe für den Farbmodus kippt von `Normal` nach `None`** in der + BR-Script3-PPD (`*DefaultBRColorMode`): `UseCIEColor` ist damit aus, + Farben bleiben gesättigt. Verifiziert per Testdruck. +- **Die PPD erhält `APPrinterPreset`-Einträge**, die die für AirPrint + verfügbaren IPP-Attribute auf Geräteoptionen abbilden: + - `print-color-mode=monochrome` → `BRPrintQuality=Black` (der *Drucker* + rendert mono, unabhängig vom PDF-Renderer), + - `print-color-mode=color` → `TonerSaveMode=False`, + - `print-quality` draft/normal/high → `TonerSaveMode` und `CAPT` + (Fine/SuperFine). +- **Neue Umgebungsvariable `PRINTER_OPTIONS`** im `entrypoint.sh`: + leerzeichengetrennte `key=value`-Paare, die per `lpadmin -o` bei jedem + Start als Queue-Defaults gesetzt werden – damit überleben + PPD-Optionen (z. B. `BRMediaType`, `TonerSaveMode`, `BRColorMode=Vivid`) + die Neuerzeugung der Queue. +- **Optionale neue PPD-Choice `BRColorMode=VividNoCIE`** + (`<>`) als Testkandidat für noch + gesättigtere Ausgabe als `None`; nur behalten, wenn der Testdruck + besser ist als `None`. +- **README**: neuer Abschnitt, warum der AirPrint-Dialog nur + IPP-Standardoptionen zeigt und wie PPD-Optionen gesetzt werden (Env-Var, + CUPS-Web-UI, `lp`); Troubleshooting „Farben sind blass" mit der + durchgeführten Testreihe; Dokumentation der funktionierenden + S/W-Abbildung. + +Kein Bestandteil: Änderungen am Containerfile (die PPD wird bereits +installiert), am Verbindungs-/Zertifikatsverhalten oder eine +Server-seitige Erzwingung von Graustufen über `pdftops-renderer=gs` +(ausgeschlossen, weil der Ghostscript-Renderer genau die +PS-Interpreter-Bugs umgeht, die der Poppler-Renderer bei Brother +vermeidet). + +## Capabilities + +### New Capabilities + +*(keine)* + +### Modified Capabilities + +- `printserver/cups`: + - **Neues Requirement** „Queue-Defaults sind zur Laufzeit konfigurierbar": + `PRINTER_OPTIONS` wird bei jedem Start als `lpadmin -o` gesetzt. + - **Neues Requirement** „Farbausgabe ist standardmäßig gesättigt": Queue + und PPD-Default für `BRColorMode` sind `None` (`UseCIEColor` aus), + sofern nicht durch `PRINTER_OPTIONS` überschrieben. + - **Geändertes Requirement** „Hardware options are sent to the printer": + Szenario „Colour or mono" wird um die driverless-Clients erweitert – + `print-color-mode=monochrome` eines AirPrint-Clients muss zu + `BRPrintQuality=Black` und damit zu den mono-Parametern im + PostScript führen; zusätzlich Szenarien für `print-quality`. + +## Impact + +- `assets/Brother HL-4150CDN/ppd/BR4150_2.PPD` (Default `BRColorMode`, + neue `APPrinterPreset`-Einträge, ggf. neue Choice) – die + Herstellerdatei wird direkt im Repo gepatcht, der Build bleibt unverändert. +- `entrypoint.sh` (Auswertung von `PRINTER_OPTIONS`, idempotente + Queue-Defaults). +- `README.md` (Env-Var-Tabelle, „Printing options", Client-Unterstützung, + Troubleshooting). +- Verhalten für alle Clients (macOS, iOS, Linux): S/W-Auswahl wirkt ab + dann geräteitig statt gar nicht; bestehende Ausgabe wird gesättigter. +- Nicht betroffen: Containerfile, Zertifikat/Discovery, Windows-Weg. diff --git a/openspec/changes/fix-colour-defaults-and-client-options/specs/printserver/cups/spec.md b/openspec/changes/fix-colour-defaults-and-client-options/specs/printserver/cups/spec.md new file mode 100644 index 0000000..b1fa18b --- /dev/null +++ b/openspec/changes/fix-colour-defaults-and-client-options/specs/printserver/cups/spec.md @@ -0,0 +1,72 @@ +# Spec Delta + +## ADDED Requirements + +### Requirement: Queue defaults are configurable at runtime +The container SHALL accept a `PRINTER_OPTIONS` environment variable holding +space-separated PPD option assignments (`key=value`) and apply each assignment +as a queue default on every start, so PPD-specific device options survive the +recreation of the queue. + +#### Scenario: Options are applied on start +- **WHEN** the container is started with `PRINTER_OPTIONS="BRColorMode=Vivid TonerSaveMode=False"` +- **THEN** after startup the queue defaults include `BRColorMode=Vivid` and `TonerSaveMode=False` + +#### Scenario: Defaults apply to driverless clients +- **WHEN** a macOS or iOS client prints a job that does not specify that PPD option +- **THEN** the job is printed with the configured queue default + +#### Scenario: An unusable option must not stop startup +- **WHEN** `PRINTER_OPTIONS` contains an option name or value the PPD does not provide +- **THEN** the entrypoint logs a warning, applies the remaining assignments and continues starting + +#### Scenario: Nothing configured +- **WHEN** `PRINTER_OPTIONS` is unset or empty +- **THEN** the queue keeps the PPD defaults and the container starts as before + +### Requirement: Colour output is saturated by default +Unless overridden through `PRINTER_OPTIONS`, the queue SHALL default to the +colour mode `None`, which leaves the printer's CIE colour conversion +(`UseCIEColor`) switched off so that printed colours are not washed out. + +#### Scenario: Default colour mode +- **WHEN** a colour job is printed without any colour-mode options +- **THEN** the emitted PostScript contains `<>` rather than `UseCIEColor true` + +#### Scenario: Default is overridable +- **WHEN** the container is started with `PRINTER_OPTIONS` containing `BRColorMode=Vivid` +- **THEN** the queue default is `Vivid` instead of `None` + +#### Scenario: A job's own selection wins +- **WHEN** a job explicitly selects another `BRColorMode` value +- **THEN** that value is used for the job instead of the queue default + +## MODIFIED Requirements + +### Requirement: Hardware options are sent to the printer +The system SHALL translate the PPD's device options into PostScript +`setpagedevice` instructions so the printer's own hardware options are used. + +#### Scenario: Paper source +- **WHEN** a job selects an input slot (auto select, a tray or the MP tray) +- **THEN** the emitted PostScript selects the corresponding paper source on the printer + +#### Scenario: Duplex +- **WHEN** a job selects long-edge or short-edge two-sided printing +- **THEN** the emitted PostScript sets `/Duplex` and `/Tumble` accordingly + +#### Scenario: Colour or mono +- **WHEN** a job selects colour or mono +- **THEN** the emitted PostScript sets the corresponding colour/mono device parameters + +#### Scenario: A driverless client selects black and white +- **WHEN** an AirPrint/IPP client sends `print-color-mode=monochrome` +- **THEN** the emitted PostScript sets the mono device parameters (`/BRProcessColor 1`) and the job prints in black and white, independent of the PDF renderer used by the server + +#### Scenario: A driverless client selects colour +- **WHEN** an AirPrint/IPP client sends `print-color-mode=color` +- **THEN** the job prints in colour and the emitted PostScript disables toner saving + +#### Scenario: A driverless client selects the print quality +- **WHEN** an AirPrint/IPP client sends `print-quality=draft`, `normal` or `high` +- **THEN** the emitted PostScript selects the mapped device settings: toner saving for draft, full toner for normal, and the `CAPT` high-resolution setting for high diff --git a/openspec/changes/fix-colour-defaults-and-client-options/tasks.md b/openspec/changes/fix-colour-defaults-and-client-options/tasks.md new file mode 100644 index 0000000..448ea3e --- /dev/null +++ b/openspec/changes/fix-colour-defaults-and-client-options/tasks.md @@ -0,0 +1,78 @@ +# Tasks + +## 1. PPD: Farbmodus-Default, Presets und Dokumentation + +- [ ] 1.1 `assets/Brother HL-4150CDN/ppd/BR4150_2.PPD`: `*DefaultBRColorMode` + von `Normal` auf `None` ändern, alle eigenen Ergänzungen mit + `%`-Kommentar (Herkunft/Zweck) markieren. + Verifikation: `grep -n 'DefaultBRColorMode\|^% Modified' "assets/Brother HL-4150CDN/ppd/BR4150_2.PPD"` + zeigt `*DefaultBRColorMode: None` und den Kommentar. +- [ ] 1.2 PPD: sechs `APPrinterPreset`-Einträge ergänzen (Kombinationen + color/monochrome × low/normal/high gemäß Tabelle in `design.md`, + z. B. `*APPrinterPreset MonoNormal/Schwarz-Weiß Normal: + "*com.apple.print.preset.output-mode=monochrome + *com.apple.print.preset.quality=normal *BRPrintQuality=Black + *TonerSaveMode=False"`). + Verifikation: `grep -c '^\*APPrinterPreset' "assets/Brother HL-4150CDN/ppd/BR4150_2.PPD"` + ergibt 6, und nach einem Build listet + `lpoptions -p -l` weiterhin alle Optionen ohne + PPD-Warnung in `/var/log/cups/error_log`. +- [ ] 1.3 PPD: Choice `VividNoCIE` unter `BRColorMode` ergänzen + (`<>setpagedevice`) und per + Testdruck gegen `None` vergleichen; nur behalten, wenn der Ausdruck + deutlich gesättigter ist. + Verifikation: `lpoptions -p -l` zeigt die Choice, die + Entscheidung (behalten/entfernen) ist im README-Auswertungs-Abschnitt + notiert. +- [ ] 1.4 README: Abschnitt „Farben sind blass" (Ursache `UseCIEColor`, + durchgeführte Testreihe mit `lp -o BRColorMode=…`, + Ergebnis `None`), Abschnitt „Änderungen an der Hersteller-PPD" + (welche Einträge ergänzt wurden und warum) und Abschnitt + „Optionen fehlen im macOS/iOS-Dialog" (nur IPP-Standardoptionen + sichtbar, PPD-Optionen über `PRINTER_OPTIONS`/CUPS-Web-UI/`lp`). + Verifikation: die im README genannten `lp`/`lpoptions`-Befehle + laufen unverändert gegen den laufenden Container. + +## 2. entrypoint: `PRINTER_OPTIONS` + +- [ ] 2.1 `entrypoint.sh`: `PRINTER_OPTIONS` (Standard leer) nach der + Queue-Erzeugung in Tokens `key=value` zerlegen und jedes per + `lpadmin -o` setzen, an derselben Stelle wie + `printer-is-shared`/`-D`/`-d`, bei jedem Start. + Verifikation: Start mit + `PRINTER_OPTIONS="BRColorMode=Vivid TonerSaveMode=False"` und + `lpoptions -p -l` zeigt `Vivid` und `True` als Default + (`*Vivid`, `*True`). +- [ ] 2.2 Fehler pro Token abfangen, damit `set -eu` den Start nicht + abbricht, und warnen. + Verifikation: Start mit `PRINTER_OPTIONS="NoSuchOption=Foo"` erzeugt + eine Warning-Zeile im Log, der Container erreicht + „ready: CUPS on 631/tcp" und `lpstat -r` meldet „scheduler is running". +- [ ] 2.3 README: neue Zeile in der Env-Var-Tabelle plus Kurzbeispiel unter + „Environment variables" (inkl. Hinweis `lpoptions -p -l` zur + Entdeckbarkeit der Namen). + Verifikation: das Beispiel aus der Tabelle in einen `podman run`-Befehl + übertragen, Start und `lpoptions`-Abfrage wie beschrieben. + +## 3. Integrationstests am laufenden System + +- [ ] 3.1 Image neu bauen und Container starten. + Verifikation: `podman build -t printserver:latest .` endet ohne Fehler, + das Log enthält „ready: CUPS on 631/tcp, mDNS on 5353/udp". +- [ ] 3.2 S/W-Druck aus dem macOS-Dialog (derselbe Farbjob wie zuvor). + Verifikation: Ausdruck ist schwarz/weiß – vorher kam er farbig heraus. +- [ ] 3.3 Farbdruck ohne weitere Optionen aus dem Dialog und per + `lp -d test.pdf`. + Verifikation: Ausdruck ist so gesättigt wie der bisherige + `BRColorMode=None`-Testdruck; `lpoptions -p -l` zeigt `*None` + als Farbmodus-Default. +- [ ] 3.4 Qualitätsstufen prüfen. + Verifikation: `lp -o print-quality=2 test.pdf` (draft, sichtbar + tonersparender) und `lp -o print-quality=5 test.pdf` (high, `CAPT` + SuperFine) erzeugen unterscheidbare Ausdrucke gegenüber + `print-quality=3`. + +## Workflow follow-up + +- Nach Review und grünem Durchlauf die Änderung mit `/opsx-archive` + archivieren und das Ergebnis prüfen. diff --git a/openspec/changes/fix-ipps-certificate-lookup/tasks.md b/openspec/changes/fix-ipps-certificate-lookup/tasks.md index 41cdcdd..9301038 100644 --- a/openspec/changes/fix-ipps-certificate-lookup/tasks.md +++ b/openspec/changes/fix-ipps-certificate-lookup/tasks.md @@ -5,7 +5,7 @@ - [x] 1.1 Add a helper that lists the container's local addresses (IPv4 and IPv6, loopback excluded) using `hostname -I`, falling back to `ip -o addr`; verify the logic with a stubbed `hostname`/`getent` (IPv4 only, IPv6 only, address containing a `%zone`, and no addresses at all) - [x] 1.2 Add a helper that mangles a name the way `http_make_path()` in CUPS does (keep `[A-Za-z0-9.-]`, replace the rest with `_`) and derive the lookup names: every DNS SAN, each address literal with `%zone` spelled `+zone`, and each address's reverse-resolved name (`getent hosts`) - [x] 1.3 Rewrite `install_default_cert_copy()` to install `.crt`/`.key` for all those names, preserving the `0644`/`0640` `root:lp` permissions; verify with a stubbed environment that the copies include `host.containers.internal.crt`, `podp.local.crt` and `.crt` -- [ ] 1.4 After rebuilding and redeploying on the podman host, verify from another host that `curl https://podp.local:631/` succeeds and `openssl s_client -connect :631 -servername podp.local` shows our certificate (SANs contain the advertised name), not `CN=host.containers.internal` +- [x] 1.4 After rebuilding and redeploying on the podman host, verify from another host that `curl https://podp.local:631/` succeeds and `openssl s_client -connect :631 -servername podp.local` shows our certificate (SANs contain the advertised name), not `CN=host.containers.internal` ## 2. Correct the reasoning and documentation