2014-09-05 14 views
9

Chcę przekazać zmienną do obsługi powiadomień, ale nie mogę znaleźć nigdzie tu ani na SO, ani na dokumentach, ani na problemach z repozytorium github, jak to zrobić. Co robię, to wdrażanie wielu aplikacji internetowych, a gdy kod jednego z tych aplikacji zostanie zmieniony, powinien ponownie uruchomić usługę dla tej aplikacji internetowej.ansible: używanie with_items with notify handler

Od this SO question, mam to do pracy, nieco:

- hosts: localhost 
    tasks: 
    - name: "task 1" 
    shell: "echo {{ item }}" 
    register: "task_1_output" 
    with_items: [a,b] 
    - name: "task 2" 
    debug: 
     msg: "{{ item.item }}" 
    when: item.changed 
    with_items: task_1_output.results 

(. Umieścić go w test.yml i uruchomić go z ansible-playbook test.yml -c local)

Ale ten rejestruje wynik pierwszego zadania i warunkowo pętle nad tym w drugim zadaniu. Mój problem polega na tym, że robi się bałagan, kiedy masz dwa lub więcej zadań, które muszą powiadomić o drugim zadaniu! Na przykład zresetuj usługę WWW, jeśli został zaktualizowany kod lub zmieniono konfigurację.

AFAICT, nie ma sposobu przekazania zmiennej do programu obsługi. To by mi to naprawiło. Znalazłem kilka problemów na github, gdzie inni ludzie napotkali ten sam problem i zaproponowano kilka składni, ale żaden z nich nie działa.

W tym pod-zakładce również nie działa, ponieważ użycie with_items wraz z include było przestarzałe.

W moich książeczkach mam site.yml, który zawiera listę ról grupy, następnie w group_vars dla tej grupy definiuję listę aplikacji internetowych (w tym wersje), które powinny zostać zainstalowane. Wydaje mi się to poprawne, ponieważ w ten sposób mogę użyć tego samego playbooka do inscenizacji i produkcji. Ale może jedynym rozwiązaniem jest zdefiniowanie roli wiele razy i skopiowanie listy ról dla etapów i produkcji.

Jaka jest tutaj mądrość?

Odpowiedz

5

I wreszcie rozwiązać go przez podzielenie aplikacje nad wiele wystąpień o tej samej roli. W ten sposób program obsługi w roli może odnosić się do zmiennych, które są zdefiniowane jako zmienna roli.

W site.yml:

- hosts: localhost 
    roles: 
    - role: something 
    name: a 
    - role: something 
    name: b 

W rolach/coś/zadania/main.yml:

- name: do something 
    shell: "echo {{ name }}" 
    notify: something happened 

- name: do something else 
    shell: "echo {{ name }}" 
    notify: something happened 

W rolach/coś/koparki/main.yml:

- name: something happened 
    debug: 
    msg: "{{ name }}" 

Wydaje się dużo mniej hackish niż pierwsze rozwiązanie!

+1

Powiedziałbym, że to nie zadziała, po prostu przetestowano to samo z Ansaly 1.8.4 i 1.9.0. Program obsługi zawsze rozwiązuje 'name' zgodnie z pierwszym wywołaniem roli,' a' tutaj, nawet po wywołaniu kolejnej inwokacji roli. Ponieważ program obsługi i jego powiadomienie są globalne dla wywołań ról, nie można tak go parametryzować. – famousgarkin

+2

Dziwne! Myślę, że to przetestowałem, z 1.7.1 w tym czasie. Ale udało mi się to ponownie uruchomić, zmieniając powiadomienia na '" coś się stało {{name}} "' w tasks/main.yml i zmieniając nazwę handlarza na '" coś się stało {{name}} " '. – j0057

+0

Patrz tutaj: https://gist.github.com/j0057/5af0ac913a203a5b94ef - przepraszam, że musiałem spłaszczyć katalogi, może jeśli je rozwidnisz, uzyskasz dostęp do wcześniejszego zatwierdzenia, w którym katalogi nie są spłaszczone. – j0057

14

Zmienne w Ansible są globalne, więc nie ma powodu, aby przekazywać zmienną do obsługi. Jeśli próbujesz sparametryzować program obsługi w taki sposób, że próbujesz użyć zmiennej w nazwie handler'a, nie będziesz mógł tego zrobić w Ansible.

Co można zrobić, to utworzyć uchwyt że pętle na liście usług dość łatwo, tutaj jest przykład roboczych, które mogą być badane lokalnie:

- hosts: localhost 
    tasks: 
    - file: > 
     path=/tmp/{{ item }} 
     state=directory 
    register: files_created 
    with_items: 
     - one 
     - two 
    notify: some_handler 

    handlers: 
    - name: "some_handler" 
     shell: "echo {{ item }} has changed!" 
     when: item.changed 
     with_items: files_created.results 
+2

próbowałem tej metody, ale to nie działa dobrze, gdy dwa lub więcej zadań może lub nie powiadamiaj obsługi. – j0057

0

Z handler'a można wywołać każdą zarejestrowaną zmienną, ale zarejestrowana zmienna jest nadpisywana przez ostatnie zadanie.

- hosts: localhost 
    tasks: 
    - name: Task1 
    file: path=/toto/ state=directory 
    register: files_created 
    notify: some_handler 

    - name: Task2 
    file: path=/toto/ state=directory 
    register: files_created 
    notify: some_handler 

    handlers: 
    - name: "some_handler" 
     debug: msg="{{ file_created.results }}" 

W tym przykładzie zmienna "file_created" zawiera tylko wynik "Task2". miałem ten sam problem i zaproponował PR: https://github.com/ansible/ansible/pull/6674

z tym, byłoby to:

- hosts: localhost 
    tasks: 
    - name: Task1 
    file: path=/toto/ state=directory 
    register: files_created 
    notify: some_handler 
    append_to_list: yes 

    - name: Task2 
    file: path=/toto/ state=directory 
    register: files_created 
    notify: some_handler 
    append_to_list: yes 


    handlers: 
    - name: "some_handler" 
     debug: msg="{{ item.results }}" 
     with_items: files_created 
+0

dobry PR, ale to jeszcze nie jest w ansibla – Evan

+0

PR został zamknięty i nigdy się nie scalił, więc nie jest to odpowiedź. –