Files
deploy_home/ansible/roles/labelprint/tasks/cups.yml
T
Bastian de BylandClaude Opus 5 6cd4d56de1 feat(labelprint): 4x6 label print proxy on a Raspberry Pi
A Pi 3B+ (stickah.local) shares a Phomemo PM246 to the LAN as a plain CUPS
queue, so any machine can print 4x6 labels -- fulfillr-site's shipping labels
in particular -- without installing the vendor driver, which is x86-64 only.
The role builds the TSPL CUPS driver from source instead.

It is Debian, not Fedora, so it lives in its own inventory and playbook
(make deploy-labelprint / check-labelprint) and the home.debyl.io roles can
never run against it. make bootfs renders its cloud-init first-boot files onto
a freshly imaged SD card from the same templates the role uses. The Wi-Fi
credentials for the home and rescue networks are in the vault.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 23:14:45 -04:00

137 lines
4.4 KiB
YAML

---
- name: configure cupsd
become: true
ansible.builtin.template:
src: cupsd.conf.j2
dest: /etc/cups/cupsd.conf
owner: root
group: lp
mode: "0640"
validate: /usr/sbin/cupsd -t -c %s
notify: restart cups
tags: [labelprint, cups]
- name: enable cups
become: true
ansible.builtin.systemd:
name: cups.service
enabled: true
state: started
tags: [labelprint, cups]
# cupsd.conf has to be in place and cupsd running before lpadmin can talk to it.
- name: apply pending cups changes before touching the queue
ansible.builtin.meta: flush_handlers
tags: [labelprint, cups]
# ---------------------------------------------------------------------------
# The queue
# ---------------------------------------------------------------------------
# lpadmin is not idempotent and has no "show me everything you would set" mode,
# so the desired definition is fingerprinted and the fingerprint compared with
# what was last applied. The marker is written only after lpadmin succeeds.
# Checksummed here rather than taken from the install task's return value, so
# that the fingerprint is the same whether or not this run included the driver
# tasks -- `make deploy-labelprint TAGS=cups` must not look like a change.
- name: checksum the installed PPD
become: true
ansible.builtin.stat:
path: "{{ labelprint_ppd_active }}"
checksum_algorithm: sha1
register: labelprint_ppd_stat
tags: [labelprint, cups]
- name: build the desired queue fingerprint
ansible.builtin.set_fact:
labelprint_queue_want: >-
{{
[
labelprint_device_uri,
labelprint_queue_info,
labelprint_queue_location,
labelprint_resolution,
labelprint_media,
labelprint_darkness | string,
labelprint_print_speed | string,
labelprint_ppd_stat.stat.checksum | default('none'),
] | join('|')
}}
tags: [labelprint, cups]
- name: read the queue fingerprint that was last applied
become: true
ansible.builtin.slurp:
src: "/etc/cups/.{{ labelprint_queue }}.fingerprint"
register: labelprint_queue_have
failed_when: false
tags: [labelprint, cups]
- name: create or update the label queue
become: true
ansible.builtin.command:
argv:
- lpadmin
- -p
- "{{ labelprint_queue }}"
- -E
- -v
- "{{ labelprint_device_uri }}"
- -P
- "{{ labelprint_ppd_active }}"
- -D
- "{{ labelprint_queue_info }}"
- -L
- "{{ labelprint_queue_location }}"
- -o
- printer-is-shared=true
- -o
- "Resolution={{ labelprint_resolution }}"
- -o
- "media={{ labelprint_media }}"
- -o
- "Darkness={{ labelprint_darkness }}"
- -o
- "PrintSpeed={{ labelprint_print_speed }}"
when: >-
(labelprint_queue_have.content | default('') | b64decode | trim)
!= labelprint_queue_want | trim
register: labelprint_lpadmin
changed_when: true
tags: [labelprint, cups]
- name: record the applied queue fingerprint
become: true
ansible.builtin.copy:
dest: "/etc/cups/.{{ labelprint_queue }}.fingerprint"
content: "{{ labelprint_queue_want | trim }}"
owner: root
group: root
mode: "0600"
when: labelprint_lpadmin is changed
tags: [labelprint, cups]
- name: accept and enable the label queue
become: true
ansible.builtin.command:
argv: ["{{ item }}", "{{ labelprint_queue }}"]
loop:
- cupsaccept
- cupsenable
changed_when: false
tags: [labelprint, cups]
# There is deliberately no `cupsctl` here. It is the obvious way to say
# "share on the LAN only", but cupsctl edits cupsd.conf through cupsd itself,
# which rewrites the file from its parsed form and drops every comment. That
# makes the template above differ on the next run, which re-templates and
# restarts cups, which lets cupsctl rewrite it again -- a deploy that reports
# changes forever and never converges.
#
# Nothing is lost. `cupsctl --share-printers` amounts to `Browsing On` plus a
# per-queue shared flag, and both are already set -- the first in the template,
# the second by lpadmin's printer-is-shared=true above. `--no-remote-any` is the
# absence of `Allow from all` in <Location />, which is how the template is
# written. The driver's own install.sh runs `cupsctl --remote-any`, which would
# offer this printer to anything that can route to the Pi; that is exactly what
# we are not doing.