2015-04-28 164 views
1

我正在通过厨师创建一个用户。他的属性存储在数据包:厨师有条件的资源参数

{ 
    "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

是否安装了带有软件包资源的zsh不是一个选项? – Tensibai

+0

@Tensibai,好吧,实际上我使用该食谱来安装'zsh'。我只是不想依赖它。 – madhead

+0

在这种情况下,@mudasobwa答案是正确的(如果答案中包含了一个关于ruby代码如何适用于未来读者的小解释,我已经投了赞成票) – Tensibai

回答

5

为了补充@ mudasobwa的答案正确的方式做到这一点的厨师和避免丢失shell,如果它是由安装另一个配方或包装资源必须使用相同的配方lazy attribute evaluation

龙版thoose兴趣在如何以及为什么:

这是厨师是如何工作的一个副作用,有一个第一次编译的资源建立一个集合,在这个阶段在配方中的任何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 

这里什么hapens是Shell属性值的评估延迟到收敛阶段,我们必须使用IF-THEN-ELSE结构(这里一个三元运算符,因为我发现它更可读)回退到我们肯定会出现的shell中(我使用/bin/bash,但故障安全值为/bin/sh)或shell属性为零,这是不允许的。

通过此延迟评估,在安装软件包并显示文件后,将对“/ bin/zsh”的存在性进行测试。如果软件包中存在问题,用户资源仍然会创建用户,但使用“/ bin/bash”

1

达到你想要什么,最简单的方法是检查外壳是否存在明确:

shell developer['shell'] if File.exist? developer['shell']