Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Сборка Python проекта

Сборка Python проекта

Эдуард Искандаров (Программист проекта Антиспама Mail.Ru Group)

Сборка — важный и ответственный этап жизненного цикла программного продукта.В мире Python этот процесс связан с некоторыми заблуждениями и необоснованными усложнениями.Доклад содержит обзор проблем со сборкой и способ их решений на примере Django проекта.Предложенный подход естественным образом вписывает проект в экосистему Python, чем значительно упрощает эксплуатацию и предоставляет ряд преимуществ.

Moscow Python Meetup

February 20, 2014
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Moscow Django MeetUp №17 fabric workflow $ fab stop_services $

    fab backup $ fab pull $ fab migrate $ fab start_services
  2. Moscow Django MeetUp №17 Workflow в Mail.Ru Group Разработка Эксплуатация

    RPM* в продакшн чик-чик-чик * любой другой формат бинарный пакетов
  3. Moscow Django MeetUp №17 Терминология • Пакет это директория, содержащая

    файлы Python • Python файлы называются модулями • Дистрибутив - бинарный дистрибутив или дистрибутив исходных кодов проекта в виде tar или zip архива
  4. Moscow Django MeetUp №17 Абстрактные требования • Понятный способ организации

    файлов • Воспроизводимость окружения • Контроль версий Python пакетов • Контроль версий системных пакетов • Контроль процесса установки проекта • Cценарии до и после установки • Предоставить удобные инструменты эксплуатации • Init скрипты • Различные утилиты
  5. Moscow Django MeetUp №17 Инструменты сборки • distutils (python setup.py

    bdist_rpm) • pypi2rpm (python setup.py bdist_rpm2) • наследует класс distutils.command.bdist_rpm.bdist_rpm • можно задавать внешний .spec файл, но при этом теряется мета информация
  6. Moscow Django MeetUp №17 Инструменты сборки • distutils (python setup.py

    bdist_rpm) • pypi2rpm (python setup.py bdist_rpm2) • наследует класс distutils.command.bdist_rpm.bdist_rpm • можно задавать внешний .spec файл, но при этом теряется мета информация virtualenv не поддерживается
  7. Moscow Django MeetUp №17 pony-homepage $ tree . ├── contrib

    │ └── pony-homepage.spec ├── pony_homepage │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── Makefile ├── manage.py └── setup.py ! 2 directories, 8 files
  8. Moscow Django MeetUp №17 urls.py и settings.py urlpatterns = patterns('',

    (r'^$', TemplateView.as_view( template_name='pony/pony.html'))) INSTALLED_APPS = ( 'pony_homepage', 'pony', 'django.contrib.admin', urls.py settings.py
  9. Moscow Django MeetUp №17 setup.py from setuptools import setup, find_packages

    setup( name = 'pony-homepage', version = '0.1.0', packages = find_packages(), scripts = ['manage.py'], ! install_requires = ['Django==1.6.2', 'django-pony==1.0'], ! # metadata for upload to PyPI author = 'Eduard Iskandarov', author_email = '[email protected]', description = 'Pony Homepage', long_description = 'AWESOME application for every pony', license = 'BSD', keywords = 'django pony rpm spec virtualenv rpm', url = 'https://github.com/toidi/pony-homepage', )
  10. Moscow Django MeetUp №17 Закрепим результат # Сборка дистрибутива выполняется

    командой $ python setup.py egg_info -RDb "" sdist ! ! # Пример установки из локальной ФС: $ pip install dist/pony-homepage-0.1.0.tar.gz
  11. Moscow Django MeetUp №17 pony-homepage.spec 24 %prep 25 %setup -qc

    26 27 %build 28 python setup.py egg_info -RDb "" sdist 29 30 %install 31 virtualenv %{buildroot}/opt/%{_name} ! 32 %{buildroot}/opt/%{_name}/bin/python -m pip install\ dist/%{_name}-%{_version}.tar.gz 33 34 # fix path 35 find %{buildroot}/opt/%{_name}/bin -type f\ 36 -exec sed -i 's:'%{buildroot}'::' {} \;
  12. Moscow Django MeetUp №17 Makefile 18 rpm: archive 19 mv

    $(NAME)-$(VERSION).tar.gz ~/rpmbuild/SOURCES ! 20 cp contrib/pony-homepage.spec ~/rpmbuild/SPECS ! 21 rpmbuild ~/rpmbuild/SPECS/pony-homepage.spec -bb\ 22 --define "_name $(NAME)"\ 23 --define "_version $(VERSION)"\ 24 --define "_release $(RELEASE)"\ 25 --define "_description $(DESCRIPTION)"\ 26 --define "_license $(LICENSE)"\ 27 --define "_url $(URL)"\ 28 --define '_long_description $(LONG_DESCRIPTION)'
  13. Moscow Django MeetUp №17 RPM готов! $ make rpm !

    # yum localinstall ponyhomepage—0.1.0-1.el6.x86_64.rpm
  14. Moscow Django MeetUp №17 Структура директорий # tree -L 5

    -d /opt/ /opt/ └── pony-homepage ├── bin ├── include │ └── python2.7 -> /usr/include/python2.7 ├── lib │ └── python2.7 │ ├── config -> /usr/lib64/python2.7/config │ ├── distutils │ ├── encodings -> /usr/lib64/python2.7/encodings │ ├── lib-dynload -> /usr/lib64/python2.7/lib-dynload │ └── site-packages │ ├── django │ ├── Django-1.6.2-py2.7.egg-info │ ├── django_pony-1.0-py2.7.egg-info │ ├── _markerlib │ ├── pip │ ├── pip-1.4.1-py2.7.egg-info │ ├── pony │ ├── pony_homepage │ ├── pony_homepage-0.1.0-py2.7.egg-info │ ├── setuptools │ └── setuptools-0.9.8-py2.7.egg-info └── lib64 -> lib ! 23 directories virtualenv
  15. Moscow Django MeetUp №17 Поехали $ /opt/pony-homepage/bin/gunicorn pony_homepage.wsgi ! !

    ! ! $ uwsgi --http :8000 --virtualenv /opt/pony-homepage\ —wsgi pony_homepage.wsgi
  16. Moscow Django MeetUp №17 Best practice • Применяем setuptools •

    Устанавливаем проект в virtualenv • Пакуем все в RPM
  17. Moscow Django MeetUp №17 Куда двигаться дальше? • запуск проекта

    после установки (init script, supervisord, daemon tools, runit, systemd) • requirements.txt • vendor lock (рассмотренный пример относится к rpm-based дистрибутивам) • страницы с руководством (man pages) (distutils, sphinx) • конфигурация проекта • advanced python packaging • конфигурация веб сервера (gunicorn, uwsgi, circus) связка с nginx • continuous integration • private pypi
  18. Moscow Django MeetUp №17 Бонусы 1. syncdb $ /opt/pony-homepage/bin/manage.py syncdb

    ! ! ! 2. ! ! ! ! ! $ /opt/pony-homepage/bin/python -m pony_homepage What does the pony say? IGOGO!
  19. Moscow Django MeetUp №17 Ссылки • https://github.com/toidi/pony-homepage! • http://docs.python.org/2.7/distutils/builtdist.html! •

    http://pythonhosted.org/setuptools! • https://bitbucket.org/tarek/pypi2rpm! • http://www.virtualenv.org! • http://www.pip-installer.org! • http://wiki.centos.org/HowTos/SetupRpmBuildEnvironment! • http://fedoraproject.org/wiki/How_to_create_an_RPM_package
  20. Moscow Django MeetUp №17 PROBLEMS?! # Activate the virtual environment

    cd $DJANGODIR source ../bin/activate export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE export PYTHONPATH=$DJANGODIR:$PYTHONPATH ! # Create the run directory if it doesn't exist RUNDIR=$(dirname $SOCKFILE) test -d $RUNDIR || mkdir -p $RUNDIR ! # Start your Django Unicorn # Programs meant to be run under supervisor should not # daemonize themselves (do not use --daemon) exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \ --name $NAME \ --workers $NUM_WORKERS \ --user=$USER --group=$GROUP \ --log-level=debug \ --bind=unix:$SOCKFILE