2015-02-25 16 views
32

Tôi đang viết một cuốn Ansible và có một công việc mà sẽ luôn luôn thất bại trong chế độ kiểm tra:Bỏ qua tác vụ Ansible khi chạy ở chế độ kiểm tra?

hosts: ... 
tasks: 
    - set_fact: filename="{{ansible_date_time.iso8601}}" 
    - file: state=touch name={{filename}} 
    - file: state=link src={{filename}} dest=latest 

Trong chế độ kiểm tra, các tập tin sẽ không được tạo nên nhiệm vụ link sẽ luôn luôn thất bại. Có cách nào để đánh dấu một tác vụ như vậy bị bỏ qua khi chạy trong chế độ kiểm tra không? Một cái gì đó như:

- file: state=link src={{filename}} dest=latest 
    when: not check_mode 

Trả lời

27

Ansible 2.1 hỗ trợ ansible_check_mode biến kỳ diệu mà được thiết lập để True ở chế độ kiểm tra (official docs). Điều này có nghĩa bạn sẽ có thể để làm điều này:

- file: 
    state: link 
    src: '{{ filename }}' 
    dest: latest 
    when: not ansible_check_mode 

hoặc

- file: 
    state: link 
    src: '{{ filename }}' 
    dest: latest 
    ignore_errors: '{{ ansible_check_mode }}' 

nào bạn thích hơn.

+0

Tôi muốn chỉ ra rằng sự hiểu biết làm thế nào các mô-đun được sử dụng xử lý kiểm tra chế độ là quan trọng, hãy chắc chắn bạn hiểu những gì bạn đang bỏ qua trong khi thử nghiệm một playbook. Ngoài ra, khi sử dụng 'ignore_errors' một lần chạy playbook sẽ không thất bại nếu một biến không được xác định trong tác vụ, nó sẽ thất bại khi bỏ qua nhiệm vụ với' when: not ansible_check_mode'. Vì vậy, một lần nữa, điều quan trọng là phải hiểu những gì bạn đang cố gắng kiểm tra khi sửa đổi hành vi tác vụ trong chế độ kiểm tra. –

-1

Bạn có thể chỉ cần đặt when: filename is defined cho tất cả các tác vụ. Nhược điểm là, bạn không thể thất bại trong chế độ bình thường nếu filename sẽ không được xác định.

hosts: ... 
tasks: 
    - set_fact: filename="{{ansible_date_time.iso_8601}}" 
    - file: state=present name={{filename}} 
     when: filename is defined 
    - file: state=link src={{filename}} dest=latest 
     when: filename is defined 
+1

Tôi quan tâm hơn đến câu hỏi chung, chứ không phải trường hợp cụ thể này. – augurar

+0

Dù sao, điều này thậm chí không hoạt động đối với trường hợp cụ thể. Vấn đề là khi tác vụ tệp đầu tiên không được thực hiện, tác vụ tệp thứ hai không thành công vì mục tiêu liên kết không tồn tại. – augurar

2

tôi đã cùng một loại tình hình với unarchive:

unarchive lỗi trong chế độ kiểm tra nếu các kho lưu trữ không tồn tại và cũng nếu thư mục đích không tồn tại (cả hai thực hiện trong các bước trước đến unarchive). tôi giải quyết vấn đề này bằng cách thiết lập always_run: true các bước chuẩn bị để họ cũng được thực hiện trong chế độ kiểm tra:

--- 

- name: create artifact directory 
    file: {{ artifact_dest_dir }} state=directory 
    always_run: true 

- name: download artifact on the remote host 
    get_url: 
    url={{ artifact_url }} 
    dest={{ artifact_dest_dir }}/{{ artifact_filename }} 
    force=yes 
    always_run: true 

- name: unpack build artifact 
    unarchive: src={{ artifact_dest_dir }}/{{ artifact_filename }} 
      dest={{ artifact_dest_dir }} 
      copy=no 

Nó hoạt động trong trường hợp của tôi, nhưng với các thư mục phụ thuộc thời gian, điều này có thể không phải là một giải pháp tốt.

+2

Trong trường hợp sử dụng thực sự của tôi, bước tạo tệp là một hoạt động mà tôi chắc chắn không muốn chạy khi ở chế độ kiểm tra. – augurar

10

Đây là một loại dung dịch hacky:

hosts: ... 
tasks: 
    - command: /bin/true 
    register: noop_result 
    - set_fact: check_mode={{ noop_result|skipped }} 

    - set_fact: filename="{{ansible_date_time.iso_8601}}" 
    - file: state=touch name={{filename}} 
    - file: state=link src={{filename}} dest=latest 
    when: not check_mode 

Trong chế độ kiểm tra, nhiệm vụ command sẽ bị bỏ qua nên check_mode sẽ được thiết lập để true. Khi không ở chế độ kiểm tra, tác vụ sẽ luôn thành công và check_mode sẽ được đặt thành false.

+1

Cuối cùng họ đã làm điều đó: https://github.com/ansible/ansible/pull/14028 Có lẽ sẽ có bản phát hành ansible tiếp theo. –

+0

@SelivanovPavel Woo! – augurar

0

Mặc dù có một accepted answer đã có, tôi muốn đề cập đến các giải pháp được đề cập bởi augurar không làm việc cho tôi như tôi vẫn tiếp tục nhận được lỗi sau: skipped expects a dictionary

gì đã kết thúc làm việc đối với tôi là một giải pháp nhẹ ít hacky bằng cách chuyển và thêm biến với cờ -e như sau:

# On the terminal 
ansible-playbook [...] --check -e '{"check_mode":true}' 

# In the playbook or role 
when: [...] and not check_mode 

# In the proper `group_vars/` file 
check_mode: false 

Hãy cho tôi biết những gì các bạn nghĩ!

+0

Tôi tò mò là tại sao giải pháp của tôi không hiệu quả với bạn. Bạn đang sử dụng phiên bản Ansible nào? Điều gì xảy ra nếu bạn thêm một tác vụ 'debug: var = noop_result' trước' set_fact'? – augurar

-1

Các tùy chọn khác cần lưu ý là các thẻ hoặc tùy chọn --step.

Thẻ

tasks: 
    - set_fact: filename="{{ansible_date_time.iso8601}}" 
    - file: state=touch name={{filename}} 
    - file: state=link src={{filename}} dest=latest 
     tags: 
     - test 

Sau đó, lệnh Ansible để sử dụng sẽ là:

ansible-playbook example.yml --skip-tags "test" --check

Có những ví dụ khác cho bỏ qua/xác định các nhiệm vụ mà bạn muốn chạy sử dụng thẻ trong số Ansible tags documentation.

Start và Bước

Ansible cũng cung cấp một bước-by-step chế độ gỡ lỗi thoải mái với các tùy chọn --step.

Chạy ansible-playbook example.yml --step --check tương tác sẽ đưa bạn qua từng nhiệm vụ trong playbook

của bạn Từ "Bắt đầu và Bước" của Ansible documentation:

This will cause ansible to stop on each task, and ask if it should execute that task. Say you had a task called “configure ssh”, the playbook run will stop and ask:

Perform task: configure ssh (y/n/c):

Answering “y” will execute the task, answering “n” will skip the task, and answering “c” will continue executing all the remaining tasks without asking.

Các vấn đề liên quan