概述:
刚开始使用 Puppet,并使用以下带有“确保”的数组,因此安装了特定版本的 Apache(而不是最新版本)并将其“保留”(这意味着它不会在标准上升级apt-get dist-upgrade
到最新版本。
问题:
使用下面的代码时,Puppet 只会考虑确保数组中的第一个值。因此,当执行下面的代码时,它会安装正确版本的 Apache,但包未设置为保留(通过运行检查dpkg --get-selection
)。
如果数组中的值被交换,那么包将被保留但会安装最新版本。
代码:
package { 'apache2':
ensure => [ "2.0.64", held ],
}
非常感谢大家对此的指点!
谢谢。
答案1
通过阅读源代码,我了解到“可保持”功能存在根本缺陷。ensure(参见ensurable.do
,第 50 行)无法接受选项数组。因此,软件包不能同时安装在特定版本上和使用 dpkg 标记已保存。我假设解析器的默认行为是,如果它收到不支持的数组,则使用第一个值。这可以解释您的结果。
在我看来,版本和/或可保留功能应该重新实现为新变量,例如:
package { 'apache2'
ensure => installed,
version => '2.0.64',
hold => true,
}
我建议您提交错误报告。与此同时,您可以执行以下操作:
package { 'apache2':
ensure => '2.0.64',
}
exec { 'hold-apache2-version':
command => 'dpkg ...',
require => Package['apache2'],
}
答案2
我想到了一个解决方法。做好准备,这太糟糕了。
if $::puppetversion == '2.7.11' {
$ensure_puppet = 'held'
} else {
$ensure_puppet = '2.7.11-1puppetlabs1'
}
package { ['puppet', 'puppet-common']:
ensure => $ensure_puppet
}
它使用内置事实$::puppetversion
进行版本查询。因此,除非安装的版本与我们想要的版本不同,否则包的状态将被“保留”。这应该使我能够随意升级 Puppet 基础设施,而不必担心无人值守升级会为我完成此操作。
这并没有回答有关 Apache 版本锁定的确切问题,但人们可以简单地编写一个自定义事实来查询 Apache 的版本。
我最初尝试了手动 dpkg 保存方法。我使用软件包类型来确保版本,然后运行执行脚本以确保它被单独保存。这与我使用 yum 版本锁定的方法类似。
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']: }
现在,这个方法有效了,但它会在日志和报告中产生很多烦人的通知。包类型无法协调包可以同时被保留和特定版本。因此它会通知我包状态已从“保留”更改为“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
我不喜欢我的报告总是谎报情况。如果我想做类似的事情,这也会引起问题:
package { ['puppet', 'puppet-common']:
ensure => '2.7.11-1puppetlabs1',
notify => Service['puppet']
}
升级后重新启动服务。每次运行 Puppet 时,服务都会被弹回。
不过,我同意其他人的意见,“held”应该是包类型的一个单独属性。