FOSS of the day: Ansible module for editing CUPS configuration files

By | December 28, 2024

I recently got a new printer, and as I’ve tweaked the integration between my printer and the numerous Linux desktops and laptops in my house, I became frustrated by how time-consuming and error-prone it was to have to use the Printers section of the GNOME Settings app, or the Printer Settings app (a.k.a. system-config-printer) to manually update the printer settings on multiple computers.

This finally came to a head when I realized that I wanted to have the printer configured with two different queues on each computer¹. It was time to figure out how to automate the configuration of CUPS queues with Ansible.

At this point I said to myself, “Surely the right way to do this is to use an Ansible module that knows how to manipulate CUPS configuration files, and surely someone has already written such a thing that I can grab and use myself!” But although I searched and searched, I was unable to find one, so I set out to write it myself.²

The result is the cups_conf Ansible module shown below, which I just wrote and am throwing out into the world on the off chance that someone else might benefit from it. I stuck a goodly amount of documentation at the top of the module code, but I’ll reiterate some of it here for the benefit of search engines. 😉

  • As far as I can tell, all of the CUPS configuration files have the same structure, so you could theoretically use this to edit any of them, but I think the one you’re going to care about most is /etc/cups/printers.conf.
  • You absolutely can’t edit printers.conf or any of the other CUPS configuration files while CUPS is running, so you need to shut down the CUPS service in your Ansible playbook while you are making edits.
  • If your printer supports driverless printing, a.k.a. “IPP Everywhere”, then I’m pretty sure the only printer setting you need to know to add a printer to cups is the correct DeviceURI setting. The easiest way to figure this out is to add the printer to one computer by hand, restart CUPS so it writes out printers.conf, and then pull the DeviceURI setting for the new printer out of printers.conf.
  • If your printer doesn’t support driverless printing or you can’t get it to work, or whatever, then in addition to adding the printer to printers.conf you’ll also want to deploy the correct PPD file for it into /etc/cups/ppd.
  • If you are modifying an existing printer or a printer that has existed in the past then there may be files for it cached in /var/cache/cups and you’ll want to remove those while CUPS is shut down so they won’t mask any changes you make.
  • The module takes these options:
    • path is the path to the configuration file you’re operating on.
    • section is the section in the configuration file, e.g., “Printer MyPrinter”.
    • option is the configuration option you’re operating on (if not specified, you’re operating on the entire section).
    • value is the value for that option.
    • state is “present” (default) or “absent” indicating whether the section or option should be there or not.
    • multi allows you to specify a list of dicts containing the above options (except path) to make multiple changes to the file in a single invocation of the module. If you use multi than you can also specify the above at the module level as defaults for the multis.
  • There’s an example in the module code which does the following:
    • Run the module in check mode to see if anything needs to change. If not, the rest of these steps are skipped
    • Stop CUPS.
    • Find cache files for the printer being updated and delete them.
    • Deploy the PPD file for the printer being updated.
    • Update printers.conf.
    • Start CUPS.

Bonus fact: I believe the configuration file format for Apache HTTPD is sufficiently close to the format for CUPS files that you can use this module without modification on those files as well. I haven’t tried it though.


¹I need both PostScript and PCL queues configured for this printer because the PostScript PPD comes from the manufacturer and therefore supports all of the printer’s features, but the generic PCL driver produces jobs that print much faster, so I want to use that driver by default and only use the PostScript driver when I need one of the printer’s esoteric features that only it supports.

²If in fact someone else has already written this, and you know where it is, please tell me so I can get rid of mine and use theirs instead. There is really no reason for two different people to maintain FOSS code that does the same thing.

Share

Leave a Reply

Your email address will not be published. Required fields are marked *