2015-03-18 8 views
5

Mam książkę kucharską szefa kuchni, z wieloma przepisami, która instaluje usługę. Sposób, w jaki pracuje kucharz-klient, ponownie się zbiegają co 15 minut (lub jakikolwiek inny regularny interwał). W tej chwili pierwszym krokiem mojej książki kucharskiej jest zatrzymanie usługi, więc usługa zatrzyma się co 15 minut, ale naprawdę chcę tego uniknąć. Problem polega na tym, że usługa musi zostać zatrzymana, aby wykonać kilka czynności.Z szefem kuchni, jak wykonać "zasób 1" przed "zasobem 2", w zależności od wykonania "zasobu 2"?

Gdybym miał tylko jeden lub dwa warunki w zasobach moich receptur, mogę po prostu zrobić:

condition1 = ... # some true/false values 
condition2 = ... # 

service myservice do 
    only_if { condition1 or condition2 } 
    action :stop 
end 

resource1 do 
    only_if { condition1 } 
end 

resource2 do 
    only_if { condition2 } 
end 

Ale jak mam kilkanaście warunków, w wielu recepturach, robi nieeleganckie. Czy istnieje sposób na wykonanie tego pseudokodu?

service_resource = service myservice do 
    # somehow don't execute this right now, but wait for 
    # signal from resource1 or resource2 
    action :stop 
end 

resource1 do 
    make sure service_resource executed first 
    only_if { condition1 } 
end 

resource2 do 
    make sure service_resource executed first 
    only_if { condition2 } 
end 

Jeśli nie było pewne „powiadamia: Przed” mechanizmu Chef (zamiast na przykład „zawiadamia niezwłocznie”), mogę to wykorzystać, ale nie znaleziono niczego w tym rodzaju. Jakieś pomysły?

EDIT:

Po myśleć o tym trochę więcej, inny sposób to zrobić, jeszcze nie jest doskonały, ale lepiej byłoby, korzystając z kompilacji fazie Chef definiując jeden atrybut, który jest zastąpiony. W ten sposób przynajmniej nie musimy utrzymywać wszystkich warunków w jednym miejscu.

# in an "attributes" file: 
default["stop_service"] = false 

# in some recipe: 
service myservice do 
    action :stop 
    only_if { node["stop_service"] } 
end 

# ... later, or in some other recipe file 
condition1 = ... # true/false 
if condition1 
    # I think this executes before the only_if of the "service" resource 
    override["stop_service"] = true 
end 

resource1 do 
    only_if { condition1 } 
end 
+1

Większość usług w systemach operacyjnych podobnych do systemu UNIX może mieć swoją konfigurację (lub nawet kod, o ile lokalny menedżer pakietów zastępuje pliki, tworząc nowe i-węzły zamiast przepisywania istniejących i-węzłów, aby zawierały nowe treści), aktualizując je na bieżąco, dlatego to nie jest często występuje problem - usługa nie musi być zatrzymywana przed rekonfiguracją lub aktualizacją. –

+0

@CharlesDuffy Na koniec może na tym polegam, ale to, co napisałem, jest w rzeczywistości uproszczeniem: mamy szereg usług i nie jestem pewien, czy wszystkie z nich mogą mieć zmienioną konfigurację podczas działania. Sądzę, że przynajmniej jeden z nich automatycznie wczytuje swoją konfigurację, aby mógł przeładować, chociaż zastosowano tylko częściowe zmiany.Również w przypadku niektórych przepisów dołączamy/zastępujemy istniejące pliki, więc w tych przypadkach nie używamy nowych i-węzłów (jeśli dobrze rozumiem, co masz na myśli). – fsdj

+1

