Thay đổi giá trị mặc định có thể thay đổi theo một điều kiện


16

Có thể thay đổi một giá trị mặc định của biến vai trò theo một số điều kiện (tức là giá trị của một biến khác)?

Chi tiết

Tôi có hai biến liên quan cho một lệnh envcomposer_opts.

Nếu cả hai được để mặc định ( env = "prod"composer_opts = "--no-dev"), mọi thứ đều ổn.

Nếu tôi thay đổi envthành dev, mặc định cho cái khác sẽ phá vỡ lệnh của tôi, vì vậy tôi luôn cần đặt cả hai. Có thể tránh điều này bằng cách đặt giá trị mặc định có điều kiện với tập lệnh tùy chỉnh / nếu?

Quan trọng: Tôi không muốn luôn đặt composer_optsgiá trị theo envgiá trị. Tôi chỉ muốn đặt nó nếu nó chưa được đặt (tức là giá trị mặc định động).

Mã giả

Tôi muốn làm một cái gì đó như thế này (mã sau đây không hợp lệ, chỉ là mã giả để thể hiện nhu cầu của tôi)

---
# defaults/main.yml

env: prod
composer_opts: 
    when: "{{env}}" = 'prod'
        '--no-dev --optimize-autoloader --no-interaction'
    when: "{{env}}" = 'dev'
        '' 

Câu trả lời:


12

Tôi đề nghị giải pháp này:

---
 - set_fact:
     composer_opts: ""
   when: "{{env}}" == 'dev'

Nó sẽ đặt composer_optsbiến thành chuỗi ""khi biến envbằng ' dev'.

Dưới đây là ví dụ về Playbook dựa trên câu hỏi cập nhật:

$ cat test.yml

---
- hosts: 127.0.0.1
  connection: local
  tasks:
  - set_fact:
      composer_opts: "{% if env == 'prod' %} '--no-dev --optimize-autoloader --no-interaction' {% else %} '' {% endif %}"

  - debug: var=composer_opts

Đầu ra mẫu:

sudo ansible-playbook test.yml -e env=dev

PLAY [127.0.0.1] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [set_fact ] ************************************************************* 
ok: [127.0.0.1]

TASK: [debug var="{{composer_opts}}"] ***************************************** 
ok: [127.0.0.1] => {
    "var": {
        " '' ": " '' "
    }
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0   


sudo ansible-playbook test.yml -e env=prod

PLAY [127.0.0.1] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [set_fact ] ************************************************************* 
ok: [127.0.0.1]

TASK: [debug var="{{composer_opts}}"] ***************************************** 
ok: [127.0.0.1] => {
    "var": {
        " '--no-dev --optimize-autoloader --no-interaction' ": " '--no-dev --optimize-autoloader --no-interaction' "
    }
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0   

1
Đây là một phần của giải pháp. Nó sẽ luôn được đặt thành composer_optschuỗi trống khi env"dev", ghi đè bất kỳ giá trị thực nào được đặt. Tôi nghĩ rằng điều kiện nên được mở rộng như thế này : when: "{{env}}" == 'dev' and "{{composer_opts}}" is undefined. Nó có vẻ tốt không? Bạn có thể udpate câu hỏi của bạn cho phù hợp?
Francesco Abeni

composer_opts sẽ được xác định vì nó có giá trị mặc định. Bạn cần một biểu thức khác để giải quyết nhiệm vụ của bạn. Ví dụ: biến custom_composer_opts.
Navern

Hãy giải thích với mã giả những gì bạn muốn làm. Tôi sẽ cập nhật câu trả lời của tôi cho phù hợp.
Navern

Tôi đã cập nhật câu hỏi của mình với lời giải thích bổ sung và mẫu mã giả. Cảm ơn bạn.
Francesco Abeni

Tôi đã cập nhật câu trả lời của tôi. Kiểm tra nó. Tôi tin rằng tôi đã hiểu những gì bạn cần.
Navern

4

Trong khi câu trả lời của @ Navern hoạt động, tôi thấy ký hiệu Jinja2 được nhúng ( "{% if env == 'prod' %} ...) cực kỳ dễ bị ký hiệu và do đó khá dễ vỡ. Ví dụ: khi gói dòng trong câu hỏi để dễ đọc hơn, chẳng hạn như trong mã chưa được kiểm tra này :

composer_opts: >
               "{% if env == 'prod' %}
                   '--no-dev --optimize-autoloader --no-interaction'
                {% else %}
                   ''
                {% endif %}"

Tôi đã kết thúc với kết quả bất ngờ, chẳng hạn như khoảng trắng bổ sung hoặc \ntrong composer_opts.

Cách tiếp cận tôi sử dụng rất nhiều, nhưng cũng ổn định hơn:

- name: set composer_opts for dev env
  set_fact:
     composer_opts: ''
     when: "{{env}}" == 'dev'

- name: set composer_opts for prod env
  set_fact:
     composer_opts: '--no-dev --optimize-autoloader --no-interaction'
     when: "{{env}}" == 'prod'

Tôi cũng thấy bài viết trên blog này rất hữu ích, về cơ bản cũng theo cách tiếp cận tương tự.


@sec nếu bạn sử dụng |thay vì >bạn có thể không gặp vấn đề về khoảng trắng. (hoặc bạn sẽ nhận được nhiều hơn về nó LOL)
Michael

@sec Sử dụng '> -' và kiểm tra thông số kỹ thuật ansible. Nó có nhiều tùy chọn để thao tác chính xác các chuỗi đa dòng. yaml-multiline.info Lưu ý, đặc biệt, chỉ báo chomping khối.
DylanYoung

Lưu ý rằng giải pháp này cũng có vấn đề ưu tiên. Một thực tế không phải là một mặc định.
DylanYoung

2

Ansible set_fact dựa trên điều kiện trong một lớp lót:

- name: "set composer_opts based on environment"
  set_fact:
     composer_opts:  "{{ '--no-dev --optimize-autoloader --no-interaction' if (env == 'prod') else '' }}"

Các vấn đề ưu tiên tương tự như các giải pháp khác (thực tế không phải là mặc định), tuy nhiên, nếu bạn đặt quyền chính xác này trong tệp defaults.yml của mình, giải pháp này sẽ hoạt động. Nó trở nên thực sự xấu xí rất nhanh nếu bạn có một số mặc định phụ thuộc vào điều kiện
DylanYoung
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.