пятница, 7 июля 2017 г.

Сборка кроссплатформенного python-инсталлятора с помощью conda constructor

Задача: необходимо собрать минимальное окружение c python 2.7 и gsutil на борту. Окружение должно устанавливаться на Linux, Mac OS X, Windows.
Конечный результат: в каталог файловой системы устанавливаются python и gsutil, который можно использовать без установки системных зависимостей.

Делаю это на основе чистого контейнера с CentOS 7:
# docker run -ti centos bash
# cat /etc/redhat-release 
CentOS Linux release 7.2.1511 (Core)

Устанавливаем miniconda, conda-build и constructor:
# DIR=/srv/miniconda
# yum install -y wget bzip2 git patch vim
# wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
# bash Miniconda3-latest-Linux-x86_64.sh -b -p $DIR
# export PATH=$DIR/bin:$PATH
# conda install constructor conda-build

Создаем скелет для gsutil:
# conda skeleton pypi gsutil

Если мы сейчас попробуем собрать gsutil, то ничего не выйдет, так как у него много зависимостей. Собираем все зависимости для него:
# conda skeleton pypi argcomplete --version 1.8.2; conda build argcomplete
# conda skeleton pypi crcmod --version 1.7; conda build crcmod
# conda skeleton pypi httplib2 --version 0.9.1; conda build httplib2
# conda skeleton pypi retry_decorator --version 1.0.0; conda build retry_decorator
# conda skeleton pypi socksipy-branch; conda build socksipy-branch
# conda skeleton pypi rsa --version 3.1.4 ; conda build rsa

oauth2client тоже собираем, но с небольшими правками в конфиге:
# conda skeleton pypi oauth2client --version 2.2.0
# vim oauth2client/meta.yaml
...
   #- oauth2client.contrib.django_util

# conda build oauth2client

Собираем остальные зависимости:
# conda skeleton pypi gcs-oauth2-boto-plugin --version 1.14 ; conda build gcs-oauth2-boto-plugin
# conda skeleton pypi unittest2 --version 0.5.1 ; conda build unittest2
# conda skeleton pypi google-apitools --version 0.5.3 ; conda build google-apitools

Все зависимости собраны, можно собирать gsutil:
# vim gsutil/meta.yaml
   #commands:
   #- gsutil --help

# vim gsutil/build.sh
python setup.py install --single-version-externally-managed --record=/tmp/record.txt

# conda build gsutil

Мы успешно собрали пакет gsutil с зависимостями для Linux, теперь конвертируем их для Windows/Mac:
# cd $DIR/conda-bld/
# ls $DIR/conda-bld/linux-64/* | grep -v "repodata" | xargs -i conda convert -f --platform osx-64 {}
# ls $DIR/conda-bld/linux-64/* | grep -v "repodata" | xargs -i conda convert -f --platform win-64 {}

Устанавливаем anaconda-client и заводим учетку в Anaconda Cloud, логинимся и загружаем наши собранные пакеты в облако:
# conda install anaconda-client
# anaconda login
# ls $DIR/conda-bld/linux-64/* -rt1 | grep -v "repodata" | xargs -i anaconda upload {}
# ls $DIR/conda-bld/osx-64/* -rt1 | grep -v "repodata" | xargs -i anaconda upload {}
# ls $DIR/conda-bld/win-64/* -rt1 | grep -v "repodata" | xargs -i anaconda upload {}

Теперь непосредственно собираем инсталлятор, в нем будет python 2.7 и gsutil:
# vim construct.yaml 
name: gsutil
version: 1.0.0

channels:
  - http://repo.continuum.io/pkgs/free/
  - https://conda.anaconda.org/conda-forge
  - https://conda.anaconda.org/editme # Ваш канал
specs:
  - python 2.7*
  - gsutil 4.27

Собираем инсталлятор для Linux и Mac OS X:
# constructor .
...
Successfully created '/gsutil-1.0.0-Linux-x86_64.sh'.

# constructor . --platform=osx-64
...
Successfully created '/gsutil-1.0.0-MacOSX-x86_64.sh'.

Для Windows инсталлятор нужно собирать только на Windows, порядок такой:
1. Ставим miniconda
2. Ставим constructor:
> conda install constructor
3. Создаем meta.yaml
4. Собираем инсталлятор:
> constructor .

Пример установки окружения:
# ./gsutil-1.0.0-Linux-x86_64.sh -b -p /root/gsutil
PREFIX=/root/gsutil
installing: python-2.7.13-1 ...
Python 2.7.13
...
installation finished.

# cd /root/gsutil/bin/
# ./gsutil --version
gsutil version: 4.27

Протестировано на:
  • CentOS 6, 7
  • Ubuntu 12.04, 16.04
  • Debian 7, 8
  • Windows 10

Не тестировал на Mac OS X (но работать должно).

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

Комментариев нет: