zc.buildout

 zc.buildout

Обзор инструмента для автоматизации сборки программ
и подготовки окружения для их выполнения.

Ee4d18563a657e6b45c19fdce003602f?s=128

Kirill Kuzminykh

November 11, 2017
Tweet

Transcript

  1. 1.
  2. 3.

    3 История создания Zope Corporation, начало 2000-ых: – помощь клиентам

    в соборке приложений на базе Zope; – очень большое разнообразие окружения - главная сложность в развёртывании приложения; – получение предскажуемого результата требует как то изолироваться от клиентского окружения. Решение: – собственная сборка Python в которую устанавливалось приложение; – автоматизация с помощью make.
  3. 4.

    4 История создания 2005 год: – приложения становятся сложнее –

    возникает желание использовать Python для автоматизации развёртывания; – внутренний прототип системы с конфигом на базе формата ConfigParser – секции описывали вещи, которые надо собирать; – несколько встроенных рецептов для сборки и возможность создавать сторонние рецепты; – всё ещё используется своя сборка Python для изоляции. Результат: решенно сделать zc.buildout.
  4. 5.

    5 История создания Появились setuptools и easy_install. Они автоматизировали скачивание

    и установку пакетов и их зависимостей. Результат: новая версия zc.buildout использует setuptools. Но easy_install устанавливал зависимости, но не обновлял их. Результат: следующая версия zc.buildout использует setuptools на более низком уровне, реализуя свою логику работы с пакетами.
  5. 7.

    7 Что это такое? Инструмент для автоматизации сборки программного обеспечения

    – Запуск инструментов для сборки программ – Выполнение программ и шаблонов для создания скриптов и конфигов – Применим на всех стадиях, от разработки до выкатки
  6. 8.

    8 Что это такое? Это не совсем: – Make или

    Apache Ant Buildout – более высокоуровневый. Он сам может использовать make и ant как часть процесса сборки. – Puppet, chef и др. Buildout – сфокусирован на конкретном приложении. Puppet, chef и др. могут использовать buildout для решения своих задач.
  7. 9.

    9 Что это такое? Принципы: – Воспроизводимость – результат сборки

    должен быть одинаков в одинаковом окружении (OS и версия Python). – Автоматизация – с помощью одной/двух простых команд должна получаться готовая к работе система. – Приложение должно быть самодостаточным настолько насколько это возможно.
  8. 11.

    11 Как это выглядит? $ git clone myproject.git $ cd

    myproject . ├── src/ ├── bootstrap.py └── buildout.cfg
  9. 13.

    13 Как это выглядит? . ├── bin/ │ ├── buildout

    │ ├── myscript │ └── ... ├── eggs/ │ ├── requests-2.18.4-py2.7.egg/ │ └── ... ├── src/ ├── bootstrap.py └── buildout.cfg
  10. 14.

    14 Как это выглядит? . ├── bin/ │ ├── buildout

    │ ├── myscript │ └── ... ├── eggs/ │ ├── requests-2.18.4-py2.7.egg/ │ └── ... ├── src/ ├── bootstrap.py └── buildout.cfg
  11. 17.

    17 А что там внутри? . ├── bin/ │ ├──

    buildout │ ├── myscript │ └── ... ├── eggs/ │ ├── requests-2.18.4-py2.7.egg/ │ └── ... ├── src/ ├── bootstrap.py └── buildout.cfg
  12. 18.

    18 А что там внутри? . └── src/ ├── myapp/

    │ ├── __init__.py │ └── main.py └── setup.py
  13. 19.

    19 А что там внутри? . └── src/ ├── myapp/

    │ ├── __init__.py │ └── main.py └── setup.py
  14. 20.

    20 ./src/setup.py from setuptools import setup setup( name='myapp', install_requires=[ 'setuptools',

    'requests', ], entry_points={ 'console_scripts': [ 'myscript = myapp.main:main', ] } )
  15. 21.

    21 А что там внутри? . ├── src/ │ ├──

    myapp/ │ │ ├── __init__.py │ │ └── main.py │ └── setup.py ├── bootstrap.py └── buildout.cfg
  16. 22.
  17. 23.

    23 А что там внутри? . ├── bin/ │ ├──

    buildout │ ├── myscript │ └── ... ├── eggs/ │ ├── requests-2.18.4-py2.7.egg/ │ └── ... ├── src/ ├── bootstrap.py └── buildout.cfg
  18. 24.

    24 ./bin/myscipt #!/usr/bin/python import sys sys.path[0:0] = [ '/home/user/myproject/src', '/home/user/myproject/eggs/requests-2.18.4-py2.7.egg',

    '/home/user/myproject/eggs/urllib3-1.22-py2.7.egg', ... ] import myapp.main if __name__ == '__main__': sys.exit(myapp.main.main())
  19. 26.

    26 Подстановка значений ${SECTION:OPTION} [myproject] recipe = zc.recipe.egg eggs =

    myapp initialization = import os os.environ['HOST'] = '${settings:host}' os.environ['POST'] = '${settings:port}' [settings] host = localhost port = 8080
  20. 29.

    29 Макросы [server] recipe = zc.zdaemonrecipe port = 8080 program

    = ${buildout:bin-directory}/serve --port ${:port} --name ${:_buildout_section_name_} [server1] <= server port = 8081 [server2] <= server port = 8082
  21. 30.

    30 Зависимости [buildout] develop = . parts = run_app [run_app]

    => app recipe = collective.recipe.cmd on_install = true cmds = ${buildout:bin-directory}/app ${config:location} [app] recipe = zc.recipe.egg:scripts eggs = myapp
  22. 31.

    31 Условные секции [create_dirs] recipe = collective.recipe.cmd on_install = true

    cmds = mkdir ${buildout:directory}/var [create_dirs:windows] cmds = md ${buildout:directory}\var [buildout:os.environ.get('ALPINELINUX')] find-links += http://privat-pypi.com/simple/numpy
  23. 33.

    33 Рецепты Рецепт: – это компонент реализующий логику "части"; –

    является обычным питонячим классом с методами: • install() • update() – в одном пакете может быть несколько рецептов; – Buildout автоматически скачивает и устнаваливает пакеты с рецептами.
  24. 34.

    34 zc.recipe.egg:scripts [myproject] revipe = zc.recipe.egg:scripts eggs = myapp ipython<6.0

    interpreter = python find-links = https://domain.com/Django index = https://private-pypi.com/simple setting = myapp.production initialisation = import os os.environ.setdefault('DJANGO_SETTINGS_MODULE', '${:settings}')
  25. 35.

    35 zc.recipe.egg:scripts ./bin/manage.py #!/usr/bin/python import sys sys.path[0:0] = [ '/home/user/myproject/src',

    '/home/user/myproject/eggs/ipython-5.0.0-py2.7.egg', ... ] import os os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.production') import myapp.manage if __name__ == '__main__': sys.exit(myapp.manage.main())
  26. 36.

    36 zc.recipe.egg:custom [pillow-simd-env] CC = cc -mavx2 [pillow-simd] recipe =

    zc.recipe.egg:custom egg = Pillow-SIMD environment = pillow-simd-env
  27. 37.

    37 zc.recipe.cmmi (configure-make-make-install) [librsync] recipe = zc.recipe.cmmi url = https://domain.com/librsync-0.9.7.tar.gz

    extra_options = --enable-shared [rdiff-backup] recipe = zc.recipe.egg:custom egg = rdiff-backup rpath = ${librsync:location}/lib include-dirs = ${librsync:location}/include library-dirs = ${librsync:location}/lib
  28. 41.

    41 mr.developer [buildout] extensions = mr.developer auto-checkout = * sources-dir

    = ext_src [sources] twisted = git git@github.com:twisted/twisted.git six = git git@github.com:benjaminp/six.git rev=1.8.0
  29. 42.
  30. 44.

    44 Воспроизводимость [buildout] allow-picked-versions = true show-picked-versions = true [versions]

    zc.buildout = 2.9.5 zc.recipe.egg = 2.0.3 setuptools = 36.6.0 six = 1.8.0 pyramid = 1.9.1
  31. 49.

    49 Eclipse + PyDev + zc.buildout [buildout] develop = ./src

    parts = myproject pydev [myproject] recipe = zc.recipe.egg:scripts eggs = myapp [pydev] recipe = pb.recipes.pydev eggs = ${myproject:eggs}
  32. 50.

    50 Other + zc.buildout [buildout] develop = ./src parts =

    myproject omelette [myproject] recipe = zc.recipe.egg:scripts eggs = myapp [omelette] recipe = collective.recipe.omelette eggs = ${myproject:eggs}
  33. 51.

    51 Other + zc.buildout . └── parts/ └── omelette/ ├──

    certifi/ ├── chardet/ ├── idna/ ├── myapp/ ├── pkg_resources/ ├── requests/ ├── setuptools/ ├── urllib3/ └── easy_install.py
  34. 54.

    54 А как же Docker, Vagrant и т.п.? Пускай будут

    – они тоже полезные, но не заменяют Buildout.
  35. 58.

    58 zc.recipe.cmmi (configure-make-make-install) [nginx] recipe = zc.recipe.cmmi url = http://sysoev.ru/nginx/nginx-0.7.65.tar.gz

    md5sum = abc4f76af450eedeb063158bd963feaa patch = ${buildout:directory}/nginx/upstream_hash.patch extra_options = --add-module=${buildout:directory}/nginx/upstream_hash