我正在通过Chef创建用户。他的属性存储在数据包中:
{
"id": "developer",
"home": "/home/developer",
"shell": "/bin/zsh",
"password": "s3cr3t"
}
食谱是:
developer = data_bag_item('users', 'developer')
user developer['id'] do
action :create
supports :manage_home => true
home developer['home']
comment developer['comment']
shell developer['shell']
password developer['password']
end
问题是如果节点上没有安装zsh
,我就无法以developer
身份登录。所以,我想有条件地为user
资源应用参数,例如:
user developer['id'] do
action :create
supports :manage_home => true
home developer['home']
comment developer['comment']
if installed?(developer['shell'])
shell developer['shell']
end
password developer['password']
end
我怎样才能做到这一点?
答案 0 :(得分:4)
为了补充@ mudasobwa回答正确的方法在厨师中做到这一点并避免错过shell,如果它是由另一个配方或包资源安装在同一个配方中你必须使用{{3 }}
对于如何以及原因感兴趣的长版:
这是关于厨师如何工作的副作用,第一次编译资源来构建集合,在此阶段,如果评估了配方中的任何ruby代码(在ruby_block资源之外)。完成后,资源集合将收敛(将所需状态与实际状态进行比较,并完成相关操作)。
以下配方可以:
package "zsh" do
action :install
end
user "myuser" do
action :create
shell lazy { File.exists? "/bin/zsh" ? "/bin/zsh" : "/bin/bash" }
end
这里最重要的是shell属性值的评估被延迟到收敛阶段,我们必须使用if-then-else结构(这里有一个三元运算符,因为我发现它更具可读性)回退到shell我们确定会出现(我使用/bin/bash
,但故障安全值为/bin/sh
)或shell属性为nil,这是不允许的。
通过这种延迟评估,测试是否存在" / bin / zsh"在安装软件包并且文件应该存在之后完成。如果包中存在问题,用户资源仍将创建用户,但使用" / bin / bash"
答案 1 :(得分:1)
实现您想要的最简单方法是明确检查shell存在:
shell developer['shell'] if File.exist? developer['shell']