เปลี่ยนค่าเริ่มต้นของการเปลี่ยนแปลงได้ตามเงื่อนไข


16

เป็นไปได้หรือไม่ที่จะเปลี่ยนค่าเริ่มต้นของตัวแปรบทบาทตามเงื่อนไขบางประการ (เช่นค่าของตัวแปรอื่น)

รายละเอียด

ฉันมีสองตัวแปรที่เกี่ยวข้องสำหรับคำสั่งและenvcomposer_opts

หากทั้งคู่ถูกปล่อยไว้ที่ค่าเริ่มต้น ( env = "prod"และcomposer_opts = "--no-dev") ทุกอย่างก็โอเค

ถ้าฉันเปลี่ยนenvไปdevเริ่มต้นสำหรับคนอื่น ๆ จะทำลายคำสั่งของฉันดังนั้นฉันมักจะต้องตั้งค่าทั้ง เป็นไปได้ไหมที่จะหลีกเลี่ยงปัญหานี้โดยการตั้งค่าเริ่มต้นตามเงื่อนไขด้วยสคริปต์ที่กำหนดเอง / หาก

สำคัญ: ฉันไม่ต้องการที่จะเสมอตั้งcomposer_optsค่าตามenvค่า ฉันต้องการตั้งค่าเฉพาะเมื่อยังไม่ได้ตั้งค่า (เช่นค่าเริ่มต้นแบบไดนามิก)

pseudocode

ฉันต้องการทำอะไรเช่นนี้ (รหัสต่อไปนี้ไม่ถูกต้องเพียงรหัสเทียมเพื่อแสดงความต้องการของฉัน)

---
# defaults/main.yml

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

คำตอบ:


12

ฉันแนะนำวิธีแก้ปัญหานี้:

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

มันจะตั้งค่าcomposer_optsตัวแปรเป็นสตริง""เมื่อตัวแปรenvเท่ากับ ' dev'

นี่คือตัวอย่างของ playbook ตามคำถามที่อัปเดต:

$ 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

ตัวอย่างผลลัพธ์:

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
นี่เป็นส่วนหนึ่งของการแก้ปัญหา มันจะถูกตั้งค่าcomposer_optsเป็นสตริงว่างเสมอเมื่อenvเป็น "dev" เขียนทับชุดค่าจริงใด ๆ when: "{{env}}" == 'dev' and "{{composer_opts}}" is undefinedผมคิดว่ามีเงื่อนไขควรจะขยายเช่นนี้ มันดูดีหรือไม่? คุณสามารถ udpate คำถามของคุณตาม?
Francesco Abeni

composer_opts จะถูกกำหนดเพราะมันมีค่าเริ่มต้น คุณต้องการนิพจน์อื่นเพื่อแก้ไขงานของคุณ ตัวอย่างเช่นตัวแปร custom_composer_opts
Navern

โปรดทำอย่างละเอียดด้วย pseudocode คุณต้องการทำอะไร ฉันจะอัปเดตคำตอบของฉันตาม
Navern

ฉันได้อัปเดตคำถามของฉันพร้อมคำอธิบายเพิ่มเติมและตัวอย่างรหัสเทียม ขอขอบคุณ.
Francesco Abeni

ฉันได้อัพเดตคำตอบแล้ว ตรวจสอบ. ฉันเชื่อว่าฉันเข้าใจสิ่งที่คุณต้องการ
Navern

4

ในขณะที่คำตอบของ @ Navernทำงานได้ฉันพบว่าสัญลักษณ์ Jinja2 แบบฝังตัว ( "{% if env == 'prod' %} ...) นั้นไวต่อสัญกรณ์อย่างมากและค่อนข้างบอบบาง ตัวอย่างเช่นเมื่อตัดสายในคำถามสำหรับการอ่านที่ดีขึ้นเช่นนี้รหัสยังไม่ทดลอง :

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

ฉันสิ้นสุดขึ้นกับผลที่ไม่คาดคิดเช่นช่องว่างเพิ่มเติมหรือใน\ncomposer_opts

วิธีที่ฉันใช้นั้นโง่มาก แต่ก็มีความเสถียรมากกว่า:

- 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'

ฉันยังพบว่าการโพสต์บล็อกนี้มีประโยชน์ซึ่งเป็นไปตามแนวทางเดียวกัน


@sec หากคุณใช้|แทนคุณ>อาจไม่มีปัญหาช่องว่าง (หรือคุณจะได้รับมากกว่านี้ LOL)
Michael

@sec Use '> -' และตรวจสอบข้อมูลจำเพาะ ansible มันมีตัวเลือกมากมายสำหรับการจัดการสตริงหลายบรรทัดอย่างถูกต้อง yaml-multiline.info หมายเหตุโดยเฉพาะอย่างยิ่งตัวบ่งชี้การ chomping บล็อก
DylanYoung

โปรดทราบว่าวิธีนี้ยังมีปัญหาที่สำคัญกว่า ความจริงไม่ใช่ค่าเริ่มต้น
DylanYoung

2

Ansible set_fact ขึ้นอยู่กับสภาพในหนึ่งซับ:

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

ปัญหาที่มาก่อนเช่นเดียวกับวิธีแก้ปัญหาอื่น ๆ (ความจริงไม่ใช่ค่าเริ่มต้น) อย่างไรก็ตามหากคุณใส่เงื่อนไขนี้ไว้ในไฟล์ มันจะเร็วขึ้นอย่างน่าเกลียดจริงหากคุณมีค่าเริ่มต้นจำนวนมากขึ้นอยู่กับเงื่อนไข
DylanYoung
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.