在 Chef 食谱的这一部分中,有 4 个execute
资源。它们应该仅在文件不存在时运行。这作为条件添加到第一个资源中,然后触发整个链的运行。
# Set up default SSL cert
execute "defaultcert1" do
not_if {File.exist?("/vol/webserver/cert")}
command "mkdir /vol/webserver/cert"
notifies :run, "execute[defaultcert2]", :immediately
end
execute "defaultcert2" do
action :nothing
command "ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem /vol/webserver/cert/server.crt"
notifies :run, "execute[defaultcert3]", :immediately
end
execute "defaultcert3" do
action :nothing
command "ln -s /etc/ssl/private/ssl-cert-snakeoil.key /vol/webserver/cert/server.key"
notifies :run, "execute[defaultcert4]", :immediately
end
execute "defaultcert4" do
action :nothing
command "chown -R ubuntu:ubuntu /vol/webserver/cert"
end
如您所见,保护 4 条命令的代码量相当大。有没有更好的方法来实现这一点?
答案1
对于你的特定示例,我建议使用 Chef 的directory
和link
资源,而不是花费:
directory "/vol/webserver/cert" do
user "ubuntu"
group "ubuntu"
end
link "/vol/webserver/cert/server.crt" do
to "/etc/ssl/certs/ssl-cert-snakeoil.pem"
end
link "/vol/webserver/cert/server.key" do
to "/etc/ssl/certs/ssl-cert-snakeoil.key"
end
您不需要用not_if
's 和通知来保护这些 - 如果目录和链接已经具有正确的属性,Chef 将不会执行任何事情。
另一方面,假设您想使用 snakeoil 证书和密钥(如果一开始什么都没有),但如果文件已经存在,则不执行任何操作。在这种情况下,我会not_if
在链接资源上使用:
directory "/vol/webserver/cert" do
user "ubuntu"
group "ubuntu"
end
link "/vol/webserver/cert/server.crt" do
to "/etc/ssl/certs/ssl-cert-snakeoil.pem"
not_if "test -e /vol/webserver/cert/server.crt"
end
link "/vol/webserver/cert/server.key" do
to "/etc/ssl/certs/ssl-cert-snakeoil.key"
not_if "test -e /vol/webserver/cert/server.key"
end
与资源字符串相比execute
,这更清楚地传达了意图 - 它表示目录需要存在(具有正确的用户和组),并且除非已经存在某些内容,否则应该创建几个符号链接。
最后,如果你确实有几个相关的 shell 命令需要一起执行,可以考虑使用script
资源。