【发布时间】:2015-03-19 01:39:38
【问题描述】:
我有一本包含多个食谱的 Chef 食谱,它安装了一项服务。 chef-client 的工作方式,它每 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 中有一些“通知 :before”机制(而不是例如“通知 :immediately”),我可以使用它,但我没有找到任何类似的东西。有什么想法吗?
编辑:
在考虑了更多之后,另一种方法仍然不是完美但更好,它是通过定义一个被覆盖的属性来利用 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
【问题讨论】:
-
类 UNIX 操作系统上的大多数服务都可以在实时更新其配置(甚至代码,只要本地包管理器通过创建新 inode 而不是重写现有 inode 以获取新内容来替换文件)更新,这就是为什么这不是一个常见问题的原因——大多数时候,在重新配置或升级之前不需要停止服务。
-
@CharlesDuffy 最后也许这就是我所依赖的,但我写的实际上是一个简化:我们有一堆服务,我不确定它们是否都能拥有他们的运行时配置更改。我认为其中至少有一个会自动重新加载其配置,因此它可以在仅应用部分更改的情况下重新加载。此外,对于某些配方,我们在现有文件中追加/替换,因此在这些情况下,我们没有使用新的 inode(如果我理解正确的话)。
-
取决于附加/替换功能的工作方式——安全实现(当附加的数据超过一个系统调用,或者需要任何就地编辑时)通过编写一个同一目录中的临时文件并将其重命名为目标。但是,是的,如果您希望这些更改是原子的,修改多个文件并实现自动重新加载行为,那么您希望围绕配置更改重新启动(或 SIGSTOP 和 SIGCONT,如果支持)是有道理的。跨度>
-
其实我没有意识到,但你是对的。大多数时候,我们使用“sed -i”(“inplace”,我刚刚读到,它按照您的描述进行)。在其他一些情况下,我们使用 Chef::Util:FileEdit,它不会完全按照您的描述进行操作,但会保留旧文件的备份,因此旧的 inode 仍然保持不变(我认为)。