1

我想在 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中,以便进行上述工作?

4

2 回答 2

3

在 puppet 中管理那个 apache 包资源吗?如果是这样,您可以指定要安装的版本,因此您只需从包资源和此 if/else 块中的相同版本变量中读取。

在您的一个初始化文件中...

$package_version = '1.0'

在节点...

package { 'your_package':
  ensure => $package_version,
}

这是在 puppet 中思考的正确方式,“让这台机器成为我所期望的”而不是“我需要处理这台机器是什么”。

您可以使用 exec 来处理条件而不管理资源,但这根本不理想。

于 2013-02-12T23:14:10.383 回答
1

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-21: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}\'")
}
于 2016-11-21T17:49:07.700 回答