Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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!

share|improve this question
add comment

4 Answers

up vote 2 down vote accepted

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"],
    }
share|improve this answer
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.