ansible: як передавати кілька команд


76

Я спробував це:

- command: ./configure chdir=/src/package/
- command: /usr/bin/make chdir=/src/package/
- command: /usr/bin/make install chdir=/src/package/

що працює, але, мабуть, є щось більше .. акуратніше.

Тож я спробував це:

з: /programming/24043561/multiple-commands-in-the-same-line-for-bruker-topspin, які повертають мені "немає такого файлу або каталогу"

- command: ./configure;/usr/bin/make;/usr/bin/make install chdir=/src/package/

Я теж спробував це: https://u.osu.edu/hasnan.1/2013/12/16/ansible-run-multiple-commands-using-command-module-and-with-items/

але я не зміг знайти правильний синтаксис для введення:

- command: "{{ item }}" chdir=/src/package/
  with_items:
      ./configure
      /usr/bin/make
      /usr/bin/make install

Це не працює, кажучи, що існує проблема з цитатами.

Хто-небудь?


3
гм, спробуйте скористатися shellмодулем. Якщо ви прочитаєте документи в командному модулі, то побачите, чому це не працює. (не повна відповідь до н.е., я не тестував)
tedder42

Ну, вибачте, але я раніше читав документи оболонки та команд, і досі не знаю, чому це не працює.
John Doe,

Я використовував модуль оболонки з крапками з комою як роздільник, який працював: shell: echo "a"; ехо "b"
Пітер Смолвуд

Відповіді:


99

