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 1Dynamicznie 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 2Leniwie 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 3Utwó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?