Відповідь: Виконайте завдання лише тоді, коли вказано тег


76

Відповідні теги можна використовувати для запуску лише підмножини завдань / ролей. Це означає, що за замовчуванням всі завдання виконуються, і ми можемо запобігти виконанню лише деяких завдань.

Чи можемо ми обмежити виконання завдання лише тоді, коли вказано тег "foo"? Чи можемо ми використовувати поточні теги в whenрозділі завдання?


2
це звучить як те, що вам потрібно, це налаштування задачі, як limit_to_tags: foo, якого не існує, і я не думаю, що це можливо зараз. Майбутня реалізація також повинна мати план щодо того, чи потрібно використовувати ІЛЕ або АБО ці теги разом.
dgh

Подивіться на мою anwser в «анзібль - За замовчуванням / Явні теги» stackoverflow.com/questions/28789912 / ...
sirkubax

Відповіді:


38

Відповідь 2.5 поставляється із спеціальними тегами neverта always. Тег neverможна використовувати саме для цієї мети. Наприклад:

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]

У цьому прикладі завдання буде виконуватися лише тоді, коли явно запитується тег debug(або never). [Посилання на довідкові документи]


20

Хоча це кругле рішення, воно працює.

Всередині списку завдань реєструйте змінну, коли запускається звичайне виконання. Потім додайте умову коли, яка перевіряє цю змінну, в тег.

- shell: /bin/true
  register: normal_task_list

- name: Only run when tag is specified
  shell: /bin/echo "Only running because of specified tag"
  when: normal_task_list is not defined
  tags: specified

Ви також можете скористатися untaggedцим:- set_fact: untagged_run=true tags: untagged
Pyzo

Чи можете ви пояснити трохи більше про це? Приклад із реального світу?
Квінтін,

17

У мене недостатньо репутації, щоб підтвердити або прокоментувати відповідь, що пропонує використання змінних командного рядка ( --extra-vars), але я маю це додати:

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

Ви можете запобігти відмові відтворення за відсутності --extra-varsвизначення, визначивши значення за замовчуванням у самій програмі:

---
- hosts: ...
# ↓↓↓
  vars:
    thorough: false
# ↑↑↑
  tasks:
  - name: apt - install nfs-common only when thorough is true
    when: thorough | bool
    apt:
      cache_valid_time: 86400
      force: yes
      pkg:
        - nfs-common

Переопределення через --extra-varsфункцію все одно буде працювати, оскільки змінні, визначені в командному рядку, мають перевагу над усіма іншими визначеннями.

Результатом є те, що відтворення запускається без помилок, коли thoroughйого не змінюють trueу командному рядку.


5
Те саме можна досягти, використовуючи thorough | default('no') | bool.
Costi Ciudatu

2
Або when: thorough is defined and thoroughякщо ви віддаєте перевагу цьому синтаксису
KCD

Спасибі, більше любите is defined andсинтаксис. більше, ніж багато труб, які я не відчуваю, є інтуїтивно зрозумілими.
Ілля Лінн

10

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

Використовуючи аргумент extra-vars, ви можете викликати виконання умовного виконання.

З ansible-playbook --help:

 -e EXTRA_VARS, --extra-vars=EXTRA_VARS
    set additional variables as key=value or YAML/JSON

Приклад:

ansible-playbook test.yaml -e "thorough=true"

test.yaml:

...
- name: apt - install nfs-common only when thorough is true
  apt:
    cache_valid_time: 86400
    force: yes
    pkg:
    - nfs-common
  when: thorough | default(False)
...

2
Щоб уникнути помилки, якщо ви не визначите "ретельний", просто використовуйте thorough | default("false") | match("true"). За замовчуванням не повинно бути false, просто нічого не збігається true, але це покращує читабельність.
Том Вілсон

4

Перевірка змінної "тегів" не працює в Ansible 2.1.1.0. Дивіться нижче про тест. У мене є інша ідея виконувати завдання лише тоді, коли визначено тег, який працює як для Ansible 1.9.X, так і для 2.XY:

- set_fact: foo=true
  tags: bar
- set_fact: foo=false
- name: do something when 'bar' tag is defined
  debug: var=foo
  when: foo
  tags: bar

При цьому, коли запускається книга для запису без будь-якого тегу, змінна 'foo' буде встановлена ​​на true, а потім на false, тому нічого не виконується. Якщо ви додасте тег 'bar', буде застосовано лише перше налаштування, тож змінна 'foo' буде істинною, тоді ваше завдання буде виконано. Насолоджуйтесь!


А ось тест про змінну 'теги' в Ansible 2.1.1.0:

Ось ігрова книга:

- hosts: localhost
  connection: local
  tasks:
    - name: display tags variable
      debug: var=tags
      tags: foo

    - name: do something only when tag 'foo' is provided
      debug: var=tag
      when: tags is defined
      tags: foo

І ось вихід:

$ ansible-playbook --version ; ansible-playbook ./test.yml -t foo
ansible-playbook 2.1.1.0
  config file = /home/nootal/projects/ivy/src/ansible/ansible.cfg
  configured module search path = Default w/o overrides

PLAY [localhost] ***************************************************************

