Odpowiedź: Wykonaj zadanie tylko wtedy, gdy podany jest znacznik


76

Znaczników Ansible można używać do uruchamiania tylko podzbioru zadań / ról. Oznacza to, że domyślnie wszystkie zadania są wykonywane i możemy tylko uniemożliwić wykonanie niektórych zadań.

Czy możemy ograniczyć wykonanie zadania tylko wtedy, gdy podany jest tag „foo”? Czy możemy użyć bieżących tagów w whensekcji zadania?


2
wygląda na to, że potrzebujesz jakiegoś ustawienia zadania, takiego jak limit_to_tags: foo, które nie istnieje i nie sądzę, aby było to w tej chwili możliwe. Przyszła implementacja musi również mieć plan określający, czy AND lub OR te znaczniki razem.
— dgh

Spójrz na moją odpowiedź w „Ansible - Default / Explicit Tags” stackoverflow.com/questions/28789912/…
— sirkubax

Odpowiedzi:


38

Ansible 2.5 jest wyposażony w specjalne tagi neveri always. Tag nevermoże być używany dokładnie w tym celu. Na przykład:

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

W tym przykładzie zadanie zostanie uruchomione tylko wtedy, gdy znacznik debug(lub never) zostanie wyraźnie zażądany. [Odniesienie do ansible docs]


20

Chociaż jest to rozwiązanie okrężne, działa.

Wewnątrz listy zadań zarejestruj zmienną, gdy uruchomione zostanie normalne wykonanie. Następnie dodaj warunek when, który sprawdza tę zmienną do oznaczonego zadania.

- 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

Możesz także użyć untaggeddo tego:- set_fact: untagged_run=true tags: untagged
— Pyzo

Czy możesz wyjaśnić coś więcej na ten temat? Przykład z prawdziwego świata?
— Quintin Par

17

Nie mam wystarczającej reputacji, aby głosować lub komentować odpowiedź sugerującą użycie zmiennych wiersza poleceń ( --extra-vars), ale muszę to dodać:

Zastrzeżeniem tej metody jest to, że gra będzie zawierać błędy i nie powiedzie się, jeśli nie zdefiniujesz tej dodatkowej zmiennej.

Można zapobiec niepowodzeniu odtwarzania w przypadku braku --extra-varsdefinicji, definiując wartość domyślną w samym podręczniku:

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

Przesłanianie przez --extra-varsnadal będzie działać, ponieważ zmienne zdefiniowane w wierszu poleceń mają pierwszeństwo przed wszystkimi innymi definicjami.

W rezultacie gra działa bezbłędnie, gdy thoroughnie jest zmieniana truena w wierszu poleceń.


5
To samo można osiągnąć za pomocą thorough | default('no') | bool.
— Costi Ciudatu,

2
Lub when: thorough is defined and thoroughjeśli wolisz tę składnię
— KCD

Dzięki, bardziej podoba mi się is defined andskładnia. więcej niż wiele rur, które nie uważam za intuicyjne.
— Elijah Lynn

10

Możesz użyć warunkowego, aby zabezpieczyć się przed przypadkowo uruchomionymi zadaniami, które w innym przypadku zostałyby wykonane, jeśli nie podasz tagu. Zastrzeżeniem tej metody jest to, że gra będzie zawierać błędy i nie powiedzie się, jeśli nie zdefiniujesz tej dodatkowej zmiennej.

Za pomocą argumentu extra-vars możesz uruchomić warunek do wykonania.

Z ansible-playbook --help:

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

Przykład:

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
Aby uniknąć błędu, jeśli nie zdefiniujesz „dokładnego”, po prostu użyj thorough | default("false") | match("true"). Domyślnie nie musi tak być false, po prostu wszystko co nie pasuje true, ale poprawia czytelność.
— Tom Wilson,

4

Sprawdzanie zmiennej „tags” nie działa w Ansible 2.1.1.0. Test poniżej. Mam inny pomysł na wykonanie zadania tylko wtedy, gdy znacznik jest zdefiniowany, działając zarówno dla Ansible 1.9.X, jak i 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

Dzięki temu podczas uruchamiania playbooka bez tagu zmienna „foo” zostanie ustawiona na true, a następnie na false, więc nic nie zostanie wykonane. Jeśli dodasz znacznik „bar”, zastosowane zostanie tylko pierwsze ustawienie, więc zmienna „foo” będzie prawdziwa, a następnie twoje zadanie zostanie wykonane. Cieszyć się!


A oto test dotyczący zmiennej „tags” w Ansible 2.1.1.0:

Oto podręcznik:

- 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

A oto wynik:

$ 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

Tak. Uruchomienie ansible-playbook z --tags fooflagą zapewni, że tylko zadania oznaczone tagiem foozostaną wykonane. Załóżmy na przykład, że mamy podręcznik o nazwie example.yml:

