Шеф — повар-Передача значения с одного ресурса на другой ресурс

#ruby #shell #chef-infra

Вопрос:

вот фрагмент моего кода chef ruby, и я пытаюсь передать значение из одного блока в другой блок. У нас на сервере запущено несколько портов, приведенный ниже код проверит порт, и если он не запущен, он попытается выполнить 2-й блок. Я приложил код и ошибку. Пожалуйста, помогите, где я иду не так.

 ports.each do |port|
  bash "Check_port_running_#{port}" do
   code <<-EOH
     pidval=$(ps -ef | grep /opt/redis/src/redis-server | grep *:#{port} | grep -vc grep)
     if (($pidval == 0));then
       portval_#{port}=true
     else
       portval_#{port}=false
     fi
   EOH
  end

  bash "Starting_redis_after_crash_for_port - #{port}" do
    only_if { "portval_#{port}" }
    code <<-EOH
      rm -f #{port}.pid
      sudo service redis@#{port} start
    EOH
  end
end
 

Ошибка : Ошибка ниже

        ================================================================================
       Error executing action `run` on resource 'bash[Starting_redis_after_crash_for_port - 54321]'
       ================================================================================

       Errno::ENOENT
       -------------
       No such file or directory - portval_54321

       Resource Declaration:
       ---------------------
       # In /tmp/kitchen/cache/cookbooks/csg_orderservices_redis/recipes/configure.rb

       184:   bash "Starting_redis_after_crash_for_port - #{port}" do
       185:     only_if "portval_#{port}"
       186:     code <<-EOH
       187:       rm -f #{port}.pid
       188:       sudo service redis@#{port} start
       189:     EOH
       190:   end
       191: end

       Compiled Resource:
       ------------------
       # Declared in /tmp/kitchen/cache/cookbooks/csg_orderservices_redis/recipes/configure.rb:184:in `block in from_file'

       bash("Starting_redis_after_crash_for_port - 54321") do
         action [:run]
         default_guard_interpreter :default
         backup 5
         interpreter "bash"
         declared_type :bash
         cookbook_name "csg_orderservices_redis"
         recipe_name "configure"
         code "      rm -f 54321.pidn      sudo service redis@54321 startn"
         domain nil
         user nil
         only_if "portval_54321"
       end
 

Комментарии:

1. only_if Охранник должен оценить true/false . Вероятно, вам нужно выражение, чтобы сравнить его и вернуть статус true или false.

2. Или вы ожидаете найти файл с таким именем (в соответствии с ошибкой)?

3. нет.. я не ожидаю никакого файла.. не уверен, почему не удается найти каталог или файл,

4. Итак , когда вы используете only_if , какому условию вы пытаетесь соответствовать portval_#{port} ?

5. пытаюсь получить истинное или ложное значение из 1-го блока.

Ответ №1:

Мое мнение состояло бы в том, чтобы избегать использования ресурсов bash для этого. Это делается для того, чтобы ваши рецепты шеф-повара были идемпотентными и могли упростить ваш код, поскольку большая часть тяжелой работы выполняется клиентом шеф-повара. Я использую ресурсы bash, powershell и т. Д. Только в крайнем случае.

Вот мое предложение и пример ниже:

Создайте файл библиотеки с именем redis.rb в папке «библиотеки» в кулинарной книге. Я предпочитаю использовать пространство имен своих библиотек, чтобы помочь организовать мои методы. Этот redis_active? метод можно использовать из любого места вашей кулинарной книги, в которую включен этот модуль.

библиотеки/redis.rb:

 # Replace CookbookName with actual cookbook name

module CookbookName
  module Redis
    include Chef::Mixin::ShellOut

    def redis_active?(port)
      cmd = "ps -ef | grep /opt/redis/src/redis-server | grep *:#{port} | grep -vc grep"
      pid_exists = shell_out(cmd).stdout.strip.to_i

      return true if pid_exists > 0
    end
  end
end
 

В вашем рецепте redis file ресурс будет действовать только в том случае, если redis_active? метод вернет значение false для указанного порта, а затем file ресурс объединится и удалит файл pid. Когда этот ресурс объединится, он уведомит service ресурс о немедленном перезапуске службы сервера redis.

рецепты/redis.rb:

 # Replace CookbookName with actual cookbook name

Chef::Resource::File.send(:include, CookbookName::Redis)

ports.each do |port|
  file "/path/to/#{port}.pid" do
    action :delete
    not_if { redis_active?(port) }
    notifies :restart, "service[redis@#{port}]", :immediately
  end

  service "redis@#{port}" do
    action :nothing
  end
end