我遇到的情况是 Chef 可能会启动一项服务 (postgres),但随后可能会在带外停止。我希望随后运行 Chef 以使该服务运行。我尝试过以下方法:
service "postgresql" do
action :start
end
但它没有效果,(up to date)
大概是因为 Chef 知道它已经启动,但无法判断它已经停止了。(可能是因为service ... status
这项服务的行为方式?)如果我这样写:
# anti-pattern warning!
execute "force-start-postgresql" do
command "service postgresql start || /etc/init.d/postgresql start"
action :run
end
我得到了想要的行为。还action :restart
让它运行起来。然而,由于可移植性(并且在后一种情况下可能会在重新启动之前停止它),这些看起来像是反模式。
那么,我怎样才能告诉 Chef 强制启动该服务,即使它认为该服务已经在运行?
这是使用 OpsCode 托管的 Chef 11.6 和默认的 postgresql 配方。(请注意,这与以下类似,但我认为不太一样:如何强制对 Chef 中的“最新”资源采取行动?。
---编辑(根据 jtimberland 帖子进行澄清)---
这里-l debug
显示:
DEBUG: service[postgresql] supports status, running
DEBUG: service[postgresql] is running
即使它没有运行。这听起来像是一个错误,我对此很感兴趣。但是我主要感兴趣的是是否有办法告诉 Chef“始终调用服务启动命令,跳过状态检查”。这就是这里的问题。
(我不是专家,但我认为确保服务正在运行的最便携的方法是启动服务,而且这几乎总是幂等的。另一方面检查服务是否正在运行不太一致,我不明白我们为什么要关心!)
答案1
默认情况下,Chef 将检查服务是否正在运行,如果服务未运行,则启动它。
如何确定服务正在运行取决于。
postgresql
默认情况下,Chef 将尝试使用 在流程表中匹配服务的名称(此处) ps
。
ps -ef | grep postgresql
本质上。检查进程表时,服务名称将用于模式匹配。这可能是也可能不是您想要/需要的,尤其是取决于平台及其如何命名“postgresql”服务。
但是,你可以告诉 Chef 该服务支持“状态”命令,这意味着 Chef 通常会执行类似以下操作:
/etc/init.d/postgresql status
并使用返回代码来确定它是否正在运行(非零表示未运行)。
Chef 默认不这样做,因为并非所有服务脚本都支持状态命令(令人沮丧),而且 Chef 天生不知道该怎么做。它会尝试做明智的默认操作,但有时很幼稚。因此,您可以告诉 Chef 该资源有一个状态命令,而不要那么幼稚。
service "postgresql" do
supports :status => true
action :start
end
现在,如果服务实际上不是名为“postgresql”,而是“postgresql-92”或类似的,您可以这样做:
service "postgresql-92" do
supports :status => true
action :start
end
或者
service "postgresql" do
service_name "postgresql-92"
supports :status => true
action :start
end
您也可以通过运行带有调试输出的 chef 来更详细地了解正在发生的事情:
chef-client -l debug