Jak leniwie oceniać dowolną zmienną za pomocą Chef

Piszę przepis szefa kuchni, aby zainstalować nasz kod aplikacji i wykonać go. Przepis musi dotyczyć katalogu, w którym znajduje się ten kod (do uruchamiania szablonów, ustawiania przekazywania dziennika itp.). W ten sposób sam katalog pojawia się w wielu miejscach w różnych przepisach.

Usiłuję pobrać / zdefiniować zmienną, dzięki czemu mogę ponownie użyć jej w moim bloku zasobów za pomocą interpolacji ciągu. To jest całkiem proste:

home = node['etc']['passwd'][node['nodejs']['user']]['dir']

Z przykładowym użyciem do uruchomienianpm install podczas mówienia mu, aby wrzucił pliki repo do katalogu domowego, w ten sposób:

execute "npm install" do
  command "npm install #{prefix}#{app} --prefix #{home}"
end

Z wyjątkiem pierwszego bloku, który definiujehome zmienna będzie działać w czasie kompilacji. Na nowym serwerze, na którym moje konto użytkownika nodejs jeszcze nie istnieje, jest to problem, dając

NoMethodError undefined method '[]' for nil:NilClass

Mam kilka obejść, ale chciałbym konkretne rozwiązanie, abyDom zmienna jest pobierana tylko w czasie wykonywania receptury, a nie w czasie kompilacji.

Obejście 1

Dynamicznie oceniaj zmienną domową wewnątrz bloku ruby, tak:

ruby_block "fetch home dir" do
  block do
    home = node['etc']['passwd'][node['nodejs']['user']]['dir']
  end
end

Wydaje się, że to nie działaNoMethodError niezdefiniowana metoda domu dla Chef :: Resource :: Directory kiedy próbujesz zrobić coś takiego:

directory ".npm" do
  path "#{home}/.npm"
end

Czuję, że muszę tu robić coś złego.

Obejście 2

Leniwie oceń parametr na każdym zasobie, który tego potrzebuje. Zamiast tego zrób to:

directory ".npm" do
  path lazy "#{node['etc']['passwd'][node['nodejs']['user']]['dir']}/.npm"
end

Ale byłoby wspaniale, gdybyśmy musieli raz zachować ten wiersz kodu, zapisać go w zmiennej i skończyć z nim.

Obejście 3

Utwórz użytkownika w czasie kompilacji. To oczywiście działa, używająctrik powiadomić tutaj, lubię to:

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)

To rozwiązuje dokładnie mój problem, ale są też inne przypadki, w których mogę sobie wyobrazić, że chcę opóźnić ocenę zmiennej, więc pozwoliłem, aby moje pytanie pozostało.

Co bym chciał

Naprawdę chciałbym móc to zrobić

home lazy = node['etc']['passwd'][node['nodejs']['user']]['dir']

Ale to nie jest składnia prawna, dawanieNameError Nie można znaleźć zasobu dla domu na ubuntu w wersji 13.10 (który jest dziwnym błędem składni, ale cokolwiek). Czy istnieje legalny sposób osiągnięcia tego celu?

questionAnswers(3)

yourAnswerToTheQuestion