Risposta: eseguire l'attività solo quando viene specificato un tag


75

I tag di risposta possono essere utilizzati per eseguire solo un sottoinsieme di attività / ruoli. Ciò significa che per impostazione predefinita tutte le attività vengono eseguite e possiamo solo impedire l'esecuzione di alcune attività.

Possiamo limitare l'esecuzione di un'attività solo quando viene specificato il tag "pippo"? Possiamo usare i tag attuali nella whensezione di un'attività?


2
sembra che ciò di cui hai bisogno sia un'impostazione di attività come limit_to_tags: foo che non esiste e non penso che sia possibile in questo momento. Un'implementazione futura deve anche avere un piano per AND o OR quei tag insieme.
DGH

Date un'occhiata al mio anwser in "Ansible - Default / Tag espliciti" stackoverflow.com/questions/28789912/...
sirkubax

Risposte:


38

Ansible 2.5 viene fornito con tag speciali nevere always. Il tag neverpuò essere utilizzato esattamente per questo scopo. Per esempio:

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

In questo esempio, l'attività verrà eseguita solo quando il tag debug(o never) viene esplicitamente richiesto. [Riferimenti su documenti rispondibili]


20

Anche se questa è una soluzione rotonda, funziona.

All'interno dell'elenco attività registra una variabile durante l'esecuzione normale. Quindi, aggiungi una condizione quando che controlla quella variabile all'attività taggata.

- 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

Puoi anche usare untaggedper realizzare questo:- set_fact: untagged_run=true tags: untagged
Pyzo,

Puoi spiegarci qualcosa in più su questo? Un esempio nel mondo reale?
Quintin Par

17

Non ho abbastanza reputazione per votare o commentare la risposta che suggerisce l'uso delle variabili della riga di comando ( --extra-vars), ma ho questo da aggiungere ad esso:

L'avvertenza di questo metodo è che il gioco si guasta e fallisce se non si definisce quella variabile aggiuntiva.

Puoi evitare errori di gioco in assenza di una --extra-varsdefinizione definendo un valore predefinito nel playbook stesso:

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

La sostituzione tramite --extra-varsfunzionerà comunque perché le variabili definite nella riga di comando hanno la precedenza su tutte le altre definizioni.

Il risultato è che il gioco viene eseguito senza errori quando thoroughnon viene modificato truenella riga di comando.


5
Lo stesso si può ottenere usando thorough | default('no') | bool.
Costi Ciudatu,

2
O when: thorough is defined and thoroughse preferisci quella sintassi
KCD,

Grazie, adoro di più la is defined andsintassi. più delle molteplici pipe che non mi sembrano intuitive.
Elijah Lynn il

10

È possibile utilizzare i condizionali per proteggersi dall'esecuzione accidentale di attività che verrebbero altrimenti eseguite se non si specifica un tag. L'avvertenza di questo metodo è che il gioco si guasta e fallisce se non si definisce quella variabile aggiuntiva.

Utilizzando l'argomento extra-var è possibile attivare l'esecuzione del condizionale.

Da ansible-playbook --help:

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

Esempio:

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
Per evitare un errore se non si definisce "completo" basta usare thorough | default("false") | match("true"). L'impostazione predefinita non deve essere false, tutto ciò che non corrisponde true, ma migliora la leggibilità.
Tom Wilson,

4

Il controllo della variabile 'tags' non funziona in Ansible 2.1.1.0. Vedi sotto per il test. Ho un'altra idea per eseguire l'attività solo quando viene definito un tag, funzionando sia per Ansible 1.9.X che per 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

Detto questo, quando si esegue il playbook senza alcun tag, la variabile 'pippo' sarà impostata su vero e poi su falso, quindi nulla viene eseguito. Se aggiungi il tag 'bar', verrà applicata solo la prima impostazione, quindi la variabile 'pippo' sarà vera, quindi il tuo compito verrà eseguito. Godere!


Ed ecco il test sulla variabile 'tags' in Ansible 2.1.1.0:

Ecco il playbook:

- 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

Ed ecco l'output:

$ 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

Sì. L'esecuzione di ansible-playbook con il --tags fooflag assicurerà che foovengano eseguite solo le attività contrassegnate con . Ad esempio, supponiamo di avere un playbook chiamato esempio.yml:

