使用Chef,如何在“资源2”之前执行“资源1”,条件是“资源2”执行?

时间:2015-03-18 15:06:17

标签: chef chef-recipe

我有一个厨师食谱,有多个食谱,可以安装服务。厨师 - 客户的工作方式,它每15分钟(或其他一些常规间隔)重新收敛。现在我的食谱的第一步是停止服务,所以服务将每15分钟停止一次,但我真的想避免这种情况。问题是需要停止服务以执行某些步骤。

如果我的食谱资源中只有一两个条件,我可以这样做:

condition1 = ... # some true/false values
condition2 = ... #

service myservice do
  only_if { condition1 or condition2 }
  action :stop
end

resource1 do
  only_if { condition1 }
end

resource2 do
  only_if { condition2 }
end

但是由于我有十几个条件,在多个食谱中,它变得不雅。有没有办法做这个伪代码呢?

service_resource = service myservice do
  # somehow don't execute this right now, but wait for
  # signal from resource1 or resource2
  action :stop
end

resource1 do
  make sure service_resource executed first
  only_if { condition1 }
end

resource2 do
  make sure service_resource executed first
  only_if { condition2 }
end

如果在Chef中有一些“通知:之前”机制(而不是例如“立即通知”),我可以使用它,但我没有发现任何类似的东西。有什么想法吗?

编辑:

在考虑了这个之后,另一种方法,仍然不完美但更好,将通过定义一个被覆盖的单个属性来利用Chef的编译阶段。这样至少我们不必将所有条件都放在一个地方。

# in an "attributes" file:
default["stop_service"] = false

# in some recipe:
service myservice do
  action :stop
  only_if { node["stop_service"] }
end

# ... later, or in some other recipe file
condition1 = ... # true/false
if condition1
  # I think this executes before the only_if of the "service" resource
  override["stop_service"] = true
end

resource1 do
  only_if { condition1 }
end

1 个答案:

答案 0 :(得分:3)

我会做什么:

将配置暂存在" staging"如果发生此更改,请通知停止,复制文件,启动服务。

沿线的东西:

service "my_service" do 
  action :nothing
end

template "/staging/conf1" do
  [... usual attributes ...]
  notifies :stop,"service[my_service]",:immediately
end

template "/staging/conf2" do
  [... usual attributes ...]
  notifies :stop,"service[my_service]",:immediately
end

remote_file "/opt/my_service/etc/conf1" do
  source "/staging/conf1"
  notifies :start,"service[my_service]" # delayed here to allow all conf files to be updated.
end

remote_file "/opt/my_service/etc/conf2" do
  source "/staging/conf2"
  notifies :start,"service[my_service]" # delayed here to allow all conf files to be updated.
end

我的个人品味是使用相同的资源循环遍历文件/模板定义哈希这种选项:

node['my_namespace']['conf_files']['conf1'] = "template1"
node['my_namespace']['conf_files']['conf2'] = "template2"

然后用

循环
node['my_namespace']['conf_files'].each do |cfgfile,tmplname|
  template "/staging/#{cfgfile}" do
     source tmplname
     notifies :stop,"service[my_service]",:immediately
  end

  remote_file "/opt/my_service/etc/#{cfgfile}" do
    source "/staging/#{cfgfile}"
    notifies :start,"service[my_service]"
  end
end

对于更复杂的用例,您可以使用哈希而不是单个值

如果涉及的资源超过2个(在更换实际文件之前执行conf文件的特定命令以验证它,等等),定义可能适合。

另一个可能是在LWRP的load_current_resource中完成所有的分段工作,但是对于所描述的用例,我可能会走得太远。