Я пишу рецепт шеф-повара, чтобы установить наш код приложения и выполнить его. Рецепт должен быть особенно посвящен каталогу, в котором находится этот код (для запуска шаблонов, настройки пересылки журналов и т.д.). Таким образом, сам каталог появляется во многих местах в разных рецептах.
Я пытаюсь получить/определить переменную, чтобы я мог повторно использовать ее в своем блоке ресурсов со строчной интерполяцией. Это довольно просто:
home = node['etc']['passwd'][node['nodejs']['user']]['dir']
При использовании примера для запуска npm install
, сообщая ему, чтобы он загружал загрузки репо в домашнем каталоге, например:
execute "npm install" do
command "npm install #{prefix}#{app} --prefix #{home}"
end
За исключением того, что первый блок, который определяет переменную home
, будет выполняться во время компиляции. На новом сервере, где моя учетная запись nodejs может еще не существовать, это проблема, предоставляющая
NoMethodError undefined method '[]' for nil:NilClass
У меня есть несколько обходных решений, но я хотел бы, чтобы конкретное решение, чтобы домашняя переменная принималась только во время выполнения рецепта, а не время компиляции.
Обходной путь 1
Динамически оценивать домашнюю переменную внутри блока ruby, например:
ruby_block "fetch home dir" do
block do
home = node['etc']['passwd'][node['nodejs']['user']]['dir']
end
end
На самом деле это не работает, предоставляя метод NoMethodError undefined для Chef:: Resource:: Directory, когда вы пытаетесь сделать что-то вроде этого:
directory ".npm" do
path "#{home}/.npm"
end
Мне кажется, что я должен делать что-то не так.
Обходной путь 2
Ленько оценивайте параметр на каждом отдельном ресурсе, который ему нужен. Поэтому вместо этого сделайте следующее:
directory ".npm" do
path lazy "#{node['etc']['passwd'][node['nodejs']['user']]['dir']}/.npm"
end
Но было бы здорово просто сохранить эту строку кода один раз, сохранить ее в переменной и сделать с ней.
Обходной путь 3
Создайте пользователя во время компиляции. Это, конечно, работает, используя сообщить трюк, связанный здесь, например:
u = user node['nodejs']['user'] do
comment "The #{node['nodejs']['user']} is the user we want all our nodejs apps will run under."
username node['nodejs']['user']
home "/home/#{node['nodejs']['user']}"
end
u.run_action(:create)
Это точно решает мою проблему, но есть и другие случаи, когда я могу себе представить, что вы хотите отложить оценку переменной, поэтому я задаю вопрос.
Что мне нравится
Мне бы очень хотелось иметь возможность делать
home lazy = node['etc']['passwd'][node['nodejs']['user']]['dir']
Но это не юридический синтаксис, дающий NameError Не удается найти ресурс для дома на ubuntu версии 13.10 (что является нечетной синтаксической ошибкой, но что угодно). Есть ли законный способ сделать это?