Chef :: Node在从配方调用的库中可用,但在通过Singleton类调用时不可用

时间:2019-05-20 16:48:47

标签: ruby chef

我已经编写了一个服务中心,使我可以停止和启动服务,下面是该结构的非常简化的版本,未添加服务依赖项。

class Otbo
  class Services (requires Singleton)
    SERVICE_WEBLOGIC = {
      :start => lambda { Otbo::Services.instance._WLStart() },
      :stop => lambda { Otbo::Services.instance._WLStop() }
    }
    module Controller
      def control(service, command)
         service[command].call()
      end
    end
    include Otbo::Services::Controller
    include Singleton
   end
end

Chef::Recipe.send(:include, Otbo::Services::Controller)
Chef::Resource.send(:include, Otbo::Services::Controller)

在另一个避免循环依赖的食谱库中,我通过send方法添加了include-将上面的代码中的lambda中的以下_WLStart()_WLStop()方法绑定在一起。

module OtboDomain
  module Util
    def _WLStart()
      if has_role?(node, 'weblogic_adminserver') or has_role?(node, 'otbo_weblogic')
        puts 'Starting WebLogic...'
      end
    end
    def _WLStop()
      if has_role?(node, 'weblogic_adminserver') or has_role?(node, 'otbo_weblogic')
        puts 'Stopping WebLogic...'
      end
    end
  end
end

Otbo::Services.send(:include, OtboDomain::Util)

通过_WLStop()从食谱直接访问_WLStart()extend OtboDomain::Util时,我能够愉快地访问node属性。一切都很好。

当我通过Otbo::Service.control(service, command)方法进行调用时,我失去了节点上下文,并且在_WLStart()_WLStop()中不可用,因此出现错误。

node01 ================================================================================
node01 Recipe Compile Error in c:/chef/cache/cookbooks/otbo_weblogic/recipes/default.rb
node01 ================================================================================
node01
node01 NameError
node01 ---------
node01 undefined local variable or method `node' for #<Otbo::Services:0x000000000819d018>
node01
node01 Cookbook Trace:
node01 ---------------
node01   c:/chef/cache/cookbooks/otbo_domain/libraries/util.rb:200:in `_WLStop'
node01   c:/chef/cache/cookbooks/otbo_services/libraries/control.rb:36:in `block in <class:Services>'
node01   c:/chef/cache/cookbooks/otbo_services/libraries/control.rb:74:in `block in control'
node01   c:/chef/cache/cookbooks/otbo_services/libraries/control.rb:69:in `each'
node01   c:/chef/cache/cookbooks/otbo_services/libraries/control.rb:69:in `control'
node01   c:/chef/cache/cookbooks/otbo_weblogic/recipes/setup.rb:114:in `from_file'
node01   c:/chef/cache/cookbooks/otbo_weblogic/recipes/default.rb:12:in `from_file'

通过node调用时是否可以使Otbo::Service.control(service, command)属性可用?

1 个答案:

答案 0 :(得分:0)

我更改了创建custom resource的方法。

resource_name :otbo_service
actions [:stop, :start, :restart, :nothing]
default_action :nothing

property :service, Hash, required: true

action_class do
  def control(commands)
    handle(new_resource.service, commands)
  end
end

def handle(service, commands)
  name = service[:name]

  for command in commands
    service[command].call()
  end
end

action :nothing do
  Chef::Log.info('Nothing to do.')
end

action :stop do
  control([:stop])
end

action :start do
  control([:start])
end

action :restart do
  control([:stop, :start])
end

我添加了一个可以访问节点变量的库函数。

module Common
  module Util
    def _WLStart() 
      Chef::Log.info("<< Starting WebLogic Server on Host: #{node['hostname']} >>")
    end

    def _WLShutdown() 
      Chef::Log.info("<< Stopping WebLogic Server on Host: #{node['hostname']} >>")
    end
  end
end

Chef::Recipe.send(:include, Common::Util)
Chef::Resource.send(:include, Common::Util)

然后在食谱中,我可以通过类似以下代码的方式调用自定义资源。

extend Common::Util

weblogic = {
  :name => 'weblogic',
  :start => lambda { _WLStart() },
  :stop => lambda { _WLShutdown() }
}

otbo_service 'Restart WebLogic' do
  action :restart
  service weblogic
end