Dapat mengubah nilai default sesuai kondisi

16

Apakah mungkin untuk mengubah nilai default variabel peran sesuai dengan beberapa kondisi (yaitu nilai variabel lain)?

Detail

Saya memiliki dua variabel terkait untuk suatu perintah, envdan composer_opts.

Jika keduanya dibiarkan secara default ( env = "prod"dan composer_opts = "--no-dev") semuanya ok.

Jika saya mengubah envke dev, default untuk yang lain akan melanggar perintah saya, jadi saya selalu perlu mengatur keduanya. Apakah mungkin untuk menghindari ini dengan menetapkan nilai standar bersyarat dengan skrip khusus / jika?

Penting: Saya tidak ingin selalu menetapkan composer_optsnilai sesuai dengan envnilainya. Saya ingin mengaturnya hanya jika belum disetel (yaitu nilai default dinamis).

Kodesemu

Saya ingin melakukan sesuatu seperti ini (kode berikut ini tidak valid, hanya pseudocode untuk mengekspresikan kebutuhan saya)

---
# defaults/main.yml

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

Jawaban:

12

Saya menyarankan solusi ini:

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

Ini akan mengatur composer_optsvariabel ke string ""ketika variabel envsama dengan ' dev'.

Berikut adalah contoh buku pedoman berdasarkan pertanyaan yang diperbarui:

$ 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

Output sampel:

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   
Navern
sumber
1
Ini adalah bagian dari solusi. Itu akan selalu diatur composer_optske string kosong ketika env"dev", menimpa nilai yang ditetapkan. Saya pikir bersyarat harus diperpanjang seperti ini: when: "{{env}}" == 'dev' and "{{composer_opts}}" is undefined. Apakah terlihat bagus? Bisakah Anda udpate pertanyaan Anda sesuai?
Francesco Abeni
composer_opts akan ditentukan karena memiliki nilai default. Anda perlu ekspresi lain untuk menyelesaikan tugas Anda. Misalnya variabel custom_composer_opts.
Navern
Tolong jelaskan dengan pseudocode apa yang ingin Anda lakukan. Saya akan memperbarui jawaban saya sesuai.
Navern
Saya telah memperbarui pertanyaan saya dengan penjelasan tambahan dan sampel pseudocode. Terima kasih.
Francesco Abeni
Saya telah memperbarui jawaban saya. Periksa. Saya percaya saya mengerti apa yang Anda butuhkan.
Navern
4

Sementara jawaban @ Navern berhasil, saya menemukan notasi Jinja2 tertanam ( "{% if env == 'prod' %} ...) sangat rentan terhadap notasi dan karenanya agak rapuh. Misalnya, ketika membungkus baris yang dimaksud untuk keterbacaan yang lebih baik seperti dalam kode yang tidak diuji ini :

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

Saya berakhir dengan hasil yang tidak terduga, seperti spasi tambahan atau \ndalam composer_opts.

Pendekatan yang saya gunakan jauh lebih bodoh, tetapi juga lebih stabil:

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

Saya juga menemukan posting blog ini bermanfaat yang pada dasarnya mengikuti pendekatan yang sama.

ssc
sumber
@sec jika Anda menggunakan |alih-alih, >Anda mungkin tidak memiliki masalah spasi putih. (atau Anda akan mendapatkan lebih banyak dari itu LOL)
Michael
@sec Gunakan '> -' dan periksa spesifikasi yang mungkin. Ini memiliki banyak opsi untuk memanipulasi string multiline dengan benar. yaml-multiline.info Catatan, khususnya, indikator blok chomping.
DylanYoung
Perhatikan bahwa solusi ini juga memiliki masalah prioritas. Fakta bukan default.
DylanYoung
2

Set_fact yang dimungkinkan berdasarkan kondisi dalam satu liner:

- name: "set composer_opts based on environment"
  set_fact:
     composer_opts:  "{{ '--no-dev --optimize-autoloader --no-interaction' if (env == 'prod') else '' }}"
SK Venkat
sumber
Masalah prioritas yang sama dengan solusi lainnya (faktanya bukan default), namun, jika Anda meletakkan kondisi kondisional ini dalam file defaults.yml Anda, solusi ini akan berfungsi. Itu menjadi sangat buruk dengan sangat cepat jika Anda memiliki sejumlah default tergantung pada kondisi
DylanYoung