역할에 정의 된 Ansible 처리기가 전체 플레이 북 또는 역할 이후에 실행 되었습니까?


13

나는 Ansible 2.0을 실행 중이며 이것을 실행할 수는 있지만 경험적 테스트에서 사실이 아닌 것을 믿도록 속일 수 있으며 핸들러가 실행될 시점을 알려주는 문서를 찾을 수 없습니다.

처리기가 끝날 때 처리기가 실행되지 않으면 이것이 수수께끼입니다. 나는 5 개의 역할을 가진 플레이 북을 가지고 있고, 마지막에 6 번째 역할을 추가하여 시작하기 전에 4 번째 역할의 처리기를 완료해야합니다.

Ansible을 실행하여 다른 작업을 수행하기 전에 완료된 핸들러 (즉, 역할이 완전히 완료된)에 의존하거나 핸들러를 잘못 사용하는 방법이 있습니까?

답변:


17

핸들러가 실행됩니다.

  • 플레이가 끝날 때 (플레이 북이 아님)
  • meta: flush_handlers작업 을 실행할 때

" 네 번째 역할의 핸들러가 필요한 끝에 6 가지 역할을 추가하려면 "

  • 역할 할당을 별도의 연극으로 나누거나;
  • 또는 메타 작업을 추가하고 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에하지 handler1handler2

2) 핸들러는 전체 "플레이"의 끝에서 섹션으로 범위가 지정된 플레이에서 실행됩니다.

3) 다시 시작 해야하는 작업에 대해 registerwhen기능을 사용합니다.이 var은 함께 수행해야합니다.

코드 소스

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

동일한 작업을 수행하는 많은 방법. 처리기는 웹 사이트, SSL 인증서 및 서비스를 다시 시작해야하는 기타 작업이있는 nginx 서버에 대한 여러 변경 사항과 같이 동일한 프로세스를 여러 번 다시 시작하지 않도록 설계되었습니다.


" 모든 작업이 특정 플레이에서 완료된 후 한 번만 실행 "을 인용 다음 완전히 다른 무언가를 주장합니다 . " 모든 역할의 끝에서 작업을 실행 " 귀하의 주장은 또한 현실과 다릅니다.
techraf

서버 역할에서 동일한 핸들러를 메타에서 4 번 호출하면 오해하지 않습니다. 그것은 한 번만 실행
Jacob Evans

문제는 분명합니다. 핸들러는 언제 실행됩니까? 그들이 몇 번이나 실행되지는 않습니다. 그리고 그들은 역할의 끝이 아니라 연극의 끝에서 실행됩니다. 기간. 이 주장이 허위임을 보여주는 예를 들어 내 답변을 게시 한 후에 했음에도 불구하고 귀하는 달리 주장하는 세 번째 사람입니다.
techraf

그리고 내 대답은 역할 내에서 다시 시작 해야하는 항목에 대해 처리기가 아닌 작업을 사용하는 것입니다.
Jacob Evans

@ techraf 거기 있습니다.
Jacob Evans
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.