17 votes

Les gestionnaires Ansible définis dans les rôles sont-ils exécutés après le playbook entier ou le rôle ?

J'exécute Ansible 2.0, et je pourrais simplement exécuter ceci, mais je pourrais aussi être trompé en croyant quelque chose qui n'est pas vrai par mes tests empiriques et je ne peux trouver aucune documentation pour me dire quand les handlers sont censés être exécutés.

Si les gestionnaires ne sont pas exécutés à la fin de leurs tâches, c'est là mon casse-tête. J'ai un livre de jeu avec 5 rôles, je veux ajouter un 6ème rôle à la fin qui doit avoir les gestionnaires du 4ème rôle terminés avant de pouvoir commencer.

Existe-t-il un moyen d'exécuter Ansible pour qu'il compte sur l'achèvement d'un gestionnaire (c.-à-d. qu'un rôle soit complètement achevé) avant de faire autre chose ou est-ce que j'utilise mal les gestionnaires ?

21voto

craigforster Points 1033

Les gestionnaires sont exécutés :

  • à la fin d'un jeu (pas du playbook)
  • lors de l'exécution de la meta: flush_handlers tâche

Donc " pour ajouter un rôle 6 à la fin qui doit avoir les gestionnaires du rôle 4. " dont vous avez besoin :

  • soit de diviser l'attribution des rôles en plusieurs pièces distinctes ;
  • ou ajouter une méta tâche et inclure le 6ème rôle avec include_role module :

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

Pour votre cas d'utilisation, je suggérerais la première méthode comme le include_role est encore très récent et il y a des bizarreries lors de son utilisation (cf. cette question sur le SO ).


De plus, veuillez noter que les noms des manipulateurs et les appels d'écoute sont globaux, donc deux manipulateurs dans des rôles distincts seront en conflit s'ils ont le même nom et que les deux rôles ont été attribués dans une seule pièce. (réf. Manipulateurs : Exécution des opérations sur les changements )

Les gestionnaires [ ] sont référencés par un nom unique au niveau mondial, et sont notifiés par des notificateurs. Si vous utilisez un gestionnaire [ ], il ne s'exécutera qu'une seule fois, après que toutes les tâches se soient achevées dans un jeu particulier.

Les noms des gestionnaires et les sujets d'écoute se trouvent dans un espace de noms global.


  • Preuve empirique (exécuter ce Shell Shell pour confirmer que les handlers sont exécutés à la fin de la pièce - il y avait des commentaires et des réponses contradictoires ici) :

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

    Résultat :

    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"
  • Jeu modifié pour contenir 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"

    Le résultat :

    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"

4voto

Jacob Evans Points 7455

Les gestionnaires sont des listes de tâches, qui ne sont pas vraiment différentes des tâches ordinaires. tâches ordinaires, qui sont référencées par un nom unique au niveau mondial, et sont notifiées par des notificateurs. Si rien ne notifie un gestionnaire, il ne sera pas exécuté. Quel que soit le nombre de tâches qui notifient un gestionnaire, celui-ci ne sera exécuté qu'une seule fois, après que toutes les tâches se soient terminées dans un jeu particulier. doc ansible

1) Les gestionnaires qui font la même chose doivent avoir le même nom.
restart nginx redémarre TOUJOURS nginx, et non pas handler1 y handler2

2) Les manipulateurs sont exécutés à la FIN de l'ensemble du "jeu", un jeu adapté à vos sections.

3) J'utiliserais le register y when pour les tâches qui doivent être redémarrées, notez que cette var doit être emportée avec vous.

Code Source

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

Il existe de nombreuses façons d'effectuer la même tâche. Les gestionnaires ont été conçus pour éviter de redémarrer le même processus plusieurs fois, comme dans le cas de modifications multiples d'un serveur nginx qui a des sites web, des certs ssl et d'autres tâches qui nécessitent des redémarrages de service.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X