<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DestaqueBlog &#187; fabric</title>
	<atom:link href="http://weblog.destaquenet.com/tag/fabric/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.destaquenet.com</link>
	<description>Blog da equipe Destaquenet.</description>
	<lastBuildDate>Tue, 23 Nov 2010 17:06:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Fabric + VirtualEnv: uma combinação explosiva (no bom sentido)</title>
		<link>http://weblog.destaquenet.com/2009/07/01/fabric-virtualenv-uma-combinacao-explosiva-no-bom-sentido/</link>
		<comments>http://weblog.destaquenet.com/2009/07/01/fabric-virtualenv-uma-combinacao-explosiva-no-bom-sentido/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 04:20:01 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[automatização]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[django-flash]]></category>
		<category><![CDATA[fabric]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[pypi]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[setuptools]]></category>
		<category><![CDATA[teste]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[virtualenv]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=554</guid>
		<description><![CDATA[Escreveu uma super-hiper-biblioteca ou aplicação em Python mas quer se certificar de que ela funciona em diferentes versões do interpretador? Embora isso possa ser resolvido através da execução manual dos testes com os vários interpretadores, isso é chato e improdutivo. &#8230; <a href="http://weblog.destaquenet.com/2009/07/01/fabric-virtualenv-uma-combinacao-explosiva-no-bom-sentido/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Escreveu uma super-hiper-biblioteca ou aplicação em <a href="http://python.org">Python</a> mas quer se certificar de que ela funciona em diferentes versões do interpretador? Embora isso possa ser resolvido através da execução <em>manual</em> dos testes com os vários interpretadores, isso é chato e improdutivo. Além do mais, cada versão do Python pode ter diferentes bibliotecas instaladas, o que pode acabar influenciando no resultado dos testes.</p>
<p>Temos portanto dois problemas a serem resolvidos. O primeiro problema, relacionado a automatização de tarefas repetitivas, pode ser facilmente solucionado com <a href="http://docs.fabfile.org/">Fabric</a>, uma ferramenta muito útil para criação de scripts de build e deployment de aplicações. Já escrevemos <a href="http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/">um texto introdutório</a> sobre a mesma, não deixe de conferir.</p>
<p>O segundo problema, entretanto, é um pouco mais complicado de se resolver, mas não é nenhum bicho de sete cabeças. Com <a href="http://pypi.python.org/pypi/virtualenv/">VirtualEnv</a>, é possível criar ambientes Python isolados com o objetivo de testar e executar aplicações em uma espécie de sandbox onde temos total controle sobre as bibliotecas ali instaladas.</p>
<p><span id="more-554"></span></p>
<h3>Instalando as diferentes versões do Python</h3>
<p>O primeiro passo é instalar as versões do Python a serem usadas nos testes. Rode o comando abaixo para instalar os diferentes interpretadores, supondo que você utilize <a href="http://www.debian.org/">Debian</a> e sua aplicação precise funcionar nas versões 2.4, 2.5 e 2.6 do Python:</p>
<pre>$ sudo apt-get install python2.4 python2.4-dev \
    python2.5 python2.5-dev \
    python2.6 python2.6-dev</pre>
<p>A versão atual do Ubuntu já inclui o Python 2.6 por padrão. Veja também que aproveitamos para instalar os arquivos de desenvolvimento para cada versão, pois eventualmente precisamos deles para compilar bibliotecas com extensões escritas em C.</p>
<h3>Instalando Fabric e VirtualEnv</h3>
<p>Da mesma forma:</p>
<pre>$ sudo apt-get install python-setuptools</pre>
<p>Após a instalação do <a href="http://pypi.python.org/pypi/setuptools/">SetupTools</a>, execute o seguinte comando para instalar o Fabric e o VirtualEnv:</p>
<pre>$ sudo easy_install Fabric virtualenv</pre>
<h3>Configurando ambientes isolados para sua aplicação</h3>
<p>O próximo passo é criar ambientes de execução isolados para sua aplicação, sendo que cada ambiente deve usar uma versão diferente do interpretador do Python. Para fazer isso, execute os comandos abaixo, substituindo o <code>APP</code> pelo nome da sua aplicação ou biblioteca:</p>
<pre>$ mkdir ~/.virtualenvs
$ cd ~/.virtualenvs
$ virtualenv --python=/usr/bin/python2.6 --no-site-packages APP-py2.6
$ virtualenv --python=/usr/bin/python2.5 --no-site-packages APP-py2.5
$ virtualenv --python=/usr/bin/python2.4 --no-site-packages APP-py2.4</pre>
<p>Primeiramente criamos o diretório <code>~/.virtualenvs</code>, que é por convenção o diretório padrão para armazenamento dos ambientes. Em seguida, criamos três ambientes para nossa aplicação <code>APP</code>. A flag <code>--no-site-packages</code> é <em>opcional</em> e indica que as bibliotecas instaladas no diretório <code>site-packages</code> do Python em questão não devem ser visíveis ao ambiente sendo criado.</p>
<p>Finalmente, não esqueça de instalar, em cada um dos ambientes, as dependências exigidas pela sua aplicação:</p>
<pre>$ source ~/.virtualenvs/APP-py2.6/bin/activate
(APP-py2.6) $ easy_install biblioteca1 biblioteca2 ... bibliotecaN
(APP-py2.6) $ source ~/.virtualenvs/APP-py2.5/bin/activate
(APP-py2.5) $ easy_install biblioteca1 biblioteca2 ... bibliotecaN
(APP-py2.5) $ source ~/.virtualenvs/APP-py2.4/bin/activate
(APP-py2.4) $ easy_install biblioteca1 biblioteca2 ... bibliotecaN</pre>
<p>Supondo que sua aplicação utilize o SetupTools para a configuração dos metadados do projeto (através do script <code>setup.py</code>), os comandos abaixo devem indicar se a aplicação funciona nos ambientes que criamos:</p>
<pre>$ source ~/.virtualenvs/APP-py2.6/bin/activate
(APP-py2.6) $ python setup.py test
...
(APP-py2.6) $ source ~/.virtualenvs/APP-py2.5/bin/activate
(APP-py2.5) $ python setup.py test
...
(APP-py2.5) $ source ~/.virtualenvs/APP-py2.4/bin/activate
(APP-py2.4) $ python setup.py test
...</pre>
<h3>Automatizando!</h3>
<p>Se tudo funcionou até aqui, estamos prontos para criar um script que nos permita rodar os testes de forma automática, nos diferentes ambientes.</p>
<p>Supondo que sua aplicação utilize o SetupTools para a configuração dos metadados do projeto, o exemplo abaixo resolve o problema:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Environment info</span>
config.<span style="color: black;">project</span> = <span style="color: #483d8b;">'APP'</span>
config.<span style="color: black;">virtualenv_dir</span> = <span style="color: #483d8b;">'~/.virtualenvs'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Supported Python versions</span>
config.<span style="color: black;">versions</span> = <span style="color: black;">&#40;</span><span style="color: #483d8b;">'2.4'</span>, <span style="color: #483d8b;">'2.5'</span>, <span style="color: #483d8b;">'2.6'</span>,<span style="color: black;">&#41;</span>
config.<span style="color: black;">default_version</span> = <span style="color: #483d8b;">'2.6'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> setup<span style="color: black;">&#40;</span>command, version=config.<span style="color: black;">default_version</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Executes the given setup command with a virtual Python installation.
    &quot;&quot;&quot;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s/%s-py%s/bin/python setup.py %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>config.<span style="color: black;">virtualenv_dir</span>, config.<span style="color: black;">project</span>, version, command<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #dc143c;">test</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Runs all tests in different Python versions.
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> version <span style="color: #ff7700;font-weight:bold;">in</span> config.<span style="color: black;">versions</span>:
        setup<span style="color: black;">&#40;</span><span style="color: #483d8b;">'test'</span>, version<span style="color: black;">&#41;</span></pre></div></div>

<p>Agora é só alegria:</p>
<pre>$ fab test
Fabric v. 0.1.1.
Running test...
[localhost] run: ~/.virtualenvs/APP-py2.4/bin/python setup.py test
...
[localhost] run: ~/.virtualenvs/APP-py2.5/bin/python setup.py test
...
[localhost] run: ~/.virtualenvs/APP-py2.6/bin/python setup.py test
...</pre>
<p>Devo lembrar que o script mostrado é só um exemplo. Você pode (e <strong>deve</strong>) modificá-lo para que este atenda às suas necessidades.</p>
<h3>(Bônus!) Distribuindo sua aplicação para diferentes versões do Python</h3>
<p>Com mais algumas linhas de código, podemos criar tasks que nos permitam gerar arquivos para distribuição da aplicação para diferentes versões do Python:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> dist_src<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Create source archive.
    &quot;&quot;&quot;</span>
    setup<span style="color: black;">&#40;</span><span style="color: #483d8b;">'sdist'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> dist_eggs<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Create binary archives, one for each Python version.
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> version <span style="color: #ff7700;font-weight:bold;">in</span> config.<span style="color: black;">versions</span>:
        setup<span style="color: black;">&#40;</span><span style="color: #483d8b;">'bdist_egg'</span>, version<span style="color: black;">&#41;</span></pre></div></div>

<h3>(Bônus!) Automatizando geração de documentação e upload para o PyPI</h3>
<p>Ainda acha pouco? <a href="http://github.com/danielfm/django-flash/blob/master/fabfile.py">Este outro exemplo</a> de script vai além e mostra, numa aplicação real, como automatizar o registro e upload dos pacotes para o <a href="http://pypi.python.org/pypi/">PyPI</a>, atualizar site de documentação, entre outras coisas.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/07/01/fabric-virtualenv-uma-combinacao-explosiva-no-bom-sentido/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deployment de aplicações Python com Fabric</title>
		<link>http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/</link>
		<comments>http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 10:00:05 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[fabric]]></category>
		<category><![CDATA[ferramenta]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=101</guid>
		<description><![CDATA[Uma coisa é fato: subir uma nova versão de uma aplicação é um procedimento que, se feito manualmente, costuma demandar tempo precioso, independente do tamanho da aplicação e dos frameworks utilizados no projeto. Não há o que discutir. Na verdade, &#8230; <a href="http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Uma coisa é fato: subir uma nova versão de uma aplicação é um procedimento que, se feito manualmente, costuma demandar tempo precioso, independente do tamanho da aplicação e dos <em>frameworks</em> utilizados no projeto. Não há o que discutir.</p>
<p>Na verdade, ninguém parecia se importar em automatizar tarefas &#8220;mecânicas&#8221; como o <em>deployment</em>, coisa que mudou de figura ao passo que <a href="http://en.wikipedia.org/wiki/Agile_software_development">metodologias ágeis</a> &#8212; juntamente com técnicas como <a href="http://martinfowler.com/articles/continuousIntegration.html">Integração Contínua</a> &#8212; passaram a se tornar populares. Desde então, algum esforço vem sendo investido para criar ferramentas para automatização de muitas dessas tarefas.</p>
<p><strong>Atualização:</strong> Trechos de código adaptados para as versões mais recentes do Fabric (22/06/2010).</p>
<p><span id="more-101"></span></p>
<h3>Fabric: ferramenta Python para deployment</h3>
<p>Apesar de já ter utilizado algumas dessas <a href="http://maven.apache.org/">ferramentas</a> no desenvolvimento de projetos em <a href="http://java.sun.com/">Java</a>, plataforma na qual eu possuo uma experiência maior, eu ainda não conhecia nenhuma ferramenta em <a href="http://python.org/">Python</a> que me permitisse automatizar o <em>deployment</em> de uma aplicação.</p>
<p>Como eu estava começando a ficar de saco cheio de ter que atualizar os arquivos de uma aplicação <a href="http://djangoproject.org/">Django</a> via SCP, eu resolvi que já era hora de ir atrás de alguma ferramenta que me ajudasse a automatizar esse processo. Finalmente, depois de muita procura, eu encontrei <a href="http://www.nongnu.org/fab/index.html">Fabric</a>, uma ferramenta mais ou menos parecida com um <a href="http://www.capify.org/">Capistrano</a> &#8220;capado&#8221;.</p>
<p>A instalação do Fabric é bem simples para quem costuma usar o <a href="http://peak.telecommunity.com/DevCenter/EasyInstall">easy_install</a>:</p>
<pre>$ sudo easy_install Fabric</pre>
<p>Basta executar esse comando para que os fontes da última versão do Fabric (0.0.9 no momento da publicação deste texto) sejam baixados e instalados.</p>
<p><strong>Atenção</strong>: Quem utiliza máquinas Windows, provavelmente precisará do <a href="http://www.cygwin.com/">Cygwin</a>, já que o Fabric assume o uso de ambientes Unix.</p>
<h3>Fabric a 3.000 pés</h3>
<p>Neste momento você já deve conseguir executar o comando <code>fab</code> no terminal. Se tudo correu bem até aqui, estamos prontos continuar.</p>
<p>Vamos começar criando o arquivo <code>fabfile.py</code> no diretório-raíz da aplicação. Coloque o seguinte conteúdo neste arquivo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> fabric.<span style="color: black;">api</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
env.<span style="color: black;">project</span> = <span style="color: #483d8b;">'project_name'</span>,
env.<span style="color: black;">package</span> = <span style="color: #483d8b;">'$(project).zip'</span>,
&nbsp;
<span style="color: #808080; font-style: italic;"># Remote servers</span>
env.<span style="color: #dc143c;">user</span>  = <span style="color: #483d8b;">'usuario_ssh'</span>,
env.<span style="color: black;">hosts</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'servidor1.com'</span>, <span style="color: #483d8b;">'servidor2.com'</span><span style="color: black;">&#93;</span>,
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> deploy<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Deploys the application to the production servers.&quot;</span>
    build<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> build<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Builds the application.&quot;</span>
    prepare<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> prepare<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Prepares the build directory.&quot;</span>
    clean<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> clean<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Removes the build directory.&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

<p>Cada método definido no arquivo é equivalente a uma <em>task</em> do Capistrano. No início temos as variáveis <code>env.*</code> necessárias para o <em>script</em>. Destaque para a variável <code>env.hosts</code>, que indica os servidores nos quais os comandos remotos devem ser executados.</p>
<p>Ok, tente executar o comando <code>fab -l</code> no terminal, no mesmo diretório onde se encontra o arquivo <code>fabfile.py</code>. Se tudo correr bem, você receberá a seguinte saída:</p>
<pre>
$  fab -l
Available commands:
   build      Build the application.
   clean      Remove the build directory.
   deploy     Deploy the application to the production servers.
   help       Display Fabric usage help, or help for a given command.
   license    Display the Fabric distribution license text.
   list       Display a list of commands with descriptions.
   prepare    Prepare the build directory.
   set        Set a Fabric variable.
   shell      Start an interactive shell connection to the specified hosts.
   warranty   Display warranty information for the Fabric software.
</pre>
<p>Veja que as <em>tasks</em> que criamos estão disponíveis para serem executadas via linha de comando. Para executar as <em>tasks</em> <code>clean</code> e <code>deploy</code>, por exemplo, utilizaríamos o seguinte comando:</p>
<pre>$  fab clean deploy</pre>
<p>Simples, não é? Antes de vermos um exemplo de script completo, vamos conhecer os três principais métodos utilizados em <em>scripts</em> Fabric: <code>local</code>, <code>run</code> e <code>put</code>:</p>
<ul>
<li><code>local</code>: Serve para executar comandos na máquina local. Ex: <code>local('mkdir build')</code>;</li>
<li><code>run</code>: Igual ao <code>local</code>, mas executa os comandos nas máquinas remotas (indicadas na variável <code>env.hosts</code>);</li>
<li><code>put</code>: Envia um arquivo para as máquinas remotas. Ex: <code>put('arquivo.zip', '/home/user/app.zip')</code>.</li>
</ul>
<h3>Finalmente, o script completo!</h3>
<p>Antes de mostrar o <em>script</em> que eu venho utilizando para fazer o deployment <a href="http://www.destaquenet.com/">de uma aplicação</a> Django, veja como seus arquivos e diretórios estão organizados: (isso deve ajudar a entender melhor o <em>script</em>)</p>
<div id="attachment_131" class="wp-caption aligncenter" style="width: 214px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/destaqueweb_structure.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/destaqueweb_structure-204x300.png" alt="Estrutura do projeto" title="Estrutura do projeto" width="204" height="300" class="size-medium wp-image-131" /></a><p class="wp-caption-text">Estrutura do projeto</p></div>
<p>E, finalmente, o <em>script</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;Build script.
&quot;&quot;&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> fabric.<span style="color: black;">api</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
&nbsp;
env.<span style="color: black;">project</span> = <span style="color: #483d8b;">'destaqueweb'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Build output directory</span>
env.<span style="color: black;">build_path</span> = <span style="color: #483d8b;">'build'</span>
env.<span style="color: black;">package</span>    = <span style="color: #483d8b;">'%s.zip'</span> <span style="color: #66cc66;">%</span> env.<span style="color: black;">project</span>
env.<span style="color: black;">local_path</span> = <span style="color: #483d8b;">'%s/%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">build_path</span>, env.<span style="color: black;">package</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Media</span>
env.<span style="color: black;">media_src</span>   = <span style="color: #483d8b;">'media'</span>
env.<span style="color: black;">media_root</span>  = <span style="color: #483d8b;">'public_html'</span>
env.<span style="color: black;">media_path</span>  = <span style="color: #483d8b;">'%s/%s/%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">media_root</span>, env.<span style="color: black;">project</span>, env.<span style="color: black;">media_src</span><span style="color: black;">&#41;</span>
env.<span style="color: black;">media_build</span> = <span style="color: #483d8b;">'%s/%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">build_path</span>, env.<span style="color: black;">media_path</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Application code</span>
env.<span style="color: black;">app_root</span>  = <span style="color: #483d8b;">'wsgi_apps'</span>
env.<span style="color: black;">app_path</span>  = <span style="color: #483d8b;">'%s/%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">app_root</span>, env.<span style="color: black;">project</span><span style="color: black;">&#41;</span>
env.<span style="color: black;">app_build</span> = <span style="color: #483d8b;">'%s/%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">build_path</span>, env.<span style="color: black;">app_path</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Remote servers</span>
env.<span style="color: black;">hosts</span>       = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'destaquenet.com'</span><span style="color: black;">&#93;</span>
env.<span style="color: black;">destination</span> = <span style="color: #483d8b;">'/home/destaquenet'</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> clean<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Removes the build directory.
    &quot;&quot;&quot;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'rm -fR %s'</span> <span style="color: #66cc66;">%</span> env.<span style="color: black;">build_path</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> prepare<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Prepares the build directory.
    &quot;&quot;&quot;</span>
    clean<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'mkdir -p %s'</span> <span style="color: #66cc66;">%</span> env.<span style="color: black;">media_build</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'mkdir -p %s'</span> <span style="color: #66cc66;">%</span> env.<span style="color: black;">app_build</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> build<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Builds the application.
    &quot;&quot;&quot;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cp -R %s/* %s/%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">project</span>, env.<span style="color: black;">build_path</span>, env.<span style="color: black;">app_path</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cp -R %s/* %s/%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">media_src</span>, env.<span style="color: black;">build_path</span>, env.<span style="color: black;">media_path</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'find %s -name *.pyc -delete'</span> <span style="color: #66cc66;">%</span> env.<span style="color: black;">build_path</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'find %s -path *upload* -delete'</span> <span style="color: #66cc66;">%</span> env.<span style="color: black;">build_path</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'find %s -path *fixtures* -delete'</span> <span style="color: #66cc66;">%</span> env.<span style="color: black;">build_path</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cd %s;zip -r %s %s %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">build_path</span>, env.<span style="color: black;">package</span>, env.<span style="color: black;">media_root</span>, env.<span style="color: black;">app_root</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> reload_app<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Reloads the app.
    &quot;&quot;&quot;</span>
    run<span style="color: black;">&#40;</span><span style="color: #483d8b;">'touch %s/%s/%s/index.wsgi'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">destination</span>, env.<span style="color: black;">media_root</span>, env.<span style="color: black;">project</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    run<span style="color: black;">&#40;</span><span style="color: #483d8b;">'python %s/%s/manage.py ping_google /sitemap.xml'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">destination</span>, env.<span style="color: black;">app_path</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> deploy<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Deploys the application to the production server.
    &quot;&quot;&quot;</span>
    build<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    put<span style="color: black;">&#40;</span>env.<span style="color: black;">local_path</span>, env.<span style="color: black;">destination</span><span style="color: black;">&#41;</span>
    run<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cd %s; unzip -uo %s; rm %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>env.<span style="color: black;">destination</span>, env.<span style="color: black;">package</span>, env.<span style="color: black;">package</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    reload_app<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Este código deve ser facilmente entendido por quem tem trabalha com uma certa facilidade no terminal.</p>
<p>Basicamente o que o código faz é organizar os arquivos da aplicação para que estes fiquem dispostos da mesma forma utilizada pelo servidor de produção, enviar os arquivos dentro de um pacote ZIP para os servidores e descompactá-los no local correto, além de executar um <code>touch</code> no <em>script</em> <acronym title="Web Server Gateway Interface">WSGI</acronym> para que o <a href="http://apache.org/">Apache</a> recarregue a aplicação.</p>
<p>Tudo pronto. Agora basta executar <code>fab deploy</code> no terminal para subir a aplicação para o(s) servidor(es) desejado(s).</p>
<h3>Fabric e ambiente de homologação</h3>
<p>Uma coisa que vem se tornando comum é o uso de diferentes ambientes onde uma aplicação costuma ser implantada (ex: ambiente de homologação). Se sua empresa costuma trabalhar dessa forma, o Fabric ainda pode te ajudar.</p>
<p>Por exemplo, vamos supor que sua empresa possua um servidor de produção e um servidor de homologação. Podemos, então, adequar o <em>script</em> para que ele possa trabalhar com ambos os ambientes:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># ...</span>
env.<span style="color: #dc143c;">user</span>  = <span style="color: #483d8b;">'production'</span>,
env.<span style="color: black;">hosts</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'app.com'</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> staging<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># deploy to staging servers</span>
    env.<span style="color: #dc143c;">user</span>  = <span style="color: #483d8b;">'staging'</span>
    env.<span style="color: black;">hosts</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'staging.app.com'</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># other tasks...</span></pre></div></div>

<p>Fazendo as mudanças mostradas acima, para executar o <em>deployment</em> no ambiente de homologação basta rodar o comando <code>fab staging deploy</code>; o deployment em ambiente de produção continua disponível através do comando <code>fab deploy</code>.</p>
<p>Isso é possível pois podemos substituir o valor de uma variável (ou configurar novas variáveis) a qualquer momento. Então, quando executamos o comando <code>fab staging deploy</code>, o Fabric executa a <em>task</em> <code>staging</code>, substituindo o valor das variáveis <code>env.user</code> e <code>env.hosts</code>, fazendo com que os comandos contidos na <em>task</em> <code>deploy</code> sejam executados nos servidores de homologação em vez de nos servidores de produção.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

