6

It makes sense, and is in fact suggested on this site, to have a critical file change trigger a service restart with puppet meta-parameters (such as notify or subscribe). For example:

  ## file definition for printers.conf
  file { "/etc/cups/printers.conf":
    [snip],
    source => "puppet:///module/etc/cups/printers.conf"
  }

  ## service definition for sshd
  service { 'cups':
    ensure => running,
    subscribe => File['/etc/cups/printers.conf']
  }

But in the case of CUPS, this triggers and endless loop of restarts; the logic works like this:

  1. Change puppetmaster's version of /etc/cups/printers.conf
  2. puppetmaster pushes new version to client, triggering cups restart
  3. cupsd restart insists on putting its own time stamp at the top of printers.conf, 'Written by cupsd...'
  4. This change will be seen as out of date, so after runinterval, we return to (1).

Is there a way to suppress cupsd's need to time stamp the file? Or is there a puppet trick that could help here?

Thanks!

4 Answers 4

2

You could copy the file to another name, and have an exec to only copy if printers.conf doesn't contain a line you require. Eg.

    file { "/etc/cups/printers.conf.puppet":
                source  => "puppet:///modules/desktop/cups/printers.conf",
                mode    => 0600,
                owner   => root,
                group   => lp;
    }

    # cups will put it's own timestamp in printers.conf, causing a loop if
    # puppet always replaces if the timestamp is different. This only replaces
    # the file is HP-Laserjet is not present
    exec { "/bin/cp /etc/cups/printers.conf.puppet /etc/cups/printers.conf":
            unless => '/bin/grep "HP-LaserJet-2300" /etc/cups/printers.conf 2>/dev/null',
            subscribe => File["/etc/cups/printers.conf.puppet"],
            refreshonly => "true",
            require => Package["cups"],
            notify => Service["cups"],
    }
5

An alternative approach is using lpadmin to add the printer to CUPS, in case it's missing from printers.conf.

For example:

exec {
    "/usr/sbin/lpadmin -p Lexmark-E450 -E -v usb://Lexmark/E450 -P /path/to/Lexmark_E450.ppd":
    unless => "/bin/grep Lexmark-E450 /etc/cups/printers.conf 2>/dev/null",
    require => File["/path/to/Lexmark_E450.ppd"];
}

This way we avoid messing with printers.conf while CUPS is running. To remove a printer, we can use lpadmin -x PRINTER-NAME (see the lpadmin manpage)

A more concrete example:

class print-common::lex250 {
    exec {
        "/usr/sbin/lpadmin -p Lexmark-E250 -E -v usb://Lexmark/E250d -P /path/to/PRINTER.ppd":
        unless => "/bin/grep Lexmark-E250 /etc/cups/printers.conf 2>/dev/null",
        require => File["/path/to/PRINTER.ppd"];
    }
}


class print-common {
    package {
        "cups": ensure => installed;
    }

    service {
        "cups":
            ensure => running,
            require => Package["cups"],
            subscribe => File["/etc/cups/cupsd.conf"];
    }

    file {
        "/etc/cups/cupsd.conf":
        ensure => present,
        owner => root,
        group => root,
        mode => 644,
        source => "puppet://puppet.mr.lan/files/etc/cups/cupsd.conf";

        "/path/to/ppd/":
        ensure => directory;

        "/path/to/PRINTER.ppd":
        ensure => present,
        owner => root,
        group => root,
        mode => 644,
        source => "puppet://puppet.mr.lan/files/path/to/PRINTER.ppd",
        require => File["/path/to/ppd/"];
    }

    case $fqdn {
            'host1.domain.name','host2.domain.name': { include print-common::lex250 }
    }
}

The print-common::lex250 could then probably be factored out to something reusable, using variable magic etc.

1
  • +1 Much better than directly hacking at printers.conf! :D Apr 28, 2015 at 14:15
3

Since cupsd insists to modify printers.conf you can't replace the whole file, instead you need to modify it on a line by line basis. Check out http://projects.puppetlabs.com/projects/puppet/wiki/Simple_Text_Patterns it'll show you how to replace parts of a file.

0

I've seen this issue before and it looks like it'll be fixed by upstream in CUPS 1.4.7, so it'll only rewrite the file (updating the timestamp) if a change has been made.

Fedora Bug #565674 describes1 this fix, and Debian used to carry a patch that prevents the timestamp from being written.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .