我有一个从源代码构建的程序.为此,我使用script资源.实现安装和更新逻辑的好方法是什么?现在,我刚刚安装了内置的not_if conditional.

script "install_program" do
  not_if {File.exists?('/program')}
  interpreter "bash"
  user "root"
  cwd "/tmp"
  code <<-EOH
    wget http://www.example.com/program.tar.gz
    tar -zxf program.tar.gz
    cd tarball
    ./configure
    make
    make install
  EOH
end

推荐答案

首先也是最重要的一点是,如果您有办法托管内部包存储库,我通常建议您为目标平台构建本机包,并使用package资源来管理它们,而不是从源代码构建.我知道这并不总是可行的,所以...

生成"/configure&;make&;make-install"样式的安装脚本幂等式的方法取决于您使用的软件类型.通常,判断目标文件是否存在就足够了.有时,需要确定所需的版本,以及使用适当的命令行选项执行时程序将输出的版本.我将使用上面的资源作为这些示例的起点.请注意,您可以使用bash作为script个具有解释器bash的资源的快捷方式.

假设:该程序安装到/usr/local/bin/program,并使用参数--version来显示版本号.我把cd、configure和make命令与&&放在一起,因为如果其中一个失败了,我们不应该try 继续执行.

bash "install_program" do
  not_if "/usr/local/bin/program --version | grep -q '#{node[:program][:version]}'"
  user "root"
  cwd "/tmp"
  code <<-EOH
    wget http://www.example.com/program-#{node[:program][:version]}.tar.gz -O /tmp/program-#{node[:program][:version]}.tar.gz
    tar -zxf program-#{node[:program][:version]}.tar.gz
    (cd program-#{node[:program][:version]}/ && ./configure && make && make install)
  EOH
end

与其使用wget,不如使用remote_file资源,因为它本身就是幂等的.请注意,添加了checksum参数,该值作为属性.此参数告诉Chef,如果本地目标文件与校验和匹配,则不要下载远程文件.这是一个SHA256校验和.此外,该资源将通知脚本立即运行,因此在下载脚本之后.脚本设置为动作:nothing,因此只有在下载远程_文件时才会执行.

remote_file "/tmp/program-#{node[:program][:version]}.tar.gz" do
  source "http://www.example.com/program-#{node[:program][:version]}.tar.gz"
  checksum node[:program][:checksum]
  notifies :run, "bash[install_program]", :immediately
end

bash "install_program" do
  user "root"
  cwd "/tmp"
  code <<-EOH
    tar -zxf program-#{node[:program][:version]}.tar.gz
    (cd program-#{node[:program][:version]}/ && ./configure && make && make install)
  EOH
  action :nothing
end

此外,重新启动时,系统上的/tmp可能会被删除.建议您下载到另一个未被删除的位置,例如Chef's file cache location,其值为Chef::Config[:file_cache_path].例如:

remote_file "#{Chef::Config[:file_cache_path]}/program.tar.gz" do
  ...
end

关于更多的例子,你可以在Opscode分享的几本食谱中看到"源"食谱:http://github.com/opscode/cookbooks.phppythongnu_parallelnagios本食谱都有"源"食谱.

Ruby相关问答推荐

如何判断 postgres 中使用 ruby​​ 的查询是否失败?

Ruby 中的 Float#floor 和 Float#to_i 有什么区别?

Ruby 中使用的-S标志是什么?

这个#divmod 方法输出这个结果是做什么的?

Ruby 3 从多个预定纤程中收集结果

ri 和 rdoc 有什么区别

将数组转换为哈希,其中键是索引

Ruby 中有内置的二进制搜索吗?

Ruby 中的字符串是可变的吗?

我如何 expect期望在 RSpec 中引发异常的东西?

无法在 OSX Lion 上使用 RVM 安装 Ruby 企业版

如何通过反射获取 Ruby 的 Module 类定义的常量?

try 学习/理解 Ruby 的 setter 和 getter 方法

Ruby 数组中的奇数(或偶数)条目

如何在 Ruby 中遍历多行字符串?

Mustache Templates 可以做模板扩展吗?

if语句末尾带有then有什么区别?

向实例对象添加方法

您的 Ruby 版本是 2.0.0,但您的 Gemfile 指定了 2.1.0

如何在 Rails 应用程序中使用 httparty 的基本身份验证?