leoarnold / puppet-cups

Puppet module for the Common Unix Printing System (CUPS)
https://forge.puppetlabs.com/leoarnold/cups
MIT License
9 stars 34 forks source link
cups-daemon cups-queues cups-service printer printing puppet puppet-forge

The CUPS module

.github/workflows/test.yml Depfu Maintainability Test Coverage Documentation

Puppet Forge Version Puppet Forge Endorsement Puppet Forge Downloads Puppet Forge Score MIT License

Table of Contents

  1. Description
  2. Setup
  3. Usage - A quick start guide
  4. Reference - The documentation of all features available
  5. Limitations
  6. Contributing - Guidelines for users and developers

Description

This module installs, configures, and manages the Common Unix Printing System (CUPS) service.

It provides Puppet types to install, configure, and manage CUPS printer queues and classes.

Key design goals include locale independence and test driven development.

Setup

What cups affects

Setup Requirements

This module is written for and tested on Linux systems with

Beginning with CUPS

First you need to install this module. One way to do this is

puppet module install leoarnold-cups

All resources in this module require the CUPS daemon to be installed and configured in a certain way. To ensure these preconditions you should include the main cups class wherever you use this module:

# General inclusion
include '::cups'

# OR

# Explicit class configuration
# (May only be defined once per catalog)
class { '::cups':
  # Your settings custom here
}

See the section on the cups class for details. Adding printer or class resources is described in the section on usage.

Usage

In this section, you will learn the straightforward way to set up CUPS queues from scratch. If the queues are already installed on the node, you can easily obtain a manifest with their current configuration by running

  puppet resource cups_queue

and adjust it following the instructions on configuring queues.

Managing Printers

There are several ways to set up a printer queue in CUPS. This section provides the minimal manifest for each method.

Note These minimal manifests will NOT update or change the PPD file on already existing queues, as CUPS does not provide a robust way to determine how a given queue was installed. See however the section on changing the driver for a workaround.

If you are unsure which way to choose, we recommend to set up the printer using the tools provided by your operating system (or the CUPS web interface), then take the corresponding PPD file from /etc/cups/ppd/ and use the ppd method.

Minimal printer manifests:

Changing the driver

When a printer queue is already present and managed using a PPD file, it is generally hard to tell which model or PPD file was used to install the queue. Nevertheless it might become necessary to change the model or update the PPD file without changing the queue name, e.g. because the PPD file contains some login credentials.

This module introduces a way to update the driver (i.e. force a reinstall) through syncing the make_and_model property, which defaults to

Example: On the node, running puppet resource cups_queue Office returns

  cups_queue { 'Office':
    ensure         => 'printer',
    make_and_model => 'HP Color LaserJet 4730mfp Postscript (recommended)',
    # ...
  }

and you would like to

Managing Classes

When defining a printer class, it is mandatory to also define its member printers in the same catalog:

  include '::cups'

  cups_queue { 'MinimalClass':
    ensure  => 'class',
    members => ['Office', 'Warehouse']
  }

  cups_queue { 'Office':
    ensure => 'printer',
    # ...
  }

  cups_queue { 'Warehouse':
    ensure => 'printer',
    # ...
  }

The Cups_queue['MinimalClass'] resource will automatically require its member resources Cups_queue['Office', 'Warehouse'].

Configuring queues

Once you have your minimal printer or class manifest, you will need to apply some configuration.

Job handling: In CUPS, newly installed queues are disabled and rejecting by default, which can lead to confusion at times. The corresponding cups_queue properties are:

If you want your print queues to "just work", you should set both to true. This module does not set default values by itself, since it might be of disadvantage in a professional copy shop environment.

Most users will prefer to set both options to true for all queues using

   Cups_queue {
     accepting => true,
     enabled   => true
   }

Option defaults: Sometimes you need to set some default values for CUPS or vendor options of a print queue, e.g. to enable Duplex to save trees or because you use A4 paper instead of US Letter.

To see all vendor options and their possible values for the queue Office, you can use lpoptions:

  $ lpoptions -p Office -l
  PageSize/Media Size: *Letter Legal Executive Tabloid A3 A4 A5 B5 EnvISOB5 Env10 EnvC5 EnvDL EnvMonarch
  InputSlot/Media Source: *Default Upper Manual
  Duplex/2-Sided Printing: *None DuplexNoTumble DuplexTumble
  Option1/Duplexer: *False True

The asterisk (*) indicates the current value. Use this to adapt your manifest

  cups_queue { 'Office':
    # ...
    options => {
      'Duplex'   => 'DuplexNoTumble',
      'PageSize' => 'A4',
    }
  }

You only need to provide values for options you actually care about.

