Как лениво оценить произвольную переменную с помощью Chef
Я пишу рецепт шеф-повара, чтобы установить код нашего приложения и выполнить его. В рецепте должен быть указан каталог, в котором заканчивается этот код (для запуска шаблонов, настройки пересылки журналов и т. Д.). Таким образом, сам каталог появляется во многих местах по разным рецептам.
Я пытаюсь получить / определить переменную, чтобы я мог повторно использовать ее в своем блоке ресурсов с интерполяцией строк. Это довольно просто:
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Динамически оценивать переменную home внутри блока ruby, например, так:
ruby_block "fetch home dir" do
block do
home = node['etc']['passwd'][node['nodejs']['user']]['dir']
end
end
Это не похоже на работу, даваяNoMethodError - неопределенный домашний метод для 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 (что является странной синтаксической ошибкой, но что угодно). Есть ли законный способ сделать это?