Назад | Перейти на главную страницу

Синтаксис конвейера Jenkins: проблемы с цитированием при использовании нескольких блоков кавычек

У меня странная установка: мне нужно запустить команду в качестве контейнера докеров в 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