tasks:

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

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

bieganie:

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

Upewni się, że wykonano tylko mniam zadanie.

Tak naprawdę tak naprawdę nie musisz używać tagów w sekcji, gdy warunkowo wykonujesz zadanie. Zauważ, że w zależności od złożoności twoich podręczników / ról może być konieczne użycie kombinacji --tags i --skip-tags, aby kontrolować, które zadania są wykonywane. Na przykład, jeśli zadania dołączania są oznaczone jako „foo”, a niektóre zadania w dołączonym podręczniku są oznaczone jako „pasek” i uruchomisz

ansible-playbook --tags "foo"

Zadanie wewnętrzne (oznaczone tylko jako „pasek”) zostanie wykonane. Aby uniknąć wykonywania wszystkich zadań wewnętrznych oznaczonych jako „bar”, musisz wykonać następujące polecenie

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

7
To nie jest prawda: „Określenie znacznika w zadaniu oznacza, że ​​zadanie zostanie wykonane tylko wtedy, gdy ten znacznik zostanie przekazany jawnie do komendy ansible-playbook.”
— gimboland

1
Po drugie, stwierdzenie nie jest prawdziwe.
— Chris,

10
tak, możesz osiągnąć takie zachowanie, upewniając się, że zawsze używasz właściwych ansible-playbookopcji, ale myślę, że OP prosi o sposób na adnotację zadania, aby nie zostało ono wykonane, chyba że w ansible-playbookpoleceniu zostanie wyraźnie dodany określony znacznik .
— dgh

4
Tak, to nie odpowiada na pytanie PO.
— Allen Luce

wszystkie akcje oznaczone / nieoznaczone są uruchamiane, gdy nie podasz tagu. Tagi nie mogą wykluczyć działania do uruchomienia, obejmują tylko. Nie ma logiki predykatów oprócz filtra addytywnego.
— bbaassssiiee


0

kiedy klauzula nie może ocenić obecności tagów. Aby obejść ten problem, używam zmiennych i tagów razem do uruchamiania zadań specyficznych dla tej zmiennej / tagu.

Przykład: Wyobraź sobie podręcznik i ekwipunek

# Inwentarz
[dev]
192.168.1.1

# site.yml
- gospodarze: dev
  role:
    - {rola: wspólna}

i we wspólnym / task / main.yml

# role / common / tasks / main.yaml
- nazwa: zainstaluj linki
  apt: name = links state = present

- obejmują: uninstall.yml
  kiedy zdefiniowano: uninstall_links
  tagi:
    - odinstaluj

# role / common / tasks / uninstall.yml
- nazwa: odinstaluj łącza
  apt: name = links state = nieobecny

Przy takim podejściu używasz znacznika, aby wybrać tylko zadania w uninstall.yml, ale musisz również ustawić zmienną „uninstall_links” na coś, aby ją włączyć. Jeśli więc uruchomisz playbook bez żadnych parametrów, domyślnie uruchomi się zadanie instalacji. Aby odinstalować, możesz ustawić znacznik „odinstaluj” w swoim playbooku (lub cmdline) i MUSISZ ustawić zmienną. Jeśli nie ustawisz tagu, uruchomi on wszystko (zainstaluje i odinstaluje) w tej kolejności, co jest dobre do przetestowania całego procesu.

Jak uruchomić wszystko (zainstaluje się i odinstaluje):

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

Jak uruchomić tylko tag „odinstaluj” w grupie programistów

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

Dlatego zmienne i tagi mogą również znajdować się w plikach site.yml / inventory, umożliwiając zatwierdzenie w SCM i zarejestrowanie zamiaru.


0

nootal ma rację, moje podejście nie działa - zignoruj ​​:( Teraz używam „kiedy: myvar jest zdefiniowany” i przełącznika wiersza poleceń „-e” myvar = X ”, aby wykonywać zadania tylko na wyraźne żądanie.

Jeszcze łatwiejsze (przynajmniej z ansible 2.1.1.0):

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

-> uruchomi się tylko wtedy, gdy tagi zostały dostarczone ORAZ tagi zawierają „foo”


0

On Ansible 2.3.2.0tu jest moje rozwiązanie problemu:

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

Zaczyna się od ustawienia, in_tagaby Truebyło to ustawienie, set_factktóre włącza go ponownie, Falsegdy nie określisz żadnego tagsz ansible-playbook.

Gdy określisz tagi, in_tagpozostanie Truei failzadanie zostanie uruchomione.

PS: możesz dodać logikę do dowolnych zadań

PS2: możesz również rozszerzyć logikę i kodować na stałe wszystkie tagi, które masz, i oczywiście set_fact: in_tag_blah=Truew połączeniu z nimi tags: ["blah"].

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.