Table Of Contents

Previous topic

Jumbo’s documentation!

Next topic

<no title>

This Page

Installazione con buildout

Scopo del setup illustrato qui di seguito è:

  • Creare un workflow in cui il setup di un sito sia fulmineo, almeno per quanto riguarda il lavoro umano...
  • Creare una setup isolato e riproducibile. Le librerie utilizzate devono essere sotto stretto controllodel programmatore
  • Deve essere possibile derogare se necessario (ad esempio non vogliamo ricompilare il modulo ‘uno’)

Possibili alternative

le alternative possibili sono

  1. virtualenv
  2. buildout (ricca documentazione su pypi)

Mentre virtualenv risulta particolarmente efficace per l’isolamento, buildout risulta più pratico per la confiugurabilità. Noi useremo buildout e costruiremo dentro un virtualenv in modo automatico. Entrambi richiedono di compilare alcuni pacchetti quindi devono essere installati anche alcuni pacchetti dev.

Buildout in pratica

L’installazione di jumbo e dei siti che lo usano viene fatta usando buildout nel seguente modo:

hg clone http://hg.thundersystems.it/siti/www.cybergun.it
cd www.cybergun.it
python bootstrap.py -t
bin/buildout
bin/django runserver

Note

Nota: l’opzione -t è necessaria solo per Ubuntu 11.10 e seleziona l’ultima versione di zc.buildout che è quella modificata da me per risolvere il problema del non funzionamento con Ubuntu 11.10 per via del fatto che la versione di python contiene il +: 2.7.2+.

Note

Al momento è necessario creare a mano alcuni link simbolici per avere accesso ai file statici (js, css, html), vedi istruzioni.

Configurazioni una tantum

Questo semplice sistema prevede che siano state prese alcune precauzioni una volta nel sistema (non per ogni pacchetto/sito) e che sia stato personalizzato il sistema opportunamente. Il modo facile è installando il pacchetto thunder-buildout dai repositori argo ma raccomando di leggere anche l’installazione manuale dove spiego i vari componenti.

installazione tramite pacchetto deb

Aggiungere la sorgente argodef:

echo deb http://apt.argolinux.org squeeze main >> /etc/apt/sources.list
apt-get update
apt-get install thunder-buildout

Attenzione che il pacchetto installa una situazione funzionante comprensiva delle seguenti configurazioni:

  • configurazione in /root/.buildout (leggi in seguito)
  • configurazione in /home/www (leggi sotto)
  • fornisce i comandi jmb-start, dj, py, ipy e jmb-test-setup

installazione manuale

  1. Occorre disabilitare -se esiste- il sistema buildout perché confligge con quello che verrà scaricato in automatico:

    apt-get remove python-zc.buildout

    per potere compilare suggeriscodi installare:

    python-dev, libpq-dev,  postgresql-server-dev-8.4 | postgresql-dev ,
    libxslt1-dev, libsasl2-dev, libjpeg62 | libjpeg8,
    libjpeg8-dev | libjpeg62-dev, libfreetype6,
    libfreetype6-dev, zlib1g-dev, python-uno, mercurial, libldap2-dev
    

    in particolare:

    libsasl2-dev:serve per compilare ldap, richiesto da django-ldap-groups e fornisce sasl.h
    libxslt1-dev:è necessario per compilare lxml
    libpq-dev:è necessario per compilare psycopg2
    libjpeg62 | libjpeg8:
     per PIL con render jpg
  2. Occorre configurare una cache locale ed il puntatore ai repository:

    ~ $ cat ~/.buildout/default.cfg
    
    [buildout]
    eggs-directory = /home/tuonome/.buildout/eggs
    download-cache = /home/tuonome/.buildout/download-cache
    
    [thunder]
    jmb = /usr/local/src/jumbo-new
    jmb2 = /usr/local/src/hg/thunder/jmb2
    dj = /usr/local/src/hg/thunder/django
    # jmb = http://read:letmeread@hg.thundersystems.it/jumbo-new/
    # jmb2 = http://read:letmeread@hg.thundersystems.it/jumbo2/
    # dj = http://read:letmeread@hg.thundersystems.it/django/
    extra-paths = /home/local/.buildout/extra-path
  3. Crea una cartella con dei link a librerie che vuoi vengano viste dal sistema isolato ma che non vuoi dovere compilare in buildout. Useremo questa princialmente per evitare di ricompilare la libreria uno di OpenOffice:

    mkdir ~/.buildout/extra-path
    cd  ~/.buildout/extra-path
    ln -s /usr/lib/python2.6/dist-packages/uno.py
    ln -s /usr/lib/python2.6/dist-packages/unohelper.py

