Проблема в команде ansible playbook? - PullRequest
7 голосов
/ 11 июля 2019

Я пытаюсь выполнить команду на докере на другом компьютере с моего компьютера. Когда я выполняю эту команду:

- name: Add header
      command: docker exec cli bash -l -c "echo '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":'$(cat jaguar_update.json)'}}}' | jq . > jaguar_update_in_envelope.json"

через ansible playbook, я получаю сообщение об ошибке, показанное ниже.

fatal:[  
   command-task
]:FAILED! =>{  
   "changed":true,
   "cmd":[  ],
   "delta":"0:00:00.131115",
   "end":"2019-07-11 17:32:44.651504",
   "msg":"non-zero return code",
   "rc":4,
   "start":"2019-07-11 17:32:44.520389",
   "stderr":"mesg: ttyname   
failed: Inappropriate ioctl for device\nparse error: Invalid numeric   
literal at line 1, column 9",
   "stderr_lines":[  
      "mesg: ttyname failed: 
Inappropriate ioctl for device",
      "parse error: Invalid numeric literal 
at line 1, column 9"
   ],
   "stdout":"",
   "stdout_lines":[  

   ]
}

Но если я вручную выполню команду в контейнере Docker, она будет работать нормально, и у меня не возникнет никаких проблем.

EDIT: Как и предполагалось, я попробовал с shell module

shell: docker exec cli -it bash -l -c "echo '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":'$(cat jaguar_update.json)'}}}' | jq . > jaguar_update_in_envelope.json"

Но я получаю ошибку ниже как

фатально: [команда-задача]: СБОЙ! => {"изменено": верно, "cmd": "докер exec cli -it bash -l -c echo {\ "Полезная нагрузка \": {\ "заголовок \": {\ "channel_header \": {\ "CHANNEL_ID \": \ "GLL \", \ "Типа \": 2}}, \ "данные \": {\ "config_update \": "$ (кот jaguar_update.json) '}}}' | JQ. > jaguar_update_in_envelope.json ", "delta": "0: 00: 00.110341", "end": "2019-07-12 10: 21: 45.204049", "msg": «ненулевой код возврата», «rc»: 4, «start»: «2019-07-12 10: 21: 45.093708 "," stderr ":" cat: jaguar_update.json: такого файла нет или directory \ nparse error: неверный числовой литерал в строке 1, столбец 4 ", "stderr_lines": ["cat: jaguar_update.json: такого файла или каталога нет", "ошибка синтаксического анализа: неверный числовой литерал в строке 1, столбец 4"], "стандартный вывод": "", "stdout_lines": []}

Все файлы 'jaguar_update.json' присутствуют в рабочем каталоге. Я подтвердил рабочий каталог.

Приведенные выше команды работают, если я помещаю их в файл сценария оболочки, а затем выполняю сценарий оболочки из ansible.

Ответы [ 3 ]

3 голосов
/ 15 июля 2019

Как уже упоминалось, для этого нужно использовать shell вместо command. Теперь вы хотите упростить эту команду, чтобы она могла сначала запускаться в bash. Что можно легко сделать, используя printf

$ printf "%s%s%s" '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":' $(<jaguar_update.json'}}}' | jq . > jaguar_update_in_envelope.json

$ cat jaguar_update_in_envelope.json
{
  "payload": {
    "header": {
      "channel_header": {
        "channel_id": "gll",
        "type": 2
      }
    },
    "data": {
      "config_update": {
        "name": "tarun"
      }
    }
  }
}

Так что теперь наши команды работают без проблем. Далее нужно переместить его в формате bash -l -c. Таким образом, вместо использования -c, который требует от нас передачи всей команды как одного параметра, мы используем многострочные команды

$ bash -l <<EOF
printf "%s%s%s" '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":' $(<jaguar_update.json) '}}}' | jq . > jaguar_update_in_envelope.json
EOF

Но это не с ошибкой

{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":{bash: line 2: name:: command not found
bash: line 3: syntax error near unexpected token `}'
bash: line 3: `} '}}}' | jq . > jaguar_update_in_envelope.json'

Это потому, что формат EOF будет обрабатывать каждую новую строку как отдельную команду. Поэтому нам нужно заменить все символы новой строки

bash -l <<EOF
printf "%s%s%s" '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":' $(sed -E 's|"|\\"|g' jaguar_update.json | tr -d '\n') '}}}' | jq . > jaguar_update_in_envelope.json
EOF

А теперь в ансибле

- name: a play that runs entirely on the ansible host
  hosts: 127.0.0.1
  connection: local
  tasks:
     - name: Solve the problem
       shell: |
           bash -l <<EOF
                printf "%s%s%s" '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":' $(sed -E 's|"|\\"|g' jaguar_update.json | tr -d '\n') '}}}' | jq . > jaguar_update_in_envelope.json
           EOF

И результат

$ ansible-playbook test.yml
PLAY [a play that runs entirely on the ansible host] *********************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************
ok: [127.0.0.1]

TASK [Solve the problem] *************************************************************************************************************************************************************
changed: [127.0.0.1]

PLAY RECAP ***************************************************************************************************************************************************************************
127.0.0.1                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

$ cat jaguar_update_in_envelope.json
{
  "payload": {
    "header": {
      "channel_header": {
        "channel_id": "gll",
        "type": 2
      }
    },
    "data": {
      "config_update": {
        "name": "tarun"
      }
    }
  }
}
1 голос
/ 11 июля 2019

cf docs -

  • Команда (ы) не будут обрабатываться через оболочку, поэтому такие переменные, как $ HOME, и такие операции, как "<", ">", "|", ";"и "&" не будет работать.Используйте модуль оболочки, если вам нужны эти функции.

shell буквально передает скрипт в синтаксический анализатор команд sh.

Еще одно замечание - вы заканчиваете одиночный-квотировать до $(cat jaguar_update.json) и перезапустить его после, но не используйте двойные кавычки вокруг него.Ваш вывод может справиться с этим, но я хотел бы обратить внимание на случай, если это имеет значение.

0 голосов
/ 15 июля 2019

Чтобы избежать любой сложности, попробуйте , как в этом вопросе , чтобы обернуть вашу команду в сценарий, и вызвать этот сценарий (с command или shell)

- name: Add header
      raw: /path/to/script/docker-add-header.sh

И в /path/to/script/docker-add-header.sh:

docker exec cli -it bash -l -c "echo '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":'$(cat jaguar_update.json)'}}}' | jq . > jaguar_update_in_envelope.json

Попробуйте сначала заставить скрипт работать в одиночку (без Ansible).
Смотрите (если он не работает, даже вне любого вызова Ansible), чтобы избежать вложенного двойного-цитаты:

docker exec cli -it bash -l -c "echo '{\"payload\":{\"header\":...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...