#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