2010.05_Buildout _[Narzedzia Programistyczne].pdf

(420 KB) Pobierz
441710214 UNPDF
Narzędzia
Buildout
Narzędzie automatyzujące budowę i zarządzanie
aplikacjami w języku Python
W trakcie rozwoju aplikacji ilość zależnych bibliotek stopniowo się
zwiększa. Ręczne zarządzanie projektem staje się mało wygodne,
a instalacja oprogramowania na nowej maszynie wydłuża się. Użycie
narzędzia Buildout pozwoli zautomatyzować większość tych czynności
i ułatwi pracę programistom i administratorom.
Dowiesz się:
• Jak tworzyć pliki koniguracyjne buildout;
• Jak instalować aplikacje używając buildout;
• Poznasz najciekawsze dodatki do buildout.
Powinieneś wiedzieć:
• Podstawy obsługi linii komend Unix;
• distutils – mechanizm dystrybucji pakietów.
Inne często używane foldery, lecz nie będą-
ce tworzone podczas pierwszego urucho-
mienia, to:
etc – pliki koniguracyjne;
src – kod źródłowy;
var – miejsce na dane, np. baza danych,
pliki logów itp.
otstrap.py ) oraz plik konfiguracyjny ( buildo-
ut.cfg ). Zadaniem skryptu rozruchowego jest
stworzenie podstawowego środowiska, dzięki
któremu buildout będzie mógł wykonać swo-
je zadania. W przypadku gdy na komputerze,
na którym jest on uruchamiany, brak jest od-
powiednich bibliotek, zostaną one ściągnięte
z Internetu.
Poziom
trudności
Generowany jest także skrypt ./bin/buildout
– wykonujący cały proces budowy aplikacji.
Pliki konfiguracyjne
Konfigurację projektu definiuje się w plikach
w formacie ConfigParser (potocznie zwanym
INI). Plik taki składa się z sekcji, a każda sek-
cja zawiera pary klucz – wartość. Za działanie
każdej z sekcji odpowiedzialna jest tak zwana
recepta (ang. recipe ). Uruchomienie systemu
buildout jest zatem w rzeczywistości wykona-
niem serii plug-in'ów budujących poszczegól-
ne części składowe projektu. Taki mechanizm
wtyczek pozwala w łatwy sposób rozszerzyć
podstawową funkcjonalność systemu.
Zmienne między sekcjami można pobierać
poprzez strukturę ${nazwa-sekcji:klucz} .
Podstawowe parametry działania skryptu de-
finiuje się w sekcji [buildout] . W parame-
trze parts określona jest lista sekcji, które po-
winny zostać zbudowane.
Przykładowy projekt składać ma się z pa-
kietu SimpleSite. Pakiet ten dostępny jest
w repozytorium pakietów Python (PyPI
sposobem na budowanie i dystrybu-
cję takich projektów składających się
z setek czy dziesiątek bibliotek – Plone , Zo-
pe , Grok . Ułatwia także instalację innych pro-
jektów – np.: Django , Pylons , repoze.bfg . Zo-
stał napisany w języku Python z myślą o bu-
dowaniu aplikacji w tym samym języku, ale
nie tylko.
Do zademonstrowania możliwości ofero-
wanych przez Buildout posłużę się aplikacją
SimpleSite – będącą przykładem strony zbu-
dowanej przy użyciu framework-u Pylons.
Jej szerszy opis można znaleźć w „Definitive
Guide to Pylons” ( http://pylonsbook.com ).
$ cd simple-site
$ touch buildout.cfg
$ wget http://tinyurl.com/bootstrap-py
$ python bootstrap.py
Po uruchomieniu skryptu następuje ścią-
gnięcie i zainstalowanie pakietu zc.buildout ,
a więc rdzenia systemu. Tworzona jest także
struktura folderów:
bin – zawiera wygenerowane skrypty;
downloads – miejsce, do którego są ścią-
gane paczki;
eggs – miejsce instalacji pakietów i bi-
bliotek Pythona;
parts – inne biblioteki lub oprogramo-
wanie.
Instalacja
Do instalacji Buildout wymagany jest jedy-
nie interpreter języka Python oraz dostęp do
Internetu. W przypadku instalowania pakie-
tów binarnych potrzebne jest zainstalowanie
Pythona w wersji deweloperskiej. Nie są wy-
magane prawa administratora, gdyż wszyst-
kie operacje wykonywane są w lokalnym
folderze i nie wpływają na pozostałe zain-
stalowane programy. Na początek potrzeb-
ne są dwie rzeczy – skrypt rozruchowy ( bo-
Listing 1. Wynik wykonania skryptu rozruchowego
$ python bootstrap.py
Creating directory ‘/tmp/simple-site/bin’.
Creating directory ‘/tmp/simple-site/parts’.
Creating directory ‘/tmp/simple-site/eggs’.
Creating directory ‘/tmp/simple-site/develop-eggs’.
Generated script ‘/tmp/simple-site/bin/buildout’ .
18
05/2010
S ystem Buildout jest podstawowym
441710214.037.png 441710214.038.png 441710214.039.png 441710214.040.png 441710214.001.png 441710214.002.png 441710214.003.png 441710214.004.png 441710214.005.png 441710214.006.png 441710214.007.png
Buildout
– ang. Python Package Index ) pod adresem
http://pypi.python.org/pypi/SimpleSite . Do uru-
chomienia tej aplikacji potrzebny będzie ser-
wer HTTP wspierający standard WSGI. Naj-
prostszym rozwiązaniem jest użycie zaimple-
mentowanego w Pythonie serwera Paste . By
móc go łatwo uruchomić wprost z listy pole-
ceń, potrzebny jest PasteScript instalowany
przez receptę zc.recipe.egg:scripts .
Aby zbudować projekt, należy teraz uru-
chomić wygenerowany podczas instalacji
skrypt ./bin/buildout . Ściągnie on i zainsta-
luje wszystkie zależne pakiety. Zależności te,
zgodnie ze standardem przyjętym dla biblio-
tek języka Python, a więc distutils , określa-
ne są w pliku setup.py każdej z paczek. W oma-
wianym przypadku głównymi składnikami,
bez których projekt nie może działać, jest Py-
lons (framework, na bazie którego zbudowana
jest aplikacja) oraz Mako (system szablonów).
Teraz można przystąpić do pierwsze-
go uruchomienia aplikacji. W tym celu ko-
nieczne jest wygenerowanie konfiguracji oraz
utworzenie bazy danych.
zainstalowana żadna biblioteka do komu-
nikacji z bazą SQL. Do czasu wdrożenia
aplikacji na serwer produkcyjny wystarczy
prosta implementacja – SQLite. Koniecz-
ne jest zatem dodanie pakietu pysqlite
do projektu. Jest to pakiet binarny, a więc
do instalacji konieczny jest kompilator
GCC, a także pliki nagłówkowe Pytho-
na. Te elementy muszą być zainstalowane
w systemie. Wymagana jest także bibliote-
ka SQLite. Ponieważ w systemie mogą wy-
stępować inne programy używające SQLi-
te w innych wersjach, wolimy, aby biblio-
teka była zainstalowana w lokalnym fol-
derze. W tym celu użyta zostanie recep-
ta zc.recipe.cmmi (skrót od conigure-
make-make-install ).
Po ponownym przebudowaniu ( ./bin/
buildout ) możliwe jest już uruchomienie
serwera:
Listing 2. Zawartość pliku buildout.cfg
[buildout]
parts = paster
eggs = SimpleSite
[paster]
recipe = zc.recipe.egg:scripts
eggs =
PasteScript
${buildout:eggs}
$ ./bin/paster make-conig SimpleSite
simplesite.ini
$ ./bin/paster setup-app simplesite.ini
Niestety ostatnia komenda zakończy się
niepowodzeniem, ponieważ nie została
$ ./bin/paster serve simplesite.ini
Listing 3. Wynik wykonania skryptu budującego
Getting distribution for ‘zc.recipe.egg’.
Got zc.recipe.egg 1.2.2.
Installing paster.
Getting distribution for ‘PasteScript’.
Searching for Paste>=1.3
Reading http://pypi.python.org/simple/Paste/
Reading http://pythonpaste.org
Best match: Paste 1.7.2
Downloading http://pypi.python.org/packages/source/P/Paste/
Paste-1.7.2.tar.gz#md5=a6a58d08dc4bff
91d5d1c519d2277f8a
Processing Paste-1.7.2.tar.gz
Got PasteScript 1.7.3.
Getting distribution for ‘SimpleSite’.
Searching for PasteDeploy
Reading http://pypi.python.org/simple/PasteDeploy/
Reading http://pythonpaste.org/deploy/
Reading http://pythonpaste.org/deploy/paste-deploy.html
Best match: PasteDeploy 1.3.3
Downloading http://pylons.cachely.net/download/0.9.7/
PasteDeploy-1.3.3.tar.gz
Processing PasteDeploy-1.3.3.tar.gz
Searching for Paste>=1.3
Reading http://pypi.python.org/simple/Paste/
Reading http://pythonpaste.org
Best match: Paste 1.7.2
Downloading http://pylons.cachely.net/download/0.9.7/Paste-
1.7.2.tar.gz
Processing Paste-1.7.2.tar.gz
Got SimpleSite 0.3.0.
Getting distribution for ‘AuthKit>=0.4.3,<=0.4.99’.
Got AuthKit 0.4.5.
Getting distribution for ‘FormBuild>=2.0.1,<=2.0.99’.
Got FormBuild 2.0.1.
Getting distribution for ‘Mako>=0.2.2,<=0.2.99’.
Got Mako 0.2.5.
Getting distribution for ‘SQLAlchemy>=0.5,<=0.5.99’.
Got SQLAlchemy 0.5.8.
Getting distribution for ‘Pylons>=0.9.7,<=0.9.7.99’.
Got Pylons 0.9.7.
Getting distribution for ‘PasteDeploy’.
Got PasteDeploy 1.3.3.
Getting distribution for ‘Paste>=1.3’.
Got Paste 1.7.2.
Getting distribution for ‘WebOb>=0.9.3’.
Got WebOb 0.9.8.
Getting distribution for ‘decorator>=2.1.0’.
Got decorator 3.1.2.
Getting distribution for ‘elementtree>=1.2,<=1.3’.
Got elementtree 1.2.7-20070827-preview.
Getting distribution for ‘python-openid>=2.1.1’.
Got python-openid 2.2.4.
Getting distribution for ‘Beaker>=1.1’.
Got Beaker 1.5.1.
Getting distribution for ‘nose>=0.9.2’.
Got nose 0.11.1.
Getting distribution for ‘WebHelpers>=0.6.1,<0.6.99’.
Got WebHelpers 0.6.4.
Getting distribution for ‘Tempita>=0.2’.
Got Tempita 0.4.
Getting distribution for ‘WebTest>=1.1’.
Got WebTest 1.2.
Getting distribution for ‘WebError>=0.10.1’.
Got WebError 0.10.2.
Getting distribution for ‘simplejson>=2.0.8’.
Got simplejson 2.0.9.
Getting distribution for ‘FormEncode>=1.2.1’.
Got FormEncode 1.2.2.
Getting distribution for ‘Routes>=1.10.3’.
Got Routes 1.11.
Getting distribution for ‘Pygments’.
Got Pygments 1.2.2.
Generated script ‘/tmp/simple-site/bin/paster’.
www.sdjournal.org
19
441710214.008.png 441710214.009.png 441710214.010.png 441710214.011.png 441710214.012.png 441710214.013.png 441710214.014.png 441710214.015.png 441710214.016.png 441710214.017.png 441710214.018.png
Narzędzia
i obejrzenie rezultatu pod adresem: http://
localhost:5000 .
z systemu kontroli wersji. Wspierane proto-
koły to: Subversion, Mercurial, Git i CVS.
Deweloperska konfiguracja może instalo-
wać także inne przydatne narzędzia. Przykła-
dem może być nosetests – skrypt automa-
tycznie znajdujący i uruchamiający testy jed-
nostkowe i funkcjonalne.
Konfiguracja dla osób rozwijających apli-
kację powinna zostać umieszczona w od-
dzielnym pliku, ponieważ zawiera elementy,
które nie powinny znaleźć się w wersji osta-
tecznej. Buildout ułatwia taki podział dzię-
ki możliwości rozszerzania plików konfigu-
racyjnych. W tym celu wykorzystany jest pa-
rametr extends sekcji buildout . W plikach,
które rozszerzają w ten sposób bazowe pliki,
możliwe jest użycie operatora += , dzięki któ-
remu odziedziczona wartość parametru zo-
stanie rozszerzona, a nie nadpisana.
Wtyczki, które ingerują w znaczny spo-
sób w proces budowania aplikacji, dołączane
są poprzez parametr extensions. W omawia-
nym przykładzie mr.developer zmienia dzia-
łanie systemu buildout w ten sposób, że pacz-
ki określone w parametrze auto-checkout
zamiast być ściągnięte z repozytorium pakie-
tów zostaną zbudowane ze źródeł. W sekcji
sources określa się adresy, pod którymi znaj-
duje się kod źródłowy.
Należy przebudować aplikację, urucha-
miając skrypt buildout z opcją -c wskazują-
cą na nowy plik:
Konfiguracja deweloperska
Obecna konfiguracja pozwala na budowanie
aplikacji na podstawie najnowszych pakietów
pochodzących z repozytorium Pythona – Py-
PI. Podczas rozwijania aplikacji programista
powinien mieć możliwości pracowania na ko-
dzie jeszcze nie opublikowanym. Najczęściej
pochodzącym wprost z systemu kontroli wer-
sji. W tej sytuacji bardzo użyteczne jest roz-
szerzenie mr.developer , które ułatwia pobra-
nie i dołączenie do projektu pakietu wprost
PasteScript
Dzięki tej bibliotece możliwe jest łatwe uruchomienie skryptów Pythona wprost z linii ko-
mend. Pakiety podczas instalacji określają w pliku setup.py nazwy funkcji, wykonanie których
uruchomi skrypt, program lub zainicjalizuje komponent – jest to tak zwany entrypoint. Paste-
Script wyszukuje wszystkie dostępne skrypty i pozwala je uruchomić bez znajomości pełnej
ścieżki do pliku, w którym znajduje się kod źródłowy.
$ ./bin/buildout -c buildout-devel.cfg
WSGI
Skrót od Python Web Server Gateway Interface . Specyikacja ta określa interfejs na styku apli-
kacji internetowych napisanych w języku Python i serwerów mającymi za zadanie obsługi-
wać przychodzące żądanie HTTP. Określa także sposób współdzielenia i wymiany danych
pomiędzy elementami wchodzącymi w skład aplikacji webowej. Jako serwery dla aplikacji
WSGI najczęściej stosuje się Paster oraz Apache wraz z mod _ wsgi . Standard WSGI wspiera
zdecydowana większość aplikacji webowych napisanych w języku Python (m.in: django , Py-
lons , repoze.bfg , CherryPy , zope ).
Po zakończeniu działania możliwe jest uru-
chomienie testów dołączonych do SimpleSi-
te. Służy do tego wygenerowany skrypt:
$ ./bin/nose SimpleSite
Dodatkowym ułatwieniem oferowanym
przez mr.developer jest skrypt pozwalający na
aktualizację wszystkich pakietów źródłowych
w jednym momencie. Nie ma tu znaczenia ro-
dzaj systemu kontroli wersji odpowiedzialny
za przechowywanie zmian. Po prostu w celu
aktualizacji wszystkich pakietów źródłowych
wystarczy uruchomić skrypt:
Listing 4. Plik buildout.cfg po dodaniu SQLite
[buildout]
parts =
sqlite
pysqlite
paster
eggs =
SimpleSite
pysqlite
./bin/develop update
Inne często wykorzystywane recepty w kon-
iguracji dla programistów to:
buildout.dumppickedversions – wy-
świetla wersje zainstalowanych pakie-
tów, przydatne przy tworzeniu konigu-
racji produkcyjnej;
pb.recipes.pydev – generuje konigu-
rację dla środowiska Eclipse z rozszerze-
niem PyDev;
collective.recipe.omelette – połą-
czenie wielu pakietów w jednym drze-
wie folderów,
hexagonit.recipe.download – pobiera
i rozpakowuje pliki (np.: przykładową
bazę danych);
collective.recipe.seleniumrc – in-
stalacja Selenium RC (testy funkcjonal-
ne w przeglądarce internetowej);
collective.recipe.funkload – instala-
cja FunkLoad (testy obciążeniowe apli-
kacji WWW);
plone.recipe.command – uruchomienie
dowolnego zestawu komend linii pole-
ceń lub kodu Pythona.
[paster]
recipe = zc.recipe.egg:scripts
eggs =
PasteScript
${buildout:eggs}
[sqlite]
# kompilacja bibliotek binarnych SQLite (lekka baza danych SQL)
recipe = zc.recipe.cmmi
url = http://www.sqlite.org/sqlite-amalgamation-3.6.22.tar.gz
[pysqlite]
# kompilacja biblioteki pozwalającej na używanie
# bazy SQLite przez programy napisane w Pythonie
recipe = zc.recipe.egg:custom
egg = pysqlite
include-dirs = ${sqlite:location}/include
library-dirs = ${sqlite:location}/lib
rpath = ${sqlite:location}/lib
20
05/2010
441710214.019.png 441710214.020.png 441710214.021.png 441710214.022.png 441710214.023.png 441710214.024.png 441710214.025.png
 
Buildout
Konfiguracja produkcyjna
Projekt przystosowany do instalacji na serwe-
rze produkcyjnym także posiada inne skład-
niki. I w tym przypadku różnicę konfiguruje
się w osobnym pliku.
W celu zabezpieczenia przed niespodzie-
wanymi błędami wynikającymi z różnic mię-
dzy kolejnymi wersjami zależnych bibliotek
często po przeprowadzeniu wszystkich te-
stów na instancji testowej zapisuje się w pliku
versions.cfg wersje wszystkich użytych bi-
bliotek. Proces ten automatyzowany jest przez
rozszerzenie buildout.dumppickedversions .
Wydanie wersji stabilnej – nadającej się do
instalacji na serwerach produkcyjnych wiąże
się z opublikowaniem nowych wersji wszyst-
kich pakietów, w których były zmiany. Jeże-
li są to biblioteki OpenSource, nowe wydania
znajdą się w ogólnym repozytorium – PyPI.
Pozostałą część należy umieścić na prywat-
nym serwerze z ograniczonym dostępem.
Nie jest konieczne instalowanie specjalistycz-
nego oprogramowania – wystarczy dowolny
serwer HTTP z włączoną opcją wyświetla-
nia zawartości folderów. Link do tak przygo-
towanego zasobu należy podać w parametrze
find-links .
Aplikacje webowe zgodne ze standardem
WSGI można uruchamiać przy użyciu dowol-
nego serwera przystosowanego do tego. W wer-
sji podstawowej użyty był Paster. W wersji pro-
dukcyjnej natomiast najczęściej spotykane jest
użycie rozszerzenia mod_wsgi do serwera Apa-
che. W tym celu aplikacja musi udostępnić
plik rozpoczynający (ang. entry point ). Plik ta-
ki generowany jest przez receptę
Podczas budowania aplikacji wygenerowa-
ny zostanie plik wsgi w folderze parts/wsgiapp .
Pełną ścieżkę do tego pliku należy ustawić
w parametrze WSGIScriptAlias konfigura-
cji Apache.
Konfiguracja produkcyjna często zawiera
także dodatkowe elementy. Najbardziej przy-
datne z nich to:
plone.recipe.apache – instalacja i kon-
iguracja serwer Apache;
plone.recipe.varnish – instalacja ser-
wera cache dla aplikacji internetowych;
zest.recipe.mysql – instalacja MySQL
wraz z MySQL-python;
zc.recipe.cmmi – instalacja dodatkowe-
go oprogramowania (np.: PostgreSQL,
memcached);
collective.recipe.supervisor – kon-
trola wielu procesów;
z3c.recipe.usercrontab – ułatwia
konigurację operacji cyklicznych (cron-
tab);
iw.recipe.backup – kopie zapasowe wy-
branych plików.
Wady i zalety
Buildout nie jest systemem pozbawionym
wad. Najbardziej irytującym z nich jest po-
wolne działanie w przypadku problemów
z siecią. Pomaga wtedy opcja -t do skryptu
buildout, pozwalająca na ustawienie limi-
tu czasu odpowiedzi. W przypadku gdy nie-
osiągalne jest repozytorium PyPI, nawet pro-
ste przebudowanie aplikacji nie jest w ogóle
możliwe. W takim przypadku można użyć
opcji -N blokującej sprawdzanie, czy dostęp-
na jest nowsza wersja pakietu lub opcji -o
włączająca tryb offline.
Utrudnione jest także szukanie przyczyn
błędów budowania. Buildout niestety poka-
zuje mało przydatne informacje. Uruchomie-
nie wraz z opcją -v lub -vv zwiększa ilość ko-
munikatów pomocniczych, ale w większości
przypadków są one mało użyteczne.
Według mnie podstawową zaletą jest to, że
przy użyciu paru komend można zbudować
lub zaktualizować całą aplikację. Jest to tym
bardziej pomocne, gdy nad projektem pra-
cuje kilka osób i co pewien czas każda z nich
musi dostosować się do najnowszych zmian.
Buildout pozwala na szybkie zbudowanie
aplikacji w identycznej konfiguracji na czy-
stym serwerze. Jest to przydatne szczególnie
w sytuacjach awaryjnych.
Sądzę, że nakład pracy potrzebny na stwo-
rzenie konfiguracji Buildout zwraca się dość
szybko, a dodatkowo oszczędza się sporo stre-
su podczas uaktualnień, migracji i sytuacji
nieoczekiwanych.
Listing 5. Plik buildout-devel.cfg
[buildout]
extensions =
mr.developer
extends =
buildout.cfg
parts +=
nose
auto-checkout =
SimpleSite
[sources]
SimpleSite = hg http://bitbucket.org/meatballhat/simplesite/
[nose]
recipe = pbp.recipe.noserunner
eggs =
${paster:eggs}
working-directory = ${buildout:directory}/src
defaults = -v --nocapture --with-doctest --doctest-tests
--with-pylons=${buildout:directory}/src/SimpleSite/test.ini
Listing 6. Plik buildout-production.cfg
[buildout]
extends =
buildout.cfg
versions.cfg
parts +=
wsgiapp
versions = versions
ind-links =
http://login:passwd@dist.example.com
WOJCIECH LICHOTA
Absolwent Uniwersytetu im. A. Mickiewicza w Po-
znaniu, kierunek Informatyka Stosowana. Obec-
nie pracuje jako analityk i programista w �rmie
STX Next (http://stxnext.pl). Zawodowo zajmu-
je się aplikacjami internetowymi, począwszy od
małych portali społecznościowych, po duże roz-
wiązania dla sektora bankowego. Języka Python
oraz systemu Linux używa od 8 lat.
Kontakt z autorem: wojciech@lichota.pl
[wsgiapp]
recipe = collective.recipe.modwsgi
eggs = ${buildout:eggs}
conig-ile = ${buildout:directory}/production.ini
www.sdjournal.org
21
441710214.026.png 441710214.027.png 441710214.028.png 441710214.029.png 441710214.030.png 441710214.031.png 441710214.032.png 441710214.033.png 441710214.034.png 441710214.035.png 441710214.036.png
 
Zgłoś jeśli naruszono regulamin