Chef infra 包含的LWRP配方中定义的通知服务

Chef infra 包含的LWRP配方中定义的通知服务,chef-infra,chef-recipe,Chef Infra,Chef Recipe,是否有方法通知包含LWRP定义的服务重新启动 我写了一个名为“sidekiq”的LWRP,它建立了一个类似这样的服务,并且看起来自己工作得很好 service "#{new_resource.name}_sidekiq" do provider Chef::Provider::Service::Upstart action [ :enable ] subscribes :restart, "template[/etc/init/#{new_resource.name}_sidekiq

是否有方法通知包含LWRP定义的服务重新启动

我写了一个名为“sidekiq”的LWRP,它建立了一个类似这样的服务,并且看起来自己工作得很好

service "#{new_resource.name}_sidekiq" do
  provider Chef::Provider::Service::Upstart
  action [ :enable ]
  subscribes :restart, "template[/etc/init/#{new_resource.name}_sidekiq.conf]", :immediately
end
问题是我正在使用它,这是我用于部署的另一个方法,需要它通知LWRP中定义的服务。我现在有一些

include_recipe "sidekiq"
deploy_revision my_dir do
  notifies :restart, "service[myapp_sidekiq]"
end
问题是在编译时,chef查看了这个配方并给出了一个错误

错误:资源部署修订版[my_dir]配置为通知资源服务[myapp_sidekiq]并重新启动操作,但在资源集合中找不到服务[myapp_sidekiq]


我可以通过在我的部署配方中定义一个空的服务来消除这个错误,比如
服务'myapp\u sidekiq'
,当第一次配置机器时,一切都会正常工作。但是,如果我运行一个部署,并且sidekiq LWRP中没有任何更改,myapp_sidekiq服务将永远不会重新定义,因此无法重新启动。

LWRP与
使用内联资源
使用自己的
运行上下文
,因此,LWRP内的资源不包括在
资源\u集合中,并且不能在LWRP外得到通知

没有内联资源标志的LWRP将其内部资源添加到资源集合中,但在收敛阶段et不是在编译阶段,因此您仍然会看到错误

但是,如果我运行部署,sidekiq LWRP中没有任何更改, myapp_sidekiq服务从未被重新定义,因此无法重新定义 重新启动

我真的不明白你的意思,除非你的deploy\u修订版应该更改服务的enable/disbale状态或它支持的内容(状态、重新启动、重新加载等),否则没有必要重新启用它,只需为deploy\u修订版定义一个服务资源来通知它重新启动。

到一个资源来完成一个操作,该资源必须在当前Chef运行之前定义,正如Tensibai指出的,未在其自身的运行上下文中定义
inline

占位符 简单的方法是在非默认提供程序的部署脚本中创建一个占位符,其操作为
:nothing
,但您可以稍后通知它

service "myapp_sidekiq deploy notifier" do
  provider      Chef::Provider::Service::Upstart
  service_name  "myapp_sidekiq"
  action        :nothing
end
如果您一直在Chef配置为其他内容的平台上使用Upstart,则还可以在
client.rb
中修改资源的总体默认提供程序,如
systemd

Chef::Platform.set :platform => :yours, :resource => :service, :provider => Chef::Provider::Service::Upstart
有一些方法可以让Chef在运行时评估使用哪个服务提供商,而不是静态配置。这基本上是由于systemd出现并动摇了曾经非常稳定和可预测的系统上的某些东西

请注意用于资源的
名称
。如果您有多个通过同一服务名称定义的
服务
资源,您可能会因为它们的方式而遇到问题,并且您可能正在运行一些您意想不到的东西。如果您正在使用多个服务定义,请尝试将它们命名为特定用途的唯一名称。然后在属性中,使用
service\u name

LWRP 如果您有一个重复定义的特别复杂的资源,并且您认为应该只为其指定一次所有通用参数,那么您可以创建自己的封装所有通用设置的资源,以便在配方中更轻松地定义资源:

service_myapp_sidekiq "deploy notifier" do
  action      :nothing
end

service_myapp_sidekiq "config subscriber" do
  action      :nothing
  subscribes  :restart, 'blah'
end
这是一项大量的工作,因为您必须为您想要支持的每个底层操作创建一个LWRP
操作
,正如您所看到的,这并不会使您的用例变得更简单

图书馆职能 您还可以使用中的函数执行相同的操作,该函数定义了资源的基础知识,并允许您添加所需的任何自定义项(如名称)

同样,这些可能仅适用于更复杂的资源设置和需要反复定义同一复杂资源的情况


TLDR:定义一个占位符
服务
,该服务对部署不起作用

如果没有任何更改,为什么必须重新定义服务?不需要重新定义服务。我只需要通知它重新启动。所以只需在你的配方中创建一个服务资源,在他的回答中没有@mtm expose这样的操作,你将拥有类型为service的资源,可以通知,你的lwrp仍然负责启用它,lwrp中的资源非常感谢详细的回答,但是占位符方法似乎不适合我。为了确保我理解正确。。我离开了我的sidekiq LWRP。在进行部署的配方中,我添加了
deploy\u revision my\u app notified:restart,“service[myapp\u sidekiq deploy notifier]”end
如果我在占位符中指定提供者
provider Chef::provider::service::Upstart
。这有必要吗?它工作正常,但现在我的部署配方取决于sidekiq配方管理服务的方式。您使用的是什么操作系统/版本?在Chef中添加了一些关于默认服务提供商的详细信息,因为我猜您使用的是您已添加systemd或最近已移动到systemd的发行版。我使用的是Ubuntu 14.04。在这种情况下,我特别不想使用默认的服务提供者,因为sidekiq配方使用Upstart来妖魔化程序。我希望我可以通知在另一个配方中定义的服务并控制那里的服务提供商,但我想这是不可能的。谢谢你的帮助!
def create_myapp_service name, action, options = {}
  s = Chef::Resource::Service.new "myapp service #{name}"
  s. service_name   "myapp_sidekiq"
  s.provider        Chef::Provider::Service::Upstart
  s.action          action
end

create_myapp_service "deploy", :nothing