我想在 Puppet .erb 文件中做这样的事情:
<% if (version_of_apache_package_installed =~ /1.5.82/) then -%>
do one thing
<% else -%>
do a different thing
<% end -%>
如何将某些已安装包的版本字符串放入变量version_of_apache_package_installed
中,以便进行上述工作?
你在 puppet 中管理那个 apache 包资源吗?如果是这样,您可以指定要安装的版本,因此您只需从包资源和此 if/else 块中的相同版本变量中读取。
在您的一个初始化文件中...
$package_version = '1.0'
在节点...
package { 'your_package':
ensure => $package_version,
}
这是在 puppet 中思考的正确方式,“让这台机器成为我所期望的”而不是“我需要处理这台机器是什么”。
您可以使用 exec 来处理条件而不管理资源,但这根本不理想。
Puppet 是一种声明性语言,可确保某些资源(在本例中为包)处于所需状态。在每个受支持的平台上,可能有不同的包管理器遵循各种约定。最终,当包状态发生变化时,可以执行一些代码,例如:
<!-- language: puppet -->
package { "apache2":
ensure => installed,
notify => Exec['apache-updated']
}
exec { 'apache-updated'
command => "/usr/bin/execute_some_script",
refreshonly => true,
}
根据文档,属性有几个特殊值ensure
:
installed
absent
3.4.12-2
或1:9.10.3.dfsg.P4-12.3+deb9u5
您可以使用以下命令从 CLI 获取当前已安装软件包的列表:
puppet resource package
这背后的动机主要是性能。检查包版本比较快,而执行自定义脚本会延长puppet agent
运行时间。
根据包版本做出决策的最佳方法是在某些模块中创建自定义事实lib/facter/apache_version.rb
:
<!-- language: ruby -->
Facter.add(:apache_version) do
setcode do
if Facter::Util::Resolution.which('apache2')
Facter::Util::Resolution.exec('apache2 -v | head -n 1 | awk '{ print $3}' | cut -d "/" -f 2')
end
end
end
这样,应该为所有受支持的操作系统处理版本控制细节。然后你可以在你的代码中写:
<!-- language: puppet -->
case $::apache_version {
undef: {
# during first run the version will be undefined, as the package is hasn't been installed yet
}
/^2/: {
# TODO
}
default: {
# TODO
}
}
如果您需要比较版本,请使用stdlib 的功能versioncmp
:
if versioncmp($::apache_version, '2.0.0') < 0 {
fail("foobar requires Apache 2.0 or greater, found: \'${::apache_version}\'")
}