Add setup script and README for Brother HL-L1222-V Android IPP print server on Raspberry Pi (openSUSE)#27
Conversation
Reviewer's GuideAdds a bash setup script to turn a Raspberry Pi 4B+ running openSUSE Tumbleweed into an IPP/Mopria-capable CUPS print server for a USB-connected Brother HL-L1222(-V), and updates the README with usage and Android printing instructions. Sequence diagram for Android IPP printing via Raspberry Pi CUPS serversequenceDiagram
actor AndroidUser
participant AndroidDevice
participant WiFiRouter
participant RaspberryPi_CUPS
participant USB_Printer
AndroidUser->>AndroidDevice: Select print and confirm job
AndroidDevice->>WiFiRouter: Send IPP print job
WiFiRouter->>RaspberryPi_CUPS: Forward IPP traffic to port 631
RaspberryPi_CUPS->>RaspberryPi_CUPS: CUPS processes IPP job
RaspberryPi_CUPS->>USB_Printer: Send rasterized job via USB
USB_Printer-->>RaspberryPi_CUPS: Print status
RaspberryPi_CUPS-->>AndroidDevice: IPP job status response
AndroidDevice-->>AndroidUser: Show job completed/failed status
Flow diagram for setup_hl_l1222_android_print.sh script logicflowchart TD
S[Start script
check root] --> CRoot{EUID is 0?}
CRoot -- No --> E1[Print run as root message
Exit 1]
CRoot -- Yes --> CheckCmds[Verify required commands
zypper systemctl lpinfo lpadmin lpstat]
CheckCmds --> Install[Install packages via zypper
cups cups-filters ghostscript
avahi nss-mdns firewalld
ipp-usb bluez bluez-tools]
Install --> EnableSvc[Enable and start services
cups avahi-daemon
firewalld bluetooth]
EnableSvc --> EditCUPS[Edit /etc/cups/cupsd.conf
Port 631
Browsing Yes
DefaultShared Yes
WebInterface Yes
<Location /> allow @LOCAL]
EditCUPS --> Firewall[Open firewall services
ipp mdns and reload]
Firewall --> DetectURI[Detect Brother USB URI via lpinfo]
DetectURI --> HasURI{Found Brother USB URI?}
HasURI -- No --> ShowDevices[Print available devices
via lpinfo]
ShowDevices --> E2[Prompt to connect printer
and rerun script
Exit 1]
HasURI -- Yes --> QueueCheck{Existing queue
Brother_HL_L1222_V?}
QueueCheck -- Yes --> DeleteQueue[Delete existing queue
lpadmin -x]
QueueCheck -- No --> CreateQueue
DeleteQueue --> CreateQueue[Create queue with lpadmin
model everywhere]
CreateQueue --> SetOptions[Set default options
sides=one-sided media=A4
printer-is-shared=true]
SetOptions --> RestartCUPS[Restart cups.service]
RestartCUPS --> TestPrint[Print test page
lp testprint]
TestPrint --> Status[Show status
lpstat -t]
Status --> Done[Print Android IPP instructions
and Bluetooth note
End]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- Before mutating
/etc/cups/cupsd.conf, consider creating a timestamped backup so reruns or manual recovery are easier if the edits or package versions change in the future. - The USB URI detection is very specific to
usb://Brother/and fails hard if not found; consider allowing an override via a script argument or prompting the user to select fromlpinfo -vinstead of exiting.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Before mutating `/etc/cups/cupsd.conf`, consider creating a timestamped backup so reruns or manual recovery are easier if the edits or package versions change in the future.
- The USB URI detection is very specific to `usb://Brother/` and fails hard if not found; consider allowing an override via a script argument or prompting the user to select from `lpinfo -v` instead of exiting.
## Individual Comments
### Comment 1
<location path="scripts/setup_hl_l1222_android_print.sh" line_range="67-72" />
<code_context>
+CUPSLOC
+fi
+
+echo "[3/8] Opening firewall for IPP + mDNS..."
+firewall-cmd --permanent --add-service=ipp || true
+firewall-cmd --permanent --add-service=mdns || true
+firewall-cmd --reload || true
+
+echo "[4/8] Detecting USB printer URI..."
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Avoid fully swallowing firewall-cmd failures or at least surface them to the user.
Using `|| true` on all three `firewall-cmd` calls means the script always reports success even if firewalld is missing or the rules fail to apply, which can leave network printing broken without any indication. Consider only relaxing failures when firewalld is intentionally inactive (e.g., via `systemctl is-active firewalld`) and/or logging a clear warning when `firewall-cmd` fails so users know IPP/mDNS might not be open.
```suggestion
echo "[3/8] Opening firewall for IPP + mDNS..."
if ! command -v firewall-cmd >/dev/null 2>&1; then
echo "Warning: firewall-cmd not found; skipping firewall configuration. Network printing may not be reachable from other devices."
elif ! systemctl is-active --quiet firewalld; then
echo "Warning: firewalld service is not active; skipping firewall configuration. Network printing may not be reachable from other devices."
else
if ! firewall-cmd --permanent --add-service=ipp; then
echo "Warning: failed to add IPP service to firewalld. Network printing may not be reachable from other devices."
fi
if ! firewall-cmd --permanent --add-service=mdns; then
echo "Warning: failed to add mDNS service to firewalld. Network printer discovery may not work."
fi
if ! firewall-cmd --reload; then
echo "Warning: failed to reload firewalld. Newly added firewall rules may not be active."
fi
fi
echo "[4/8] Detecting USB printer URI..."
```
</issue_to_address>
### Comment 2
<location path="README.md" line_range="29" />
<code_context>
+ - `ipp://<raspberrypi-ip>/printers/Brother_HL_L1222_V`
+
+## Notes
+- Script uses CUPS `everywhere` model as default for broad compatibility.
+- If you have an official Brother HL-L1222-V Linux PPD/driver package, install it and adjust queue model if desired.
</code_context>
<issue_to_address>
**nitpick (typo):** Consider adding an article: "as the default" for smoother grammar.
Suggestion: "Script uses CUPS `everywhere` model as the default for broad compatibility."
```suggestion
- Script uses CUPS `everywhere` model as the default for broad compatibility.
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| echo "[3/8] Opening firewall for IPP + mDNS..." | ||
| firewall-cmd --permanent --add-service=ipp || true | ||
| firewall-cmd --permanent --add-service=mdns || true | ||
| firewall-cmd --reload || true | ||
|
|
||
| echo "[4/8] Detecting USB printer URI..." |
There was a problem hiding this comment.
suggestion (bug_risk): Avoid fully swallowing firewall-cmd failures or at least surface them to the user.
Using || true on all three firewall-cmd calls means the script always reports success even if firewalld is missing or the rules fail to apply, which can leave network printing broken without any indication. Consider only relaxing failures when firewalld is intentionally inactive (e.g., via systemctl is-active firewalld) and/or logging a clear warning when firewall-cmd fails so users know IPP/mDNS might not be open.
| echo "[3/8] Opening firewall for IPP + mDNS..." | |
| firewall-cmd --permanent --add-service=ipp || true | |
| firewall-cmd --permanent --add-service=mdns || true | |
| firewall-cmd --reload || true | |
| echo "[4/8] Detecting USB printer URI..." | |
| echo "[3/8] Opening firewall for IPP + mDNS..." | |
| if ! command -v firewall-cmd >/dev/null 2>&1; then | |
| echo "Warning: firewall-cmd not found; skipping firewall configuration. Network printing may not be reachable from other devices." | |
| elif ! systemctl is-active --quiet firewalld; then | |
| echo "Warning: firewalld service is not active; skipping firewall configuration. Network printing may not be reachable from other devices." | |
| else | |
| if ! firewall-cmd --permanent --add-service=ipp; then | |
| echo "Warning: failed to add IPP service to firewalld. Network printing may not be reachable from other devices." | |
| fi | |
| if ! firewall-cmd --permanent --add-service=mdns; then | |
| echo "Warning: failed to add mDNS service to firewalld. Network printer discovery may not work." | |
| fi | |
| if ! firewall-cmd --reload; then | |
| echo "Warning: failed to reload firewalld. Newly added firewall rules may not be active." | |
| fi | |
| fi | |
| echo "[4/8] Detecting USB printer URI..." |
| - `ipp://<raspberrypi-ip>/printers/Brother_HL_L1222_V` | ||
|
|
||
| ## Notes | ||
| - Script uses CUPS `everywhere` model as default for broad compatibility. |
There was a problem hiding this comment.
nitpick (typo): Consider adding an article: "as the default" for smoother grammar.
Suggestion: "Script uses CUPS everywhere model as the default for broad compatibility."
| - Script uses CUPS `everywhere` model as default for broad compatibility. | |
| - Script uses CUPS `everywhere` model as the default for broad compatibility. |
There was a problem hiding this comment.
Code Review
This pull request introduces a setup script and documentation to configure a Raspberry Pi running openSUSE Tumbleweed as a print server for the Brother HL-L1222-V printer, enabling Android printing via IPP/Mopria. The review identifies critical issues with the manual configuration of /etc/cups/cupsd.conf, suggesting the use of cupsctl for more reliable and idempotent setup. Additionally, it points out a compatibility conflict between the everywhere PPD model and the usb:// URI for this specific printer, recommending the use of ipp-usb discovery or the brlaser driver to ensure a functional print queue.
| # Ensure cupsd listens on local network for Android clients using IPP/Mopria. | ||
| CUPSD_CONF="/etc/cups/cupsd.conf" | ||
| if ! grep -q '^Port 631' "$CUPSD_CONF"; then | ||
| sed -i 's/^Listen localhost:631/# &/' "$CUPSD_CONF" || true | ||
| echo 'Port 631' >> "$CUPSD_CONF" | ||
| fi | ||
|
|
||
| if ! grep -q '^Browsing Yes' "$CUPSD_CONF"; then | ||
| echo 'Browsing Yes' >> "$CUPSD_CONF" | ||
| fi | ||
|
|
||
| if ! grep -q '^DefaultShared Yes' "$CUPSD_CONF"; then | ||
| echo 'DefaultShared Yes' >> "$CUPSD_CONF" | ||
| fi | ||
|
|
||
| if ! grep -q '^WebInterface Yes' "$CUPSD_CONF"; then | ||
| echo 'WebInterface Yes' >> "$CUPSD_CONF" | ||
| fi | ||
|
|
||
| if ! grep -q '<Location />' "$CUPSD_CONF"; then | ||
| cat >> "$CUPSD_CONF" <<'CUPSLOC' | ||
| <Location /> | ||
| Order allow,deny | ||
| Allow @LOCAL | ||
| </Location> | ||
|
|
||
| <Location /admin> | ||
| Order allow,deny | ||
| Allow @LOCAL | ||
| </Location> | ||
| CUPSLOC | ||
| fi |
There was a problem hiding this comment.
The manual modification of /etc/cups/cupsd.conf is fragile and contains logic errors:
- Logic Error: The check
grep -q '<Location />'will return true on most default CUPS installations because the block usually exists (though restricted). Consequently, the script will skip adding theAllow @LOCALdirective, and network printing will remain blocked ('Forbidden'). - Port Conflict: The
sedcommand only targetslocalhost:631. If the configuration uses127.0.0.1:631or*:631, it won't be commented out, and appendingPort 631will cause CUPS to fail to start due to a port binding conflict.
Using cupsctl is the standard, safe, and idempotent way to configure these settings.
| # Ensure cupsd listens on local network for Android clients using IPP/Mopria. | |
| CUPSD_CONF="/etc/cups/cupsd.conf" | |
| if ! grep -q '^Port 631' "$CUPSD_CONF"; then | |
| sed -i 's/^Listen localhost:631/# &/' "$CUPSD_CONF" || true | |
| echo 'Port 631' >> "$CUPSD_CONF" | |
| fi | |
| if ! grep -q '^Browsing Yes' "$CUPSD_CONF"; then | |
| echo 'Browsing Yes' >> "$CUPSD_CONF" | |
| fi | |
| if ! grep -q '^DefaultShared Yes' "$CUPSD_CONF"; then | |
| echo 'DefaultShared Yes' >> "$CUPSD_CONF" | |
| fi | |
| if ! grep -q '^WebInterface Yes' "$CUPSD_CONF"; then | |
| echo 'WebInterface Yes' >> "$CUPSD_CONF" | |
| fi | |
| if ! grep -q '<Location />' "$CUPSD_CONF"; then | |
| cat >> "$CUPSD_CONF" <<'CUPSLOC' | |
| <Location /> | |
| Order allow,deny | |
| Allow @LOCAL | |
| </Location> | |
| <Location /admin> | |
| Order allow,deny | |
| Allow @LOCAL | |
| </Location> | |
| CUPSLOC | |
| fi | |
| # Configure CUPS for network access and sharing | |
| cupsctl --remote-any --share-printers --remote-admin WebInterface=Yes |
| if lpstat -p "$PRINTER_NAME" >/dev/null 2>&1; then | ||
| lpadmin -x "$PRINTER_NAME" | ||
| fi | ||
| lpadmin -p "$PRINTER_NAME" -E -v "$USB_URI" -m "$PPD_MODEL" |
There was a problem hiding this comment.
The everywhere model (IPP Everywhere) is incompatible with a raw usb:// URI for the Brother HL-L1222-V, as this printer does not support IPP natively over USB. Using this combination will result in a non-functional print queue.
Since ipp-usb is installed (line 26), it may claim the device and provide an ipp:// or driverless:// URI. If you intend to use the everywhere model, you should use one of those URIs discovered via lpinfo. Otherwise, for this specific model, you likely need the brlaser driver (e.g., -m drv:///brlaser.drv/brl1222.ppd).
| exit 1 | ||
| fi | ||
|
|
||
| REQ_CMDS=(zypper systemctl lpinfo lpadmin lpstat) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: df4d1d348f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| REQ_CMDS=(zypper systemctl lpinfo lpadmin lpstat) | ||
| for c in "${REQ_CMDS[@]}"; do | ||
| command -v "$c" >/dev/null || { echo "Missing command: $c"; exit 1; } |
There was a problem hiding this comment.
Remove CUPS CLI prereq checks before package install
The script checks for lpinfo, lpadmin, and lpstat before running zypper install, so on a fresh openSUSE host (the primary bootstrap case) it exits with “Missing command” and never reaches the package installation step that would provide those binaries. This makes the setup non-functional unless CUPS client tools are already preinstalled.
Useful? React with 👍 / 👎.
| if lpstat -p "$PRINTER_NAME" >/dev/null 2>&1; then | ||
| lpadmin -x "$PRINTER_NAME" | ||
| fi | ||
| lpadmin -p "$PRINTER_NAME" -E -v "$USB_URI" -m "$PPD_MODEL" |
There was a problem hiding this comment.
Use IPP URI when configuring the
everywhere model
The queue is created with -m everywhere, but USB_URI is constrained to direct usb://Brother/...; per lpadmin(8), everywhere queries the printer via a specified IPP device URI. With a direct USB URI this frequently fails queue creation (or produces a non-working driverless setup), breaking the script’s default path for this printer.
Useful? React with 👍 / 👎.
| REQ_CMDS=(zypper systemctl lpinfo lpadmin lpstat) | ||
| for c in "${REQ_CMDS[@]}"; do | ||
| command -v "$c" >/dev/null || { echo "Missing command: $c"; exit 1; } | ||
| done |
There was a problem hiding this comment.
🔴 CUPS commands (lpinfo, lpadmin, lpstat) are checked before CUPS is installed, blocking fresh installs
Lines 17-19 check that lpinfo, lpadmin, and lpstat are available via command -v, but these are CUPS binaries provided by the cups package which isn't installed until lines 24-26. On a fresh system (the primary target for a setup script), the prerequisite check fails with "Missing command: lpinfo" and exits before the zypper install cups step ever runs. The check should either move these CUPS-specific commands after the install step, or only verify base OS commands (zypper, systemctl) before installation.
| REQ_CMDS=(zypper systemctl lpinfo lpadmin lpstat) | |
| for c in "${REQ_CMDS[@]}"; do | |
| command -v "$c" >/dev/null || { echo "Missing command: $c"; exit 1; } | |
| done | |
| REQ_CMDS=(zypper systemctl) | |
| for c in "${REQ_CMDS[@]}"; do | |
| command -v "$c" >/dev/null || { echo "Missing command: $c"; exit 1; } | |
| done | |
Was this helpful? React with 👍 or 👎 to provide feedback.
| if ! grep -q '<Location />' "$CUPSD_CONF"; then | ||
| cat >> "$CUPSD_CONF" <<'CUPSLOC' | ||
| <Location /> | ||
| Order allow,deny | ||
| Allow @LOCAL | ||
| </Location> | ||
|
|
||
| <Location /admin> | ||
| Order allow,deny | ||
| Allow @LOCAL | ||
| </Location> | ||
| CUPSLOC | ||
| fi |
There was a problem hiding this comment.
🔴 guard skips adding Allow @Local when default CUPS block already exists
Line 53 checks whether <Location /> already exists in cupsd.conf. The default CUPS installation ships with a <Location /> block that typically does not include Allow @LOCAL. Because the grep finds the existing block, the script skips appending the new block with Allow @LOCAL, so LAN clients (i.e. Android phones) are still denied access. This silently defeats the script's primary purpose — enabling network printing over IPP/Mopria. The fix should either inject Allow @LOCAL into the existing <Location /> block, or replace the existing block rather than simply checking for its presence.
Prompt for agents
The guard on line 53 checks for the presence of `<Location />` in cupsd.conf and skips the entire block if found. However, the default CUPS cupsd.conf already contains a `<Location />` directive — typically without `Allow @LOCAL`. This means the script never adds the crucial `Allow @LOCAL` rule that enables LAN printing.
The fix should handle two scenarios:
1. If `<Location />` already exists but lacks `Allow @LOCAL`, inject `Allow @LOCAL` into the existing block (e.g. using sed to insert after the `Order allow,deny` line within `<Location />`). Do the same for `<Location /admin>`.
2. If `<Location />` doesn't exist at all, append the full block as currently done.
Also consider checking for `Allow @LOCAL` specifically (e.g., `grep -q 'Allow @LOCAL' cupsd.conf`) rather than checking for `<Location />`.
Relevant function: the block at scripts/setup_hl_l1222_android_print.sh lines 53-65.
Was this helpful? React with 👍 or 👎 to provide feedback.
| firewall-cmd --reload || true | ||
|
|
||
| echo "[4/8] Detecting USB printer URI..." | ||
| USB_URI="$(lpinfo -v | awk '/^direct usb:\/\/Brother\//{print $2; exit}')" |
There was a problem hiding this comment.
🚩 ipp-usb package may conflict with direct USB backend for printer detection
The script installs ipp-usb at scripts/setup_hl_l1222_android_print.sh:26, which provides an IPP-over-USB bridge. Once running, ipp-usb may take exclusive ownership of the USB device, causing the lpinfo -v detection at line 73 to fail to find the direct usb://Brother/... URI. The printer might instead appear only as an ipp://localhost:60000/... endpoint. If this happens, the awk filter /^direct usb:\/\/Brother\// wouldn't match and the script would exit at line 78 claiming no printer was found. Whether this actually occurs depends on the ipp-usb daemon activation timing and USB device locking behavior on the target platform — it warrants testing.
Was this helpful? React with 👍 or 👎 to provide feedback.
| systemctl restart cups.service | ||
|
|
||
| echo "[7/8] Printing a test page..." | ||
| lp -d "$PRINTER_NAME" /usr/share/cups/data/testprint || true |
There was a problem hiding this comment.
📝 Info: Test print may silently fail due to CUPS restart timing
At line 97, CUPS is restarted with systemctl restart cups.service, and the very next command at line 100 submits a test print job via lp. There is no delay or readiness check between the restart and the print submission. If CUPS hasn't fully started accepting connections, lp would fail. The || true prevents the script from aborting, but the test page would silently not print. This is non-critical (all configuration is already persisted), but could confuse users who expect to see a test page.
Was this helpful? React with 👍 or 👎 to provide feedback.
| lp -d "$PRINTER_NAME" /usr/share/cups/data/testprint || true | ||
|
|
||
| echo "[8/8] Final status" | ||
| lpstat -t |
There was a problem hiding this comment.
📝 Info: lpstat -t at end of script can abort under set -e if CUPS is still restarting
Line 103 runs lpstat -t to display final status. Unlike the test print on line 100 which has || true, this command has no error suppression. Under set -e, if CUPS hasn't fully restarted yet (same timing concern as ANALYSIS-0002), lpstat -t would fail and cause the script to exit with an error after all setup is already complete. This would give a misleading impression of failure. Adding || true or a brief sleep before status commands would make the script more robust.
Was this helpful? React with 👍 or 👎 to provide feedback.
| if ! grep -q '^Port 631' "$CUPSD_CONF"; then | ||
| sed -i 's/^Listen localhost:631/# &/' "$CUPSD_CONF" || true | ||
| echo 'Port 631' >> "$CUPSD_CONF" | ||
| fi | ||
|
|
||
| if ! grep -q '^Browsing Yes' "$CUPSD_CONF"; then | ||
| echo 'Browsing Yes' >> "$CUPSD_CONF" | ||
| fi | ||
|
|
||
| if ! grep -q '^DefaultShared Yes' "$CUPSD_CONF"; then | ||
| echo 'DefaultShared Yes' >> "$CUPSD_CONF" | ||
| fi | ||
|
|
||
| if ! grep -q '^WebInterface Yes' "$CUPSD_CONF"; then | ||
| echo 'WebInterface Yes' >> "$CUPSD_CONF" | ||
| fi |
There was a problem hiding this comment.
📝 Info: Appending directives to cupsd.conf creates ordering issues
Lines 36-51 append Port 631, Browsing Yes, DefaultShared Yes, and WebInterface Yes to the end of cupsd.conf. CUPS processes directives in order, and some of these may conflict with or be overridden by earlier directives already in the file. For example, if the original file has Browsing No near the top, appending Browsing Yes at the bottom means CUPS sees both — and the last value typically wins. While this happens to work in CUPS's favor for this script, it leaves behind contradictory entries. A cleaner approach would be sed -i to replace existing directives in-place rather than appending duplicates.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
4 issues found across 2 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/setup_hl_l1222_android_print.sh">
<violation number="1" location="scripts/setup_hl_l1222_android_print.sh:17">
P1: Preflight checks require CUPS commands before CUPS is installed, so the script can fail immediately on fresh systems.</violation>
<violation number="2" location="scripts/setup_hl_l1222_android_print.sh:53">
P1: Logic error: `grep -q '<Location />'` will match the existing `<Location />` block present in default CUPS configurations (which typically has restrictive ACLs). Since the block already exists, this check passes and the script never adds `Allow @LOCAL`, leaving network access blocked (HTTP 403 Forbidden for LAN clients).
Additionally, the `sed` on line 37 only targets `Listen localhost:631` — if the config uses `127.0.0.1:631` or `*:631`, it won't be commented out, and appending `Port 631` will cause a port binding conflict that prevents CUPS from starting.
Consider using `cupsctl --remote-any --share-printers` which handles these cases safely and idempotently.</violation>
<violation number="3" location="scripts/setup_hl_l1222_android_print.sh:68">
P2: Do not swallow firewall command failures; this can produce a false successful setup with broken network printing.</violation>
<violation number="4" location="scripts/setup_hl_l1222_android_print.sh:87">
P0: The `everywhere` model requires an IPP device URI to query the printer's capabilities (per `lpadmin(8)`: "the model 'everywhere' queries the printer referred to by the specified IPP device-uri"). The `USB_URI` here is a `usb://` scheme which cannot be queried via IPP, so this will either fail queue creation or produce a non-functional driverless queue.
Since `ipp-usb` is installed, you should detect the `ipp://` or `driverless://` URI it provides (via `lpinfo -v`), or fall back to a compatible driver like `brlaser` (e.g., `-m drv:///brlaser.drv/brl1222.ppd`) for the USB path.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| if lpstat -p "$PRINTER_NAME" >/dev/null 2>&1; then | ||
| lpadmin -x "$PRINTER_NAME" | ||
| fi | ||
| lpadmin -p "$PRINTER_NAME" -E -v "$USB_URI" -m "$PPD_MODEL" |
There was a problem hiding this comment.
P0: The everywhere model requires an IPP device URI to query the printer's capabilities (per lpadmin(8): "the model 'everywhere' queries the printer referred to by the specified IPP device-uri"). The USB_URI here is a usb:// scheme which cannot be queried via IPP, so this will either fail queue creation or produce a non-functional driverless queue.
Since ipp-usb is installed, you should detect the ipp:// or driverless:// URI it provides (via lpinfo -v), or fall back to a compatible driver like brlaser (e.g., -m drv:///brlaser.drv/brl1222.ppd) for the USB path.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/setup_hl_l1222_android_print.sh, line 87:
<comment>The `everywhere` model requires an IPP device URI to query the printer's capabilities (per `lpadmin(8)`: "the model 'everywhere' queries the printer referred to by the specified IPP device-uri"). The `USB_URI` here is a `usb://` scheme which cannot be queried via IPP, so this will either fail queue creation or produce a non-functional driverless queue.
Since `ipp-usb` is installed, you should detect the `ipp://` or `driverless://` URI it provides (via `lpinfo -v`), or fall back to a compatible driver like `brlaser` (e.g., `-m drv:///brlaser.drv/brl1222.ppd`) for the USB path.</comment>
<file context>
@@ -0,0 +1,118 @@
+if lpstat -p "$PRINTER_NAME" >/dev/null 2>&1; then
+ lpadmin -x "$PRINTER_NAME"
+fi
+lpadmin -p "$PRINTER_NAME" -E -v "$USB_URI" -m "$PPD_MODEL"
+lpoptions -d "$PRINTER_NAME"
+
</file context>
| exit 1 | ||
| fi | ||
|
|
||
| REQ_CMDS=(zypper systemctl lpinfo lpadmin lpstat) |
There was a problem hiding this comment.
P1: Preflight checks require CUPS commands before CUPS is installed, so the script can fail immediately on fresh systems.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/setup_hl_l1222_android_print.sh, line 17:
<comment>Preflight checks require CUPS commands before CUPS is installed, so the script can fail immediately on fresh systems.</comment>
<file context>
@@ -0,0 +1,118 @@
+ exit 1
+fi
+
+REQ_CMDS=(zypper systemctl lpinfo lpadmin lpstat)
+for c in "${REQ_CMDS[@]}"; do
+ command -v "$c" >/dev/null || { echo "Missing command: $c"; exit 1; }
</file context>
| REQ_CMDS=(zypper systemctl lpinfo lpadmin lpstat) | |
| REQ_CMDS=(zypper systemctl) |
| echo 'WebInterface Yes' >> "$CUPSD_CONF" | ||
| fi | ||
|
|
||
| if ! grep -q '<Location />' "$CUPSD_CONF"; then |
There was a problem hiding this comment.
P1: Logic error: grep -q '<Location />' will match the existing <Location /> block present in default CUPS configurations (which typically has restrictive ACLs). Since the block already exists, this check passes and the script never adds Allow @LOCAL, leaving network access blocked (HTTP 403 Forbidden for LAN clients).
Additionally, the sed on line 37 only targets Listen localhost:631 — if the config uses 127.0.0.1:631 or *:631, it won't be commented out, and appending Port 631 will cause a port binding conflict that prevents CUPS from starting.
Consider using cupsctl --remote-any --share-printers which handles these cases safely and idempotently.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/setup_hl_l1222_android_print.sh, line 53:
<comment>Logic error: `grep -q '<Location />'` will match the existing `<Location />` block present in default CUPS configurations (which typically has restrictive ACLs). Since the block already exists, this check passes and the script never adds `Allow @LOCAL`, leaving network access blocked (HTTP 403 Forbidden for LAN clients).
Additionally, the `sed` on line 37 only targets `Listen localhost:631` — if the config uses `127.0.0.1:631` or `*:631`, it won't be commented out, and appending `Port 631` will cause a port binding conflict that prevents CUPS from starting.
Consider using `cupsctl --remote-any --share-printers` which handles these cases safely and idempotently.</comment>
<file context>
@@ -0,0 +1,118 @@
+ echo 'WebInterface Yes' >> "$CUPSD_CONF"
+fi
+
+if ! grep -q '<Location />' "$CUPSD_CONF"; then
+ cat >> "$CUPSD_CONF" <<'CUPSLOC'
+<Location />
</file context>
| fi | ||
|
|
||
| echo "[3/8] Opening firewall for IPP + mDNS..." | ||
| firewall-cmd --permanent --add-service=ipp || true |
There was a problem hiding this comment.
P2: Do not swallow firewall command failures; this can produce a false successful setup with broken network printing.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/setup_hl_l1222_android_print.sh, line 68:
<comment>Do not swallow firewall command failures; this can produce a false successful setup with broken network printing.</comment>
<file context>
@@ -0,0 +1,118 @@
+fi
+
+echo "[3/8] Opening firewall for IPP + mDNS..."
+firewall-cmd --permanent --add-service=ipp || true
+firewall-cmd --permanent --add-service=mdns || true
+firewall-cmd --reload || true
</file context>
Motivation
Description
scripts/setup_hl_l1222_android_print.shthat installs required packages withzypper, enables services viasystemctl, and configures CUPS, Avahi, Firewalld, and Bluetooth./etc/cups/cupsd.confto enable network listening, sharing, and web interface, opens firewall rules forippandmdnsviafirewall-cmd, and attempts to auto-detect the Brother USB URI usinglpinfo.lpadminusing theeverywheremodel, sets default options (one-sided, A4), enables sharing, restarts CUPS, and issues a test print andlpstat -tstatus.README.mdwith usage instructions, the recommended IPPipp://<raspberrypi-ip>/printers/Brother_HL_L1222_Vworkflow, and notes about Bluetooth and driver options.Testing
Codex Task
Summary by Sourcery
Add a setup script and documentation to configure a Raspberry Pi (openSUSE Tumbleweed) as an IPP/Mopria-compatible print server for a USB-connected Brother HL-L1222/HL-L1222-V printer, enabling Android Wi‑Fi printing.
New Features:
Enhancements:
Documentation:
Summary by cubic
Adds an automated setup script to turn a Raspberry Pi 4B+ (openSUSE Tumbleweed) into a CUPS IPP print server for a USB Brother HL‑L1222/HL‑L1222‑V. Updates the README with Android IPP steps and Bluetooth caveats.
scripts/setup_hl_l1222_android_print.shto install deps (cups,cups-filters,ghostscript,avahi,nss-mdns,firewalld,ipp-usb,bluez,bluez-tools) viazypper, enable services viasystemctl, and configure CUPS, Avahi, and the firewall./etc/cups/cupsd.conf(Port 631, browsing, sharing, web UI, allow@LOCAL) and opensipp/mdnsinfirewalld.Brother_HL_L1222_Vqueue with modeleverywhere, sets A4 and one-sided, restarts CUPS, prints a test page, and shows status.README.mdwith run instructions and the Android IPP URL:ipp://<raspberrypi-ip>/printers/Brother_HL_L1222_V, plus a note that Bluetooth printing is unreliable; use Wi‑Fi IPP/Mopria.Written for commit df4d1d3. Summary will update on new commits. Review in cubic