Przekazywanie dowolnych poleceń do Ansible przy użyciu złożonego argumentu

9

Używam generowanych programowo instrukcji Ansible. Ogólnie rzecz biorąc, ponieważ podręczniki są po prostu YAML, jest to proste. Jednak w przypadku korzystania z „prostej” key=valueformy podręczniki nie są czystym YAML - zawierają treści osadzone w shlexformie możliwej do przygotowania.

Aby uniknąć dwuznaczności w tej formie (czy jest to key=valueparowanie argumentu z poleceniem czy argumentem ansible?) I posiadanie tylko jednego formatu do parsowania i generowania, bezwarunkowo używam złożonego mechanizmu args pokazanego na przykładzie w ansible -przykładowe repozytorium .

Używa następującej składni:

action: module-name
args:
  key1: value1
  key2: value2

... co jest dobre i dobre. Jednak podczas próby użycia tego formularza dla modułów shelllub command( których dokumentacja opisuje faktyczne polecenie przekazane w argumencie o nazwie free_form), to nie działa tak dobrze:

action: shell
args:
  free_form: echo hello_world >/tmp/something
  creates: /tmp/something

Po wywołaniu uruchamia to:

/bin/sh -c " free_form='echo hello_world >/tmp/something'  "

... co bardzo nie jest tym, co staram się osiągnąć.

Jaki jest właściwy sposób korzystania z modułów Ansible przyjmujących polecenia „w dowolnej formie” przy użyciu czystej składni YAML?

Charles Duffy
źródło

Odpowiedzi:

5

Krótka odpowiedź: Nie używaj command, raw, scriptlub shellmodułów. Napisz własny moduł, który akceptuje polecenie jako „normalny” argument.

Długa odpowiedź:

W większości przypadków możesz to zrobić:

- shell: echo hello_world > /tmp/something
  args:
    creates: /tmp/something

Nie udaje się to jednak w niektórych przypadkach:

- shell: echo hello_world > creates=something
  args:
    creates: creates=something  # The file is named "creates=something"

Nie znam ogólnego sposobu na poradzenie sobie z tym, ale rozwiązaniem specyficznym dla bash jest:

- shell: echo hello_world > "creates=something"
  args:
    creates: creates=something
Śnieżna kula
źródło
Czy istnieje struktura danych, którą mogę przekazać do dowolnego zgodnego generatora YAML w celu emisji - shell: ...? Jeśli ta struktura jest czymś, co można wiarygodnie wygenerować tylko ręcznie, to w pewien sposób przeczy to pytaniu.
Charles Duffy
@CharlesDuffy: Nie sądzę, że można uciec od tej roli ...w ogóle. Jeśli spojrzeć library/commands/command, znajdziesz dość hojne dopasowanie regex creates=, removes=, chdir=, i tak dalej. Jeśli chcesz zagwarantować, że jakiekolwiek polecenie zostanie przekazane, musisz napisać własny moduł.
Snowball
Fair 'nuff. Moim zdaniem jest to znacząca pomyłka projektowa ... ale cóż, taka jest.
Charles Duffy
0

Zostało to teraz rozwiązane w dokumentacji Ansible .

# You can also use the 'args' form to provide the options. This command
# will change the working directory to somedir/ and will only run when
# /path/to/database doesn't exist.
- command: /usr/bin/make_database.sh arg1 arg2
  args:
    chdir: somedir/
    creates: /path/to/database

Zauważ, że nie ma parametru o nazwie „free_form”.

Christian Long
źródło
Czy obecność par argszapobiega k=vanalizowaniu par command, czy powinna istnieć? (Jeśli tak, to czysto rozwiązuje to dwuznaczność; w przeciwnym razie wydaje się, że nadal istnieje).
Charles Duffy