Назад | Перейти на главную страницу

Определены ли обработчики Ansible в ролях, выполняемых после всего сценария или роли?

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

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

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

Обработчики выполняются:

  • в конце пьесы (не пьесы)
  • по выполнению 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"
    

Обработчики - это списки задач, которые на самом деле не отличаются от обычных задач, на которые ссылаются глобально уникальное имя и которые уведомляются уведомителями. Если ничего не уведомляет обработчик, он не будет запущен. Независимо от того, сколько задач уведомляет обработчик, он будет запущен только один раз после того, как все задачи будут выполнены в конкретной игре. доступный документ

1) Обработчики, которые делают одно и то же, должны называться одинаково.
restart nginx ВСЕГДА перезапускает nginx, а не handler1 и handler2

2) Обработчики запускаются в КОНЦЕ всего "Play", ограниченного вашими разделами.

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