Chef :: Node доступен в библиотеке, вызываемой по рецепту, но не при вызове через класс Singleton - PullRequest
1 голос
/ 20 мая 2019

Я написал сервисный хаб, который позволяет мне останавливать и запускать сервисы, очень упрощенная версия структуры приведена ниже без добавления сервисных зависимостей.

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, который связывает приведенные ниже методы _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 голосов
/ 21 мая 2019

Я изменил свой подход к созданию пользовательского ресурса .

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
...