Я пишу рецепт шеф-повара, чтобы установить наш код приложения и выполнить его. Рецепт должен быть особенно посвящен каталогу, в котором находится этот код (для запуска шаблонов, настройки пересылки журналов и т.д.). Таким образом, сам каталог появляется во многих местах в разных рецептах.
Я пытаюсь получить/определить переменную, чтобы я мог повторно использовать ее в своем блоке ресурсов со строчной интерполяцией. Это довольно просто:
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 (что является нечетной синтаксической ошибкой, но что угодно). Есть ли законный способ сделать это?