我有一个我从源码构建的程序。为此,我使用script
资源。实现安装和更新逻辑的好方法是什么?现在我只使用内置的not_if
条件实现安装。
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
答案 0 :(得分:68)
首先,如果您有办法托管内部软件包存储库,我通常建议您为目标平台构建本机软件包,并使用package
资源来管理它们,而不是从源头建设。我知道这并不总是可行或可行的,所以......
您制作“./configure&amp;&amp; make&amp;&amp; make install”样式安装脚本idempotent的方法取决于您使用的软件类型。通常,检查目标文件是否存在就足够了。有时,需要确定需要什么版本,以及使用正确的命令行选项执行时程序将输出的版本。我将使用上面的资源作为这些示例的起点。请注意,您可以使用bash
作为拥有解释器script
的{{1}}资源的快捷方式。
假设:程序安装到bash
并且可能会显示参数/usr/local/bin/program
以显示版本号。我把cd,configure和make命令与--version
放在一起,因为如果一个失败,我们就不应该继续执行。
&&
使用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时才会执行该脚本。
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的文件缓存位置,即Chef::Config[:file_cache_path]
的值。例如:
remote_file "#{Chef::Config[:file_cache_path]}/program.tar.gz" do
...
end
有关更多示例,您可以在Opscode共享的几本食谱中看到“来源”食谱:http://github.com/opscode/cookbooks。 php
,python
,gnu_parallel
和nagios
食谱都有“来源”食谱。