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

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   

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.


@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 '' }}"

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.