एक स्थिति के अनुसार परिवर्तनशील डिफ़ॉल्ट मान


16

क्या किसी स्थिति (यानी दूसरे चर के मूल्य) के अनुसार एक भूमिका चर डिफ़ॉल्ट मान बदलना संभव है?

विवरण

मेरे पास एक कमांड के लिए दो संबंधित चर हैं, envऔर composer_opts

यदि दोनों को डिफ़ॉल्ट ( env = "prod"और composer_opts = "--no-dev") पर छोड़ दिया जाए तो सब कुछ ठीक है।

अगर मैं बदल envजाता devहूं, तो दूसरे के लिए डिफ़ॉल्ट मेरी कमांड को तोड़ देगा, इसलिए मुझे हमेशा दोनों को सेट करने की आवश्यकता है। क्या कस्टम स्क्रिप्ट / / के साथ सशर्त डिफ़ॉल्ट मान सेट करके इससे बचना संभव होगा?

महत्वपूर्ण: मैं हमेशाcomposer_opts मूल्य के अनुसार मूल्य निर्धारित नहीं करना चाहता env। मैं इसे तभी सेट करना चाहता हूं जब यह पहले से सेट न हो (यानी डायनेमिक डिफ़ॉल्ट मान)।

स्यूडोकोड

मैं ऐसा कुछ करना चाहूंगा (निम्नलिखित कोड मान्य नहीं है, बस अपनी आवश्यकता व्यक्त करने के लिए छद्म कोड)

---
# 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' के बराबर होगा ।

अपडेट किए गए प्रश्न के आधार पर यहां प्लेबुक का उदाहरण दिया गया है:

$ 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, किसी भी वास्तविक मूल्य सेट को ओवरराइट कर रहा है। मुझे लगता है कि सशर्त को इस तरह बढ़ाया जाना चाहिए when: "{{env}}" == 'dev' and "{{composer_opts}}" is undefined:। क्या यह अच्छा लग रहा है? क्या आप अपने प्रश्न को उसके अनुसार बता सकते हैं?
फ्रांसेस्को अबेनी

composer_opts को परिभाषित किया जाएगा क्योंकि इसका डिफ़ॉल्ट मान है। अपने कार्य को हल करने के लिए आपको एक और अभिव्यक्ति की आवश्यकता है। उदाहरण के लिए चर custom_composer_opts।
Navern

कृपया स्यूडोकोड के साथ विस्तृत करें कि आप क्या करना चाहते हैं। मैं अपने उत्तर को तदनुसार अपडेट करूंगा।
Navern

मैंने अपने प्रश्न को अतिरिक्त स्पष्टीकरण और स्यूडोकोड नमूना के साथ अद्यतन किया है। धन्यवाद।
फ्रांसेस्को एबेनी

मैंने अपना उत्तर अपडेट कर दिया है। इसे जाँचे। मेरा मानना ​​है कि मुझे समझ में आया कि आपको क्या चाहिए।
Navern

4

जबकि @ Navern का जवाब काम नहीं करता है, मैंने एम्बेडेड Jinja2 संकेतन ( "{% if env == 'prod' %} ...) को संकेतन के प्रति अतिसंवेदनशील माना और इस तरह बल्कि नाजुक पाया। उदाहरण के लिए, जब इस अनुपयोगी कोड में बेहतर पठनीयता के लिए प्रश्न में लाइन लपेटते हैं :

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

मैं अनपेक्षित परिणामों के साथ समाप्त हुआ, जैसे कि अतिरिक्त व्हाट्सएप या \nमें composer_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'

मुझे यह ब्लॉग पोस्ट उपयोगी भी लगी जो अनिवार्य रूप से उसी दृष्टिकोण का अनुसरण करती है।


@ यदि आप के |बजाय का उपयोग आप व्हाट्सएप >समस्या नहीं हो सकता है। (या आप इसे अधिक प्राप्त करेंगे)
माइकल

@ एसईसी उपयोग '> -' और ansible युक्ति की जाँच करें। इसमें मल्टीलाइन स्ट्रिंग्स को सही तरीके से मैनिपुलेट करने के कई विकल्प हैं। yaml-multiline.info नोट, विशेष रूप से, ब्लॉक चोमिंग इंडिकेटर।
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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.