Các trình xử lý Ansible được xác định trong các vai trò được chạy sau toàn bộ playbook hay vai trò?


12

Tôi đang chạy Ansible 2.0 và tôi chỉ có thể chạy nó, nhưng tôi cũng có thể bị lừa để tin vào điều gì đó không đúng với các thử nghiệm thực nghiệm của tôi và tôi không thể tìm thấy tài liệu nào để cho tôi biết khi nào cần xử lý.

Nếu các trình xử lý không chạy khi kết thúc nhiệm vụ thì đây là câu hỏi hóc búa của tôi. Tôi đã có một playbook với 5 vai trò trong đó, tôi muốn thêm 6 vai trò vào cuối cần phải xử lý vai trò thứ 4 trước khi nó có thể bắt đầu.

Có cách nào để chạy Ansible dựa vào trình xử lý được hoàn thành (nghĩa là một vai trò đã hoàn thành) trước khi làm việc khác hoặc tôi sử dụng trình xử lý sai?

Câu trả lời:


15

Xử lý được thực thi:

  • vào cuối vở kịch (không phải vở kịch)
  • thực hiện meta: flush_handlersnhiệm vụ

Vì vậy, " để thêm 6 vai trò vào cuối cần có người xử lý vai trò thứ 4 " bạn cần:

  • hoặc để phân chia vai trò phân chia thành các vở kịch riêng biệt;
  • hoặc thêm một nhiệm vụ meta và bao gồm vai trò thứ 6 với include_rolemô-đun :

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

Đối với trường hợp sử dụng của bạn, tôi đề xuất phương pháp đầu tiên vì include_rolemô-đun vẫn còn rất mới và có những điểm kỳ quặc khi sử dụng nó (xem câu hỏi này trên SO ).


Hơn nữa, xin lưu ý rằng tên của người xử lý và cuộc gọi nghe là toàn cầu, vì vậy hai người xử lý trong các vai trò riêng biệt sẽ xung đột nếu họ có cùng tên và cả hai vai trò được gán trong một lần chơi. (ref. Handlers: Chạy các hoạt động khi thay đổi )

Trình xử lý [] được tham chiếu bằng một tên duy nhất trên toàn cầu và được thông báo bởi các thông báo. [] một trình xử lý, nó sẽ chỉ chạy một lần, sau khi tất cả các nhiệm vụ hoàn thành trong một lần chơi cụ thể.

Tên xử lý và nghe chủ đề sống trong một không gian tên toàn cầu.


  • Bằng chứng thực nghiệm (chạy tập lệnh shell này để xác nhận các trình xử lý được thực thi vào cuối vở kịch - có những bình luận và câu trả lời trái ngược nhau ở đây):

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

    Kết quả:

    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"
    
  • Chơi sửa đổi để chứa 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"
    

    Kết quả:

    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

Trình xử lý là danh sách các tác vụ, không thực sự khác biệt so với các tác vụ thông thường, được tham chiếu bằng một tên duy nhất trên toàn cầu và được thông báo bởi các thông báo. Nếu không có gì thông báo cho một trình xử lý, nó sẽ không chạy. Bất kể có bao nhiêu nhiệm vụ thông báo cho một người xử lý, nó sẽ chỉ chạy một lần, sau khi tất cả các nhiệm vụ hoàn thành trong một lần chơi cụ thể. tài liệu ansible

1) Người xử lý làm điều tương tự nên được đặt tên giống nhau.
restart nginxLUÔN LUÔN khởi động lại nginx, không handler1handler2

2) Trình xử lý được chạy ở KẾT THÚC của toàn bộ "Phát" một lần phát trong phạm vi các phần của bạn.

3) Tôi sẽ sử dụng registervà các whenchức năng cho các nhiệm vụ nên được khởi động lại, lưu ý var này sẽ mang theo bên mình.

Mã nguồn

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

Rất nhiều cách để làm cùng một nhiệm vụ. Trình xử lý được thiết kế để ngăn khởi động lại cùng một quy trình nhiều lần, chẳng hạn như nhiều thay đổi đối với máy chủ nginx có trang web, ssl certs và các tác vụ khác cần khởi động lại dịch vụ.


Bạn đang trích dẫn " chỉ chạy một lần, sau khi tất cả các nhiệm vụ hoàn thành trong một lần chơi cụ thể " và sau đó yêu cầu một thứ hoàn toàn khác " chạy một nhiệm vụ ở cuối mỗi vai trò ". Yêu cầu của bạn cũng khác với thực tế.
techraf

không bạn hiểu lầm, nếu tôi gọi trình xử lý tương tự từ vai trò máy chủ 4 lần từ meta. nó chỉ chạy một lần
Jacob Evans

Câu hỏi rất rõ ràng: khi nào các trình xử lý chạy? Không phải họ chạy bao nhiêu lần. Và họ được chạy ở cuối vở kịch, không phải ở cuối vai trò. Giai đoạn = Stage. Bạn là người thứ ba tuyên bố khác, mặc dù bạn đã làm điều đó sau khi tôi đăng câu trả lời của mình với các ví dụ cho thấy tuyên bố này là sai.
techraf

và câu trả lời của tôi là, sử dụng các tác vụ không phải xử lý cho các mục phải được khởi động lại trong vai trò của chúng.
Jacob Evans

@Techraf có bạn đây.
Jacob Evans
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.