Les gestionnaires Ansible définis dans les rôles sont-ils exécutés après l'intégralité du manuel ou du rôle?


13

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

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

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

Réponses:


17

Les gestionnaires sont exécutés:

  • à la fin d'une pièce (pas playbook)
  • sur l'exécution de la meta: flush_handlerstâche

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

  • soit de diviser l'attribution du rôle en jeux séparés;
  • ou ajoutez une méta-tâche et incluez le 6ème rôle avec le include_rolemodule :

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

Pour votre cas d'utilisation, je suggère la première méthode car le include_rolemodule est encore très frais et il y a des bizarreries lors de son utilisation (voir cette question sur SO ).


De plus, veuillez noter que les noms des gestionnaires et les appels d'écoute sont globaux, donc deux gestionnaires dans des rôles distincts seront en conflit s'ils avaient le même nom et que les deux rôles ont été attribués en une seule fois. (réf. Gestionnaires: exécution d'opérations sur changement )

Les gestionnaires [] sont référencés par un nom globalement unique et sont notifiés par les notifiants. [] un gestionnaire, il ne s'exécutera qu'une seule fois, une fois toutes les tâches terminées dans un jeu particulier.

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


  • Preuve empirique (exécutez ce script shell pour confirmer que les gestionnaires 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"
    
  • Jouer 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"
    

2

Les gestionnaires sont des listes de tâches, qui ne diffèrent pas vraiment des tâches normales, qui sont référencées par un nom globalement unique et qui sont notifiées par les notifiants. Si rien n'informe un gestionnaire, il ne s'exécutera pas. Quel que soit le nombre de tâches notifiées à un gestionnaire, il ne s'exécutera qu'une seule fois, une fois toutes les tâches terminées dans un jeu particulier. doc ansible

1) Les gestionnaires qui font la même chose doivent être nommés de la même manière.
restart nginxTOUJOURS redémarre nginx, pas handler1ethandler2

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

3) J'utiliserais les fonctions registeret whenpour les tâches qui devraient être redémarrées, notez que cette var doit être avec vous.

Source du code

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

Beaucoup de façons de faire la même tâche. Les gestionnaires ont été conçus pour empêcher le redémarrage du même processus plusieurs fois, comme les modifications multiples d'un serveur nginx qui a des sites Web, des certificats SSL et d'autres tâches qui nécessitent des redémarrages de service.


Vous citez " exécuter une seule fois, après que toutes les tâches soient terminées dans un jeu particulier " et revendiquez ensuite quelque chose de complètement différent " exécuter une tâche à la fin de chaque rôle ". Votre revendication est également différente de la réalité.
techraf

non vous vous méprenez, si j'appelle le même gestionnaire à partir du rôle serveur 4 fois à partir de méta. il ne fonctionne qu'une seule fois
Jacob Evans

La question est claire: quand les gestionnaires sont-ils exécutés? Pas combien de fois ils sont exécutés. Et ils sont exécutés à la fin d'une pièce, pas à la fin d'un rôle. Période. Vous êtes une troisième personne affirmant le contraire, même si vous l'avez fait après avoir posté ma réponse avec des exemples montrant que cette affirmation est fausse.
techraf

et ma réponse est, utilisez des tâches et non des gestionnaires pour les éléments qui doivent être redémarrés dans leur rôle.
Jacob Evans

@techraf vous y êtes.
Jacob Evans
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.