Nota che buildout NON espande correttamente ~ che va quindi scritta in esplicito. La cartella della cache e quella delle egg non sono indispensabili ma accelerano immensamente il deploy.

La sezione [thunder] imposta invece la posizione dei repository. Conviene farli puntare alla copia locale invece che a quella remota per ovvii vantaggi di velocità.

Struttura cartelle

Il comandi riportati sopra (file:python boostrap.py e file:bin/buildout) creano una struttura come la seguente:

.
|-- bin
|    `--python         << eseguibile "isolato"
|-- develop-eggs       << egg-link ai sorgenti
|-- parts
|   |-- buildout
|   `-- vpython        << virtual evironment
`-- .src
    |-- django-south    <<  codice sorgente (hg clone ...)
    |-- jumbo-core

mentre altre eggs saranno depositate nella cartella indicata nella configurazionedi default ~/.buildout/default.cfg.

Sotto .src troviamo tutti i sorgenti di cui è stato fatto il checkout. È possibile ed è lasciata libertà (dalla ricetta, non da me) di scegliere se sostituirlo con un link simbolico.

buildout.cfg

buildout usa “ricette” ed “estensioni” per implementare le cose che vogliamo fare. le ricette che ho scelto puntano a:

creare un ambiente isolato:
 questo è compito di tl.buildout_virtual_python, il compito è quello di fare in modo che il nostro ambiente non “veda” nessuna libreria di sistema in modo da essere sicuri che le librerie dichiarate in setup.py e in buildout.cfg siano le uniche necessarie.
creare ambiente per django:
 

questo è compito di djangorecipe: crea un binario chiamato django che è l’equivalente di manage.py ma che ha già impostato il path nel modo corretto: ogni volta che avremmo suato ./manage.py suiamo questo in alternativa per avere un manage.py che opera sullo stesso ambiente virtuale. Ad esempio:

bin/django test
bin/django runserver
bin/django shell

djangorecipe crea anche una configurazione per wsgi che però è incompatibile con il virtualenv, vedi dj

usare i nostri sorgenti:
 

questo è compito di mr.developer. Buildout può lavorare in modo eggs o develop. In sostanza per ogni libreria dichiarata in ${vpython:eggs} verrà creata una voce di sys.path che punta ad una cartella egg.

La ricetta che ho creato jmb.extensions.links invece serve per creare nella cartella site-packages i link simbolici ai pacchetti nella forma di eggs.

Suggerisco di creare la configuraione iniziale con jmb-start, ma riporto un esempio di buildout.cfg che non è completo:

[buildout]
extends = thunder-buildout.cfg
develop = .                  # dichiariamo la cartella corrente
                             # come cartella in sviluppo

parts = req django ipython
extensions = mr.developer
auto-checkout = *
sources-dir = .src

[vpython]                     # creiamo un ambiente isolato analogo
                              # a quello creato da virtualenv

recipe = tl.buildout_virtual_python
eggs = tl.buildout_virtual_python
       cybergun
       jumbo-core
       jumbo-contacts
       jumbo-ecommerce

extra-paths = ${thunder:extra-paths}
site-packages = false          # come --no-site-packages di virtualenv


[req]
recipe = zc.recipe.egg
python = vpython             # forza l'uso dell'ambiente virtuale
eggs = babel
interpreter = py

[sources]
# le sorgenti elencate qui sono automaticamnete messe
# nelle develop-egg quindi disponibili senza bisogno di aggiungerle nelle egg
jumbo-core      = hg ${thunder:jn}/jumbo-core
jumbo-contacts  = hg ${thunder:jn}/jumbo-contacts

[django]
recipe = djangorecipe
settings = settings
eggs = django==1.2.7
python = vpython
project = cybergun

[ipython]
recipe = zc.recipe.egg
python = vpython
eggs =  ipython

setup.py

tutto il sistema di packaging di python si basa sulla configurazione contenuta in setup.py in particolare nella direttive:

name:

nome del pacchetto (es.: jumbo-core)

install_required:
 

dipendenze esplicite del pacchetto:

['setuptools', 'xlwt', 'xlrd', 'django <= 1.2.7']
packages:

pacchetti messi a disposizione (es.: [‘admin_tools’, ‘jumbo’, ...]) nella maggior parte dei casi va bene il default scritto nel template usato da jmb-start:

packages=find_packages(exclude=['tests', 'tests.*'])
version:

è la versione di un pacchetto, indispensabile per potere fissare le rel che veramente funzionano

package_data:

sono i file che devono essere inclusi nel pacchetto anche se non sono moduli python: file css, js, html, png e txt. Oltre che qui vanno segnalati anche in MANIFEST.in. Il progetto di default mostra lesempio di come fare questo. Nel setup.py di default è inclusa la funzione get_data_files per facilitare l’inclusione degli stessi.

Una esauriente introduzione al setup può essere letta qui

jmb-start

Per rendere più facile ed immediato partire con un nuovo progetto, ed in attesa di creare un vero sistema di templating, ho creato una semplice script che prende un mini-template per un progetto ed inserisce già la configurazione per buildout.cfg, setup.py, MANIFEST.in ed una intera struttura:

jmb-start nome-progetto

o alternativamente:

jmb-start nome-progetto python_app

es:

jmb-start jumbo-timereport timereport

Volendo aggiungere la struttura buildout ad un progetto esistente è possibile usare l’opzione -e:

jmb-start -e jumbo-timereport timereport

È importante scrivere le dipendenze per ogni project/application direttamente nel setup.py come scritto sopra piuttosto che nel file buildout.cfg così che vengano correttamente ereditate da ogni altro progetto che dichiari questo come dipendenza. Le dipendenze espresse in buildout.cfg devono servire o per integrare pacchetti di terze parti non ben configurate (es.: manca dipendenza da PIL in sorl-thunmbnail) o per imporre una determinata versione, nel qual caso occorre usare la sezione [versions] (attenzione al case):

[versions]
Django == 1.2.7
south  = 0.7.3

jmb-start copia anche una versione di .hgignore, ed un testsettings.py che viene usato come default, sta a voi correggere a mano.

dj

il comando di gran lunga più utilizzato sarà bin/django che è l’equivalente di manage.py. Con lo script dj sarà possibile chiamarlo anche da sottocartelle del progetto nel modo corretto. Senza argomenti è equivalente a bin/django shell. leggere dj -h per ulteriori scorciatoie.

py

analogamente a dj, py chiama bin/py in ogni sotto cartella

ipy

analogamente a dj, ipy chiama bin/py in ogni sotto cartella

jmb-test-setup

Questa script permette di testare una aspetto della configurazione che può failmente sfuggire: che siano inclusi nella distribuzione i file di dati, ovvero quelli che non sono moduli python: css, html, png, js, txt. Crea una distribuzione binaria e controlla quali file vengono effettivamente inclusi. I file inclusi sono controllati da MANIFEST.in e dalla apposita funzione get_data_files in setup.py.

Le opzioni -m e -b permettono di creare la distro binaria e sorgente e di metterla nella cache di buildout (vedi help).

wsgi

djangorecipe crea una configurazione di wsgi che è incompatibile con il virtualenv. La motivazione è che il modulo indicato nella configurazione di apache, viene importato da una istanza di python che non è isolata, mentre il meccanismo necessario per rendere disponibili i pacchetti del porgetto (le eggs) e basato sull’uso dei file .pth che risiedono solo in alcune cartelle definite in fase di compilazione. È possibile aggiungere altre cartelle con il comando site.addsitedir(). Per ottenere una situazione funzionante è quindi necessario al momento aggiungere nel file django.wsgi:

import site
site.addsitedir(${buildout:directory} + \
                '/parts/vpython/lib/python2.6/site-packages')

Avendo cura di sostituire opportunamente ${buildout:directory}...

Documentazione

La documentazione sta in docs. Nella configurazione standard viene automaticamente creata bin/docs una script che genera la documentazione e rigenera docs/Makefile in modo che punti ai file corretti con l’abiemte corretto. Può essere chiamato semplicemente con:

dj docs

Per le application occorre dichiarare come settings: testsettings nella sezione [django]

Test

i test per le application stanno in nome_application/tests/__init__.py e possono essere lanciati con:

dj t

equivalente a python manage.py test.