我正在使用 chef 和脚本资源从源代码安装某些内容。我是否应该检查生成的可执行文件等?
例如我目前拥有的是:
remote_file "/tmp/foo.tar.gz" do
source "foo.tar.gz"
mode "0644"
end
script "install_foo" do
interpreter "bash"
user "root"
cwd "/tmp"
code <<-EOH
tar -zxf foo.tar.gz
cd foo
make
cp foo /usr/local/bin
EOH
end
答案1
1
如果不存在,此脚本将退出foo
,因此无法复制。如果chef
可以正确处理未成功退出的脚本(退出代码0
),则严格来说您不需要进行另一次检查,但如果不需要,我强烈建议创建一个。
chef
我现在无法检查的行为,但测试这个很容易:把exit 1
作为脚本的最后一行,看看会发生什么。
无论如何,既然检查现有文件并不困难,为什么不简单地这样做,只是为了安全起见呢?
答案2
您一定要对脚本资源使用 not_if 或 only_if 元参数,否则 Chef 每次在节点上运行时都会执行该脚本。根据您正在编译的软件,这可以简单到文件存在,或者文件大小不为零,也可以复杂到验证在 /usr/local/bin 中复制的命令是否输出某个特定字符串。
例如,如果您想查看文件是否存在并做出最佳假设:
script "install_foo" do
# .. other stuff you wrote!
not_if "test -x /usr/local/bin/foo"
end
您可能应该确保该文件是可执行的,因为您将其放在了 /usr/local/bin 中。
file "/usr/local/bin/foo" do
mode 0755
end
如果你想检查命令是否有某些特定的输出,你可以执行以下操作:
script "install_foo" do
# .. other stuff you wrote!
not_if "test -x /usr/local/bin/foo && /usr/local/bin/foo | grep -x 'foo is awesome'"
end
(当然,假设运行 foo 会有该输出。)
not_if(和 only_if)元参数可以采用字符串或 Ruby 块。如果是字符串,则它将是在系统上执行的 shell 命令。如果是 Ruby 块(do .. end 或 { }),则它将作为 Ruby 执行。
元参数记录在 Chef wiki 的“资源”页面。
答案3
我宁愿使用 Chef::Mixin::ShellOut 实用程序,就像这篇文章中一样https://stackoverflow.com/questions/16309808/how-can-i-put-the-output-of-a-chef-execute-resource-into-a-variable
我将使用正确的参数运行命令来检查其版本号(大多数情况下为 -v [?]),这样您就可以检查两件事:
- 编译不仅成功,而且生成了一个可运行的二进制文件
- 您拥有的版本与您期望的版本相同
因为仅有一个文件并不足以假设二进制文件可以运行并且它是您期望的版本