Найти - Пользователи
Полная версия: окружение питона и deploy
Начало » Python для экспертов » окружение питона и deploy
1 2
shiza
Давненько я тут не был =)

Кто-нибудь встречался с такой ситуацией, когда идет разработка одного чего-либо на нескольких компьютерах ( в несколько человек). И нужно поддерживать в актуальном (и одинаковом) состоянии питоновские библиотеки на всех этих машинах + боевой сервер.
Код синхонизируется и выкатывается в продакшн с помощью hg.

p.s. либы есть и бинарные, а машины возможны с разными архитектурами
slav0nic
pip с указанием зависимостей (поддерживает hg и может их дообновлять) + virtualenv
хотя у себя я обычно делаю setup.py develop и вручную обновляю репозитории либ
или я не понял сложностей)
shiza
Выразил мысль неоднозначно. Попробую доавить конкретики =)

Есть большой веб-проект, разрабатывается в несколько (больше 5) человек. Не все из них питоновые програмисты (есть верстальщики, дизайнеры… )

Цикл разработки проходит так:
Каждый забирают актуальную версию проекта с выделенного как корневой репозиторий hg. Работают над ней и заливают обратно.
При работе у каждого из них крутится его личная локальная копия веб-проекта (чтоб он мог работать не мешая остальным).

Переодически происходит выкладка на продакшен (с помощью hg).

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

Внимание вопрос!
Как сделать так, чтоб не пришлось бегать по всем машинам разработчиков + продакшн сервер и ставить ручками появившиеся в проекте новые сторонние модули. =)
Андрей Светлов
slav0nic правильно подсказывает.
Во первых - обязательно virtualenv. Просто потому что…
Затем - по меньшей мере свой код должен ставиться через setup.py develop. Вероятно, потом потребуется и install с bdist_<что хочется>.
С third party к сожалению не всегда все просто. То “яиц” нужных нет, то версия должна быть очень уж специфическая.
Решали так: есть спец проект для deployment. В нем несколько полезных утилит и - главное - набор egg файлов. Egg можно сделать практически из любой библиотеки - даже если она это не поддерживает изначально. И есть спец утилита, которая ставит эти egg в правильном dependency order (он вычислялся с помощью pkg_resources).
Пример: нужно добавить xlwt и pil для win23, win64 и linux32. xlwt сделан на чистом питоне - хватит одного яцйа. Для pil качаем/собираем яйца для каждой платформы.
Потом ложим их в data folder (он тоже часть deployment project).
data/
xlwt_version.egg
win32/
pil_version.egg
win64/
pil_version.egg
linux32/
pil_version.egg
запускаем update_deps - это наш скрипт.
Он проверит - что уже установлено, что нужно поставить - фильтруя по архитектуре.
Посортирует все и заинсталлит.

Еще были утилиты для создания virtualenv (в режиме without site packages по умолчанию), setup develop для всех своих проектов и т.д. - в том числе “сделать все”.

Обычная схема работы - программист добавляет новое яйцо (если это свежая версия - то и удаляет старое, номер версии прописан в egg metadata). Пишет в рассылку: обновитесь.
Вся команда дружно обновляет свои репозитарии и запускает update_eggs.

Минусы: это несколько велосипед - но от него никуда не деться, слишком много разных форматов для дистрибутивов существует. Собирать библиотеки с C Extensions из исходников на винде - тяжело, не каждому под силу настроить environment.
После скандала с setuptools egg - не самый любимый формат. Но он единственный “бинарный кроссплатформенный”.
Иногда приходится повозиться пару часов, чтобы сделать egg из либы, которая очень сильно тому сопротивляется. Делать приходится очень редко.

