--- - 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 , 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.