Zależy dokładnie, w jaki sposób dodać/wymienić funkcjonalność działa - bezpieczne implementacje (gdy dane są dołączane jest więcej niż pasuje w jednym syscall lub gdy potrzebne są jakiekolwiek zmiany w miejscu), pisząc pracę tymczasowy plik w tym samym katalogu i zmieniając nazwę nad miejscem docelowym. Ale tak, ma sens, że chcesz chcesz zrobić restart (lub SIGSTOP i SIGCONT, jeśli jest obsługiwany) wokół zmian konfiguracyjnych jeśli chcesz te zmiany były atomowy, wielokrotne pliki są modyfikowane i automatyczne zachowanie przeładowania jest realizowany. –

Odpowiedz

3

Co bym zrobił:

etapie konfiguracji w „pomostowym” miejsce, jeśli tej zmianie powiadomi stop, kopiowanie plików, uruchomić usługę.

Coś wzdłuż linii:

service "my_service" do 
    action :nothing 
end 

template "/staging/conf1" do 
    [... usual attributes ...] 
    notifies :stop,"service[my_service]",:immediately 
end 

template "/staging/conf2" do 
    [... usual attributes ...] 
    notifies :stop,"service[my_service]",:immediately 
end 

remote_file "/opt/my_service/etc/conf1" do 
    source "/staging/conf1" 
    notifies :start,"service[my_service]" # delayed here to allow all conf files to be updated. 
end 

remote_file "/opt/my_service/etc/conf2" do 
    source "/staging/conf2" 
    notifies :start,"service[my_service]" # delayed here to allow all conf files to be updated. 
end 

Mój osobisty smak idzie do pętli nad files/szablonu definicji hash dla tego rodzaju opcja z tych samych zasobów, takich jak:

node['my_namespace']['conf_files']['conf1'] = "template1" 
node['my_namespace']['conf_files']['conf2'] = "template2" 

a następnie zapętlenie nad z

node['my_namespace']['conf_files'].each do |cfgfile,tmplname| 
    template "/staging/#{cfgfile}" do 
    source tmplname 
    notifies :stop,"service[my_service]",:immediately 
    end 

    remote_file "/opt/my_service/etc/#{cfgfile}" do 
    source "/staging/#{cfgfile}" 
    notifies :start,"service[my_service]" 
    end 
end 

Dla bardziej skomplikowanych przypadków użycia możesz użyć zamiast tego skrótu o pojedynczej wartości też

Jeśli zaangażowanych jest więcej niż 2 zasoby (wykonanie określonych poleceń dla pliku conf w celu zatwierdzenia go przed zastąpieniem faktycznego itd.), definicja może pasować.

Innym przykładem może być wykonanie wszystkich prac związanych z przemieszczaniem w module LWRP w wersji load_current_resource, ale może być zbyt daleko w przypadku opisanego przypadku użycia.

+0

Dzięki @Tensibai. Może to działać w przypadku niektórych rodzajów zasobów, ale tak naprawdę wpływa to na strukturę receptur. Staram się unikać tak dużych zmian i utrzymywać przepisy "jak najbardziej naturalne", dlatego szukam czegoś takiego jak "powiadamia: przed" (co wymagałoby trochę magii z "Kolejką zasobów szefa kuchni" ... ale jeśli nie jest to w ramach, nie ma wiele do zrobienia). – fsdj

+1

@fsdj Cóż, sprawa została omówiona [tutaj] (https://tickets.opscode.com/browse/CHEF-2421) z kilkoma próbami na ten temat. Komentarze na temat PR powiązanego w bilecie informują, dlaczego go nie ma szef kuchni w rzeczywistości. – Tensibai

+0

Oh wow, to dokładnie to, co miałem na myśli. Więc tak, myślę, że naprawdę nie jest to możliwe w Chef na razie ("bez dużego refaktora", jak mówi PR). "Zależy" między zasobami byłby jeszcze lepszy (aby uniknąć wielokrotnego uruchamiania poprzedniego kroku, jak wspomniano przez kogoś). Wielkie dzięki, które pozwolą uniknąć dalszego bezużytecznego kopania. – fsdj

Powiązane problemy