I came up with a workaround. Brace yourself, this is gross.
if $::puppetversion == '2.7.11' {
$ensure_puppet = 'held'
} else {
$ensure_puppet = '2.7.11-1puppetlabs1'
}
package { ['puppet', 'puppet-common']:
ensure => $ensure_puppet
}
It uses the built-in fact $::puppetversion
to do version interrogation. So the state of the package will be 'held' unless the installed version is different from what we want. This should enable me to upgrade the puppet infrastructure at will without worrying about unattended-upgrades doing it for me.
This doesn't answer the exact question regarding version locking Apache, but one could trivially write a custom fact to query Apache for its version.
I had initially tried the manual dpkg hold approach. I used the package type to ensure versions and then ran an execute script to make sure it was held separately. It's similar to the approach that I take with yum version locking.
define apt::hold() {
exec { "hold-${name}":
command => "/bin/echo '${name} hold' | /usr/bin/dpkg --set-selections",
unless => "/usr/bin/dpkg --get-selections ${name} | /bin/grep hold",
require => Package[$name]
}
}
package { ['puppet', 'puppet-common']:
ensure => '2.7.11-1puppetlabs1'
}
apt::hold { ['puppet', 'puppet-common']: }
Now, this works, but it produces a lot of annoying notifications in the logs and reports. The package type can't reconcile that a package can be both held and a certain version. So it will notify me that the package state has changed from 'held' to '2.7.11-1puppetlabs1'.
[sanitized.server.name.net] out: info: Retrieving plugin
[sanitized.server.name.net] out: info: Loading facts in /var/lib/puppet/lib/facter/operatingsystemmajor.rb
[sanitized.server.name.net] out: info: Loading facts in /var/lib/puppet/lib/facter/datacenter.rb
[sanitized.server.name.net] out: info: Caching catalog for sanitized.server.name.net
[sanitized.server.name.net] out: info: Applying configuration version '1333727048'
[sanitized.server.name.net] out: notice: /Stage[main]/Puppet/Package[facter]/ensure: ensure changed 'held' to '1.6.6-1puppetlabs1'
[sanitized.server.name.net] out: notice: /Stage[main]/Puppet::Client/Package[puppet-common]/ensure: ensure changed 'held' to '2.7.11-1puppetlabs1'
[sanitized.server.name.net] out: notice: /Stage[main]/Puppet::Client/Package[puppet]/ensure: ensure changed 'held' to '2.7.11-1puppetlabs1'
[sanitized.server.name.net] out: notice: Finished catalog run in 6.25 seconds
I don't like my reports crying wolf all the time. It also causes issues if I want to do something like:
package { ['puppet', 'puppet-common']:
ensure => '2.7.11-1puppetlabs1',
notify => Service['puppet']
}
To restart the service after an upgrade. I end with the service being bounced every single time puppet runs.
I agree with everyone else though that 'held' should probably be a separate attribute of the package type.