Access control: Of course you want your boss Mr. Lumbergh, the secretary Nina and every member of the workers' council to be able to print to the office printer from every node. But all others should be denied to use this printer.

Assuming they respectively have the user accounts lumbergh, nina, and the user group council, this can be achieved by:

  cups_queue { 'Office':
    # ...
    access => {
      'policy' => 'allow',
      'users'  => ['lumbergh', 'nina', '@council'],
    }
  }

Note that group names must be prefixed with an @ sign.

Changing the policy to deny would deny all users, but allow everybody else. Furthermore, you can unset all restrictions by using

  cups_queue { 'Office':
    # ...
    access => {
      'policy' => 'allow',
      'users'  => ['all'],
    }
  }

because all is interpreted by CUPS as a wildcard, not as an account name.

Configuring CUPS

Now that you have created manifest for all your queues, you may want to set the default destination.

  class { '::cups':
    default_queue => 'Office',
  }

This will require the resource Cups_queue['Office'] to be defined in the catalog.

To find out about all options available for Class['::cups'] see the section below.

Automatic dependencies

For your convenience, this module establishes many resource dependencies automatically. For example, on a Debian system the manifest

class { '::cups':
  default_queue => 'Warehouse'
}

cups_queue { 'GroundFloor':
  ensure  => 'class',
  members => ['Office', 'Warehouse']
}

cups_queue { 'Office':
  ensure => 'printer',
  # ...
}

cups_queue { 'Warehouse':
  ensure => 'printer',
  # ...
}

by default generates the dependencies

                     Class['cups']
                    /             \
Cups_queue['Office']               Cups_queue['Warehouse']
                    \             /                       \
               Cups_queue['GroundFloor']                   Class['cups::queues::default']

Using Hiera

Make sure your Puppet setup includes the ::cups class on the relevant nodes. Configuration is straightforward:

cups::default_queue: Warehouse
cups::web_interface: true

Beyond that you can also create cups_queue resources using Hiera. Just replace a manifest like

class { 'cups':
  default_queue => 'Warehouse',
  web_interface => true
}

cups_queue { 'MinimalClass':
  ensure  => 'class',
  members => ['Office', 'Warehouse']
}

cups_queue { 'Office':
  ensure => 'printer',
  uri    => 'socket://office.initech.com',
}

cups_queue { 'Warehouse':
  ensure => 'printer',
  uri    => 'socket://warehouse.initech.com',
}

with the Hiera data

cups::default_queue: Warehouse
cups::web_interface: true
cups::resources:
  GroundFloor:
    ensure: class
    members:
      - Office
      - Warehouse
  Office:
    ensure: printer
    uri: socket://office.initech.com
  Warehouse:
    ensure: printer
    uri: socket://warehouse.initech.com

Reference

Classes

Types

Class: cups

Installs, configures, and manages the CUPS service.

Attributes

Type: cups_queue

Installs and manages CUPS print queues.

Attributes
Class-only attributes
Printers-only attributes

Limitations

Evince (aka Document Viewer)

Setting papersize => 'a4' only modifies /etc/papersize, but Evince uses the environment variable LC_PAPER to determine your preferred paper size, as Patrick Min figured out.

On Debian and Ubuntu, you can set a global default value for LC_PAPER using the manifest

augeas { 'papersize':
  context => '/files/etc/default/locale',
  changes => 'set LC_PAPER \'"es_ES.UTF-8"\'' # Change to your locale
}

Option defaults

Sometimes it may be necessary to modify the default values for some queue options to ensure an intuitive user experience, e.g. to enable the use of an optional duplex unit. For historic reasons there are two ways to set default values for all users:

Hence there is no robust way to determine the current daemon defaults when used in conjunction with local defaults. If local defaults aren't used, the command lpoptions -p [queue_name] -l will return the daemon defaults.

In order to provide a stable and idempotent way for Puppet to set default option values for all jobs sent to a queue, this module will disable the use of local defaults by deleting the file /etc/cups/lpoptions.

Systemd based Linux distributions

On some systemd based Linux distributions the Puppet run fails because during service restart systemd would prematurely yield back control to Puppet which would then fail to install print queues.

You can deal with this by installing the Puppet systemd module

puppet module install camptocamp-systemd

and then include a workaround class in your catalog

include '::cups::workarounds::systemd_service_restart'

which makes the cups.socket unit wait for CUPS to listen on localhost:631 before systemd yields back control.

If you want to add the ListenStream to a different systemd unit, you can include

class { '::cups::workarounds::systemd_service_restart':
  unit => 'mycups.socket'
}

Contributing

There are several ways to contribute for both users and developers:

Thank you for your interest in the CUPS module.