Определены ли обработчики Ansible в ролях после всей пьесы или роли?


13

Я использую Ansible 2.0, и я мог бы просто запустить это, но я также мог бы обмануть себя, полагая, что мои эмпирические тесты не верят чему-то неверному, и я не могу найти никакой документации, чтобы сказать мне, когда предполагается запускать обработчики.

Если обработчики не выполняются в конце их задач, это моя загадка. У меня есть книга с 5 ролями, и я хочу добавить 6 ролей к концу, которым нужно завершить обработчики 4 роли, прежде чем она сможет начаться.

Есть ли способ запустить Ansible, чтобы положиться на завершение обработчика (то есть полностью завершенную роль), прежде чем делать что-то еще, или я неправильно использую обработчики?

Ответы:


17

Обработчики выполнены:

  • в конце игры (не playbook)
  • на выполнение meta: flush_handlersзадачи

Итак, чтобы «добавить 6 роль в конец, который должен иметь обработчики 4-й роли », вам нужно:

  • либо разделить распределение ролей на отдельные пьесы;
  • или добавьте мета-задачу и включите шестую роль с include_roleмодулем :

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

Для вашего случая использования, я бы предложил первый метод, так как include_roleмодуль все еще очень свежий, и при его использовании есть причуды (см. Этот вопрос по SO ).


Кроме того, обратите внимание, что имена обработчиков и вызовы прослушивания являются глобальными, поэтому два обработчика в разных ролях будут конфликтовать, если у них одинаковое имя и обе роли были назначены в одной игре. (см. Обработчики: выполнение операций при изменении )

На обработчики [] ссылается глобально уникальное имя, и они уведомляются уведомителями. [] обработчик, он будет запущен только один раз, после того, как все задачи завершены в конкретной игре.

Имена обработчиков и темы прослушивания живут в глобальном пространстве имен.


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

    #!/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-сертификатами и другие задачи, требующие перезапуска службы.


Вы цитируете « выполнить только один раз, после того как все задачи завершены в определенной игре », а затем заявляете о чем-то совершенно ином « запускаете задачу в конце каждой роли ». Ваша претензия также отличается от реальности.
Techraf

нет, вы не правильно поняли, если я вызову один и тот же обработчик из роли сервера 4 раза из мета. он запускается только один раз
Джейкоб Эванс

Вопрос ясен: когда запускаются обработчики? Не сколько раз они запускаются. И они запускаются в конце пьесы, а не в конце роли. Период. Вы являетесь третьим лицом, утверждающим обратное, даже если вы сделали это после того, как я опубликовал свой ответ с примерами, показывающими, что это утверждение неверно.
techraf

и мой ответ: используйте задачи, а не обработчики для элементов, которые должны быть перезапущены в рамках их роли.
Джейкоб Эванс

@ techraf вот ты где.
Джейкоб Эванс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.