Как создать виртуальный диск Python в Jenkins?

Я использую Makefile для обеспечения согласованных одиночных команд для настройки virtualenv, запуска тестов и т.д. Я настроил свой экземпляр Jenkins для переноса из меркурийного репо и затем запустил "make virtualenv", который делает это:

virtualenv --python=/usr/bin/python2.7 --no-site-packages . && . ./bin/activate && pip install -r requirements.txt

Но по какой-то причине он настаивает на использовании установленного системой пипа и пытается установить мои зависимости пакета в системных сайтах-пакетах, а не в virtualenv:

error: could not create '/usr/local/lib/python2.7/dist-packages/flask': Permission denied

Если я добавлю некоторые команды отладки и явно укажу на пипс в своем виртуальном пространстве, все становится еще более запутанным:

virtualenv --python=/usr/bin/python2.7 --no-site-packages . && . ./bin/activate && ls -l bin && which pip && pwd && ./bin/pip install -r requirements.txt

Что генерирует следующий вывод:

New python executable in ./bin/python2.7
Not overwriting existing python script ./bin/python (you must use ./bin/python2.7)
Installing setuptools, pip...done.
Running virtualenv with interpreter /usr/bin/python2.7

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

Вывод из "ls -l bin" показывает, что pip должен быть установлен в virtualenv и исполняемый файл:

-rw-r--r-- 1 jenkins jenkins    2248 Apr  9 21:14 activate
-rw-r--r-- 1 jenkins jenkins    1304 Apr  9 21:14 activate.csh
-rw-r--r-- 1 jenkins jenkins    2517 Apr  9 21:14 activate.fish
-rw-r--r-- 1 jenkins jenkins    1129 Apr  9 21:14 activate_this.py
-rwxr-xr-x 1 jenkins jenkins     278 Apr  9 21:14 easy_install
-rwxr-xr-x 1 jenkins jenkins     278 Apr  9 21:14 easy_install-2.7
-rwxr-xr-x 1 jenkins jenkins     250 Apr  9 21:14 pip
-rwxr-xr-x 1 jenkins jenkins     250 Apr  9 21:14 pip2
-rwxr-xr-x 1 jenkins jenkins     250 Apr  9 21:14 pip2.7
lrwxrwxrwx 1 jenkins jenkins       9 Apr 10 19:31 python -> python2.7
lrwxrwxrwx 1 jenkins jenkins       9 Apr 10 19:31 python2 -> python2.7
-rwxr-xr-x 1 jenkins jenkins 3349512 Apr 10 19:31 python2.7

Вывод "какой пип", похоже, хочет использовать правильный:

/var/lib/jenkins/jobs/Run Tests/workspace/bin/pip

Мой текущий рабочий каталог - это то, что я ожидаю:

/var/lib/jenkins/jobs/Run Tests/workspace

Но... wtf?

/bin/sh: 1: ./bin/pip: Permission denied
make: *** [virtualenv] Error 126
Build step 'Execute shell' marked build as failure
Finished: FAILURE

Ответ 1

Я использую python virtualenvs с Jenkins каждый день за последние два года, в нескольких компаниях и для небольших проектов, и не могу сказать, что нашел ответ "THE". Тем не менее, я надеюсь, что обмен опытом поможет другим сэкономить время. Надеюсь, я получу дальнейшую обратную связь, чтобы облегчить решение.

  • Избегать ShiningPanda - он не поддерживается, несовместим с конвейерами Jenkins2 и предотвращает параллельное выполнение заданий. Также у него есть плохая привычка выходить из сиротских окружений на диск.
  • DIY через bash и virtualenv - мой текущий любимый. Создайте его внутри $WORKSPACE и, если не всегда, очистите, запустите relocatable, прежде чем активировать их. Это связано с тем, что местоположение дискового пространства рабочей папки jenkins может меняться между выполнением задания N и N + 1.