tasks:

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

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

in esecuzione:

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

Si assicurerà che venga eseguita solo l'attività yum.

Quindi in realtà non è necessario utilizzare i tag in quando la sezione per eseguire in modo condizionale un'attività. Nota che a seconda della complessità dei tuoi libri di gioco / ruoli potresti dover usare una combinazione di --tags e --skip-tags per controllare quali attività vengono eseguite. Ad esempio, se un'attività include è contrassegnata come "pippo" e alcune attività all'interno del playbook incluso sono contrassegnate come "barra" ed esegui

ansible-playbook --tags "foo"

L'attività interna (contrassegnata solo come "barra") verrà eseguita. Per evitare l'esecuzione di tutte le attività interne etichettate come 'barra' dovrai eseguire il seguente comando

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

7
Questo non è vero: "Specificare un tag su un'attività significa che solo quando questo tag viene passato esplicitamente al comando ansible-playbook quell'attività verrà eseguita."
gimboland,

1
In secondo luogo, l'affermazione non è vera.
Chris,

10
sì, puoi ottenere il comportamento assicurandoti di utilizzare sempre le ansible-playbookopzioni giuste , ma penso che l'OP stia chiedendo un modo per annotare un'attività in modo che non venga eseguita a meno che un tag specifico non sia esplicitamente aggiunto nel ansible-playbookcomando.
DGH

4
Sì, questo non risponde alla domanda del PO.
Allen Luce

tutte le azioni taggate / non taggate vengono eseguite quando non si specifica un tag. I tag non possono escludere un'azione da eseguire, includere solo. Non esiste una logica predicato ad eccezione di un filtro additivo.
bbaassssiiee,


0

quando la clausola non può valutare la presenza di tag. Per ovviare a questo problema, utilizzo insieme variabili e tag per eseguire attività specifiche di tale tag / variabile.

Esempio: immagina un playbook e un inventario

# inventario
[It]
192.168.1.1

# site.yml
- host: dev
  ruoli:
    - {ruolo: comune}

e in common / task / main.yml

# ruoli / comuni / attività / main.yaml
- nome: installa collegamenti
  apt: name = links state = presente

- include: uninstall.yml
  quando: uninstall_links è definito
  tags:
    - disinstallare

# ruoli / comuni / attività / uninstall.yml
- nome: disinstalla i collegamenti
  apt: name = links state = assente

Con questo approccio, si utilizza il tag per selezionare solo le attività in uninstall.yml, ma è anche necessario impostare la variabile 'uninstall_links' su qualcosa per abilitarlo. Quindi, se si esegue il playbook senza parametri, per impostazione predefinita eseguirà l'attività di installazione. Per disinstallare, puoi impostare il tag 'Uninstall' sul tuo playbook (o cmdline) e DEVE impostare la variabile. Se non imposti il ​​tag, eseguirà tutto (installa e disinstalla) in quell'ordine, il che è utile per testare l'intero processo.

Come eseguire tutto (verrà installato e disinstallato):

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

Come eseguire solo il tag 'Uninstall' sul gruppo di sviluppo

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

Pertanto, variabili e tag potrebbero anche trovarsi nei file site.yml / inventario, consentendo di impegnarsi nel proprio SCM e registrare le proprie intenzioni.


0

nootal ha ragione, il mio approccio non funziona - ignoralo :( Ora uso "quando: myvar è definito" e l'opzione della riga di comando "-e" myvar = X "per eseguire attività solo quando esplicitamente richiesto.

Ancora più semplice (almeno con Ansible 2.1.1.0):

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

-> verrà eseguito solo quando i tag sono stati forniti E i tag includono "pippo"


0

Su Ansible 2.3.2.0, ecco la mia soluzione al problema:

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

Si inizia impostando in_tagsu Truequindi c'è un set_factche lo reimposta su Falseon quando non si specifica alcun tagsda ansible-playbook.

Quando si specificano i tag, in_tagrimangono attivi Truee l' failattività viene eseguita.

PS: puoi aggiungere la logica a qualsiasi attività tu voglia

PS2: puoi anche estendere la logica e hardcode tutti i tag che hai e set_fact: in_tag_blah=Truein combinazione con tags: ["blah"]ovviamente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.