Відповідне змінення значення за замовчуванням відповідно до умови


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це "dev", перезаписуючи будь-який фактичний набір значень. Я думаю , що умовне повинен бути продовжений так: when: "{{env}}" == 'dev' and "{{composer_opts}}" is undefined. Це добре виглядає? Чи можете ви відповідно відповісти на своє запитання?
Франческо Абені

composer_opts буде визначено, оскільки воно має значення за замовчуванням. Для вирішення поставленого завдання вам потрібен інший вираз. Наприклад змінна custom_composer_opts.
Наверн

Будь ласка, уточнюйте з псевдокодом, що ви хочете зробити. Відповідно оновлю відповідь.
Наверн

Я оновив своє запитання додатковим поясненням та зразком псевдокоду. Дякую.
Франческо Абені

Я оновив свою відповідь. Перевір це. Я вважаю, що я зрозумів, що вам потрібно.
Наверн

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'

Я також вважав, що ця публікація в блозі є корисною, яка, по суті, дотримується того самого підходу.


@sec, якщо ви використовуєте |замість >вас, можливо, не буде проблеми з пробілом. (або ви отримаєте більше його LOL)
Майкл

@sec Використовуйте '> -' і перевірте специфікацію ansible. У ньому є безліч варіантів правильної обробки багаторядкових рядків. yaml-multiline.info Зазначимо, зокрема, індикатор блокування блоку.
DylanYoung

Зауважте, що це рішення також мало проблеми з пріоритетом. Факт не є дефолтом.
DylanYoung

2

Відповідальний set_fact на основі умови в одному вкладиші:

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

Питання пріоритету те саме, що й інші рішення (факт не є типовим), однак, якщо ви поставите це умовне право у свій файл defaults.yml, це рішення спрацює. Це стає дуже потворним реально швидко, якщо у вас є кількість за замовчуванням залежно від стану
DylanYoung
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.