Если вы используете несколько сборщиков, которым нужен тот же самый virtualenv, самый простой способ - выгрузить вашу среду в файл и указать ее в начале нового построителя.

Чтобы облегчить обслуживание, я планирую изучить их:

  • direnvm
  • virtualenv-wrapper (mkvirtualenv)
  • pyenv

Если вы нажмете ограничения командной строки shebang, самое лучшее, что вам нужно сделать, это изменить домашний каталог jenkins на /j.

Ответ 2

Конвейеры Jenkins могут быть созданы для работы с виртуальными средами, но есть несколько вещей, которые следует учитывать.

  • Стандартная оболочка, используемая Jenkins, /bin/sh - это настраивается в Управлять Дженкинсом → Конфигурировать систему → Shell → Shell исполняемый. Установка этого параметра в /bin/bash приведет к работе source.
  • Активированный venv просто изменяет переменные среды, а переменные окружения не сохраняются между этапами в jenkins. См. withEnv
  • Если вы используете управляемые версиями мультибрендовые конвейеры, jenkins создает рабочую область с именем ветки и хешем фиксации на пути - который может быть довольно длинным. venv-скрипты (например, pip) начинаются с строки hashbang, которая включает полный путь к интерпретатору python в venv (сам интерпретатор python является символической ссылкой). Например.

    ~/workspace/ink_feature-use-jenkinsfile-VGRPYD53GGGDDSBIJDLSUDYPJ34QR63ITGMC5VJNB56W6ID244AA/env/bin$ cat pip
    #!/var/jenkins_home/workspace/ink_feature-use-jenkinsfile-VGRPYD53GGGDDSBIJDLSUDYPJ34QR63ITGMC5VJNB56W6ID244AA/env/bin/python3.5
    

    Bash только считывает первые N символы любого исполняемого файла, который я нашел, не совсем включал полный путь venv:

    bash: ./pip: /var/jenkins_home/workspace/ink_feature-use-jenkinsfile-VGRPYD53GGGDDSBIJDLSU: bad interpreter: No such file or directory
    

    Эту конкретную проблему можно избежать, выполнив вместо этого script с помощью Python. Например. python3.5 ./pip

Ответ 3

Вы можете найти этот плагин Jenkins полезным: https://wiki.jenkins-ci.org/display/JENKINS/ShiningPanda+Plugin

Этот плагин добавляет поддержку Python Jenkins с помощью некоторых полезных построителей (построитель Python, конструктор virtualenv, построитель тонов...) и возможность использовать ось Python в проектах с несколькими конфигурациями (для тестирования на нескольких версиях Python).

Ответ 4

У меня такая же проблема. Как я вижу, проект называется "Run Tests". Итак, это имя содержит пробел. Это была проблема для меня. Я просто переименовал проект, например RunTests, и теперь Venv работает! Внимание - jenkins спрашивают вас о проекте переименования подтверждения.

Ответ 5

Я бы рекомендовал избегать ShiningPanda.

Я установил свои виртуальные среды с помощью Anaconda/Miniconda. При установке conda убедитесь, что вы работаете как пользователь jenkins.

[email protected]$ sudo -u jenkins sh
[email protected]$ wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
[email protected]$ bash Miniconda3-latest-Linux-x86_64.sh

Поскольку Jenkins запускает sh, а не bash, я добавил путь conda к /etc/profile:

export PATH="/var/lib/jenkins/miniconda3/bin:$PATH"

Затем в файле Jenkinsfile вы можете создавать и удалять среды конда. Вот пример, который создает новую среду для каждой сборки:

pipeline {
    agent any
    stages {
        stage('Unit tests') {
            steps {
            sh '''
                conda create --yes -n ${BUILD_TAG} python
                source activate ${BUILD_TAG}
                // example of unit test with nose2
                pip install nose2
                nose2
            '''
            }
        }
    }
    post {
        always {
            sh 'conda remove --yes -n ${BUILD_TAG} --all'
        }
    }
}