shiza, еще вопросы остались?
shiza
virtualenv с pip конечно используем.
Даже одно время хранили окружения virtualenv (вместе со всеми либами) в репозиториях и их синхронизировали между машинами, пока не уперлись в разницу архитектур x32, x64. Windows платформ не используем =)
shiza
Андрей Светлов
Спасибо, сейчас попробую вникнуть в эту схему.
shiza
а ни у кого нет опыта использования buildout? читаю про эту штуку, но уж больно мудреная =)
poltergeist
Выложу свой метод выкладки и организации проекта, недавно решил попробовать tornado веб сервер, поэтому в конфигах использую его.
Хост:
- дистр: debian
- собранный из исходников питон лежит тут: /home/web/python
- кэш для загружаемых пакетов тут: /home/web/downloads, там же складываются пакеты, которых нет на PyPi (tornado например)
- репозиторий: /var/hg/vmagamedov - стандартный джанговский проект, в корне лежит settings.py
- проекты лежат в домашней директории юзера “web”, т.е. /home/web/magamedov.com/
Структура проекта до запуска buildout:
bin/
server.template
manage.template
etc/
local_settings.py
src/
var/
log/
run/
buildout.cfg
bootstrap.py
Собираем проект:
python bootstrap.py
bin/buildout
Что добавилось после запуска buildout и запуска сервера (bin/server start):
bin/
python
buildout
server # скрипт для запуска и останова сервера
manage # джанговский manage.py с правильным окружением
develop-eggs/ # new
eggs/ # new
etc/ # не изменилось
parts/ # new
src/
vmagamedov # new
var/
log/
access.log # логи сюда пишет nginx
error.log
run/
server.pid # new
Файл buildout.cfg
[buildout]
newest = false
download-cache = /home/web/downloads
parts =
python
install
update
manage
server

[python]
recipe = zc.recipe.egg
interpreter = python
find-links = ${buildout:download-cache}
extra-paths =
${buildout:directory}/etc
${buildout:directory}/src/vmagamedov
eggs =
django
python-openid
tornado
python-daemon

[install]
recipe = collective.recipe.cmd
on_install = true
cmds =
hg clone /var/hg/vmagamedov ${buildout:directory}/src/vmagamedov

[update]
recipe = collective.recipe.cmd
on_update = true
cmds =
cd ${buildout:directory}/src/vmagamedov
hg pull
hg update

[manage]
recipe = buildout_script
template = ${buildout:directory}/bin/manage.template
PYTHON = ${buildout:directory}/bin/${python:interpreter}
SETTINGS = settings

[server]
recipe = buildout_script
template = ${buildout:directory}/bin/server.template
PORT = 8000
PIDFILE = ${buildout:directory}/var/run/server.pid
PYTHON = ${manage:PYTHON}
SETTINGS = ${manage:SETTINGS}
Файл server.template
#!%(PYTHON)s
from __future__ import with_statement

import os
import sys
import signal

from daemon import DaemonContext
from daemon.pidlockfile import PIDLockFile
from tornado.ioloop import IOLoop
from tornado.httpserver import HTTPServer
from tornado.wsgi import WSGIContainer


PORT = %(PORT)s
PIDFILE = '%(PIDFILE)s'


def start():
from django.core.management import setup_environ
import %(SETTINGS)s
setup_environ(%(SETTINGS)s)
#
from django.core.handlers.wsgi import WSGIHandler
from django.core.servers.basehttp import AdminMediaHandler
#
wsgi_app = AdminMediaHandler(WSGIHandler())
container = WSGIContainer(wsgi_app)
#
context = DaemonContext(pidfile=PIDLockFile(PIDFILE))
context.signal_map = {
signal.SIGTERM: lambda signum, frame: IOLoop.instance().stop(),
}
with context:
http_server = HTTPServer(container)
http_server.listen(PORT)
IOLoop.instance().start()


def stop():
if os.path.exists(PIDFILE):
try:
pid = int(open(PIDFILE, 'r').read())
except Exception:
print 'Error: wrong PIDFILE'
else:
os.kill(pid, signal.SIGTERM)
else:
print 'Error: PIDFILE not found'


if __name__ == '__main__':
if 'start' in sys.argv:
start()
elif 'stop' in sys.argv:
stop()
Файл manage.template
#!%(PYTHON)s
from django.core.management import execute_manager

import %(SETTINGS)s

if __name__ == "__main__":
execute_manager(%(SETTINGS)s)
Скачать:
http://magamedov.com/pub/buildout.cfg
http://magamedov.com/pub/server.template
http://magamedov.com/pub/manage.template

Это конечно не конец, но меня пока устраивает.
Александр Кошелев
А в чем суть собственной сборки питона?
poltergeist
У меня debian etch, там питон 2.4, а для моих проектов минимальным требованием будет 2.5.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB