2013-10-02 7 views
5

Próbuję napisać bibliotekę do książki kucharskiej, która upraszcza niektóre typowe wyszukiwania.Jak uzyskać dostęp do bieżącego węzła z biblioteki w książce kucharskiej Chef?

Na przykład chciałbym być w stanie zrobić coś takiego w cookbook/libraries/library.rb a następnie używać go z przepisu w tej samej książki kucharskiej:

module Example 
    def self.search_attribute(attribute_name) 
     return search(:nodes, node[attribute_name]) 
    end 
end 

Problemem jest to, że wewnątrz pliku biblioteki Chef ani obiekt node ani funkcja search nie są dostępne.

Wyszukiwanie wydaje się możliwe przy użyciu Chef::Search::Query.new().search(...), ale nie mogę znaleźć niczego, co działa w celu uzyskania dostępu do node. Wynikowy błąd z tego to:

undefined local variable or method `node' for Example:Module 

Korzystanie z Chef 10.16.4.

+0

powiązane http://stackoverflow.com/a/22081109/1626687 – spuder

Odpowiedz

6

Co można zrobić, to uwzględnić moduł w swoim przepisie. W ten sposób funkcje modułu uzyskają dostęp do metod przepisu, w tym node.

I zwykle to zrobić dla moich modułów bibliotecznych:

# my_cookbook/libraries/helpers.rb 
module MyCookbook 
    module Helpers 
    def foo 
     node["foo"] 
    end 
    end 
end 

Następnie w przepisie, że to moduł do bieżącej instancji przepisu:

# my_cookbook/recipes/default.rb 
extend MyCookbook::Helpers 

tamtędy tylko obecny przepis zawiera moduł, nie wszystkie z nich w całym biegu szefa kuchni (unikasz w ten sposób starć nazw).

Alternatywnie można przekazać bieżący węzeł jako parametr do funkcji. W ten sposób nie trzeba uwzględniać modułu (który ma pozytywny wpływ na zachowanie przestrzeni nazw modułów), ale ma on wadę bardziej skomplikowanego wywołania metody.

+0

Prawdopodobnie głupie pytanie, ale co masz na myśli przez "W ten sposób, tylko obecny przepis zawiera moduł, nie wszystkie z nich w całym szefa kuchni biegać"? –

+2

Ludzie często nazywają 'Chef :: Recipe.include MyCookbook :: Helpers', który udostępnia funkcje pomocnicze we wszystkich przepisach (i może nadpisywać potencjalnie już istniejące z tą samą nazwą). Myślę, że to jest zapach kodu i wolę, aby moja wersja zawierała tylko moduł 'Helpers' w przepisie. –

+0

Myślę, że rozumiem. Używanie rozszerzenia Ruby dodawałoby tylko metody z modułu do działającego obiektu pojedynczej receptury, podczas gdy użycie tego, co wspomniałeś, dodawałoby go do wszystkich obiektów Chef :: Recipe. Dzięki! –

0

Po prostu wpadłem na to, próbując uzyskać dostęp do bieżącego środowiska w bibliotece. Nie mogłem naprawdę dowiedzieć się, jak używać modułów, aby uzyskać dostęp do węzła i nie chciałem przekazać węzła do każdego wywołania metody (lub wywołania instancji), więc zrobiłem to (przykładowy kod ... nie faktyczna funkcjonalność):

# libraries/account.rb 
class Account 
    @@env = "_default" 

    def self.env=(env) 
    @@env = env 
    end 

    def settings 
    Chef::EncryptedDataBagItem.load(@@env, "settings") || {} 
    end 
end 

# recipes/accounts.rb 
Account.env = node.chef_environment 

Account.new.settings 

ja nie wiem, czy za pomocą zmiennych klasy jest mile widziana, ale działa we wszystkich moich testów i to jest miłe i łatwe w użyciu.

Powiązane problemy