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

Ответы на вопрос(3)

Ваш ответ на вопрос