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

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

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

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

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

Avatar for Moscow Python Meetup

Moscow Python Meetup PRO

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