У меня странная установка: мне нужно запустить команду в качестве контейнера докеров в sh
блок в файле Jenkins.
Проблема, с которой я столкнулся, связана с awk
команда, используемая для обрезки вывода.
Вот команда, которая РАБОТАЕТ ОТЛИЧНО когда бежал прямо на оболочке bash:
OPFILENAME=$(docker run -t \
-e AWS_SECRET_ACCESS_KEY='<omitted>' \
-e AWS_ACCESS_KEY_ID='<omitted>' \
-e AWS_DEFAULT_REGION='us-east-1' \
mydockerimage:0.1 \
bash -c "aws s3 ls my-bucket-name/dir/ | sort | tail -n 1 | awk '{print \$4}' ") && \
echo $OPFILENAME
Поэтому мне нужно запустить то же самое на удаленном хосте через конвейер Jenkins, вот общий синтаксис:
pipeline {
agent any
environment {
BUILDHOST = 'buildhost.example.com'
SSHCMD = "ssh -o StrictHostKeyChecking=no jenkins@${env.BUILDHOST}"
}
stages {
stage('Get filename from s3') {
steps {
sshagent ( ['ssh_config']) {
sh """${SSHCMD} '''
OPFILENAME=\$(sudo docker run -t \
-e AWS_SECRET_ACCESS_KEY='<omitted>' \
-e AWS_ACCESS_KEY_ID='<omitted>' \
-e AWS_DEFAULT_REGION='us-east-1' \
mydockerimage:0.1 \
bash -c "aws s3 ls my-bucket-name/dir/ | sort | tail -n 1 | awk '{print \$4}') && \
echo \$OPFILENAME
'''
"""
}
}
}
}
}
Вот ошибка, которую выдает Дженкинс:
...bash -c "aws s3 ls my-bucket-name/dir/ | sort | tail -n 1 | awk {print' '}") && echo $OPFILENAME "
'
bash: -c: line 1: unexpected EOF while looking for matching `"'
bash: -c: line 3: syntax error: unexpected end of file
Обратите внимание, как он изменил awk
команда как таковая: awk {print' '}
Пробуем разные изменения: ...| sort | tail -n 1 | awk \'{print \$4}\'")
приводит к точно такой же ошибке.
Пробовал вот так: awk "'{print \$4}'"
и это не выдает ошибку но в журналах это выглядит так: awk "{print' '}"
таким образом, желаемая обрезка awk не выполняется. Грр!
Итак, я знаю, что с цитированием что-то не так, и поскольку я использую тройные кавычки для многострочных команд, это еще больше загрязняет его!
Я сослался на эту суть, пытаясь понять, как это сделать: https://gist.github.com/Faheetah/e11bd0315c34ed32e681616e41279ef4 но все еще сталкивается с проблемой за проблемой.
Предостережения: - Команда должна выполняться в sshagent
блок и на удаленном хосте. Команды нельзя запускать в локальной рабочей области Jenkins.
Ошибка связана с отсутствующей двойной кавычкой между '{print \$4}'
и )
. Он есть в исходном скрипте, но отсутствует в файле Jenkins.
Тем не менее, это очень сложная проблема, поскольку несколько процессов будут удалять / обрабатывать предложение. Во-первых, это сам Groovy. Тогда есть Дженкинс sh
команда (плюс процесс оболочки, который запустит команда), затем ssh
, затем удаленная оболочка, которая ssh
начнется, затем bash
который вы запускаете. Один из них - удаление \
перед $4
что ломает ваш сценарий AWK.
Вы можете попытаться решить эту конкретную проблему, используя awk -f script
или используя sed
чтобы свернуть несколько пробелов в одно, а затем использовать cut
: ... | sed -e 's/ +/ /g' | cut -d " " -f 4 | ...
Но, в конце концов, он всегда будет хрупким.
Я настоятельно рекомендую создать файл сценария, скопировать его на удаленный хост и запустить ssh bash ./script.sh
. Это снимет такую головную боль. Кроме того, вы сможете тестировать и отлаживать сценарий из командной строки без необходимости проходить через Jenkins после каждого изменения.
В качестве альтернативы поместите большую часть сценария в настраиваемый образ докера и выберите его в качестве команды по умолчанию для образа.
Используя Плагин SSH Pipeline Steps может помочь, так как в нем есть опция sshScript, которая копирует сценарий на удаленный сервер и затем выполняет его там: https://github.com/jenkinsci/ssh-steps-plugin#sshscript