TASK [display tags variable] ***************************************************
ok: [localhost] => {
    "tags": "VARIABLE IS NOT DEFINED!"
}

TASK [do something only when tag 'foo' is provided] ****************************

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0   

2

Так. Запуск ansible-playbook із --tags fooпрапором забезпечить виконання лише завдань, позначених тегом foo. Наприклад, припустимо, що у нас є ігрова книга під назвою example.yml:

tasks:

  - yum: name={{ item }} state=installed
    with_items:
       - httpd
       - memcached
    tags:
       - packages

  - name: some other task
    ..
    tags:
      - some other tag

працює:

ansible-playbook example.yml --tags "packages"

Переконайтеся, що виконується лише завдання yum.

Тож насправді вам не потрібно використовувати теги, коли розділ умовно виконує завдання. Зауважте, що залежно від складності ваших ігрових книжок / ролей вам може знадобитися комбінація --tags та --skip-тегів, щоб контролювати, які завдання виконуються. Наприклад, якщо завдання, що включають, позначені як "foo", а якесь завдання всередині доданої книги відзначено як "bar", і ви запустите

ansible-playbook --tags "foo"

Внутрішнє завдання (позначене лише як "бар") буде виконано. Щоб уникнути виконання всіх внутрішніх завдань, позначених як "бар", вам доведеться виконати наступну команду

ansible-playbook --tags foo --skip-tags bar

7
Це неправда: "Вказівка ​​тегу на завдання означає, що лише тоді, коли цей тег буде явно переданий команді ansible-playbook, це завдання буде виконано."
gimboland

1
По-друге, твердження не відповідає дійсності.
Кріс

10
так, ви можете досягти поведінки, гарантуючи, що ви завжди використовуєте правильні ansible-playbookпараметри, але я думаю, що ОП просить спосіб анотувати завдання, щоб воно не виконувалося, якщо в ansible-playbookкоманді явно не додано конкретний тег .
dgh

4
Так, це не відповідає на питання ОП.
Аллен Люс

усі дії, позначені тегом / без тегів, виконуються, коли ви не вказуєте тег. Теги не можуть виключати запущену дію, включають лише. Не існує логіки предиката, крім фільтра добавок.
bbaassssiiee

1

Існує спеціальний тег - "ніколи" , який не дозволить виконувати завдання, якщо тег спеціально не вимагається.

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]

Вже згадувалося у вищезгаданій відповіді: serverfault.com/a/907329/105928
Taha Jahangir

0

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

Наприклад: Уявіть собі іграшку та інвентар

# інвентар
[dev]
192.168.1.1

# site.yml
- господарі: дев
  ролі:
    - {роль: загальний}

і спільне / завдання / main.yml

# ролі / загальні / завдання / main.yaml
- ім'я: Встановити посилання
  apt: name = посилання, стан = присутні

- включати: uninstall.yml
  коли: визначено uninstall_links
  теги:
    - видалити

# ролі / загальні / завдання / uninstall.yml
- ім'я: видалення посилань
  apt: name = посилання, стан = відсутні

При такому підході ви використовуєте тег для вибору лише завдань у uninstall.yml, але вам також потрібно встановити змінну 'uninstall_links', щоб увімкнути її. Тож якщо ви запускаєте книгу без будь-яких параметрів, вона за замовчуванням виконає завдання встановлення. Щоб видалити, ви можете встановити тег "видалити" у вашій програмі (або cmdline) та ОБОВ'ЯЗКИ встановити змінну. Якщо ви не встановите тег, він запустить усе (встановлення та видалення) у такому порядку, що добре перевірити весь процес.

Як запустити все (це встановить і видалить):

$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true"

Як запустити лише тег "видалення" для групи розробників

$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true" -t uninstall

Тому змінні та теги також можуть бути у файлах site.yml / інвентаризації, що дозволяє вам взяти участь у вашому SCM та записати свій намір.


0

nootal вірно, мій підхід не працює - ігноруйте його :( Я зараз використовую "when: myvar визначений", а перемикач командного рядка "-e" myvar = X "виконувати завдання лише за явного запиту.

Ще простіше (принаймні, з ansible 2.1.1.0):

- name: do something only when tag 'foo' is provided
  when: tags is defined
  tags: foo

-> буде виконуватися лише тоді, коли теги надані І теги включають "foo"


0

На Ansible 2.3.2.0, ось моє рішення проблеми:

---
- hosts: localhost
  gather_facts: no
  vars:
    in_tag: yes
  tasks:
    - set_fact: in_tag=no
    - fail:
        msg: "recently_added is set and you're using blah tag"
      when: ( in_tag | bool )
      tags:
        - blah
    - debug:
        msg: "always remember"

Вона починається з установки in_tagна Trueте є , set_factщо ставить його назад False, коли ви не вказуєте який - або tagsз ansible-playbook.

Коли ви вказуєте теги, in_tagзалишається на Trueта failвиконується завдання.

PS: Ви можете додати логіку до будь-яких завдань, які хочете

PS2: ви також можете розширити логіку і жорстко все теги у вас є і set_fact: in_tag_blah=Trueв поєднанні з tags: ["blah"]звичайно.

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