Якщо значення в YAML починається з фігурних дужок ( {), парсер YAML припускає, що це словник . Отже, для подібних випадків, коли у значенні є змінна (Jinja2), потрібно застосувати одну з наступних двох стратегій, щоб уникнути плутанини синтаксичного аналізатора YAML:

Процитуйте всю команду:

- command: "{{ item }} chdir=/src/package/"
  with_items:
  - ./configure
  - /usr/bin/make
  - /usr/bin/make install    

або змінити порядок аргументів:

- command: chdir=/src/package/ {{ item }}
  with_items:
  - ./configure
  - /usr/bin/make
  - /usr/bin/make install

Дякуємо за альтернативну пропозицію @RamondelaFuente.


Вам потрібно цитувати змінні в деяких ситуаціях, наприклад, коли вони містять пробіли, наприклад.
Педро Романо,

5
Вам потрібні подвійні лапки навколо всієї команди. Проблема полягає в тому, що першим символом значення є "{", що має значення в YAML. Отож - команда: "{{item}} chdir = / src / package /"
Рамон де ла Фуенте

що, якщо у вас є змінна в одному з ваших елементів? тобто - cp {{base_dir}}
хв. 1

Безпечний варіант з будь-якого рядка ( в тому числі зі змінними), щоб просто процитувати всю рядок: "cp {{base_dir}}".
Педро Романо,

80

Для запуску декількох команд оболонки з ansible ви можете використовувати модуль оболонки з багаторядковим рядком (зверніть увагу на трубу після shell:), як показано в цьому прикладі:

  - name: Build nginx 
    shell: |
      cd nginx-1.11.13
      sudo ./configure
      sudo make
      sudo make install

Дякую. чи є спосіб сказати йому ігнорувати збої та продовжувати наступні команди у списку?
sogwiz

5

Я зіткнувся з тим же питанням. У моєму випадку частина моїх змінних знаходилась у словнику, тобто with_dict змінної (цикл), і мені доводилося запускати по 3 команди на кожному item.key. Це рішення є більш доречним, коли вам доводиться використовувати словник with_dict із запуском декількох команд ( не вимагаючи with_items )

Використання with_dict та with_items в одному завданні не допомогло, оскільки воно не вирішувало змінні.

Моє завдання було таким:

- name: Make install git source
  command: "{{ item }}"
  with_items:
    - cd {{ tools_dir }}/{{ item.value.artifact_dir }}
    - make prefix={{ tools_dir }}/{{ item.value.artifact_dir }} all
    - make prefix={{ tools_dir }}/{{ item.value.artifact_dir }} install
  with_dict: "{{ git_versions }}"

role / git / за замовчуванням / main.yml було:

---
tool: git
default_git: git_2_6_3

git_versions:
  git_2_6_3:
    git_tar_name: git-2.6.3.tar.gz
    git_tar_dir: git-2.6.3
    git_tar_url: https://www.kernel.org/pub/software/scm/git/git-2.6.3.tar.gz

Вищезазначене призвело до помилки, подібної до наведеної нижче, для кожного {{item}} (для 3 команд, як зазначено вище). Як бачите, значення tools_dir не заповнюються (tools_dir - це змінна, яка визначена за замовчуванням загальної ролі / main.yml, а також значення item.value.git_tar_dir не заповнено / вирішено).

failed: [server01.poc.jenkins] => (item=cd {# tools_dir #}/{# item.value.git_tar_dir #}) => {"cmd": "cd '{#' tools_dir '#}/{#' item.value.git_tar_dir '#}'", "failed": true, "item": "cd {# tools_dir #}/{# item.value.git_tar_dir #}", "rc": 2}
msg: [Errno 2] No such file or directory

Рішення було простим. Замість того, щоб використовувати модуль "КОМАНДА" в Ansible, я використав модуль "Оболонка" і створив змінну в role / git / defaults / main.yml

Отже, тепер role / git / defaults / main.yml виглядає так:

---
tool: git
default_git: git_2_6_3

git_versions:
  git_2_6_3:
    git_tar_name: git-2.6.3.tar.gz
    git_tar_dir: git-2.6.3
    git_tar_url: https://www.kernel.org/pub/software/scm/git/git-2.6.3.tar.gz

#git_pre_requisites_install_cmds: "cd {{ tools_dir }}/{{ item.value.git_tar_dir }} && make prefix={{ tools_dir }}/{{ item.value.git_tar_dir }} all && make prefix={{ tools_dir }}/{{ item.value.git_tar_dir }} install"

#or use this if you want git installation to work in ~/tools/git-x.x.x
git_pre_requisites_install_cmds: "cd {{ tools_dir }}/{{ item.value.git_tar_dir }} && make prefix=`pwd` all && make prefix=`pwd` install"

#or use this if you want git installation to use the default prefix during make 
#git_pre_requisites_install_cmds: "cd {{ tools_dir }}/{{ item.value.git_tar_dir }} && make all && make install"

а завдання task / git / tasks / main.yml виглядає так:

- name: Make install from git source
  shell: "{{ git_pre_requisites_install_cmds }}"
  become_user: "{{ build_user }}"
  with_dict: "{{ git_versions }}"
  tags:
    - koba

Цього разу значення були успішно замінені, оскільки модуль мав значення "SHELL", а відповідні результати відображали правильні значення. Для цього не потрібен цикл with_items:.

"cmd": "cd ~/tools/git-2.6.3 && make prefix=/home/giga/tools/git-2.6.3 all && make prefix=/home/giga/tools/git-2.6.3 install",

4

Ви також можете зробити так:

- command: "{{ item }}"
  args:
    chdir: "/src/package/"
  with_items:
    - "./configure"
    - "/usr/bin/make"
    - "/usr/bin/make install"

Сподіваюся, це може допомогти іншим


3

Shell працює на мене.

Простіше кажучи, Shell - це те саме, що ви запускаєте сценарій оболонки.

Примітки:

  1. Обов’язково використовуйте | при запуску декількох cmds.
  2. Оболонка не поверне помилок, якщо останній cmd є успішним (як звичайна оболонка)
  3. Керуйте цим за допомогою виходу 0/1, якщо ви хочете зупинити ансеблі при виникненні помилки.

Наступний приклад показує помилку в оболонці, але це успіх в кінці виконання.

- name: test shell with an error
become: no
shell: |
  rm -f /test1  # This should be an error.
  echo "test2"
  echo "test1"
  echo "test3" # success

У цьому прикладі показано оболонку зупинки з помилкою виходу 1.

- name: test shell with exit 1
become: no
shell: |
  rm -f /test1  # This should be an error.
  echo "test2"
  exit 1        # this stops ansible due to returning an error
  echo "test1"
  echo "test3" # success

посилання: https://docs.ansible.com/ansible/latest/modules/shell_module.html


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