Чи визначені обробники Ansible, визначені в ролях, після всіх ігрових книжок чи ролей?


13

Я запускаю Ansible 2.0, і я міг би просто запустити це, але я також міг би натрапити на те, щоб повірити в те, що не відповідає дійсності моїх емпіричних тестів, і я не можу знайти жодної документації, яка би могла сказати мені, коли слід обробляти обробники.

Якщо обробники не виконуються в кінці своїх завдань, це моя головоломка. У мене є ігрова книга з 5 ролями в ній, я хочу додати 6 ролей до кінця, які повинні мати завершені обробники 4-ї ролі, перш ніж вона може початися.

Чи є якийсь спосіб запустити Ansible, щоб покластися на завершення обробника (тобто роль, яка повністю виконана), перш ніж робити щось інше чи я неправильно використовую обробники?

Відповіді:


17

Обробники виконуються:

  • наприкінці гри (не книги)
  • на виконання meta: flush_handlersзавдання

Отже, " щоб додати 6 ролей до кінця, які повинні мати обробники 4-ї ролі ", вам потрібно:

  • або розділити розподіл ролей на окремі п’єси;
  • або додати мета завдання та включити 6-ю роль з include_roleмодулем :

    roles:
      - role4
    tasks:
      - meta: flush_handlers
      - include_role:
          name: role6
    

Для вашого випадку використання я б запропонував перший метод, оскільки include_roleмодуль ще дуже свіжий, і при його використанні є химерності (див. Це питання на ТАК ).


Крім того, зауважте, що імена обробників та прослуховування дзвінків є глобальними, тому два обробники в окремих ролях будуть конфліктувати, якщо вони мали одне ім’я та обидві ролі були призначені в одній виставі. (посилання обробники: Запуск операцій із зміни )

Обробники [] посилаються на глобально унікальне ім'я та повідомляються повідомленнями. [] обробник, він запуститься лише один раз, після того, як всі завдання будуть виконані в певній грі.

Назви обробників та теми прослуховування живуть у глобальному просторі імен.


  • Емпіричний доказ (запустіть цей скрипт оболонки, щоб підтвердити, що обробники виконуються в кінці гри - тут суперечливі коментарі та відповіді):

    #!/bin/bash
    
    mkdir -p ./sf831880/roles/role1
    mkdir -p ./sf831880/roles/role1/handlers
    mkdir -p ./sf831880/roles/role1/tasks
    mkdir -p ./sf831880/roles/role2
    mkdir -p ./sf831880/roles/role2/handlers
    mkdir -p ./sf831880/roles/role2/tasks
    
    cat >./sf831880/roles/role1/tasks/main.yml <<TASKS1_END
    ---
    - name: Always true in role1
      command: echo role1
      notify: handler1
    TASKS1_END
    
    cat >./sf831880/roles/role2/tasks/main.yml <<TASKS2_END
    ---
    - name: Always true in role2
      command: echo role2
      notify: handler2
    TASKS2_END
    
    cat >./sf831880/roles/role1/handlers/main.yml <<HANDLERS1_END
    ---
    - name: handler1
      debug:
        msg: "This is a handler in role1"
    HANDLERS1_END
    
    cat >./sf831880/roles/role2/handlers/main.yml <<HANDLERS2_END
    ---
    - name: handler2
      debug:
        msg: "This is a handler in role2"
    HANDLERS2_END
    
    cat >./sf831880/playbook.yml <<PLAYBOOK_END
    ---
    - hosts: localhost
      gather_facts: no
      connection: local
      roles:
        - role1
        - role2
      tasks:
        - debug:
            msg: "This is a task in a play"
    PLAYBOOK_END
    
    ansible-playbook ./sf831880/playbook.yml
    

    Результат:

    PLAY [localhost] ***************************************************************
    
    TASK [role1 : Always true in role1] ********************************************
    changed: [localhost]
    
    TASK [role2 : Always true in role2] ********************************************
    changed: [localhost]
    
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "msg": "This is a task in a play"
    }
    
    RUNNING HANDLER [role1 : handler1] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role1"
    }
    
    RUNNING HANDLER [role2 : handler2] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role2"
    
  • Відтворити модифіковано, щоб містити meta: flush_handlers:

    ---
    - hosts: localhost
      gather_facts: no
      connection: local
      roles:
        - role1
        - role2
      tasks:
        - meta: flush_handlers
        - debug:
            msg: "This is a task in a play"
    

    Результат:

    PLAY [localhost] ***************************************************************
    
    TASK [role1 : Always true in role1] ********************************************
    changed: [localhost]
    
    TASK [role2 : Always true in role2] ********************************************
    changed: [localhost]
    
    RUNNING HANDLER [role1 : handler1] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role1"
    }
    
    RUNNING HANDLER [role2 : handler2] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role2"
    }
    
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "msg": "This is a task in a play"
    

2

Обробники - це списки завдань, які насправді не відрізняються від звичайних завдань, на які посилається глобальне унікальне ім’я та повідомляються повідомленнями. Якщо нічого не сповістить обробник, він не запуститься. Незалежно від того, скільки завдань сповістить обробник, він запуститься лише один раз, після того, як всі завдання будуть виконані в певній програмі. відповідальний док

1) Обробники, які роблять те саме, повинні бути названі однаковими.
restart nginxЗАВЖДИ перезапускає nginx, не handler1іhandler2

2) Обробники запускаються в КІНЦІ всієї п’єси "Відтворити", яка охоплюється вашими секціями.

3) Я використовував би функції registerта whenфункції для завдань, які слід перезапустити, зауважте, що цей вар повинен мати із собою.

Джерело коду

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Play 1"
}

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role2 : Run if change in task c of role 1] *******************************
changed: [localhost]

TASK [role2 : Always true in role2] ********************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "This is a task in a play"
}

RUNNING HANDLER [role1 : handler] **********************************************
ok: [localhost] => {
    "msg": "This is a handler in role1"
}

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Play 2"
}

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role2 : Run if change in task c of role 1] *******************************
changed: [localhost]

TASK [role2 : Always true in role2] ********************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "This is a task in a play"
}

RUNNING HANDLER [role1 : handler] **********************************************
ok: [localhost] => {
    "msg": "This is a handler in role1"
}

PLAY RECAP *********************************************************************
localhost                  : ok=20   changed=14   unreachable=0    failed=0

Дуже багато способів виконати те саме завдання. Обробники були розроблені для запобігання повторного запуску одного і того ж процесу кілька разів, наприклад, декількох змін сервера nginx, який має веб-сайти, ssl certs та інші завдання, які потребують перезавантаження сервісу.


Ви цитуєте " виконати лише один раз, після того, як всі завдання виконані в певній грі ", а потім заявляєте щось зовсім інше: " запустіть завдання в кінці кожної ролі ". Ваше твердження також відрізняється від реальності.
techraf

ні, ти неправильно розумієш, якщо я 4 рази з мета закликаю одного і того ж обробника з ролі сервера. він працює лише один раз
Джейкоб Еванс

Питання зрозуміле: коли запускаються обробники? Не скільки разів вони бігають. І вони запускаються в кінці п'єси, а не в кінці ролі. Період. Ви є третьою особою, яка стверджує інакше, хоча ви зробили це після того, як я опублікував свою відповідь із прикладами, що показують, що ця претензія є помилковою.
techraf

і моя відповідь - використовувати завдання, а не обробники для предметів, які потрібно перезапустити в межах своєї ролі.
Джейкоб Еванс

@techraf там ти.
Джейкоб Еванс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.