diff --git a/ansible/printserver.yml b/ansible/printserver.yml index 8b223e3..fc139c8 100644 --- a/ansible/printserver.yml +++ b/ansible/printserver.yml @@ -6,8 +6,7 @@ tags: - printserver vars: - # The identifier below specifies HP LasterJet P1102 - hplip_printer_vendor_product_id: "03f0:002a" + cups_printer_model: "P1102" + cups_printer_name: "HP_LaserJet_P1102" roles: - role: cups - - role: hplip diff --git a/ansible/roles/cups/defaults/main.yml b/ansible/roles/cups/defaults/main.yml new file mode 100644 index 0000000..2247004 --- /dev/null +++ b/ansible/roles/cups/defaults/main.yml @@ -0,0 +1,3 @@ +--- +# This is used in few greps +cups_printer_model: "" diff --git a/ansible/roles/cups/tasks/main.yml b/ansible/roles/cups/tasks/main.yml index dbf76b6..133161e 100644 --- a/ansible/roles/cups/tasks/main.yml +++ b/ansible/roles/cups/tasks/main.yml @@ -1,19 +1,24 @@ --- -- name: Install cups +# There are some strong assumptions about foo2zjs and grep patterns in this file +# It's still better than hardcoding thing, but it's likely that specific models +# may require changes in this code +# TODO: this whole thing can be rewritten using ansible.builtin.command and python instead of grepping +- name: Install cups and foo2zjs become: true become_user: root ansible.builtin.apt: name: - cups + - printer-driver-foo2zjs state: present -# TODO: proper checks for the admin endpoints - name: Allow connections from LAN become: true become_user: root notify: - Restart cups block: + # TODO: proper permissions for the endpoints - name: Allow / from LAN become: true become_user: root @@ -21,7 +26,6 @@ dest: /etc/cups/cupsd.conf insertafter: "" line: " Allow 192.168.1.*" - backup: true - name: Listen on the LAN host become: true @@ -30,4 +34,86 @@ dest: /etc/cups/cupsd.conf insertafter: "Listen localhost:631" line: "Listen {{ ansible_hostname }}:631" - backup: true + +- name: Check the cups_printer_model + ansible.builtin.fail: + msg: cups_printer_model variable can not be empty + when: cups_printer_model | length == 0 + +- name: Check if the printer is already configured + become: true + become_user: root + ansible.builtin.shell: + cmd: | + set -o pipefail + lpstat -a | grep "^{{ cups_printer_name | default(cups_printer_model) }}" + executable: /bin/bash + failed_when: false + changed_when: false + register: lpstat + +- name: Set the printer_already_configured variable + changed_when: false + ansible.builtin.set_fact: + printer_already_configured: "{{ True if lpstat.rc == 0 else False }}" + +- name: Set up the printer + when: not printer_already_configured + # Restart cups just in case + notify: + - Restart cups + block: + - name: Find the cups-device-uri of the printer + block: + - name: Check for the device + become: true + become_user: root + ansible.builtin.shell: + cmd: | + set -o pipefail + lpinfo -v | grep "^direct usb" | grep "{{ cups_printer_model }}" | cut -d " " -f2 + executable: /bin/bash + register: cups_device_uri_cmd + changed_when: false + failed_when: false + + - name: Print error message + ansible.builtin.fail: + msg: "{{ cups_printer_model }} device is not present in the system" + when: cups_device_uri_cmd.rc != 0 + + - name: Set the cups_device_uri variable + changed_when: false + ansible.builtin.set_fact: + cups_device_uri: "{{ cups_device_uri_cmd.stdout }}" + + - name: Find the foo2zjs driver for the printer + block: + - name: Check for the driver + become: true + become_user: root + ansible.builtin.shell: + cmd: | + set -o pipefail + lpinfo -m | grep "foo2zjs" | grep "{{ cups_printer_model }}.ppd" | cut -d " " -f1 + executable: /bin/bash + register: cups_device_driver_cmd + changed_when: false + failed_when: false + + - name: Print error message + ansible.builtin.fail: + msg: "{{ cups_printer_model }} foo2zjs driver is not present in the system" + when: cups_device_driver_cmd.rc != 0 + + - name: Set the cups_device_driver variable + changed_when: false + ansible.builtin.set_fact: + cups_device_driver: "{{ cups_device_driver_cmd.stdout }}" + + - name: Configure the printer + changed_when: true + become: true + become_user: root + ansible.builtin.command: + cmd: lpadmin -p "{{ cups_printer_name | default(cups_printer_model) }}" -E -v "{{ cups_device_uri }}" -m "{{ cups_device_driver }}" diff --git a/ansible/roles/hplip/defaults/main.yml b/ansible/roles/hplip/defaults/main.yml deleted file mode 100644 index 046e4f8..0000000 --- a/ansible/roles/hplip/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -# Can be obtained with `lsusb` or googled -hplip_printer_vendor_product_id: "" -hplip_print_test_page: true diff --git a/ansible/roles/hplip/tasks/main.yml b/ansible/roles/hplip/tasks/main.yml deleted file mode 100644 index f01f443..0000000 --- a/ansible/roles/hplip/tasks/main.yml +++ /dev/null @@ -1,113 +0,0 @@ ---- -- name: Install dependencies - become: true - become_user: root - ansible.builtin.apt: - name: - # For lsusb command - - usbutils - # As hp-plugin requires it - # Downloading this on the host is probably a way to do it, - # but I don't want to play with the incompatible versions and stuff - - gpg - # For scripting around the hp-plugin installer - - python3-pexpect - - hplip - state: present - -- name: Check the hplip_printer_vendor_product_id - ansible.builtin.fail: - msg: hplip_printer_vendor_product_id variable can not be empty - when: hplip_printer_vendor_product_id | length == 0 - - -- name: Check if the hplip_printer_vendor_product_id device is present - block: - - name: Check for the device - ansible.builtin.shell: - cmd: | - set -o pipefail - lsusb | grep "{{ hplip_printer_vendor_product_id }}" - executable: /bin/bash - register: usb_device_present - changed_when: false - failed_when: false - - - name: Print error message - ansible.builtin.fail: - msg: "{{ hplip_printer_vendor_product_id }} device is not present in the system" - when: usb_device_present.rc != 0 - -# TODO: this is pretty ugly -# We assume that the USB device and product IDs are 3-digit numbers -# It's probably standardized, but mentioning this just in case -- name: Obtain the printer usb address - block: - - name: Obtain the printer bus address - changed_when: false - ansible.builtin.shell: - cmd: | - set -o pipefail - lsusb | grep "{{ hplip_printer_vendor_product_id }}" | cut -d ":" -f1 | grep -oE "Bus [0-9]{3}" | cut -d " " -f2 - executable: /bin/bash - register: usb_bus - - - name: Obtain the printer device address - changed_when: false - ansible.builtin.shell: - cmd: | - set -o pipefail - lsusb | grep "{{ hplip_printer_vendor_product_id }}" | cut -d ":" -f1 | grep -oE "Device [0-9]{3}" | cut -d " " -f2 - executable: /bin/bash - register: usb_device - - - name: Set the printer_usb_address variable - changed_when: false - ansible.builtin.set_fact: - printer_usb_address: "{{usb_bus.stdout}}:{{usb_device.stdout}}" - -# This assumes that there is only one printer configured on the host -# USB address is not listed in the output -# and I don't want to add yet another variable for the printer model name or similar -- name: Check if the printer is already configured - ansible.builtin.command: - cmd: hp-info -i - failed_when: false - changed_when: false - register: hp_info - -- name: Set the printer_already_configured variable - changed_when: false - ansible.builtin.set_fact: - printer_already_configured: "{{ True if hp_info.rc == 0 else False }}" - -- name: Install the hplip plugin - # TODO: can we handle the reinstall case properly? - # In theory we could use something like "removes" here - # but in practice what if there's an hplip update? - # Will it work without the driver reinstallation? - changed_when: true - become: true - # Docs recommend to run this as non-root user - # but it complains about no-network then - become_user: root - ansible.builtin.expect: - command: hp-plugin -i - responses: - "(.*)Enter option \\(d=download\\*, p=specify path, q=quit\\)(.*)": "d" - "(.*)Do you accept the license terms for the plug-in \\(y=yes\\*, n=no, q=quit\\)(.*)": "y" - "(.*)Do you wish to download and re-install the plug-in\\? \\(y=yes\\*, n=no, q=quit\\)(.*)": "n" - when: not printer_already_configured - -- name: Configure the printer - changed_when: true - become: true - become_user: root - ansible.builtin.command: - cmd: hp-setup -i -a {{ '' if hplip_print_test_page else '-x' }} {{ printer_usb_address }} - when: not printer_already_configured - -# - name: Reboot the machine just in case -# ansible.builtin.reboot: -# post_reboot_delay: 60 -# when: not printer_already_configured