Os manipuladores Ansible definidos nas funções foram executados após todo o manual ou a função?

11

Estou usando o Ansible 2.0, e posso executar isso, mas também posso acreditar que algo não é verdade com meus testes empíricos e não consigo encontrar nenhuma documentação para dizer quando os manipuladores devem ser executado.

Se os manipuladores não forem executados no final de suas tarefas, esse é o meu enigma. Eu tenho um playbook com cinco funções, eu quero adicionar um papel de 6 ao final que precisa ter os manipuladores da quarta função concluída antes que ele possa começar.

Existe alguma maneira de executar o Ansible para confiar em um manipulador sendo concluído (ou seja, uma função sendo completamente concluída) antes de fazer outra coisa ou estou usando manipuladores errado?

    
por Peter Turner 10.02.2017 / 19:18

2 respostas

12

Os manipuladores são executados:

  • no final de um jogo (não playbook)
  • ao executar a tarefa meta: flush_handlers

Então " para adicionar uma função 6 ao final que precisa ter os manipuladores da 4ª função " você precisa:

  • para dividir a atribuição de função em reproduções separadas;
  • ou adicione uma meta tarefa e inclua a 6ª função com o include_role module :

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

Para o seu caso de uso, sugiro o primeiro método, pois o módulo include_role ainda é muito novo e há peculiaridades ao usá-lo (consulte esta questão em SO ).

Além disso, observe que os nomes dos manipuladores e as chamadas de escuta são globais, portanto, dois manipuladores em funções separadas estarão em conflito se tiverem o mesmo nome e as duas funções tiverem sido atribuídas em uma única reprodução. (ref. Manipuladores: executando operações em mudança )

Handlers [ ] are referenced by a globally unique name, and are notified by notifiers. [ ] a handler, it will run only once, after all of the tasks complete in a particular play.

Handler names and listen topics live in a global namespace.

  • Prova empírica (execute este shell script para confirmar que os manipuladores são executados no final da peça - houve comentários e respostas contraditórios aqui):

    #!/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
    

    Resultado:

    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"
    
  • Reproduzir modificado para conter 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"
    

    O resultado:

    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"
    
por 11.02.2017 / 00:59
2

Handlers are lists of tasks, not really any different from regular tasks, that are referenced by a globally unique name, and are notified by notifiers. If nothing notifies a handler, it will not run. Regardless of how many tasks notify a handler, it will run only once, after all of the tasks complete in a particular play. ansible doc

1) Os manipuladores que fazem a mesma coisa devem ter o mesmo nome.
restart nginx SEMPRE reinicia nginx, não handler1 e handler2

2) Os manipuladores são executados no final de todo o "Play" um jogo com escopo para suas seções.

3) Eu usaria o register e when funções para tarefas que devem ser reiniciadas, note que este var deve carregar com você.

Código de origem

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

Muitas maneiras de fazer a mesma tarefa. Os manipuladores foram projetados para impedir a reinicialização do mesmo processo várias vezes, como várias alterações em um servidor nginx que possui sites, certificados SSL e outras tarefas que precisam de reinicialização de serviço.

    
por 11.02.2017 / 06:19

Tags